@schukai/monster 3.86.4 → 3.87.0
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 +16 -0
- package/package.json +1 -1
- package/source/components/datatable/datatable.mjs +912 -778
- package/source/components/datatable/filter.mjs +978 -949
- package/source/components/datatable/pagination.mjs +6 -10
- package/source/components/datatable/style/datatable.pcss +20 -0
- package/source/components/datatable/style/filter.pcss +23 -24
- package/source/components/datatable/stylesheet/column-bar.mjs +6 -13
- package/source/components/datatable/stylesheet/datatable.mjs +7 -14
- package/source/components/datatable/stylesheet/filter.mjs +7 -14
- package/source/components/form/action-button.mjs +2 -2
- package/source/components/form/api-button.mjs +7 -38
- package/source/components/form/style/action-button.pcss +2 -1
- package/source/components/form/style/button.pcss +1 -1
- package/source/components/form/style/confirm-button.pcss +1 -1
- package/source/components/form/style/popper-button.pcss +6 -5
- package/source/components/form/style/state-button.pcss +1 -1
- package/source/components/form/stylesheet/action-button.mjs +7 -14
- package/source/components/form/stylesheet/button.mjs +7 -14
- package/source/components/form/stylesheet/confirm-button.mjs +7 -14
- package/source/components/form/stylesheet/popper-button.mjs +7 -14
- package/source/components/form/stylesheet/state-button.mjs +7 -14
|
@@ -12,48 +12,49 @@
|
|
|
12
12
|
* SPDX-License-Identifier: AGPL-3.0
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
15
|
+
import {instanceSymbol} from "../../constants.mjs";
|
|
16
|
+
import {findTargetElementFromEvent} from "../../dom/events.mjs";
|
|
17
17
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
findElementWithIdUpwards,
|
|
19
|
+
findElementWithSelectorUpwards,
|
|
20
20
|
} from "../../dom/util.mjs";
|
|
21
21
|
import {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
assembleMethodSymbol,
|
|
23
|
+
CustomElement,
|
|
24
|
+
getSlottedElements,
|
|
25
|
+
registerCustomElement,
|
|
26
26
|
} from "../../dom/customelement.mjs";
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
27
|
+
import {ID} from "../../types/id.mjs";
|
|
28
|
+
import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
|
|
29
|
+
import {Settings} from "./filter/settings.mjs";
|
|
30
|
+
import {FilterStyleSheet} from "./stylesheet/filter.mjs";
|
|
31
|
+
import {getDocument, getWindow} from "../../dom/util.mjs";
|
|
32
|
+
import {getGlobal} from "../../types/global.mjs";
|
|
33
|
+
import {isInstance, isFunction, isObject, isArray} from "../../types/is.mjs";
|
|
34
|
+
import {Host} from "../host/host.mjs";
|
|
35
|
+
import {addAttributeToken} from "../../dom/attributes.mjs";
|
|
36
|
+
import {ATTRIBUTE_ERRORMESSAGE} from "../../dom/constants.mjs";
|
|
36
37
|
import "../form/message-state-button.mjs";
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
38
|
+
import {Formatter} from "../../text/formatter.mjs";
|
|
39
|
+
import {generateRangeComparisonExpression} from "../../text/util.mjs";
|
|
39
40
|
|
|
40
41
|
import {
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
parseBracketedKeyValueHash,
|
|
43
|
+
createBracketedKeyValueHash,
|
|
43
44
|
} from "../../text/bracketed-key-value-hash.mjs";
|
|
44
|
-
import {
|
|
45
|
-
import {
|
|
46
|
-
import {
|
|
45
|
+
import {ThemeStyleSheet} from "../stylesheet/theme.mjs";
|
|
46
|
+
import {SpaceStyleSheet} from "../stylesheet/space.mjs";
|
|
47
|
+
import {FormStyleSheet} from "../stylesheet/form.mjs";
|
|
47
48
|
|
|
48
49
|
import {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
getStoredFilterConfigKey,
|
|
51
|
+
getFilterConfigKey,
|
|
52
|
+
parseDateInput,
|
|
52
53
|
} from "./filter/util.mjs";
|
|
53
54
|
|
|
54
55
|
import "./filter/select.mjs";
|
|
55
56
|
|
|
56
|
-
export {
|
|
57
|
+
export {Filter};
|
|
57
58
|
|
|
58
59
|
/**
|
|
59
60
|
* @private
|
|
@@ -90,7 +91,7 @@ const filterControlElementSymbol = Symbol("filterControlElement");
|
|
|
90
91
|
* @type {symbol}
|
|
91
92
|
*/
|
|
92
93
|
const filterSaveActionButtonElementSymbol = Symbol(
|
|
93
|
-
|
|
94
|
+
"filterSaveActionButtonElement",
|
|
94
95
|
);
|
|
95
96
|
|
|
96
97
|
/**
|
|
@@ -111,6 +112,25 @@ const locationChangeHandlerSymbol = Symbol("locationChangeHandler");
|
|
|
111
112
|
*/
|
|
112
113
|
const settingsSymbol = Symbol("settings");
|
|
113
114
|
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* @private
|
|
118
|
+
* @type {symbol}
|
|
119
|
+
*/
|
|
120
|
+
const resizeObserverSymbol = Symbol("resizeObserver");
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @private
|
|
124
|
+
* @type {symbol}
|
|
125
|
+
*/
|
|
126
|
+
const sizeDataSymbol = Symbol("sizeData");
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @private
|
|
130
|
+
* @type {symbol}
|
|
131
|
+
*/
|
|
132
|
+
const debounceSizeSymbol = Symbol("debounceSize");
|
|
133
|
+
|
|
114
134
|
/**
|
|
115
135
|
* The Filter component is used to show and handle the filter values.
|
|
116
136
|
*
|
|
@@ -118,199 +138,211 @@ const settingsSymbol = Symbol("settings");
|
|
|
118
138
|
* @summary The Filter component is used to show and handle the filter values.
|
|
119
139
|
*/
|
|
120
140
|
class Filter extends CustomElement {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
-
|
|
141
|
+
/**
|
|
142
|
+
*
|
|
143
|
+
*/
|
|
144
|
+
constructor() {
|
|
145
|
+
super();
|
|
146
|
+
this[settingsSymbol] = new Settings();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* This method is called by the `instanceof` operator.
|
|
151
|
+
* @return {symbol}
|
|
152
|
+
*/
|
|
153
|
+
static get [instanceSymbol]() {
|
|
154
|
+
return Symbol.for("@schukai/monster/components/filter@@instance");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
*
|
|
159
|
+
* @param {string} message
|
|
160
|
+
* @return {Filter}
|
|
161
|
+
*/
|
|
162
|
+
showFailureMessage(message) {
|
|
163
|
+
this[searchButtonElementSymbol].setState(
|
|
164
|
+
"failed",
|
|
165
|
+
this.getOption("timeouts.message", 4000),
|
|
166
|
+
);
|
|
167
|
+
this[searchButtonElementSymbol]
|
|
168
|
+
.setMessage(message.toString())
|
|
169
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
*
|
|
175
|
+
* @return {{Filter}}
|
|
176
|
+
*/
|
|
177
|
+
resetFailureMessage() {
|
|
178
|
+
this[searchButtonElementSymbol].hideMessage();
|
|
179
|
+
this[searchButtonElementSymbol].removeState();
|
|
180
|
+
return this;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
*
|
|
185
|
+
* @return {{Filter}}
|
|
186
|
+
*/
|
|
187
|
+
showSuccess() {
|
|
188
|
+
this[searchButtonElementSymbol].setState(
|
|
189
|
+
"successful",
|
|
190
|
+
this.getOption("timeouts.message", 4000),
|
|
191
|
+
);
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
|
197
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
198
|
+
*
|
|
199
|
+
* The individual configuration values can be found in the table.
|
|
200
|
+
*
|
|
201
|
+
* @property {Object} templates Template definitions
|
|
202
|
+
* @property {string} templates.main Main template
|
|
203
|
+
* @property {Object} labels Label definitions
|
|
204
|
+
* @property {string} labels.search Search button label
|
|
205
|
+
* @property {string} labels.reset Reset button label
|
|
206
|
+
* @property {string} labels.save Save button label
|
|
207
|
+
* @property {string} labels.filter-name Filter name label
|
|
208
|
+
* @property {string} labels.empty-query-and-no-default Empty query and no default query label
|
|
209
|
+
* @property {string} labels.query-not-changed Query not changed label
|
|
210
|
+
* @property {Object} formatter Formatter definitions
|
|
211
|
+
* @property {Object} formatter.marker Marker definitions
|
|
212
|
+
* @property {Object} formatter.marker.open Marker open
|
|
213
|
+
* @property {Object} formatter.marker.close Marker close
|
|
214
|
+
* @property {Object} storedConfig Stored configuration
|
|
215
|
+
* @property {boolean} storedConfig.enabled Enabled
|
|
216
|
+
* @property {string} storedConfig.selector Selector
|
|
217
|
+
* @property {Object} timeouts Timeout definitions
|
|
218
|
+
* @property {number} timeouts.message Message timeout
|
|
219
|
+
* @property {Object} queries Query definitions
|
|
220
|
+
* @property {Function} queries.wrap Wrap callback
|
|
221
|
+
* @property {Function} queries.join Join callback
|
|
222
|
+
* @property {string} query Query
|
|
223
|
+
* @property {string} defaultQuery Default query
|
|
224
|
+
* @property {boolean} eventProcessing Event processing
|
|
225
|
+
*/
|
|
226
|
+
get defaults() {
|
|
227
|
+
return Object.assign({}, super.defaults, {
|
|
228
|
+
templates: {
|
|
229
|
+
main: getTemplate(),
|
|
230
|
+
},
|
|
231
|
+
formatter: {
|
|
232
|
+
marker: {
|
|
233
|
+
open: null,
|
|
234
|
+
close: null,
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
labels: {
|
|
238
|
+
search: "Search",
|
|
239
|
+
reset: "Reset",
|
|
240
|
+
save: "Save",
|
|
241
|
+
"filter-name": "Filter name",
|
|
242
|
+
"empty-query-and-no-default": "Please select a filter",
|
|
243
|
+
"query-not-changed": "The query has not changed",
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
templateMapping: {
|
|
247
|
+
"filter-save-label": null,
|
|
248
|
+
"filter-name-label": name,
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
storedConfig: {
|
|
252
|
+
enabled: true,
|
|
253
|
+
selector: "",
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
timeouts: {
|
|
257
|
+
message: 4000,
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
queries: {
|
|
261
|
+
wrap: (value, definition) => {
|
|
262
|
+
return value;
|
|
263
|
+
},
|
|
264
|
+
join: (queries) => {
|
|
265
|
+
if (queries.length === 0) {
|
|
266
|
+
return "";
|
|
267
|
+
}
|
|
268
|
+
return queries.join(" AND ");
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
query: undefined,
|
|
273
|
+
defaultQuery: "",
|
|
274
|
+
eventProcessing: true,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
*
|
|
280
|
+
* @return {string}
|
|
281
|
+
*/
|
|
282
|
+
static getTag() {
|
|
283
|
+
return "monster-datatable-filter";
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* @return {FilterButton}
|
|
288
|
+
*/
|
|
289
|
+
[assembleMethodSymbol]() {
|
|
290
|
+
this.setOption(
|
|
291
|
+
"templateMapping.filter-save-label",
|
|
292
|
+
this.getOption("labels.save"),
|
|
293
|
+
);
|
|
294
|
+
this.setOption(
|
|
295
|
+
"templateMapping.filter-name-label",
|
|
296
|
+
this.getOption("labels.filter-name"),
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
super[assembleMethodSymbol]();
|
|
300
|
+
|
|
301
|
+
initControlReferences.call(this);
|
|
302
|
+
initEventHandler.call(this);
|
|
303
|
+
|
|
304
|
+
initFromConfig
|
|
305
|
+
.call(this)
|
|
306
|
+
.then(() => {
|
|
307
|
+
initFilter.call(this);
|
|
308
|
+
updateFilterTabs.call(this);
|
|
309
|
+
})
|
|
310
|
+
.catch((error) => {
|
|
311
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error?.message);
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
*
|
|
317
|
+
*/
|
|
318
|
+
connectedCallback() {
|
|
319
|
+
super.connectedCallback();
|
|
320
|
+
|
|
321
|
+
getWindow().addEventListener(
|
|
322
|
+
"hashchange",
|
|
323
|
+
this[locationChangeHandlerSymbol],
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
*
|
|
329
|
+
*/
|
|
330
|
+
disconnectedCallback() {
|
|
331
|
+
super.disconnectedCallback();
|
|
332
|
+
|
|
333
|
+
getWindow().removeEventListener(
|
|
334
|
+
"hashchange",
|
|
335
|
+
this[locationChangeHandlerSymbol],
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* @return {Array<CSSStyleSheet>}
|
|
342
|
+
*/
|
|
343
|
+
static getCSSStyleSheet() {
|
|
344
|
+
return [FilterStyleSheet, FormStyleSheet, ThemeStyleSheet, SpaceStyleSheet];
|
|
345
|
+
}
|
|
314
346
|
}
|
|
315
347
|
|
|
316
348
|
/**
|
|
@@ -318,48 +350,48 @@ class Filter extends CustomElement {
|
|
|
318
350
|
* @return {FilterButton}
|
|
319
351
|
*/
|
|
320
352
|
function initControlReferences() {
|
|
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
|
-
|
|
353
|
+
if (!this.shadowRoot) {
|
|
354
|
+
throw new Error("no shadow-root is defined");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
this[filterControlElementSymbol] = this.shadowRoot.querySelector(
|
|
358
|
+
"[data-monster-role=control]",
|
|
359
|
+
);
|
|
360
|
+
this[filterSelectElementSymbol] = this.shadowRoot.querySelector(
|
|
361
|
+
"[data-monster-role=filter-select]",
|
|
362
|
+
);
|
|
363
|
+
this[searchButtonElementSymbol] = this.shadowRoot.querySelector(
|
|
364
|
+
"[data-monster-role=search-button]",
|
|
365
|
+
);
|
|
366
|
+
this[resetButtonElementSymbol] = this.shadowRoot.querySelector(
|
|
367
|
+
"[data-monster-role=reset-button]",
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
this[saveButtonElementSymbol] = this.shadowRoot.querySelector(
|
|
371
|
+
"[data-monster-role=save-button]",
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
this[filterSaveActionButtonElementSymbol] = this.shadowRoot.querySelector(
|
|
375
|
+
"[data-monster-role=save-action-button]",
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
this[filterTabElementSymbol] = findElementWithSelectorUpwards(
|
|
379
|
+
this,
|
|
380
|
+
this.getOption("storedConfig.selector", ""),
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
return this;
|
|
352
384
|
}
|
|
353
385
|
|
|
354
386
|
function updateFilterSelections() {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
387
|
+
queueMicrotask(() => {
|
|
388
|
+
const options = this[settingsSymbol].getOptions();
|
|
389
|
+
this[filterSelectElementSymbol].setOption("options", options);
|
|
390
|
+
queueMicrotask(() => {
|
|
391
|
+
this[filterSelectElementSymbol].value =
|
|
392
|
+
this[settingsSymbol].getSelected();
|
|
393
|
+
});
|
|
394
|
+
});
|
|
363
395
|
}
|
|
364
396
|
|
|
365
397
|
/**
|
|
@@ -367,58 +399,59 @@ function updateFilterSelections() {
|
|
|
367
399
|
* @throws {Error} no filter label is defined
|
|
368
400
|
*/
|
|
369
401
|
function initFilter() {
|
|
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
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
402
|
+
const storedSetting = this[settingsSymbol];
|
|
403
|
+
this[settingsSymbol] = new Settings();
|
|
404
|
+
|
|
405
|
+
const result = parseBracketedKeyValueHash(getGlobal().location.hash);
|
|
406
|
+
let valuesFromHash = {};
|
|
407
|
+
if (isObject(result) && result?.[this.id]) {
|
|
408
|
+
valuesFromHash = result[this.id];
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
getSlottedElements
|
|
412
|
+
.call(this, "label[data-monster-label]")
|
|
413
|
+
.forEach((element) => {
|
|
414
|
+
const label = element.getAttribute("data-monster-label");
|
|
415
|
+
if (!label) {
|
|
416
|
+
throw new Error("no filter label is defined");
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
let value = element.id;
|
|
420
|
+
if (!value) {
|
|
421
|
+
const prefix = label.replace(/\W/g, "-");
|
|
422
|
+
prefix.charAt(0).match(/[\d_]/g)?.length ? `f${prefix}` : prefix;
|
|
423
|
+
|
|
424
|
+
value = new ID(prefix + "-").toString();
|
|
425
|
+
element.id = value;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
let setting = storedSetting.get(value);
|
|
429
|
+
|
|
430
|
+
if (setting) {
|
|
431
|
+
this[settingsSymbol].set(setting);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (valuesFromHash?.[element.id]) {
|
|
435
|
+
const v = escapeAttributeValue(valuesFromHash[element.id]);
|
|
436
|
+
const searchInput = element.firstElementChild;
|
|
437
|
+
try {
|
|
438
|
+
searchInput.value = v;
|
|
439
|
+
} catch (error) {
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
setting = this[settingsSymbol].get(value);
|
|
444
|
+
let visible = false;
|
|
445
|
+
if (setting) {
|
|
446
|
+
setSlotAttribute(element, setting.visible);
|
|
447
|
+
visible = setting.visible;
|
|
448
|
+
} else {
|
|
449
|
+
visible = getVisibilityFromSlotAttribute(element);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
this[settingsSymbol].set({value, label, visible});
|
|
453
|
+
});
|
|
454
|
+
updateFilterSelections.call(this);
|
|
422
455
|
}
|
|
423
456
|
|
|
424
457
|
/**
|
|
@@ -427,16 +460,16 @@ function initFilter() {
|
|
|
427
460
|
* @return {*}
|
|
428
461
|
*/
|
|
429
462
|
function escapeAttributeValue(input) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
463
|
+
if (input === undefined || input === null) {
|
|
464
|
+
return input;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return input
|
|
468
|
+
.replace(/&/g, "&")
|
|
469
|
+
.replace(/"/g, """)
|
|
470
|
+
.replace(/'/g, "'")
|
|
471
|
+
.replace(/</g, "<")
|
|
472
|
+
.replace(/>/g, ">");
|
|
440
473
|
}
|
|
441
474
|
|
|
442
475
|
/**
|
|
@@ -445,9 +478,9 @@ function escapeAttributeValue(input) {
|
|
|
445
478
|
* @return {boolean}
|
|
446
479
|
*/
|
|
447
480
|
function getVisibilityFromSlotAttribute(element) {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
481
|
+
return !(
|
|
482
|
+
element.hasAttribute("slot") && element.getAttribute("slot") === "hidden"
|
|
483
|
+
);
|
|
451
484
|
}
|
|
452
485
|
|
|
453
486
|
/**
|
|
@@ -456,343 +489,338 @@ function getVisibilityFromSlotAttribute(element) {
|
|
|
456
489
|
* @param {boolean} visible
|
|
457
490
|
*/
|
|
458
491
|
function setSlotAttribute(element, visible) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
492
|
+
if (visible) {
|
|
493
|
+
element.removeAttribute("slot");
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
463
496
|
|
|
464
|
-
|
|
497
|
+
element.setAttribute("slot", "hidden");
|
|
465
498
|
}
|
|
466
499
|
|
|
467
500
|
/**
|
|
468
501
|
* @private
|
|
469
502
|
*/
|
|
470
503
|
function initEventHandler() {
|
|
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
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
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
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
// tabs
|
|
670
|
-
const element = this[filterTabElementSymbol];
|
|
671
|
-
if (element) {
|
|
672
|
-
initTabEvents.call(this);
|
|
673
|
-
}
|
|
504
|
+
const self = this;
|
|
505
|
+
/**
|
|
506
|
+
* Monster.Components.Form.event:monster-selection-cleared
|
|
507
|
+
*/
|
|
508
|
+
if (self[filterSelectElementSymbol]) {
|
|
509
|
+
self[filterSelectElementSymbol].addEventListener(
|
|
510
|
+
"monster-selection-cleared",
|
|
511
|
+
function () {
|
|
512
|
+
const settings = self[settingsSymbol].getOptions();
|
|
513
|
+
|
|
514
|
+
for (const setting of settings) {
|
|
515
|
+
const filterElement = findElementWithIdUpwards(self, setting.value);
|
|
516
|
+
if (filterElement) {
|
|
517
|
+
setSlotAttribute(filterElement, false);
|
|
518
|
+
|
|
519
|
+
self[settingsSymbol].set({value: setting.value, visible: false});
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
updateConfig.call(self);
|
|
524
|
+
},
|
|
525
|
+
);
|
|
526
|
+
|
|
527
|
+
self[filterSelectElementSymbol].addEventListener(
|
|
528
|
+
"monster-changed",
|
|
529
|
+
function (event) {
|
|
530
|
+
const filterElement = findElementWithIdUpwards(
|
|
531
|
+
self,
|
|
532
|
+
event.detail.value,
|
|
533
|
+
);
|
|
534
|
+
if (filterElement) {
|
|
535
|
+
setSlotAttribute(filterElement, event.detail.checked);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
self[settingsSymbol].set({
|
|
539
|
+
value: event.detail.value,
|
|
540
|
+
visible: event.detail.checked,
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
updateConfig.call(self);
|
|
544
|
+
},
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (self[filterSaveActionButtonElementSymbol]) {
|
|
549
|
+
self[filterSaveActionButtonElementSymbol].setOption(
|
|
550
|
+
"actions.click",
|
|
551
|
+
function (event) {
|
|
552
|
+
const button = findTargetElementFromEvent(
|
|
553
|
+
event,
|
|
554
|
+
"data-monster-role",
|
|
555
|
+
"save-action-button",
|
|
556
|
+
);
|
|
557
|
+
const form = button.closest("[data-monster-role=form]");
|
|
558
|
+
|
|
559
|
+
if (!form) {
|
|
560
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
const input = form.querySelector("input[name=filter-name]");
|
|
565
|
+
if (!input) {
|
|
566
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
const name = input.value;
|
|
571
|
+
if (!name) {
|
|
572
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
|
573
|
+
button.setMessage("Please enter a name").showMessage();
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
doSearch
|
|
578
|
+
.call(self, {showEffect: false})
|
|
579
|
+
.then(() => {
|
|
580
|
+
const configKey = getStoredFilterConfigKey.call(self);
|
|
581
|
+
const host = getDocument().querySelector("monster-host");
|
|
582
|
+
if (!host) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const query = self.getOption("query");
|
|
587
|
+
if (!query) {
|
|
588
|
+
button.setState(
|
|
589
|
+
"failed",
|
|
590
|
+
self.getOption(
|
|
591
|
+
"timeouts.message",
|
|
592
|
+
self.getOption("timeouts.message", 4000),
|
|
593
|
+
),
|
|
594
|
+
);
|
|
595
|
+
button
|
|
596
|
+
.setMessage("No query found")
|
|
597
|
+
.showMessage(self.getOption("timeouts.message", 4000));
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
host
|
|
602
|
+
.hasConfig(configKey)
|
|
603
|
+
.then((hasConfig) => {
|
|
604
|
+
return new Promise((resolve, reject) => {
|
|
605
|
+
if (hasConfig) {
|
|
606
|
+
host.getConfig(configKey).then(resolve).catch(reject);
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
return resolve({});
|
|
610
|
+
});
|
|
611
|
+
})
|
|
612
|
+
.then((config) => {
|
|
613
|
+
config[name] = query;
|
|
614
|
+
return host.setConfig(configKey, {
|
|
615
|
+
...config,
|
|
616
|
+
});
|
|
617
|
+
})
|
|
618
|
+
.then(() => {
|
|
619
|
+
button.setState(
|
|
620
|
+
"successful",
|
|
621
|
+
self.getOption("timeouts.message", 4000),
|
|
622
|
+
);
|
|
623
|
+
updateFilterTabs.call(self);
|
|
624
|
+
})
|
|
625
|
+
.catch((error) => {
|
|
626
|
+
button.setState(
|
|
627
|
+
"failed",
|
|
628
|
+
self.getOption("timeouts.message", 4000),
|
|
629
|
+
);
|
|
630
|
+
button
|
|
631
|
+
.setMessage(error.message)
|
|
632
|
+
.showMessage(self.getOption("timeouts.message", 4000));
|
|
633
|
+
});
|
|
634
|
+
})
|
|
635
|
+
.catch((error) => {
|
|
636
|
+
button.setState("failed", self.getOption("timeouts.message", 4000));
|
|
637
|
+
const msg = error.message || error;
|
|
638
|
+
button
|
|
639
|
+
.setMessage(msg)
|
|
640
|
+
.showMessage(self.getOption("timeouts.message", 4000));
|
|
641
|
+
});
|
|
642
|
+
},
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
self[searchButtonElementSymbol].setOption("actions.click", () => {
|
|
647
|
+
doSearch
|
|
648
|
+
.call(self)
|
|
649
|
+
.then(() => {
|
|
650
|
+
})
|
|
651
|
+
.catch((error) => {
|
|
652
|
+
});
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
// the reset button should reset the filter and the search query
|
|
656
|
+
// all input elements should be reset to their default values
|
|
657
|
+
// which is the empty string. we search for all input elements
|
|
658
|
+
// in the filter and reset them to their default value
|
|
659
|
+
self[resetButtonElementSymbol].setOption("actions.click", () => {
|
|
660
|
+
getSlottedElements
|
|
661
|
+
.call(self, "label[data-monster-label]")
|
|
662
|
+
.forEach((element) => {
|
|
663
|
+
const label = element.getAttribute("data-monster-label");
|
|
664
|
+
if (!label) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
const input = element.firstElementChild;
|
|
669
|
+
|
|
670
|
+
if (input) {
|
|
671
|
+
input.value = "";
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
|
|
675
|
+
doSearch
|
|
676
|
+
.call(self, {showEffect: false})
|
|
677
|
+
.then(() => {
|
|
678
|
+
})
|
|
679
|
+
.catch((e) => addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message));
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
self.addEventListener("keyup", (event) => {
|
|
683
|
+
const path = event.composedPath();
|
|
684
|
+
if (path.length === 0) {
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
if (!(path[0] instanceof HTMLInputElement)) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
if (event.keyCode === 13) {
|
|
693
|
+
doSearch.call(self, {showEffect: false});
|
|
694
|
+
}
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
// tabs
|
|
698
|
+
const element = this[filterTabElementSymbol];
|
|
699
|
+
if (element) {
|
|
700
|
+
initTabEvents.call(this);
|
|
701
|
+
}
|
|
674
702
|
}
|
|
675
703
|
|
|
676
704
|
function initTabEvents() {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
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
|
-
|
|
705
|
+
this[filterTabElementSymbol].addEventListener(
|
|
706
|
+
"monster-tab-changed",
|
|
707
|
+
(event) => {
|
|
708
|
+
const query = event?.detail?.data?.["data-monster-query"];
|
|
709
|
+
const q = this.getOption("query");
|
|
710
|
+
if (query !== q) {
|
|
711
|
+
this.setOption("query", query);
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
);
|
|
715
|
+
|
|
716
|
+
this[filterTabElementSymbol].addEventListener(
|
|
717
|
+
"monster-tab-remove",
|
|
718
|
+
(event) => {
|
|
719
|
+
const labels = [];
|
|
720
|
+
const buttons = this[filterTabElementSymbol].getOption("buttons");
|
|
721
|
+
|
|
722
|
+
const keys = ["popper", "standard"];
|
|
723
|
+
for (let i = 0; i < keys.length; i++) {
|
|
724
|
+
const key = keys[i];
|
|
725
|
+
|
|
726
|
+
for (const button of buttons[key]) {
|
|
727
|
+
if (button.label !== event.detail.label) {
|
|
728
|
+
labels.push(button.label);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
|
734
|
+
if (!(host && this.id)) {
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
const configKey = getStoredFilterConfigKey.call(this);
|
|
739
|
+
host
|
|
740
|
+
.hasConfig(configKey)
|
|
741
|
+
.then((hasConfig) => {
|
|
742
|
+
if (!hasConfig) {
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
return host.getConfig(configKey);
|
|
747
|
+
})
|
|
748
|
+
.then((config) => {
|
|
749
|
+
for (const [name, query] of Object.entries(config)) {
|
|
750
|
+
if (labels.includes(name)) {
|
|
751
|
+
continue;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
delete config[name];
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
return host.setConfig(configKey, {
|
|
758
|
+
...config,
|
|
759
|
+
});
|
|
760
|
+
});
|
|
761
|
+
},
|
|
762
|
+
);
|
|
735
763
|
}
|
|
736
764
|
|
|
737
765
|
/**
|
|
738
766
|
* @private
|
|
739
767
|
*/
|
|
740
768
|
function updateFilterTabs() {
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
769
|
+
const element = this[filterTabElementSymbol];
|
|
770
|
+
if (!element) {
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
|
775
|
+
if (!(host && this.id)) {
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
const configKey = getStoredFilterConfigKey.call(this);
|
|
780
|
+
host
|
|
781
|
+
.hasConfig(configKey)
|
|
782
|
+
.then((hasConfig) => {
|
|
783
|
+
if (!hasConfig) {
|
|
784
|
+
return;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
return host.getConfig(configKey);
|
|
788
|
+
})
|
|
789
|
+
.then((config) => {
|
|
790
|
+
for (const [name, query] of Object.entries(config)) {
|
|
791
|
+
const found = element.querySelector(
|
|
792
|
+
`[data-monster-button-label="${name}"]`,
|
|
793
|
+
);
|
|
794
|
+
if (found) {
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
if (query === undefined || query === null) {
|
|
799
|
+
continue;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
const escapedQuery = escapeAttributeValue(query);
|
|
803
|
+
|
|
804
|
+
element.insertAdjacentHTML(
|
|
805
|
+
"beforeend",
|
|
806
|
+
`<div data-monster-button-label="${name}"
|
|
779
807
|
data-monster-removable="true"
|
|
780
808
|
data-monster-query="${escapedQuery}" data-monster-role="filter-tab" >
|
|
781
809
|
</div>`,
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
810
|
+
);
|
|
811
|
+
}
|
|
812
|
+
})
|
|
813
|
+
.catch((error) => {
|
|
814
|
+
if (error instanceof Error) {
|
|
815
|
+
addAttributeToken(
|
|
816
|
+
this,
|
|
817
|
+
ATTRIBUTE_ERRORMESSAGE,
|
|
818
|
+
error.message + " " + error.stack,
|
|
819
|
+
);
|
|
820
|
+
} else {
|
|
821
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error + "");
|
|
822
|
+
}
|
|
823
|
+
});
|
|
796
824
|
}
|
|
797
825
|
|
|
798
826
|
/**
|
|
@@ -800,76 +828,76 @@ function updateFilterTabs() {
|
|
|
800
828
|
* @param showEffect
|
|
801
829
|
* @return {Promise<*>}
|
|
802
830
|
*/
|
|
803
|
-
function doSearch({
|
|
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
|
-
|
|
831
|
+
function doSearch({showEffect} = {showEffect: true}) {
|
|
832
|
+
this.resetFailureMessage();
|
|
833
|
+
|
|
834
|
+
if (showEffect) {
|
|
835
|
+
this[searchButtonElementSymbol].setState(
|
|
836
|
+
"activity",
|
|
837
|
+
this.getOption("timeouts.message", 4000),
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
return collectSearchQueries
|
|
842
|
+
.call(this)
|
|
843
|
+
.then((query) => {
|
|
844
|
+
const buildQuery = buildSearchQuery.call(this, query);
|
|
845
|
+
if (buildQuery === "" && !this.getOption("defaultQuery")) {
|
|
846
|
+
const msg = this.getOption("labels.empty-query-and-no-default");
|
|
847
|
+
|
|
848
|
+
if (showEffect) {
|
|
849
|
+
this[searchButtonElementSymbol].removeState();
|
|
850
|
+
this[searchButtonElementSymbol]
|
|
851
|
+
.setMessage(msg)
|
|
852
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
throw new Error(msg);
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
if (buildQuery === this.getOption("query")) {
|
|
859
|
+
const msg = this.getOption("labels.query-not-changed");
|
|
860
|
+
|
|
861
|
+
if (showEffect) {
|
|
862
|
+
this[searchButtonElementSymbol].removeState();
|
|
863
|
+
this[searchButtonElementSymbol]
|
|
864
|
+
.setMessage(msg)
|
|
865
|
+
.showMessage(this.getOption("timeouts.message", 4000));
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
throw new Error(msg);
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
if (showEffect) {
|
|
872
|
+
this[searchButtonElementSymbol].setState(
|
|
873
|
+
"activity",
|
|
874
|
+
this.getOption("timeouts.message", 4000),
|
|
875
|
+
);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
this.setOption("query", buildSearchQuery.call(this, query));
|
|
879
|
+
})
|
|
880
|
+
.catch((error) => {
|
|
881
|
+
if (error instanceof Error) {
|
|
882
|
+
addAttributeToken(
|
|
883
|
+
this,
|
|
884
|
+
ATTRIBUTE_ERRORMESSAGE,
|
|
885
|
+
error.message + " " + error.stack,
|
|
886
|
+
);
|
|
887
|
+
} else {
|
|
888
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, String(error));
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
if (showEffect) {
|
|
892
|
+
this[searchButtonElementSymbol].setState(
|
|
893
|
+
"failed",
|
|
894
|
+
this.getOption("timeouts.message", 4000),
|
|
895
|
+
);
|
|
896
|
+
this[searchButtonElementSymbol].setMessage(error.message).showMessage();
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
return Promise.reject(error);
|
|
900
|
+
});
|
|
873
901
|
}
|
|
874
902
|
|
|
875
903
|
/**
|
|
@@ -878,21 +906,21 @@ function doSearch({ showEffect } = { showEffect: true }) {
|
|
|
878
906
|
* @return {*|string}
|
|
879
907
|
*/
|
|
880
908
|
function buildSearchQuery(queries) {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
909
|
+
if (!isArray(queries) || queries.length === 0) {
|
|
910
|
+
return this.getOption("defaultQuery");
|
|
911
|
+
}
|
|
884
912
|
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
913
|
+
const joinCallback = this.getOption("queries.join");
|
|
914
|
+
if (isFunction(joinCallback)) {
|
|
915
|
+
return joinCallback(queries);
|
|
916
|
+
}
|
|
889
917
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
918
|
+
const q = queries.join(" ").trim();
|
|
919
|
+
if (q.length === 0) {
|
|
920
|
+
return this.getOption("defaultQuery");
|
|
921
|
+
}
|
|
894
922
|
|
|
895
|
-
|
|
923
|
+
return q;
|
|
896
924
|
}
|
|
897
925
|
|
|
898
926
|
/**
|
|
@@ -900,108 +928,108 @@ function buildSearchQuery(queries) {
|
|
|
900
928
|
* @return {Promise<unknown>}
|
|
901
929
|
*/
|
|
902
930
|
function collectSearchQueries() {
|
|
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
|
-
|
|
931
|
+
const currentHash = parseBracketedKeyValueHash(getGlobal().location.hash);
|
|
932
|
+
const self = this;
|
|
933
|
+
|
|
934
|
+
return new Promise((resolve, reject) => {
|
|
935
|
+
const query = [];
|
|
936
|
+
const wrapCallback = this.getOption("queries.wrap");
|
|
937
|
+
|
|
938
|
+
let hasNoIdError = false;
|
|
939
|
+
|
|
940
|
+
getSlottedElements
|
|
941
|
+
.call(this, "label[data-monster-label]")
|
|
942
|
+
.forEach((element) => {
|
|
943
|
+
const label = element.getAttribute("data-monster-label");
|
|
944
|
+
if (!label) {
|
|
945
|
+
throw new Error("no filter label is defined");
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
const id = element.id;
|
|
949
|
+
if (!id) {
|
|
950
|
+
hasNoIdError = true;
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
//const visible = window.getComputedStyle(element).display !== "none";
|
|
955
|
+
const visible = getVisibilityFromSlotAttribute(element);
|
|
956
|
+
if (!visible) {
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
let template = element.getAttribute("data-monster-template");
|
|
961
|
+
if (!template) {
|
|
962
|
+
template = "${id}=${value}";
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
const controlValue = getControlValuesFromLabel(element);
|
|
966
|
+
if (!controlValue) {
|
|
967
|
+
if (controlValue === "" && currentHash?.[this.id]?.[id]) {
|
|
968
|
+
delete currentHash[this.id][id];
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
if (!isObject(currentHash[this.id])) {
|
|
975
|
+
currentHash[this.id] = {};
|
|
976
|
+
}
|
|
977
|
+
currentHash[this.id][id] = controlValue;
|
|
978
|
+
|
|
979
|
+
const mapping = {
|
|
980
|
+
id,
|
|
981
|
+
value: controlValue,
|
|
982
|
+
label,
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
const formatter = new Formatter(mapping, {
|
|
986
|
+
callbacks: {
|
|
987
|
+
range: (value, key) => {
|
|
988
|
+
return generateRangeComparisonExpression(value, key, {
|
|
989
|
+
urlEncode: true,
|
|
990
|
+
andOp: "AND",
|
|
991
|
+
orOp: "OR",
|
|
992
|
+
eqOp: "=",
|
|
993
|
+
gtOp: ">",
|
|
994
|
+
ltOp: "<",
|
|
995
|
+
});
|
|
996
|
+
},
|
|
997
|
+
"date-range": (value, key) => {
|
|
998
|
+
const query = parseDateInput(value, key);
|
|
999
|
+
if (!query || query === "false") {
|
|
1000
|
+
return "";
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
// return query as url encoded
|
|
1004
|
+
return encodeURIComponent(query);
|
|
1005
|
+
},
|
|
1006
|
+
},
|
|
1007
|
+
});
|
|
1008
|
+
|
|
1009
|
+
if (self.getOption("formatter.marker.open")) {
|
|
1010
|
+
formatter.setMarker(
|
|
1011
|
+
self.getOption("formatter.marker.open"),
|
|
1012
|
+
self.getOption("formatter.marker.close"),
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
let queryPart = formatter.format(template);
|
|
1017
|
+
if (queryPart) {
|
|
1018
|
+
if (isFunction(wrapCallback)) {
|
|
1019
|
+
queryPart = wrapCallback(queryPart, mapping);
|
|
1020
|
+
}
|
|
1021
|
+
query.push(queryPart);
|
|
1022
|
+
}
|
|
1023
|
+
});
|
|
1024
|
+
|
|
1025
|
+
if (hasNoIdError) {
|
|
1026
|
+
reject(new Error("some or all filter elements have no id"));
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
getGlobal().location.hash = createBracketedKeyValueHash(currentHash);
|
|
1031
|
+
resolve(query);
|
|
1032
|
+
});
|
|
1005
1033
|
}
|
|
1006
1034
|
|
|
1007
1035
|
/**
|
|
@@ -1010,38 +1038,38 @@ function collectSearchQueries() {
|
|
|
1010
1038
|
* @return {null|Array|undefined|string}
|
|
1011
1039
|
*/
|
|
1012
1040
|
function getControlValuesFromLabel(label) {
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
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
|
-
|
|
1041
|
+
const foundControl = label.firstElementChild;
|
|
1042
|
+
|
|
1043
|
+
if (foundControl) {
|
|
1044
|
+
if (foundControl.tagName === "INPUT") {
|
|
1045
|
+
if (foundControl.type === "checkbox") {
|
|
1046
|
+
const checkedControls = label.querySelectorAll(
|
|
1047
|
+
`${foundControl}:checked`,
|
|
1048
|
+
);
|
|
1049
|
+
const values = [];
|
|
1050
|
+
|
|
1051
|
+
checkedControls.forEach((checkedControl) => {
|
|
1052
|
+
values.push(checkedControl.value);
|
|
1053
|
+
});
|
|
1054
|
+
|
|
1055
|
+
return values;
|
|
1056
|
+
} else if (foundControl.type === "radio") {
|
|
1057
|
+
const checkedControl = label.querySelector(`${foundControl}:checked`);
|
|
1058
|
+
|
|
1059
|
+
if (checkedControl) {
|
|
1060
|
+
return checkedControl.value;
|
|
1061
|
+
} else {
|
|
1062
|
+
return null;
|
|
1063
|
+
}
|
|
1064
|
+
} else {
|
|
1065
|
+
return foundControl.value;
|
|
1066
|
+
}
|
|
1067
|
+
} else {
|
|
1068
|
+
return foundControl.value;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
return null;
|
|
1045
1073
|
}
|
|
1046
1074
|
|
|
1047
1075
|
/**
|
|
@@ -1049,60 +1077,60 @@ function getControlValuesFromLabel(label) {
|
|
|
1049
1077
|
* @return {Promise<unknown>}
|
|
1050
1078
|
*/
|
|
1051
1079
|
function initFromConfig() {
|
|
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
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1080
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
|
1081
|
+
|
|
1082
|
+
if (!(isInstance(host, Host) && this.id)) {
|
|
1083
|
+
return Promise.resolve();
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
const configKey = getFilterConfigKey.call(this);
|
|
1087
|
+
|
|
1088
|
+
return new Promise((resolve, reject) => {
|
|
1089
|
+
host
|
|
1090
|
+
.getConfig(configKey)
|
|
1091
|
+
.then((config) => {
|
|
1092
|
+
if ((config && isObject(config)) || isArray(config)) {
|
|
1093
|
+
this[settingsSymbol].setOptions(config);
|
|
1094
|
+
}
|
|
1095
|
+
resolve();
|
|
1096
|
+
})
|
|
1097
|
+
.catch((error) => {
|
|
1098
|
+
if (error === undefined) {
|
|
1099
|
+
resolve();
|
|
1100
|
+
return;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
// config not written
|
|
1104
|
+
if (error?.message?.match(/is not defined/)) {
|
|
1105
|
+
resolve();
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
addAttributeToken(
|
|
1110
|
+
this,
|
|
1111
|
+
ATTRIBUTE_ERRORMESSAGE,
|
|
1112
|
+
error?.message || error,
|
|
1113
|
+
);
|
|
1114
|
+
reject(error);
|
|
1115
|
+
});
|
|
1116
|
+
});
|
|
1089
1117
|
}
|
|
1090
1118
|
|
|
1091
1119
|
/**
|
|
1092
1120
|
* @private
|
|
1093
1121
|
*/
|
|
1094
1122
|
function updateConfig() {
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1123
|
+
const host = findElementWithSelectorUpwards(this, "monster-host");
|
|
1124
|
+
if (!(host && this.id)) {
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
const configKey = getFilterConfigKey.call(this);
|
|
1128
|
+
|
|
1129
|
+
try {
|
|
1130
|
+
host.setConfig(configKey, this[settingsSymbol].getOptions());
|
|
1131
|
+
} catch (error) {
|
|
1132
|
+
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error?.message || error);
|
|
1133
|
+
}
|
|
1106
1134
|
}
|
|
1107
1135
|
|
|
1108
1136
|
/**
|
|
@@ -1110,49 +1138,50 @@ function updateConfig() {
|
|
|
1110
1138
|
* @return {string}
|
|
1111
1139
|
*/
|
|
1112
1140
|
function getTemplate() {
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
</div>
|
|
1121
|
-
<div data-monster-role="select-and-search">
|
|
1122
|
-
<monster-message-state-button data-monster-role="search-button" class="stretched-control"
|
|
1123
|
-
data-monster-replace="path:labels.search">
|
|
1124
|
-
</monster-message-state-button>
|
|
1125
|
-
<monster-select class="stretched-control"
|
|
1126
|
-
data-monster-selected-template="summary"
|
|
1127
|
-
data-monster-option-type="checkbox"
|
|
1128
|
-
data-monster-option-filter-mode="options"
|
|
1129
|
-
data-monster-option-filter-position="popper"
|
|
1130
|
-
data-monster-role="filter-select"></monster-select>
|
|
1131
|
-
<monster-popper-button data-monster-role="save-button" class="stretched-control"
|
|
1132
|
-
data-monster-attributes="data-monster-visible path:storedConfig.enabled">
|
|
1133
|
-
<div slot="button">\${filter-save-label}</div>
|
|
1134
|
-
<div class="monster-form" data-monster-role="form">
|
|
1135
|
-
|
|
1136
|
-
<label for="filter-name">\${filter-name-label}
|
|
1137
|
-
<input name="filter-name"
|
|
1138
|
-
type="search"
|
|
1139
|
-
class="monster-margin-bottom-5"></label>
|
|
1140
|
-
<monster-message-state-button
|
|
1141
|
-
data-monster-role="save-action-button"
|
|
1142
|
-
data-monster-option-labels-button="\${filter-save-label}">
|
|
1143
|
-
</monster-message-state-button>
|
|
1144
|
-
|
|
1145
|
-
</div>
|
|
1146
|
-
</monster-popper-button>
|
|
1147
|
-
<monster-button data-monster-role="reset-button" class="stretched-control"
|
|
1148
|
-
data-monster-replace="path:labels.reset">
|
|
1149
|
-
</monster-button>
|
|
1150
|
-
</div>
|
|
1151
|
-
|
|
1141
|
+
// language=HTML
|
|
1142
|
+
return `<div data-monster-role="control" part="control">
|
|
1143
|
+
<div data-monster-role="container">
|
|
1144
|
+
<div data-monster-role="layout">
|
|
1145
|
+
<div data-monster-role="filter">
|
|
1146
|
+
<slot></slot>
|
|
1147
|
+
<slot name="hidden"></slot>
|
|
1152
1148
|
</div>
|
|
1153
|
-
<
|
|
1154
|
-
|
|
1149
|
+
<div data-monster-role="select-and-search">
|
|
1150
|
+
<monster-message-state-button data-monster-role="search-button" class="stretched-control"
|
|
1151
|
+
data-monster-replace="path:labels.search">
|
|
1152
|
+
</monster-message-state-button>
|
|
1153
|
+
<monster-select class="stretched-control"
|
|
1154
|
+
data-monster-selected-template="summary"
|
|
1155
|
+
data-monster-option-type="checkbox"
|
|
1156
|
+
data-monster-option-filter-mode="options"
|
|
1157
|
+
data-monster-option-filter-position="popper"
|
|
1158
|
+
data-monster-role="filter-select"></monster-select>
|
|
1159
|
+
<monster-popper-button data-monster-role="save-button" class="stretched-control"
|
|
1160
|
+
data-monster-attributes="data-monster-visible path:storedConfig.enabled">
|
|
1161
|
+
<div slot="button">\${filter-save-label}</div>
|
|
1162
|
+
<div class="monster-form" data-monster-role="form">
|
|
1163
|
+
|
|
1164
|
+
<label for="filter-name">\${filter-name-label}
|
|
1165
|
+
<input name="filter-name"
|
|
1166
|
+
type="search"
|
|
1167
|
+
class="monster-margin-bottom-5"></label>
|
|
1168
|
+
<monster-message-state-button
|
|
1169
|
+
data-monster-role="save-action-button"
|
|
1170
|
+
data-monster-option-labels-button="\${filter-save-label}">
|
|
1171
|
+
</monster-message-state-button>
|
|
1172
|
+
|
|
1173
|
+
</div>
|
|
1174
|
+
</monster-popper-button>
|
|
1175
|
+
<monster-button data-monster-role="reset-button" class="stretched-control"
|
|
1176
|
+
data-monster-replace="path:labels.reset">
|
|
1177
|
+
</monster-button>
|
|
1178
|
+
</div>
|
|
1179
|
+
|
|
1155
1180
|
</div>
|
|
1181
|
+
<input class="hidden" name="query" data-monster-role="query"
|
|
1182
|
+
data-monster-attributes="value path:query">
|
|
1183
|
+
</div>
|
|
1184
|
+
</div>
|
|
1156
1185
|
`;
|
|
1157
1186
|
}
|
|
1158
1187
|
|