@schukai/monster 4.38.3 → 4.38.4
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.
- package/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/source/components/datatable/filter.mjs +1342 -1321
- package/source/components/form/select.mjs +2854 -2853
- package/source/i18n/translations.mjs +215 -205
- package/source/types/version.mjs +1 -1
- package/test/cases/monster.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +21 -11
@@ -14,18 +14,18 @@
|
|
14
14
|
|
15
15
|
import { instanceSymbol } from "../../constants.mjs";
|
16
16
|
import {
|
17
|
-
|
18
|
-
|
17
|
+
findTargetElementFromEvent,
|
18
|
+
fireCustomEvent,
|
19
19
|
} from "../../dom/events.mjs";
|
20
20
|
import {
|
21
|
-
|
22
|
-
|
21
|
+
findElementWithIdUpwards,
|
22
|
+
findElementWithSelectorUpwards,
|
23
23
|
} from "../../dom/util.mjs";
|
24
24
|
import {
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
assembleMethodSymbol,
|
26
|
+
CustomElement,
|
27
|
+
getSlottedElements,
|
28
|
+
registerCustomElement,
|
29
29
|
} from "../../dom/customelement.mjs";
|
30
30
|
import { ID } from "../../types/id.mjs";
|
31
31
|
import { Settings } from "./filter/settings.mjs";
|
@@ -33,11 +33,11 @@ import { FilterStyleSheet } from "./stylesheet/filter.mjs";
|
|
33
33
|
import { getDocument, getWindow } from "../../dom/util.mjs";
|
34
34
|
import { getGlobal } from "../../types/global.mjs";
|
35
35
|
import {
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
36
|
+
isInstance,
|
37
|
+
isFunction,
|
38
|
+
isObject,
|
39
|
+
isArray,
|
40
|
+
isString,
|
41
41
|
} from "../../types/is.mjs";
|
42
42
|
import { Host } from "../host/host.mjs";
|
43
43
|
import { addAttributeToken } from "../../dom/attributes.mjs";
|
@@ -47,17 +47,17 @@ import { Formatter } from "../../text/formatter.mjs";
|
|
47
47
|
import { generateRangeComparisonExpression } from "../../text/util.mjs";
|
48
48
|
|
49
49
|
import {
|
50
|
-
|
51
|
-
|
50
|
+
parseBracketedKeyValueHash,
|
51
|
+
createBracketedKeyValueHash,
|
52
52
|
} from "../../text/bracketed-key-value-hash.mjs";
|
53
53
|
import { ThemeStyleSheet } from "../stylesheet/theme.mjs";
|
54
54
|
import { SpaceStyleSheet } from "../stylesheet/space.mjs";
|
55
55
|
import { FormStyleSheet } from "../stylesheet/form.mjs";
|
56
56
|
|
57
57
|
import {
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
getStoredFilterConfigKey,
|
59
|
+
getFilterConfigKey,
|
60
|
+
parseDateInput,
|
61
61
|
} from "./filter/util.mjs";
|
62
62
|
|
63
63
|
import "./filter/select.mjs";
|
@@ -110,7 +110,7 @@ const filterControlElementSymbol = Symbol("filterControlElement");
|
|
110
110
|
* @type {symbol}
|
111
111
|
*/
|
112
112
|
const filterSaveActionButtonElementSymbol = Symbol(
|
113
|
-
|
113
|
+
"filterSaveActionButtonElement",
|
114
114
|
);
|
115
115
|
|
116
116
|
/**
|
@@ -170,241 +170,241 @@ const hashChangeSymbol = Symbol("hashChange");
|
|
170
170
|
* @summary The Filter component is used to show and handle the filter values.
|
171
171
|
*/
|
172
172
|
class Filter extends CustomElement {
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
173
|
+
/**
|
174
|
+
*
|
175
|
+
*/
|
176
|
+
constructor() {
|
177
|
+
super();
|
178
|
+
this[settingsSymbol] = new Settings();
|
179
|
+
|
180
|
+
// debounce the hash change event if doSearch is called by click the search button
|
181
|
+
this[hashChangeSymbol] = 0;
|
182
|
+
}
|
183
|
+
|
184
|
+
/**
|
185
|
+
* This method is called by the `instanceof` operator.
|
186
|
+
* @return {symbol}
|
187
|
+
*/
|
188
|
+
static get [instanceSymbol]() {
|
189
|
+
return Symbol.for("@schukai/monster/components/filter@@instance");
|
190
|
+
}
|
191
|
+
|
192
|
+
/**
|
193
|
+
*
|
194
|
+
* @param {string} message
|
195
|
+
* @return {Filter}
|
196
|
+
*/
|
197
|
+
showFailureMessage(message) {
|
198
|
+
this[searchButtonElementSymbol].setState(
|
199
|
+
"failed",
|
200
|
+
this.getOption("timeouts.message", 4000),
|
201
|
+
);
|
202
|
+
this[searchButtonElementSymbol]
|
203
|
+
.setMessage(message.toString())
|
204
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
205
|
+
return this;
|
206
|
+
}
|
207
|
+
|
208
|
+
/**
|
209
|
+
*
|
210
|
+
* @return {Filter}
|
211
|
+
*/
|
212
|
+
resetFailureMessage() {
|
213
|
+
this[searchButtonElementSymbol].hideMessage();
|
214
|
+
this[searchButtonElementSymbol].removeState();
|
215
|
+
return this;
|
216
|
+
}
|
217
|
+
|
218
|
+
/**
|
219
|
+
*
|
220
|
+
* @return {Filter}
|
221
|
+
*/
|
222
|
+
showSuccess() {
|
223
|
+
this[searchButtonElementSymbol].setState(
|
224
|
+
"successful",
|
225
|
+
this.getOption("timeouts.message", 4000),
|
226
|
+
);
|
227
|
+
return this;
|
228
|
+
}
|
229
|
+
|
230
|
+
/**
|
231
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
232
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
233
|
+
*
|
234
|
+
* The individual configuration values can be found in the table.
|
235
|
+
*
|
236
|
+
* @property {Object} templates Template definitions
|
237
|
+
* @property {string} templates.main Main template
|
238
|
+
* @property {Object} labels Label definitions
|
239
|
+
* @property {string} labels.search Search button label
|
240
|
+
* @property {string} labels.reset Reset button label
|
241
|
+
* @property {string} labels.save Save button label
|
242
|
+
* @property {string} labels.filter-name Filter name label
|
243
|
+
* @property {string} labels.empty-query-and-no-default Empty query and no default query label
|
244
|
+
* @property {string} labels.query-not-changed Query not changed label
|
245
|
+
* @property {Object} formatter Formatter definitions
|
246
|
+
* @property {Object} formatter.marker Marker definitions
|
247
|
+
* @property {Object} formatter.marker.open Marker open
|
248
|
+
* @property {Object} formatter.marker.close Marker close
|
249
|
+
* @property {Object} features Feature definitions
|
250
|
+
* @property {boolean} features.storedConfig Stored configuration, this replaces the setting `storedConfig.enabled` @since 3.97.0
|
251
|
+
* @property {boolean} features.autoFilter Auto filter @since 3.100.0
|
252
|
+
* @property {boolean} features.preventSameQuery Prevent same query @since 3.103.0
|
253
|
+
* @property {Object} storedConfig Stored configuration
|
254
|
+
* @property {boolean} storedConfig.enabled The store has been enabled, this option will no longer have any effect. @deprecated 20250101
|
255
|
+
* @property {string} storedConfig.selector Selector
|
256
|
+
* @property {Object} timeouts Timeout definitions
|
257
|
+
* @property {number} timeouts.message Message timeout
|
258
|
+
* @property {Object} queries Query definitions
|
259
|
+
* @property {Function} queries.wrap Wrap callback
|
260
|
+
* @property {Function} queries.join Join callback
|
261
|
+
* @property {string} query Query
|
262
|
+
* @property {string} defaultQuery Default query
|
263
|
+
* @property {boolean} eventProcessing Event processing
|
264
|
+
*/
|
265
|
+
get defaults() {
|
266
|
+
return Object.assign({}, super.defaults, {
|
267
|
+
templates: {
|
268
|
+
main: getTemplate(),
|
269
|
+
},
|
270
|
+
|
271
|
+
formatter: {
|
272
|
+
marker: {
|
273
|
+
open: null,
|
274
|
+
close: null,
|
275
|
+
},
|
276
|
+
},
|
277
|
+
|
278
|
+
labels: getTranslations(),
|
279
|
+
|
280
|
+
templateMapping: {
|
281
|
+
"filter-save-label": null,
|
282
|
+
"filter-name-label": name,
|
283
|
+
},
|
284
|
+
|
285
|
+
features: {
|
286
|
+
storedConfig: false,
|
287
|
+
autoFilter: true,
|
288
|
+
preventSameQuery: false,
|
289
|
+
},
|
290
|
+
|
291
|
+
storedConfig: {
|
292
|
+
enabled: true,
|
293
|
+
selector: "",
|
294
|
+
},
|
295
|
+
|
296
|
+
timeouts: {
|
297
|
+
message: 4000,
|
298
|
+
},
|
299
|
+
|
300
|
+
queries: {
|
301
|
+
wrap: (value, definition) => {
|
302
|
+
return value;
|
303
|
+
},
|
304
|
+
join: (queries) => {
|
305
|
+
if (queries.length === 0) {
|
306
|
+
return "";
|
307
|
+
}
|
308
|
+
return queries.join(" AND ");
|
309
|
+
},
|
310
|
+
},
|
311
|
+
|
312
|
+
query: null,
|
313
|
+
defaultQuery: null,
|
314
|
+
eventProcessing: true,
|
315
|
+
|
316
|
+
templateFormatter: {
|
317
|
+
marker: {
|
318
|
+
open: null,
|
319
|
+
close: null,
|
320
|
+
},
|
321
|
+
i18n: true,
|
322
|
+
},
|
323
|
+
});
|
324
|
+
}
|
325
|
+
|
326
|
+
/**
|
327
|
+
*
|
328
|
+
* @return {string}
|
329
|
+
*/
|
330
|
+
static getTag() {
|
331
|
+
return "monster-datatable-filter";
|
332
|
+
}
|
333
|
+
|
334
|
+
/**
|
335
|
+
* @return {FilterButton}
|
336
|
+
* @fires monster-filter-initialized
|
337
|
+
*/
|
338
|
+
[assembleMethodSymbol]() {
|
339
|
+
const self = this;
|
340
|
+
|
341
|
+
this.setOption(
|
342
|
+
"templateMapping.filter-save-label",
|
343
|
+
this.getOption("labels.save"),
|
344
|
+
);
|
345
|
+
|
346
|
+
this.setOption(
|
347
|
+
"templateMapping.filter-name-label",
|
348
|
+
this.getOption("labels.filter-name"),
|
349
|
+
);
|
350
|
+
|
351
|
+
super[assembleMethodSymbol]();
|
352
|
+
|
353
|
+
initControlReferences.call(self);
|
354
|
+
getWindow().requestAnimationFrame(() => {
|
355
|
+
initEventHandler.call(self);
|
356
|
+
});
|
357
|
+
|
358
|
+
initFromConfig
|
359
|
+
.call(self)
|
360
|
+
.then(() => {})
|
361
|
+
.catch((error) => {
|
362
|
+
addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, error?.message);
|
363
|
+
})
|
364
|
+
.finally(() => {
|
365
|
+
initFilter.call(self);
|
366
|
+
updateFilterTabs.call(self);
|
367
|
+
|
368
|
+
if (self.getOption("features.autoFilter") === true) {
|
369
|
+
doSearch
|
370
|
+
.call(self, { showEffect: false })
|
371
|
+
.then(() => {
|
372
|
+
fireCustomEvent(self, "monster-filter-initialized");
|
373
|
+
})
|
374
|
+
.catch(() => {});
|
375
|
+
}
|
376
|
+
});
|
377
|
+
}
|
378
|
+
|
379
|
+
/**
|
380
|
+
*
|
381
|
+
*/
|
382
|
+
connectedCallback() {
|
383
|
+
super.connectedCallback();
|
384
|
+
getWindow().addEventListener(
|
385
|
+
"hashchange",
|
386
|
+
this[locationChangeHandlerSymbol],
|
387
|
+
);
|
388
|
+
}
|
389
|
+
|
390
|
+
/**
|
391
|
+
*
|
392
|
+
*/
|
393
|
+
disconnectedCallback() {
|
394
|
+
super.disconnectedCallback();
|
395
|
+
|
396
|
+
getWindow().removeEventListener(
|
397
|
+
"hashchange",
|
398
|
+
this[locationChangeHandlerSymbol],
|
399
|
+
);
|
400
|
+
}
|
401
|
+
|
402
|
+
/**
|
403
|
+
* @return {CSSStyleSheet[]}
|
404
|
+
*/
|
405
|
+
static getCSSStyleSheet() {
|
406
|
+
return [FilterStyleSheet, FormStyleSheet, ThemeStyleSheet, SpaceStyleSheet];
|
407
|
+
}
|
408
408
|
}
|
409
409
|
|
410
410
|
/**
|
@@ -412,212 +412,215 @@ class Filter extends CustomElement {
|
|
412
412
|
* @returns {object}
|
413
413
|
*/
|
414
414
|
function getTranslations() {
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
415
|
+
const locale = getLocaleOfDocument();
|
416
|
+
switch (locale.language) {
|
417
|
+
case "de":
|
418
|
+
return {
|
419
|
+
search: "Suchen",
|
420
|
+
reset: "Zurücksetzen",
|
421
|
+
save: "Speichern",
|
422
|
+
"filter-name": "Filtername",
|
423
|
+
"empty-query-and-no-default":
|
424
|
+
"Die Abfrage ist leer und es gibt keine Standardabfrage.",
|
425
|
+
"query-not-changed":
|
426
|
+
"Die Suchanfrage hat sich nicht verändert, daher ist keine Suche erforderlich.",
|
427
|
+
};
|
428
|
+
case "fr":
|
429
|
+
return {
|
430
|
+
search: "Chercher",
|
431
|
+
reset: "Réinitialiser",
|
432
|
+
save: "Sauvegarder",
|
433
|
+
"filter-name": "Nom du filtre",
|
434
|
+
"empty-query-and-no-default":
|
435
|
+
"La requête est vide et il n'y a pas de requête par défaut.",
|
436
|
+
"query-not-changed":
|
437
|
+
"La requête de recherche n'a pas changé, donc aucune recherche n'est nécessaire.",
|
438
|
+
};
|
439
|
+
case "es":
|
440
|
+
return {
|
441
|
+
search: "Buscar",
|
442
|
+
reset: "Restablecer",
|
443
|
+
save: "Guardar",
|
444
|
+
"filter-name": "Nombre del filtro",
|
445
|
+
"empty-query-and-no-default":
|
446
|
+
"La consulta está vacía y no hay una consulta predeterminada.",
|
447
|
+
"query-not-changed":
|
448
|
+
"La solicitud de búsqueda no ha cambiado, por lo que no se requiere búsqueda.",
|
449
|
+
};
|
450
|
+
case "it":
|
451
|
+
return {
|
452
|
+
search: "Cerca",
|
453
|
+
reset: "Reimposta",
|
454
|
+
save: "Salva",
|
455
|
+
"filter-name": "Nome del filtro",
|
456
|
+
"empty-query-and-no-default":
|
457
|
+
"La query è vuota e non c'è una query predefinita.",
|
458
|
+
"query-not-changed":
|
459
|
+
"La richiesta di ricerca non è cambiata, quindi non è necessaria una ricerca.",
|
460
|
+
};
|
461
|
+
case "pl":
|
462
|
+
return {
|
463
|
+
search: "Szukaj",
|
464
|
+
reset: "Resetuj",
|
465
|
+
save: "Zapisz",
|
466
|
+
"filter-name": "Nazwa filtra",
|
467
|
+
"empty-query-and-no-default":
|
468
|
+
"Zapytanie jest puste i nie ma domyślnego zapytania.",
|
469
|
+
"query-not-changed":
|
470
|
+
"Żądanie wyszukiwania nie zmieniło się, więc wyszukiwanie nie jest wymagane.",
|
471
|
+
};
|
472
|
+
case "no":
|
473
|
+
return {
|
474
|
+
search: "Søk",
|
475
|
+
reset: "Tilbakestill",
|
476
|
+
save: "Lagre",
|
477
|
+
"filter-name": "Filternavn",
|
478
|
+
"empty-query-and-no-default":
|
479
|
+
"Spørringen er tom og det er ingen standardspørring.",
|
480
|
+
"query-not-changed":
|
481
|
+
"Søkeforespørselen har ikke endret seg, så ingen søk er nødvendig.",
|
482
|
+
};
|
483
|
+
case "da":
|
484
|
+
return {
|
485
|
+
search: "Søg",
|
486
|
+
reset: "Nulstil",
|
487
|
+
save: "Gem",
|
488
|
+
"filter-name": "Filternavn",
|
489
|
+
"empty-query-and-no-default":
|
490
|
+
"Forespørgslen er tom og der er ingen standardforespørgsel.",
|
491
|
+
"query-not-changed":
|
492
|
+
"Søgeanmodningen er ikke ændret, så ingen søgning er nødvendig.",
|
493
|
+
};
|
494
|
+
case "sv":
|
495
|
+
return {
|
496
|
+
search: "Sök",
|
497
|
+
reset: "Återställ",
|
498
|
+
save: "Spara",
|
499
|
+
"filter-name": "Filternamn",
|
500
|
+
"empty-query-and-no-default":
|
501
|
+
"Förfrågan är tom och det finns ingen standardförfrågan.",
|
502
|
+
"query-not-changed":
|
503
|
+
"Sökförfrågan har inte ändrats, så ingen sökning krävs.",
|
504
|
+
};
|
505
|
+
case "nl":
|
506
|
+
return {
|
507
|
+
search: "Zoeken",
|
508
|
+
reset: "Resetten",
|
509
|
+
save: "Opslaan",
|
510
|
+
"filter-name": "Filternaam",
|
511
|
+
"empty-query-and-no-default":
|
512
|
+
"De zoekopdracht is leeg en er is geen standaardzoekopdracht.",
|
513
|
+
"query-not-changed":
|
514
|
+
"De zoekopdracht is niet gewijzigd, dus zoeken is niet nodig.",
|
515
|
+
};
|
516
|
+
case "fi":
|
517
|
+
return {
|
518
|
+
search: "Haku",
|
519
|
+
reset: "Palauta",
|
520
|
+
save: "Tallenna",
|
521
|
+
"filter-name": "Suodattimen nimi",
|
522
|
+
"empty-query-and-no-default":
|
523
|
+
"Hakukysely on tyhjä eikä oletushakua ole määritetty.",
|
524
|
+
"query-not-changed":
|
525
|
+
"Hakupyyntö ei ole muuttunut, joten hakua ei tarvita.",
|
526
|
+
};
|
527
|
+
case "cs":
|
528
|
+
return {
|
529
|
+
search: "Hledat",
|
530
|
+
reset: "Resetovat",
|
531
|
+
save: "Uložit",
|
532
|
+
"filter-name": "Název filtru",
|
533
|
+
"empty-query-and-no-default":
|
534
|
+
"Dotaz je prázdný a není nastavena žádná výchozí hodnota.",
|
535
|
+
"query-not-changed":
|
536
|
+
"Dotaz na hledání se nezměnil, takže hledání není nutné.",
|
537
|
+
};
|
538
|
+
case "pt":
|
539
|
+
return {
|
540
|
+
search: "Buscar",
|
541
|
+
reset: "Redefinir",
|
542
|
+
save: "Salvar",
|
543
|
+
"filter-name": "Nome do filtro",
|
544
|
+
"empty-query-and-no-default":
|
545
|
+
"A consulta está vazia e não há uma consulta padrão.",
|
546
|
+
"query-not-changed":
|
547
|
+
"A solicitação de pesquisa não foi alterada, portanto, nenhuma pesquisa é necessária.",
|
548
|
+
};
|
549
|
+
case "ru":
|
550
|
+
return {
|
551
|
+
search: "Поиск",
|
552
|
+
reset: "Сброс",
|
553
|
+
save: "Сохранить",
|
554
|
+
"filter-name": "Имя фильтра",
|
555
|
+
"empty-query-and-no-default": "Запрос пуст и нет запроса по умолчанию.",
|
556
|
+
"query-not-changed":
|
557
|
+
"Поисковый запрос не изменился, поэтому поиск не требуется.",
|
558
|
+
};
|
559
|
+
case "zh":
|
560
|
+
return {
|
561
|
+
search: "搜索",
|
562
|
+
reset: "重置",
|
563
|
+
save: "保存",
|
564
|
+
"filter-name": "过滤器名称",
|
565
|
+
"empty-query-and-no-default": "查询为空,且没有默认查询。",
|
566
|
+
"query-not-changed": "搜索请求没有更改,因此不需要进行搜索。",
|
567
|
+
};
|
568
|
+
case "hi":
|
569
|
+
return {
|
570
|
+
search: "खोजें",
|
571
|
+
reset: "रीसेट करें",
|
572
|
+
save: "सहेजें",
|
573
|
+
"filter-name": "फ़िल्टर नाम",
|
574
|
+
"empty-query-and-no-default":
|
575
|
+
"क्वेरी खाली है और कोई डिफ़ॉल्ट क्वेरी नहीं है।",
|
576
|
+
"query-not-changed":
|
577
|
+
"खोज अनुरोध में कोई बदलाव नहीं हुआ है, इसलिए खोज आवश्यक नहीं है।",
|
578
|
+
};
|
579
|
+
case "bn":
|
580
|
+
return {
|
581
|
+
search: "অনুসন্ধান",
|
582
|
+
reset: "রিসেট",
|
583
|
+
save: "সংরক্ষণ করুন",
|
584
|
+
"filter-name": "ফিল্টারের নাম",
|
585
|
+
"empty-query-and-no-default":
|
586
|
+
"কোয়েরি খালি এবং কোনো ডিফল্ট কোয়েরি নেই।",
|
587
|
+
"query-not-changed":
|
588
|
+
"অনুসন্ধানের অনুরোধ পরিবর্তন হয়নি, তাই অনুসন্ধান প্রয়োজন নয়।",
|
589
|
+
};
|
590
|
+
case "ja":
|
591
|
+
return {
|
592
|
+
search: "検索",
|
593
|
+
reset: "リセット",
|
594
|
+
save: "保存",
|
595
|
+
"filter-name": "フィルター名",
|
596
|
+
"empty-query-and-no-default":
|
597
|
+
"クエリが空で、デフォルトクエリがありません。",
|
598
|
+
"query-not-changed": "検索リクエストに変更がないため、検索は不要です。",
|
599
|
+
};
|
600
|
+
case "pa":
|
601
|
+
return {
|
602
|
+
search: "ਖੋਜੋ",
|
603
|
+
reset: "ਰੀਸੈੱਟ ਕਰੋ",
|
604
|
+
save: "ਸੇਵ ਕਰੋ",
|
605
|
+
"filter-name": "ਫਿਲਟਰ ਦਾ ਨਾਂ",
|
606
|
+
"empty-query-and-no-default":
|
607
|
+
"ਕੁਐਰੀ ਖਾਲੀ ਹੈ ਅਤੇ ਕੋਈ ਡਿਫੌਲਟ ਕੁਐਰੀ ਨਹੀਂ ਹੈ।",
|
608
|
+
"query-not-changed":
|
609
|
+
"ਖੋਜ ਦੀ ਬੇਨਤੀ ਵਿੱਚ ਕੋਈ ਤਬਦੀਲੀ ਨਹੀਂ ਆਈ ਹੈ, ਇਸ ਲਈ ਖੋਜ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।",
|
610
|
+
};
|
611
|
+
default:
|
612
|
+
case "en":
|
613
|
+
return {
|
614
|
+
search: "Search",
|
615
|
+
reset: "Reset",
|
616
|
+
save: "Save",
|
617
|
+
"filter-name": "Filter name",
|
618
|
+
"empty-query-and-no-default":
|
619
|
+
"The query is empty and there is no default query.",
|
620
|
+
"query-not-changed":
|
621
|
+
"The search request has not changed, so no search is required.",
|
622
|
+
};
|
623
|
+
}
|
621
624
|
}
|
622
625
|
|
623
626
|
/**
|
@@ -625,52 +628,52 @@ function getTranslations() {
|
|
625
628
|
* @return {FilterButton}
|
626
629
|
*/
|
627
630
|
function initControlReferences() {
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
631
|
+
if (!this.shadowRoot) {
|
632
|
+
throw new Error("no shadow-root is defined");
|
633
|
+
}
|
634
|
+
|
635
|
+
this[filterControlElementSymbol] = this.shadowRoot.querySelector(
|
636
|
+
"[data-monster-role=control]",
|
637
|
+
);
|
638
|
+
this[filterSelectElementSymbol] = this.shadowRoot.querySelector(
|
639
|
+
"[data-monster-role=filter-select]",
|
640
|
+
);
|
641
|
+
this[searchButtonElementSymbol] = this.shadowRoot.querySelector(
|
642
|
+
"[data-monster-role=search-button]",
|
643
|
+
);
|
644
|
+
this[resetButtonElementSymbol] = this.shadowRoot.querySelector(
|
645
|
+
"[data-monster-role=reset-button]",
|
646
|
+
);
|
647
|
+
|
648
|
+
this[saveButtonElementSymbol] = this.shadowRoot.querySelector(
|
649
|
+
"[data-monster-role=save-button]",
|
650
|
+
);
|
651
|
+
|
652
|
+
this[filterSaveActionButtonElementSymbol] = this.shadowRoot.querySelector(
|
653
|
+
"[data-monster-role=save-action-button]",
|
654
|
+
);
|
655
|
+
|
656
|
+
this[filterTabElementSymbol] = findElementWithSelectorUpwards(
|
657
|
+
this,
|
658
|
+
this.getOption("storedConfig.selector", ""),
|
659
|
+
);
|
660
|
+
|
661
|
+
return this;
|
659
662
|
}
|
660
663
|
|
661
664
|
/**
|
662
665
|
* @private
|
663
666
|
*/
|
664
667
|
function updateFilterSelections() {
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
668
|
+
queueMicrotask(() => {
|
669
|
+
const options = this[settingsSymbol].getOptions();
|
670
|
+
this[filterSelectElementSymbol].setOption("options", options);
|
671
|
+
|
672
|
+
setTimeout(() => {
|
673
|
+
this[filterSelectElementSymbol].value =
|
674
|
+
this[settingsSymbol].getSelected();
|
675
|
+
}, 10);
|
676
|
+
});
|
674
677
|
}
|
675
678
|
|
676
679
|
/**
|
@@ -678,64 +681,64 @@ function updateFilterSelections() {
|
|
678
681
|
* @throws {Error} no filter label is defined
|
679
682
|
*/
|
680
683
|
function initFilter() {
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
684
|
+
const storedSetting = this[settingsSymbol];
|
685
|
+
this[settingsSymbol] = new Settings();
|
686
|
+
|
687
|
+
const result = parseBracketedKeyValueHash(getGlobal().location.hash);
|
688
|
+
let valuesFromHash = {};
|
689
|
+
if (isObject(result) && result?.[this.id]) {
|
690
|
+
valuesFromHash = result[this.id];
|
691
|
+
}
|
692
|
+
|
693
|
+
getSlottedElements
|
694
|
+
.call(this, "label[data-monster-label]")
|
695
|
+
.forEach((element) => {
|
696
|
+
const label = element.getAttribute("data-monster-label");
|
697
|
+
if (!label) {
|
698
|
+
addAttributeToken(
|
699
|
+
this,
|
700
|
+
ATTRIBUTE_ERRORMESSAGE,
|
701
|
+
"no filter label is defined",
|
702
|
+
);
|
703
|
+
return;
|
704
|
+
}
|
705
|
+
|
706
|
+
let value = element.id;
|
707
|
+
if (!value) {
|
708
|
+
const prefix = label.replace(/\W/g, "-");
|
709
|
+
prefix.charAt(0).match(/[\d_]/g)?.length ? `f${prefix}` : prefix;
|
710
|
+
|
711
|
+
value = new ID(prefix + "-").toString();
|
712
|
+
element.id = value;
|
713
|
+
}
|
714
|
+
|
715
|
+
let setting = storedSetting.get(value);
|
716
|
+
|
717
|
+
if (setting) {
|
718
|
+
this[settingsSymbol].set(setting);
|
719
|
+
}
|
720
|
+
|
721
|
+
if (valuesFromHash?.[element.id]) {
|
722
|
+
const v = escapeAttributeValue(valuesFromHash[element.id]);
|
723
|
+
const searchInput = element.firstElementChild;
|
724
|
+
try {
|
725
|
+
searchInput.value = v;
|
726
|
+
} catch (error) {}
|
727
|
+
}
|
728
|
+
|
729
|
+
setting = this[settingsSymbol].get(value);
|
730
|
+
let visible = false;
|
731
|
+
if (setting) {
|
732
|
+
setSlotAttribute(element, setting.visible);
|
733
|
+
visible = setting.visible;
|
734
|
+
} else {
|
735
|
+
visible = getVisibilityFromSlotAttribute(element);
|
736
|
+
}
|
737
|
+
|
738
|
+
this[settingsSymbol].set({ value, label, visible });
|
739
|
+
});
|
740
|
+
|
741
|
+
updateFilterSelections.call(this);
|
739
742
|
}
|
740
743
|
|
741
744
|
/**
|
@@ -744,16 +747,16 @@ function initFilter() {
|
|
744
747
|
* @return {*}
|
745
748
|
*/
|
746
749
|
function escapeAttributeValue(input) {
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
750
|
+
if (input === undefined || input === null) {
|
751
|
+
return input;
|
752
|
+
}
|
753
|
+
|
754
|
+
return input
|
755
|
+
.replace(/&/g, "&")
|
756
|
+
.replace(/"/g, """)
|
757
|
+
.replace(/'/g, "'")
|
758
|
+
.replace(/</g, "<")
|
759
|
+
.replace(/>/g, ">");
|
757
760
|
}
|
758
761
|
|
759
762
|
/**
|
@@ -762,9 +765,9 @@ function escapeAttributeValue(input) {
|
|
762
765
|
* @return {boolean}
|
763
766
|
*/
|
764
767
|
function getVisibilityFromSlotAttribute(element) {
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
+
return !(
|
769
|
+
element.hasAttribute("slot") && element.getAttribute("slot") === "hidden"
|
770
|
+
);
|
768
771
|
}
|
769
772
|
|
770
773
|
/**
|
@@ -773,369 +776,369 @@ function getVisibilityFromSlotAttribute(element) {
|
|
773
776
|
* @param {boolean} visible
|
774
777
|
*/
|
775
778
|
function setSlotAttribute(element, visible) {
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
779
|
+
if (visible) {
|
780
|
+
element.removeAttribute("slot");
|
781
|
+
return;
|
782
|
+
}
|
780
783
|
|
781
|
-
|
784
|
+
element.setAttribute("slot", "hidden");
|
782
785
|
}
|
783
786
|
|
784
787
|
/**
|
785
788
|
* @private
|
786
789
|
*/
|
787
790
|
function initEventHandler() {
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
791
|
+
const self = this;
|
792
|
+
|
793
|
+
let lastHash = getGlobal().location.hash;
|
794
|
+
self[locationChangeHandlerSymbol] = () => {
|
795
|
+
if (lastHash === getGlobal().location.hash) {
|
796
|
+
return;
|
797
|
+
}
|
798
|
+
|
799
|
+
/**
|
800
|
+
* debounce the hash change event if doSearch
|
801
|
+
* is called by click the search button
|
802
|
+
*/
|
803
|
+
if (self[hashChangeSymbol] > 0) {
|
804
|
+
self[hashChangeSymbol]--;
|
805
|
+
return;
|
806
|
+
}
|
807
|
+
|
808
|
+
initFilter.call(this);
|
809
|
+
|
810
|
+
doSearch
|
811
|
+
.call(self)
|
812
|
+
.then(() => {})
|
813
|
+
.catch((error) => {})
|
814
|
+
.finally(() => {
|
815
|
+
lastHash = getGlobal().location.hash;
|
816
|
+
});
|
817
|
+
};
|
818
|
+
|
819
|
+
/**
|
820
|
+
* Monster.Components.Form.event:monster-selection-cleared
|
821
|
+
*/
|
822
|
+
if (self[filterSelectElementSymbol]) {
|
823
|
+
self[filterSelectElementSymbol].addEventListener(
|
824
|
+
"monster-selection-cleared",
|
825
|
+
function () {
|
826
|
+
const settings = self[settingsSymbol].getOptions();
|
827
|
+
|
828
|
+
for (const setting of settings) {
|
829
|
+
const filterElement = findElementWithIdUpwards(self, setting.value);
|
830
|
+
if (filterElement) {
|
831
|
+
setSlotAttribute(filterElement, false);
|
832
|
+
|
833
|
+
self[settingsSymbol].set({ value: setting.value, visible: false });
|
834
|
+
}
|
835
|
+
}
|
836
|
+
|
837
|
+
updateConfig.call(self);
|
838
|
+
},
|
839
|
+
);
|
840
|
+
|
841
|
+
self[filterSelectElementSymbol].addEventListener(
|
842
|
+
"monster-changed",
|
843
|
+
function (event) {
|
844
|
+
const filterElement = findElementWithIdUpwards(
|
845
|
+
self,
|
846
|
+
event.detail.value,
|
847
|
+
);
|
848
|
+
if (filterElement) {
|
849
|
+
setSlotAttribute(filterElement, event.detail.checked);
|
850
|
+
}
|
851
|
+
|
852
|
+
self[settingsSymbol].set({
|
853
|
+
value: event.detail.value,
|
854
|
+
visible: event.detail.checked,
|
855
|
+
});
|
856
|
+
|
857
|
+
updateConfig.call(self);
|
858
|
+
},
|
859
|
+
);
|
860
|
+
}
|
861
|
+
|
862
|
+
/** save the current filter */
|
863
|
+
if (self[filterSaveActionButtonElementSymbol]) {
|
864
|
+
self[filterSaveActionButtonElementSymbol].setOption(
|
865
|
+
"actions.click",
|
866
|
+
function (event) {
|
867
|
+
const button = findTargetElementFromEvent(
|
868
|
+
event,
|
869
|
+
"data-monster-role",
|
870
|
+
"save-action-button",
|
871
|
+
);
|
872
|
+
const form = button.closest("[data-monster-role=form]");
|
873
|
+
|
874
|
+
if (!form) {
|
875
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
876
|
+
return;
|
877
|
+
}
|
878
|
+
|
879
|
+
const input = form.querySelector("input[name=filter-name]");
|
880
|
+
if (!input) {
|
881
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
882
|
+
return;
|
883
|
+
}
|
884
|
+
|
885
|
+
const name = input.value;
|
886
|
+
if (!name) {
|
887
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
888
|
+
button.setMessage("Please enter a name").showMessage();
|
889
|
+
return;
|
890
|
+
}
|
891
|
+
|
892
|
+
doSearch
|
893
|
+
.call(self, { showEffect: false })
|
894
|
+
.then(() => {
|
895
|
+
const configKey = getStoredFilterConfigKey.call(self);
|
896
|
+
const host = getDocument().querySelector("monster-host");
|
897
|
+
if (!host) {
|
898
|
+
return;
|
899
|
+
}
|
900
|
+
|
901
|
+
const query = self.getOption("query");
|
902
|
+
if (!query) {
|
903
|
+
button.setState(
|
904
|
+
"failed",
|
905
|
+
self.getOption(
|
906
|
+
"timeouts.message",
|
907
|
+
self.getOption("timeouts.message", 4000),
|
908
|
+
),
|
909
|
+
);
|
910
|
+
button
|
911
|
+
.setMessage("No query found")
|
912
|
+
.showMessage(self.getOption("timeouts.message", 4000));
|
913
|
+
return;
|
914
|
+
}
|
915
|
+
|
916
|
+
host
|
917
|
+
.hasConfig(configKey)
|
918
|
+
.then((hasConfig) => {
|
919
|
+
return new Promise((resolve, reject) => {
|
920
|
+
if (hasConfig) {
|
921
|
+
host.getConfig(configKey).then(resolve).catch(reject);
|
922
|
+
return;
|
923
|
+
}
|
924
|
+
return resolve({});
|
925
|
+
});
|
926
|
+
})
|
927
|
+
.then((config) => {
|
928
|
+
config[name] = query;
|
929
|
+
return host.setConfig(configKey, {
|
930
|
+
...config,
|
931
|
+
});
|
932
|
+
})
|
933
|
+
.then(() => {
|
934
|
+
button.setState(
|
935
|
+
"successful",
|
936
|
+
self.getOption("timeouts.message", 4000),
|
937
|
+
);
|
938
|
+
updateFilterTabs.call(self);
|
939
|
+
})
|
940
|
+
.catch((error) => {
|
941
|
+
button.setState(
|
942
|
+
"failed",
|
943
|
+
self.getOption("timeouts.message", 4000),
|
944
|
+
);
|
945
|
+
button
|
946
|
+
.setMessage(error.message)
|
947
|
+
.showMessage(self.getOption("timeouts.message", 4000));
|
948
|
+
});
|
949
|
+
})
|
950
|
+
.catch((error) => {
|
951
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
952
|
+
const msg = error.message || error;
|
953
|
+
button
|
954
|
+
.setMessage(msg)
|
955
|
+
.showMessage(self.getOption("timeouts.message", 4000));
|
956
|
+
});
|
957
|
+
},
|
958
|
+
);
|
959
|
+
}
|
960
|
+
|
961
|
+
self[searchButtonElementSymbol].setOption("actions.click", () => {
|
962
|
+
self[hashChangeSymbol] = 1;
|
963
|
+
|
964
|
+
doSearch
|
965
|
+
.call(self)
|
966
|
+
.then(() => {})
|
967
|
+
.catch((error) => {});
|
968
|
+
});
|
969
|
+
|
970
|
+
// the reset button should reset the filter and the search query
|
971
|
+
// all input elements should be reset to their default values
|
972
|
+
// which is the empty string. we search for all input elements
|
973
|
+
// in the filter and reset them to their default value
|
974
|
+
self[resetButtonElementSymbol].setOption("actions.click", () => {
|
975
|
+
getSlottedElements
|
976
|
+
.call(self, "label[data-monster-label]")
|
977
|
+
.forEach((element) => {
|
978
|
+
const label = element.getAttribute("data-monster-label");
|
979
|
+
if (!label) {
|
980
|
+
return;
|
981
|
+
}
|
982
|
+
|
983
|
+
const input = element.firstElementChild;
|
984
|
+
|
985
|
+
if (input) {
|
986
|
+
input.value = "";
|
987
|
+
}
|
988
|
+
});
|
989
|
+
|
990
|
+
doSearch
|
991
|
+
.call(self, { showEffect: false })
|
992
|
+
.then(() => {})
|
993
|
+
.catch((e) => addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message));
|
994
|
+
});
|
995
|
+
|
996
|
+
self.addEventListener("keyup", (event) => {
|
997
|
+
const path = event.composedPath();
|
998
|
+
if (path.length === 0) {
|
999
|
+
return;
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
if (!(path[0] instanceof HTMLInputElement)) {
|
1003
|
+
return;
|
1004
|
+
}
|
1005
|
+
|
1006
|
+
if (event.keyCode === 13) {
|
1007
|
+
doSearch
|
1008
|
+
.call(self, { showEffect: false })
|
1009
|
+
.then(() => {})
|
1010
|
+
.catch((error) => {});
|
1011
|
+
}
|
1012
|
+
});
|
1013
|
+
|
1014
|
+
// tabs
|
1015
|
+
const element = this[filterTabElementSymbol];
|
1016
|
+
if (element) {
|
1017
|
+
initTabEvents.call(this);
|
1018
|
+
}
|
1016
1019
|
}
|
1017
1020
|
|
1018
1021
|
function initTabEvents() {
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1022
|
+
const self = this;
|
1023
|
+
this[filterTabElementSymbol].addEventListener(
|
1024
|
+
"monster-tab-changed",
|
1025
|
+
(event) => {
|
1026
|
+
const query = event?.detail?.data?.["data-monster-query"];
|
1027
|
+
const q = this.getOption("query");
|
1028
|
+
if (query !== q) {
|
1029
|
+
this.setOption("query", query);
|
1030
|
+
}
|
1031
|
+
},
|
1032
|
+
);
|
1033
|
+
|
1034
|
+
this[filterTabElementSymbol].addEventListener(
|
1035
|
+
"monster-tab-remove",
|
1036
|
+
(event) => {
|
1037
|
+
const labels = [];
|
1038
|
+
const buttons = this[filterTabElementSymbol].getOption("buttons");
|
1039
|
+
|
1040
|
+
const keys = ["popper", "standard"];
|
1041
|
+
for (let i = 0; i < keys.length; i++) {
|
1042
|
+
const key = keys[i];
|
1043
|
+
|
1044
|
+
for (const button of buttons[key]) {
|
1045
|
+
if (button.label !== event.detail.label) {
|
1046
|
+
labels.push(button.label);
|
1047
|
+
}
|
1048
|
+
}
|
1049
|
+
}
|
1050
|
+
|
1051
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1052
|
+
if (!(host && this.id)) {
|
1053
|
+
return;
|
1054
|
+
}
|
1055
|
+
|
1056
|
+
const configKey = getStoredFilterConfigKey.call(this);
|
1057
|
+
host
|
1058
|
+
.hasConfig(configKey)
|
1059
|
+
.then((hasConfig) => {
|
1060
|
+
if (!hasConfig) {
|
1061
|
+
return;
|
1062
|
+
}
|
1063
|
+
|
1064
|
+
return host.getConfig(configKey);
|
1065
|
+
})
|
1066
|
+
.then((config) => {
|
1067
|
+
for (const [name, query] of Object.entries(config)) {
|
1068
|
+
if (labels.includes(name)) {
|
1069
|
+
continue;
|
1070
|
+
}
|
1071
|
+
|
1072
|
+
delete config[name];
|
1073
|
+
}
|
1074
|
+
|
1075
|
+
return host.setConfig(configKey, {
|
1076
|
+
...config,
|
1077
|
+
});
|
1078
|
+
});
|
1079
|
+
},
|
1080
|
+
);
|
1078
1081
|
}
|
1079
1082
|
|
1080
1083
|
/**
|
1081
1084
|
* @private
|
1082
1085
|
*/
|
1083
1086
|
function updateFilterTabs() {
|
1084
|
-
|
1085
|
-
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1087
|
+
const element = this[filterTabElementSymbol];
|
1088
|
+
if (!element) {
|
1089
|
+
return;
|
1090
|
+
}
|
1091
|
+
|
1092
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1093
|
+
if (!(host && this.id)) {
|
1094
|
+
return;
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
const configKey = getStoredFilterConfigKey.call(this);
|
1098
|
+
host
|
1099
|
+
.hasConfig(configKey)
|
1100
|
+
.then((hasConfig) => {
|
1101
|
+
if (!hasConfig) {
|
1102
|
+
return;
|
1103
|
+
}
|
1104
|
+
|
1105
|
+
return host.getConfig(configKey);
|
1106
|
+
})
|
1107
|
+
.then((config) => {
|
1108
|
+
for (const [name, query] of Object.entries(config)) {
|
1109
|
+
const found = element.querySelector(
|
1110
|
+
`[data-monster-button-label="${name}"]`,
|
1111
|
+
);
|
1112
|
+
if (found) {
|
1113
|
+
continue;
|
1114
|
+
}
|
1115
|
+
|
1116
|
+
if (query === undefined || query === null) {
|
1117
|
+
continue;
|
1118
|
+
}
|
1119
|
+
|
1120
|
+
const escapedQuery = escapeAttributeValue(query);
|
1121
|
+
|
1122
|
+
element.insertAdjacentHTML(
|
1123
|
+
"beforeend",
|
1124
|
+
`<div data-monster-button-label="${name}"
|
1122
1125
|
data-monster-removable="true"
|
1123
1126
|
data-monster-query="${escapedQuery}" data-monster-role="filter-tab" >
|
1124
1127
|
</div>`,
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1128
|
+
);
|
1129
|
+
}
|
1130
|
+
})
|
1131
|
+
.catch((error) => {
|
1132
|
+
if (error instanceof Error) {
|
1133
|
+
addAttributeToken(
|
1134
|
+
this,
|
1135
|
+
ATTRIBUTE_ERRORMESSAGE,
|
1136
|
+
error.message + " " + error.stack,
|
1137
|
+
);
|
1138
|
+
} else {
|
1139
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error + "");
|
1140
|
+
}
|
1141
|
+
});
|
1139
1142
|
}
|
1140
1143
|
|
1141
1144
|
/**
|
@@ -1144,92 +1147,92 @@ function updateFilterTabs() {
|
|
1144
1147
|
* @return {Promise}
|
1145
1148
|
*/
|
1146
1149
|
function doSearch({ showEffect } = { showEffect: true }) {
|
1147
|
-
|
1148
|
-
|
1149
|
-
|
1150
|
-
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1196
|
-
|
1197
|
-
|
1198
|
-
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1150
|
+
this.resetFailureMessage();
|
1151
|
+
|
1152
|
+
if (showEffect) {
|
1153
|
+
this[searchButtonElementSymbol].setState(
|
1154
|
+
"activity",
|
1155
|
+
this.getOption("timeouts.message", 4000),
|
1156
|
+
);
|
1157
|
+
}
|
1158
|
+
|
1159
|
+
return collectSearchQueries
|
1160
|
+
.call(this)
|
1161
|
+
.then((query) => {
|
1162
|
+
const buildQuery = buildSearchQuery.call(this, query);
|
1163
|
+
if (buildQuery === null) {
|
1164
|
+
const msg = this.getOption("labels.empty-query-and-no-default");
|
1165
|
+
if (showEffect) {
|
1166
|
+
this[searchButtonElementSymbol].removeState();
|
1167
|
+
this[searchButtonElementSymbol]
|
1168
|
+
.setMessage(msg)
|
1169
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
1170
|
+
}
|
1171
|
+
return Promise.reject(new Error(msg));
|
1172
|
+
}
|
1173
|
+
|
1174
|
+
if (buildQuery === "" && this.getOption("defaultQuery") === null) {
|
1175
|
+
const msg = this.getOption("labels.empty-query-and-no-default");
|
1176
|
+
|
1177
|
+
if (showEffect) {
|
1178
|
+
this[searchButtonElementSymbol].removeState();
|
1179
|
+
this[searchButtonElementSymbol]
|
1180
|
+
.setMessage(msg)
|
1181
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
1182
|
+
}
|
1183
|
+
|
1184
|
+
return Promise.reject(new Error(msg));
|
1185
|
+
}
|
1186
|
+
|
1187
|
+
if (
|
1188
|
+
this.getOption("features.preventSameQuery") &&
|
1189
|
+
buildQuery === this.getOption("query")
|
1190
|
+
) {
|
1191
|
+
const msg = this.getOption("labels.query-not-changed");
|
1192
|
+
|
1193
|
+
if (showEffect) {
|
1194
|
+
this[searchButtonElementSymbol].removeState();
|
1195
|
+
this[searchButtonElementSymbol]
|
1196
|
+
.setMessage(msg)
|
1197
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
1198
|
+
}
|
1199
|
+
|
1200
|
+
return Promise.reject(new Error(msg));
|
1201
|
+
}
|
1202
|
+
|
1203
|
+
if (showEffect) {
|
1204
|
+
this[searchButtonElementSymbol].removeState();
|
1205
|
+
this[searchButtonElementSymbol].setState(
|
1206
|
+
"activity",
|
1207
|
+
this.getOption("timeouts.message", 4000),
|
1208
|
+
);
|
1209
|
+
}
|
1210
|
+
|
1211
|
+
this.setOption("query", buildSearchQuery.call(this, query));
|
1212
|
+
|
1213
|
+
return Promise.resolve();
|
1214
|
+
})
|
1215
|
+
.catch((error) => {
|
1216
|
+
if (error instanceof Error) {
|
1217
|
+
addAttributeToken(
|
1218
|
+
this,
|
1219
|
+
ATTRIBUTE_ERRORMESSAGE,
|
1220
|
+
error.message + " " + error.stack,
|
1221
|
+
);
|
1222
|
+
} else {
|
1223
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
|
1224
|
+
}
|
1225
|
+
|
1226
|
+
if (showEffect) {
|
1227
|
+
this[searchButtonElementSymbol].setState(
|
1228
|
+
"failed",
|
1229
|
+
this.getOption("timeouts.message", 4000),
|
1230
|
+
);
|
1231
|
+
this[searchButtonElementSymbol].setMessage(error.message).showMessage();
|
1232
|
+
}
|
1233
|
+
|
1234
|
+
return Promise.reject(error);
|
1235
|
+
});
|
1233
1236
|
}
|
1234
1237
|
|
1235
1238
|
/**
|
@@ -1238,21 +1241,21 @@ function doSearch({ showEffect } = { showEffect: true }) {
|
|
1238
1241
|
* @return {*|string}
|
1239
1242
|
*/
|
1240
1243
|
function buildSearchQuery(queries) {
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
+
if (!isArray(queries) || queries.length === 0) {
|
1245
|
+
return this.getOption("defaultQuery");
|
1246
|
+
}
|
1244
1247
|
|
1245
|
-
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1248
|
+
const joinCallback = this.getOption("queries.join");
|
1249
|
+
if (isFunction(joinCallback)) {
|
1250
|
+
return joinCallback(queries);
|
1251
|
+
}
|
1249
1252
|
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1253
|
+
const q = queries.join(" ").trim();
|
1254
|
+
if (q.length === 0) {
|
1255
|
+
return this.getOption("defaultQuery");
|
1256
|
+
}
|
1254
1257
|
|
1255
|
-
|
1258
|
+
return q;
|
1256
1259
|
}
|
1257
1260
|
|
1258
1261
|
/**
|
@@ -1260,229 +1263,247 @@ function buildSearchQuery(queries) {
|
|
1260
1263
|
* @return {Promise<unknown>}
|
1261
1264
|
*/
|
1262
1265
|
function collectSearchQueries() {
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1347
|
-
|
1348
|
-
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1387
|
-
|
1388
|
-
|
1389
|
-
|
1390
|
-
|
1391
|
-
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1266
|
+
const currentHash = parseBracketedKeyValueHash(getGlobal().location.hash);
|
1267
|
+
const self = this;
|
1268
|
+
|
1269
|
+
return new Promise((resolve, reject) => {
|
1270
|
+
const query = [];
|
1271
|
+
const wrapCallback = this.getOption("queries.wrap");
|
1272
|
+
|
1273
|
+
let hasNoIdError = false;
|
1274
|
+
|
1275
|
+
getSlottedElements
|
1276
|
+
.call(this, "label[data-monster-label]")
|
1277
|
+
.forEach((element) => {
|
1278
|
+
const label = element.getAttribute("data-monster-label");
|
1279
|
+
if (!label) {
|
1280
|
+
throw new Error("no filter label is defined");
|
1281
|
+
}
|
1282
|
+
|
1283
|
+
const id = element.id;
|
1284
|
+
if (!id) {
|
1285
|
+
hasNoIdError = true;
|
1286
|
+
return;
|
1287
|
+
}
|
1288
|
+
|
1289
|
+
const visible = getVisibilityFromSlotAttribute(element);
|
1290
|
+
if (!visible) {
|
1291
|
+
return;
|
1292
|
+
}
|
1293
|
+
|
1294
|
+
let template = element.getAttribute("data-monster-template");
|
1295
|
+
if (!template) {
|
1296
|
+
template = "${id}=${value}";
|
1297
|
+
}
|
1298
|
+
|
1299
|
+
const controlValue = getControlValuesFromLabel(element);
|
1300
|
+
if (!controlValue) {
|
1301
|
+
if (controlValue === "" && currentHash?.[this.id]?.[id]) {
|
1302
|
+
delete currentHash[this.id][id];
|
1303
|
+
}
|
1304
|
+
|
1305
|
+
return;
|
1306
|
+
}
|
1307
|
+
|
1308
|
+
if (!isObject(currentHash[this.id])) {
|
1309
|
+
currentHash[this.id] = {};
|
1310
|
+
}
|
1311
|
+
currentHash[this.id][id] = controlValue;
|
1312
|
+
|
1313
|
+
const mapping = {
|
1314
|
+
id,
|
1315
|
+
value: controlValue,
|
1316
|
+
label,
|
1317
|
+
};
|
1318
|
+
|
1319
|
+
const formatter = new Formatter(mapping, {
|
1320
|
+
callbacks: {
|
1321
|
+
range: (value, key) => {
|
1322
|
+
return generateRangeComparisonExpression(value, key, {
|
1323
|
+
urlEncode: true,
|
1324
|
+
andOp: "AND",
|
1325
|
+
orOp: "OR",
|
1326
|
+
eqOp: "=",
|
1327
|
+
gtOp: ">",
|
1328
|
+
ltOp: "<",
|
1329
|
+
});
|
1330
|
+
},
|
1331
|
+
"tag-list": (value, key) => {
|
1332
|
+
if (isString(value)) {
|
1333
|
+
value = value.split(",");
|
1334
|
+
}
|
1335
|
+
|
1336
|
+
if (!isArray(value)) {
|
1337
|
+
return "";
|
1338
|
+
}
|
1339
|
+
|
1340
|
+
return (
|
1341
|
+
key +
|
1342
|
+
" IN " +
|
1343
|
+
value
|
1344
|
+
.map((v) => {
|
1345
|
+
return `"${encodeURIComponent(v)}"`;
|
1346
|
+
})
|
1347
|
+
.join(",")
|
1348
|
+
);
|
1349
|
+
},
|
1350
|
+
"list-tag": (value, key) => {
|
1351
|
+
if (isString(value)) {
|
1352
|
+
value = value.split(",");
|
1353
|
+
}
|
1354
|
+
|
1355
|
+
if (!isArray(value)) {
|
1356
|
+
return "";
|
1357
|
+
}
|
1358
|
+
|
1359
|
+
return (
|
1360
|
+
value
|
1361
|
+
.map((v) => {
|
1362
|
+
return `"${encodeURIComponent(v)}"`;
|
1363
|
+
})
|
1364
|
+
.join(",") +
|
1365
|
+
" IN " +
|
1366
|
+
encodeURIComponent(key)
|
1367
|
+
);
|
1368
|
+
},
|
1369
|
+
"tags-in-list": (value, key, op) => {
|
1370
|
+
if (isString(value)) {
|
1371
|
+
value = value.split(",");
|
1372
|
+
}
|
1373
|
+
|
1374
|
+
if (!isArray(value)) {
|
1375
|
+
return "";
|
1376
|
+
}
|
1377
|
+
|
1378
|
+
if (!op || !isString(op)) op = "OR";
|
1379
|
+
op = " " + op.toUpperCase().trim() + " ";
|
1380
|
+
|
1381
|
+
let query = "";
|
1382
|
+
value.forEach((v) => {
|
1383
|
+
if (query.length > 0) {
|
1384
|
+
query += op;
|
1385
|
+
}
|
1386
|
+
query += `${encodeURIComponent(key)} IN "${encodeURIComponent(v)}"`;
|
1387
|
+
});
|
1388
|
+
|
1389
|
+
return query;
|
1390
|
+
},
|
1391
|
+
"list-not-in-tags": (value, key, op) => {
|
1392
|
+
if (isString(value)) {
|
1393
|
+
value = value.split(",");
|
1394
|
+
}
|
1395
|
+
if (!isArray(value)) {
|
1396
|
+
return "";
|
1397
|
+
}
|
1398
|
+
if (!op || !isString(op)) op = "OR";
|
1399
|
+
op = " " + op.toUpperCase().trim() + " ";
|
1400
|
+
let query = "";
|
1401
|
+
value.forEach((v) => {
|
1402
|
+
if (query.length > 0) {
|
1403
|
+
query += op;
|
1404
|
+
}
|
1405
|
+
query += `"${encodeURIComponent(v)}" NOT IN ${encodeURIComponent(key)}`;
|
1406
|
+
});
|
1407
|
+
return query;
|
1408
|
+
},
|
1409
|
+
"list-in-tags": (value, key, op) => {
|
1410
|
+
if (isString(value)) {
|
1411
|
+
value = value.split(",");
|
1412
|
+
}
|
1413
|
+
|
1414
|
+
if (!isArray(value)) {
|
1415
|
+
return "";
|
1416
|
+
}
|
1417
|
+
|
1418
|
+
if (!op || !isString(op)) op = "OR";
|
1419
|
+
op = " " + op.toUpperCase().trim() + " ";
|
1420
|
+
|
1421
|
+
let query = "";
|
1422
|
+
value.forEach((v) => {
|
1423
|
+
if (query.length > 0) {
|
1424
|
+
query += op;
|
1425
|
+
}
|
1426
|
+
query += `"${encodeURIComponent(v)}" IN ${encodeURIComponent(key)}`;
|
1427
|
+
});
|
1428
|
+
|
1429
|
+
return query;
|
1430
|
+
},
|
1431
|
+
"array-list": (value, key) => {
|
1432
|
+
if (isString(value)) {
|
1433
|
+
value = value.split(",");
|
1434
|
+
}
|
1435
|
+
|
1436
|
+
if (!isArray(value)) {
|
1437
|
+
return "";
|
1438
|
+
}
|
1439
|
+
|
1440
|
+
return (
|
1441
|
+
key +
|
1442
|
+
"=" +
|
1443
|
+
value
|
1444
|
+
.map((v) => {
|
1445
|
+
return `"${encodeURIComponent(v)}"`;
|
1446
|
+
})
|
1447
|
+
.join(",")
|
1448
|
+
);
|
1449
|
+
},
|
1450
|
+
"date-range": (value, key) => {
|
1451
|
+
const query = parseDateInput(value, key);
|
1452
|
+
if (!query || query === "false") {
|
1453
|
+
return "";
|
1454
|
+
}
|
1455
|
+
|
1456
|
+
// return query as url encoded
|
1457
|
+
return encodeURIComponent(query);
|
1458
|
+
},
|
1459
|
+
"to-int-2": (value, key) => {
|
1460
|
+
const query = normalizeNumber(value);
|
1461
|
+
if (Number.isNaN(query)) {
|
1462
|
+
return key + " IS NULL";
|
1463
|
+
}
|
1464
|
+
return key + "=" + encodeURIComponent(Math.round(query * 100));
|
1465
|
+
},
|
1466
|
+
"to-int-3": (value, key) => {
|
1467
|
+
const query = normalizeNumber(value);
|
1468
|
+
if (Number.isNaN(query)) {
|
1469
|
+
return "";
|
1470
|
+
}
|
1471
|
+
return key + "=" + encodeURIComponent(Math.round(query * 1000));
|
1472
|
+
},
|
1473
|
+
"to-int-4": (value, key) => {
|
1474
|
+
const query = normalizeNumber(value);
|
1475
|
+
if (Number.isNaN(query)) {
|
1476
|
+
return "";
|
1477
|
+
}
|
1478
|
+
return key + "=" + encodeURIComponent(Math.round(query * 10000));
|
1479
|
+
},
|
1480
|
+
},
|
1481
|
+
});
|
1482
|
+
|
1483
|
+
if (self.getOption("formatter.marker.open")) {
|
1484
|
+
formatter.setMarker(
|
1485
|
+
self.getOption("formatter.marker.open"),
|
1486
|
+
self.getOption("formatter.marker.close"),
|
1487
|
+
);
|
1488
|
+
}
|
1489
|
+
|
1490
|
+
let queryPart = formatter.format(template);
|
1491
|
+
if (queryPart) {
|
1492
|
+
if (isFunction(wrapCallback)) {
|
1493
|
+
queryPart = wrapCallback(queryPart, mapping);
|
1494
|
+
}
|
1495
|
+
query.push(queryPart);
|
1496
|
+
}
|
1497
|
+
});
|
1498
|
+
|
1499
|
+
if (hasNoIdError) {
|
1500
|
+
reject(new Error("some or all filter elements have no id"));
|
1501
|
+
return;
|
1502
|
+
}
|
1503
|
+
|
1504
|
+
getGlobal().location.hash = createBracketedKeyValueHash(currentHash);
|
1505
|
+
resolve(query);
|
1506
|
+
});
|
1486
1507
|
}
|
1487
1508
|
|
1488
1509
|
/**
|
@@ -1491,41 +1512,41 @@ function collectSearchQueries() {
|
|
1491
1512
|
* @return {null|Array|undefined|string}
|
1492
1513
|
*/
|
1493
1514
|
function getControlValuesFromLabel(label) {
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1515
|
+
// finde das erste Kind-Element vom type input
|
1516
|
+
// wenn es ein input-Element ist, dann @todo
|
1517
|
+
|
1518
|
+
const foundControl = label.firstElementChild;
|
1519
|
+
|
1520
|
+
if (foundControl) {
|
1521
|
+
if (foundControl.tagName === "INPUT") {
|
1522
|
+
if (foundControl.type === "checkbox") {
|
1523
|
+
const checkedControls = label.querySelectorAll(
|
1524
|
+
`${foundControl}:checked`,
|
1525
|
+
);
|
1526
|
+
const values = [];
|
1527
|
+
|
1528
|
+
checkedControls.forEach((checkedControl) => {
|
1529
|
+
values.push(checkedControl.value);
|
1530
|
+
});
|
1531
|
+
|
1532
|
+
return values;
|
1533
|
+
} else if (foundControl.type === "radio") {
|
1534
|
+
const checkedControl = label.querySelector(`${foundControl}:checked`);
|
1535
|
+
|
1536
|
+
if (checkedControl) {
|
1537
|
+
return checkedControl.value;
|
1538
|
+
} else {
|
1539
|
+
return null;
|
1540
|
+
}
|
1541
|
+
} else {
|
1542
|
+
return foundControl.value;
|
1543
|
+
}
|
1544
|
+
} else {
|
1545
|
+
return foundControl.value;
|
1546
|
+
}
|
1547
|
+
}
|
1548
|
+
|
1549
|
+
return null;
|
1529
1550
|
}
|
1530
1551
|
|
1531
1552
|
/**
|
@@ -1533,60 +1554,60 @@ function getControlValuesFromLabel(label) {
|
|
1533
1554
|
* @return {Promise<unknown>}
|
1534
1555
|
*/
|
1535
1556
|
function initFromConfig() {
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
|
1555
|
-
|
1556
|
-
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1564
|
-
|
1565
|
-
|
1566
|
-
|
1567
|
-
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1557
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1558
|
+
|
1559
|
+
if (!(isInstance(host, Host) && this.id)) {
|
1560
|
+
return Promise.resolve();
|
1561
|
+
}
|
1562
|
+
|
1563
|
+
const configKey = getFilterConfigKey.call(this);
|
1564
|
+
|
1565
|
+
return new Promise((resolve, reject) => {
|
1566
|
+
host
|
1567
|
+
.getConfig(configKey)
|
1568
|
+
.then((config) => {
|
1569
|
+
if ((config && isObject(config)) || isArray(config)) {
|
1570
|
+
this[settingsSymbol].setOptions(config);
|
1571
|
+
}
|
1572
|
+
resolve();
|
1573
|
+
})
|
1574
|
+
.catch((error) => {
|
1575
|
+
if (error === undefined) {
|
1576
|
+
resolve();
|
1577
|
+
return;
|
1578
|
+
}
|
1579
|
+
|
1580
|
+
// config not written
|
1581
|
+
if (error?.message?.match(/is not defined/)) {
|
1582
|
+
resolve();
|
1583
|
+
return;
|
1584
|
+
}
|
1585
|
+
|
1586
|
+
addAttributeToken(
|
1587
|
+
this,
|
1588
|
+
ATTRIBUTE_ERRORMESSAGE,
|
1589
|
+
error?.message || error,
|
1590
|
+
);
|
1591
|
+
reject(error);
|
1592
|
+
});
|
1593
|
+
});
|
1573
1594
|
}
|
1574
1595
|
|
1575
1596
|
/**
|
1576
1597
|
* @private
|
1577
1598
|
*/
|
1578
1599
|
function updateConfig() {
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1600
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
1601
|
+
if (!(host && this.id)) {
|
1602
|
+
return;
|
1603
|
+
}
|
1604
|
+
const configKey = getFilterConfigKey.call(this);
|
1605
|
+
|
1606
|
+
try {
|
1607
|
+
host.setConfig(configKey, this[settingsSymbol].getOptions());
|
1608
|
+
} catch (error) {
|
1609
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error?.message || error);
|
1610
|
+
}
|
1590
1611
|
}
|
1591
1612
|
|
1592
1613
|
/**
|
@@ -1594,8 +1615,8 @@ function updateConfig() {
|
|
1594
1615
|
* @return {string}
|
1595
1616
|
*/
|
1596
1617
|
function getTemplate() {
|
1597
|
-
|
1598
|
-
|
1618
|
+
// language=HTML
|
1619
|
+
return `
|
1599
1620
|
<div data-monster-role="control" part="control">
|
1600
1621
|
<div data-monster-role="container">
|
1601
1622
|
<div data-monster-role="layout">
|