@schukai/monster 4.66.1 → 4.67.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 +19 -0
- package/package.json +1 -1
- package/source/components/datatable/filter/date-presets.mjs +435 -0
- package/source/components/datatable/filter/date-time.mjs +145 -0
- package/source/components/datatable/filter/date.mjs +145 -0
- package/source/components/datatable/filter/text-operator.mjs +380 -0
- package/source/components/datatable/filter/time.mjs +145 -0
- package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +1 -1
- package/source/components/form/buy-box.mjs +1 -0
- package/source/components/form/variant-select.mjs +1 -0
- package/source/monster.mjs +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
## [4.67.0] - 2025-12-31
|
|
6
|
+
|
|
7
|
+
### Add Features
|
|
8
|
+
|
|
9
|
+
- Add new filter controls for date, datetime, and time [#354](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/354)
|
|
10
|
+
### Changes
|
|
11
|
+
|
|
12
|
+
- close issue [#354](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/354)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## [4.66.2] - 2025-12-31
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
- Add version annotation to component documentation
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
5
24
|
## [4.66.1] - 2025-12-31
|
|
6
25
|
|
|
7
26
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.4","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.
|
|
1
|
+
{"author":"Volker Schukai","dependencies":{"@floating-ui/dom":"^1.7.4","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"4.67.0"}
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
|
|
3
|
+
* Node module: @schukai/monster
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
|
|
6
|
+
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
|
|
7
|
+
*
|
|
8
|
+
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
|
|
9
|
+
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
|
|
10
|
+
* For more information about purchasing a commercial license, please contact Volker Schukai.
|
|
11
|
+
*
|
|
12
|
+
* SPDX-License-Identifier: AGPL-3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { instanceSymbol } from "../../../constants.mjs";
|
|
16
|
+
import {
|
|
17
|
+
assembleMethodSymbol,
|
|
18
|
+
registerCustomElement,
|
|
19
|
+
} from "../../../dom/customelement.mjs";
|
|
20
|
+
import { FilterControlsDefaultsStyleSheet } from "../stylesheet/filter-controls-defaults.mjs";
|
|
21
|
+
import { FilterStyleSheet } from "../stylesheet/filter.mjs";
|
|
22
|
+
import { AbstractBase } from "./abstract-base.mjs";
|
|
23
|
+
import { getLocaleOfDocument } from "../../../dom/locale.mjs";
|
|
24
|
+
|
|
25
|
+
export { DatePresets };
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* local symbol
|
|
29
|
+
* @private
|
|
30
|
+
* @type {symbol}
|
|
31
|
+
*/
|
|
32
|
+
const selectElementSymbol = Symbol("selectElement");
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The Filter component is used to show and handle the filter values.
|
|
36
|
+
*
|
|
37
|
+
* @copyright Volker Schukai
|
|
38
|
+
* @summary The FilterDatePresets component provides quick date presets.
|
|
39
|
+
*/
|
|
40
|
+
class DatePresets extends AbstractBase {
|
|
41
|
+
/**
|
|
42
|
+
* This method is called by the `instanceof` operator.
|
|
43
|
+
* @return {symbol}
|
|
44
|
+
*/
|
|
45
|
+
static get [instanceSymbol]() {
|
|
46
|
+
return Symbol.for("@schukai/monster/components/filter/date-presets@@instance");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
|
51
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
52
|
+
*
|
|
53
|
+
* The individual configuration values can be found in the table.
|
|
54
|
+
*
|
|
55
|
+
* @property {Object} templates Template definitions
|
|
56
|
+
* @property {string} templates.main Main template
|
|
57
|
+
* @property {Object} labels Text labels
|
|
58
|
+
*/
|
|
59
|
+
get defaults() {
|
|
60
|
+
return Object.assign({}, super.defaults, {
|
|
61
|
+
templates: {
|
|
62
|
+
main: getTemplate(),
|
|
63
|
+
},
|
|
64
|
+
labels: getTranslations(),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @return {string}
|
|
71
|
+
*/
|
|
72
|
+
static getTag() {
|
|
73
|
+
return "monster-filter-date-presets";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @return {FilterButton}
|
|
79
|
+
*/
|
|
80
|
+
[assembleMethodSymbol]() {
|
|
81
|
+
super[assembleMethodSymbol]();
|
|
82
|
+
|
|
83
|
+
initControlReferences.call(this);
|
|
84
|
+
updateOptions.call(this);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @return Array<CSSStyleSheet>
|
|
89
|
+
*/
|
|
90
|
+
static getCSSStyleSheet() {
|
|
91
|
+
return [FilterControlsDefaultsStyleSheet, FilterStyleSheet];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
96
|
+
*
|
|
97
|
+
* @param {*} value
|
|
98
|
+
*/
|
|
99
|
+
set value(value) {
|
|
100
|
+
this[selectElementSymbol].value = value;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @return {*}
|
|
105
|
+
*/
|
|
106
|
+
get value() {
|
|
107
|
+
return this[selectElementSymbol].value;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @private
|
|
113
|
+
* @returns {Object}
|
|
114
|
+
*/
|
|
115
|
+
function getTranslations() {
|
|
116
|
+
const locale = getLocaleOfDocument();
|
|
117
|
+
switch (locale.language) {
|
|
118
|
+
case "de":
|
|
119
|
+
return {
|
|
120
|
+
any: "Beliebig",
|
|
121
|
+
today: "Heute",
|
|
122
|
+
yesterday: "Gestern",
|
|
123
|
+
last7: "Letzte 7 Tage",
|
|
124
|
+
last30: "Letzte 30 Tage",
|
|
125
|
+
thisMonth: "Dieser Monat",
|
|
126
|
+
lastMonth: "Letzter Monat",
|
|
127
|
+
};
|
|
128
|
+
case "es":
|
|
129
|
+
return {
|
|
130
|
+
any: "Cualquiera",
|
|
131
|
+
today: "Hoy",
|
|
132
|
+
yesterday: "Ayer",
|
|
133
|
+
last7: "Últimos 7 días",
|
|
134
|
+
last30: "Últimos 30 días",
|
|
135
|
+
thisMonth: "Este mes",
|
|
136
|
+
lastMonth: "Mes pasado",
|
|
137
|
+
};
|
|
138
|
+
case "zh":
|
|
139
|
+
return {
|
|
140
|
+
any: "不限",
|
|
141
|
+
today: "今天",
|
|
142
|
+
yesterday: "昨天",
|
|
143
|
+
last7: "最近7天",
|
|
144
|
+
last30: "最近30天",
|
|
145
|
+
thisMonth: "本月",
|
|
146
|
+
lastMonth: "上个月",
|
|
147
|
+
};
|
|
148
|
+
case "hi":
|
|
149
|
+
return {
|
|
150
|
+
any: "कोई भी",
|
|
151
|
+
today: "आज",
|
|
152
|
+
yesterday: "कल",
|
|
153
|
+
last7: "पिछले 7 दिन",
|
|
154
|
+
last30: "पिछले 30 दिन",
|
|
155
|
+
thisMonth: "इस माह",
|
|
156
|
+
lastMonth: "पिछला माह",
|
|
157
|
+
};
|
|
158
|
+
case "bn":
|
|
159
|
+
return {
|
|
160
|
+
any: "যেকোনো",
|
|
161
|
+
today: "আজ",
|
|
162
|
+
yesterday: "গতকাল",
|
|
163
|
+
last7: "শেষ ৭ দিন",
|
|
164
|
+
last30: "শেষ ৩০ দিন",
|
|
165
|
+
thisMonth: "এই মাস",
|
|
166
|
+
lastMonth: "গত মাস",
|
|
167
|
+
};
|
|
168
|
+
case "pt":
|
|
169
|
+
return {
|
|
170
|
+
any: "Qualquer",
|
|
171
|
+
today: "Hoje",
|
|
172
|
+
yesterday: "Ontem",
|
|
173
|
+
last7: "Últimos 7 dias",
|
|
174
|
+
last30: "Últimos 30 dias",
|
|
175
|
+
thisMonth: "Este mês",
|
|
176
|
+
lastMonth: "Mês passado",
|
|
177
|
+
};
|
|
178
|
+
case "ru":
|
|
179
|
+
return {
|
|
180
|
+
any: "Любой",
|
|
181
|
+
today: "Сегодня",
|
|
182
|
+
yesterday: "Вчера",
|
|
183
|
+
last7: "Последние 7 дней",
|
|
184
|
+
last30: "Последние 30 дней",
|
|
185
|
+
thisMonth: "Этот месяц",
|
|
186
|
+
lastMonth: "Прошлый месяц",
|
|
187
|
+
};
|
|
188
|
+
case "ja":
|
|
189
|
+
return {
|
|
190
|
+
any: "指定なし",
|
|
191
|
+
today: "今日",
|
|
192
|
+
yesterday: "昨日",
|
|
193
|
+
last7: "過去7日",
|
|
194
|
+
last30: "過去30日",
|
|
195
|
+
thisMonth: "今月",
|
|
196
|
+
lastMonth: "先月",
|
|
197
|
+
};
|
|
198
|
+
case "pa":
|
|
199
|
+
return {
|
|
200
|
+
any: "ਕੋਈ ਵੀ",
|
|
201
|
+
today: "ਅੱਜ",
|
|
202
|
+
yesterday: "ਕੱਲ੍ਹ",
|
|
203
|
+
last7: "ਪਿਛਲੇ 7 ਦਿਨ",
|
|
204
|
+
last30: "ਪਿਛਲੇ 30 ਦਿਨ",
|
|
205
|
+
thisMonth: "ਇਸ ਮਹੀਨੇ",
|
|
206
|
+
lastMonth: "ਪਿਛਲਾ ਮਹੀਨਾ",
|
|
207
|
+
};
|
|
208
|
+
case "mr":
|
|
209
|
+
return {
|
|
210
|
+
any: "कोणतेही",
|
|
211
|
+
today: "आज",
|
|
212
|
+
yesterday: "काल",
|
|
213
|
+
last7: "मागील 7 दिवस",
|
|
214
|
+
last30: "मागील 30 दिवस",
|
|
215
|
+
thisMonth: "हा महिना",
|
|
216
|
+
lastMonth: "मागील महिना",
|
|
217
|
+
};
|
|
218
|
+
case "fr":
|
|
219
|
+
return {
|
|
220
|
+
any: "Tout",
|
|
221
|
+
today: "Aujourd'hui",
|
|
222
|
+
yesterday: "Hier",
|
|
223
|
+
last7: "7 derniers jours",
|
|
224
|
+
last30: "30 derniers jours",
|
|
225
|
+
thisMonth: "Ce mois",
|
|
226
|
+
lastMonth: "Mois dernier",
|
|
227
|
+
};
|
|
228
|
+
case "it":
|
|
229
|
+
return {
|
|
230
|
+
any: "Qualsiasi",
|
|
231
|
+
today: "Oggi",
|
|
232
|
+
yesterday: "Ieri",
|
|
233
|
+
last7: "Ultimi 7 giorni",
|
|
234
|
+
last30: "Ultimi 30 giorni",
|
|
235
|
+
thisMonth: "Questo mese",
|
|
236
|
+
lastMonth: "Mese scorso",
|
|
237
|
+
};
|
|
238
|
+
case "nl":
|
|
239
|
+
return {
|
|
240
|
+
any: "Elke",
|
|
241
|
+
today: "Vandaag",
|
|
242
|
+
yesterday: "Gisteren",
|
|
243
|
+
last7: "Laatste 7 dagen",
|
|
244
|
+
last30: "Laatste 30 dagen",
|
|
245
|
+
thisMonth: "Deze maand",
|
|
246
|
+
lastMonth: "Vorige maand",
|
|
247
|
+
};
|
|
248
|
+
case "sv":
|
|
249
|
+
return {
|
|
250
|
+
any: "Alla",
|
|
251
|
+
today: "Idag",
|
|
252
|
+
yesterday: "Igår",
|
|
253
|
+
last7: "Senaste 7 dagar",
|
|
254
|
+
last30: "Senaste 30 dagar",
|
|
255
|
+
thisMonth: "Denna månad",
|
|
256
|
+
lastMonth: "Förra månaden",
|
|
257
|
+
};
|
|
258
|
+
case "pl":
|
|
259
|
+
return {
|
|
260
|
+
any: "Dowolny",
|
|
261
|
+
today: "Dzisiaj",
|
|
262
|
+
yesterday: "Wczoraj",
|
|
263
|
+
last7: "Ostatnie 7 dni",
|
|
264
|
+
last30: "Ostatnie 30 dni",
|
|
265
|
+
thisMonth: "Ten miesiąc",
|
|
266
|
+
lastMonth: "Poprzedni miesiąc",
|
|
267
|
+
};
|
|
268
|
+
case "da":
|
|
269
|
+
return {
|
|
270
|
+
any: "Alle",
|
|
271
|
+
today: "I dag",
|
|
272
|
+
yesterday: "I går",
|
|
273
|
+
last7: "Seneste 7 dage",
|
|
274
|
+
last30: "Seneste 30 dage",
|
|
275
|
+
thisMonth: "Denne måned",
|
|
276
|
+
lastMonth: "Sidste måned",
|
|
277
|
+
};
|
|
278
|
+
case "fi":
|
|
279
|
+
return {
|
|
280
|
+
any: "Kaikki",
|
|
281
|
+
today: "Tänään",
|
|
282
|
+
yesterday: "Eilen",
|
|
283
|
+
last7: "Viimeiset 7 päivää",
|
|
284
|
+
last30: "Viimeiset 30 päivää",
|
|
285
|
+
thisMonth: "Tämä kuukausi",
|
|
286
|
+
lastMonth: "Edellinen kuukausi",
|
|
287
|
+
};
|
|
288
|
+
case "no":
|
|
289
|
+
return {
|
|
290
|
+
any: "Alle",
|
|
291
|
+
today: "I dag",
|
|
292
|
+
yesterday: "I går",
|
|
293
|
+
last7: "Siste 7 dager",
|
|
294
|
+
last30: "Siste 30 dager",
|
|
295
|
+
thisMonth: "Denne måneden",
|
|
296
|
+
lastMonth: "Forrige måned",
|
|
297
|
+
};
|
|
298
|
+
case "cs":
|
|
299
|
+
return {
|
|
300
|
+
any: "Libovolný",
|
|
301
|
+
today: "Dnes",
|
|
302
|
+
yesterday: "Včera",
|
|
303
|
+
last7: "Posledních 7 dní",
|
|
304
|
+
last30: "Posledních 30 dní",
|
|
305
|
+
thisMonth: "Tento měsíc",
|
|
306
|
+
lastMonth: "Minulý měsíc",
|
|
307
|
+
};
|
|
308
|
+
default:
|
|
309
|
+
case "en":
|
|
310
|
+
return {
|
|
311
|
+
any: "Any",
|
|
312
|
+
today: "Today",
|
|
313
|
+
yesterday: "Yesterday",
|
|
314
|
+
last7: "Last 7 days",
|
|
315
|
+
last30: "Last 30 days",
|
|
316
|
+
thisMonth: "This month",
|
|
317
|
+
lastMonth: "Last month",
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* @private
|
|
324
|
+
* @return {DatePresets}
|
|
325
|
+
*/
|
|
326
|
+
function initControlReferences() {
|
|
327
|
+
if (!this.shadowRoot) {
|
|
328
|
+
throw new Error("no shadow-root is defined");
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
this[selectElementSymbol] = this.shadowRoot.querySelector(
|
|
332
|
+
"[data-monster-role=query]",
|
|
333
|
+
);
|
|
334
|
+
return this;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* @private
|
|
339
|
+
* @return {void}
|
|
340
|
+
*/
|
|
341
|
+
function updateOptions() {
|
|
342
|
+
const labels = this.getOption("labels");
|
|
343
|
+
const currentValue = this[selectElementSymbol].value;
|
|
344
|
+
const presets = buildPresets(labels);
|
|
345
|
+
|
|
346
|
+
this[selectElementSymbol].innerHTML = "";
|
|
347
|
+
|
|
348
|
+
for (const preset of presets) {
|
|
349
|
+
const option = document.createElement("option");
|
|
350
|
+
option.value = preset.value;
|
|
351
|
+
option.textContent = preset.label;
|
|
352
|
+
this[selectElementSymbol].append(option);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (currentValue) {
|
|
356
|
+
this[selectElementSymbol].value = currentValue;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* @private
|
|
362
|
+
* @param {Object} labels
|
|
363
|
+
* @return {Array<{label: string, value: string}>}
|
|
364
|
+
*/
|
|
365
|
+
function buildPresets(labels) {
|
|
366
|
+
const today = new Date();
|
|
367
|
+
const todayString = formatDate(today);
|
|
368
|
+
const yesterday = formatDate(addDays(today, -1));
|
|
369
|
+
const last7 = buildRange(addDays(today, -6), today);
|
|
370
|
+
const last30 = buildRange(addDays(today, -29), today);
|
|
371
|
+
const thisMonthStart = new Date(today.getFullYear(), today.getMonth(), 1);
|
|
372
|
+
const thisMonthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0);
|
|
373
|
+
const lastMonthStart = new Date(today.getFullYear(), today.getMonth() - 1, 1);
|
|
374
|
+
const lastMonthEnd = new Date(today.getFullYear(), today.getMonth(), 0);
|
|
375
|
+
|
|
376
|
+
return [
|
|
377
|
+
{ label: labels.any, value: "" },
|
|
378
|
+
{ label: labels.today, value: todayString },
|
|
379
|
+
{ label: labels.yesterday, value: yesterday },
|
|
380
|
+
{ label: labels.last7, value: last7 },
|
|
381
|
+
{ label: labels.last30, value: last30 },
|
|
382
|
+
{ label: labels.thisMonth, value: buildRange(thisMonthStart, thisMonthEnd) },
|
|
383
|
+
{ label: labels.lastMonth, value: buildRange(lastMonthStart, lastMonthEnd) },
|
|
384
|
+
];
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* @private
|
|
389
|
+
* @param {Date} date
|
|
390
|
+
* @return {string}
|
|
391
|
+
*/
|
|
392
|
+
function formatDate(date) {
|
|
393
|
+
const year = date.getFullYear();
|
|
394
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
395
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
396
|
+
return `${year}-${month}-${day}`;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* @private
|
|
401
|
+
* @param {Date} from
|
|
402
|
+
* @param {Date} to
|
|
403
|
+
* @return {string}
|
|
404
|
+
*/
|
|
405
|
+
function buildRange(from, to) {
|
|
406
|
+
return `${formatDate(from)} - ${formatDate(to)}`;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* @private
|
|
411
|
+
* @param {Date} date
|
|
412
|
+
* @param {number} amount
|
|
413
|
+
* @return {Date}
|
|
414
|
+
*/
|
|
415
|
+
function addDays(date, amount) {
|
|
416
|
+
const d = new Date(date);
|
|
417
|
+
d.setDate(d.getDate() + amount);
|
|
418
|
+
return d;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* @private
|
|
423
|
+
* @return {string}
|
|
424
|
+
*/
|
|
425
|
+
function getTemplate() {
|
|
426
|
+
// language=HTML
|
|
427
|
+
return `
|
|
428
|
+
<div data-monster-role="control" part="control">
|
|
429
|
+
<slot></slot>
|
|
430
|
+
<select name="query" data-monster-role="query" data-monster-attributes="value path:query"></select>
|
|
431
|
+
</div>
|
|
432
|
+
`;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
registerCustomElement(DatePresets);
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
|
|
3
|
+
* Node module: @schukai/monster
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
|
|
6
|
+
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
|
|
7
|
+
*
|
|
8
|
+
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
|
|
9
|
+
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
|
|
10
|
+
* For more information about purchasing a commercial license, please contact Volker Schukai.
|
|
11
|
+
*
|
|
12
|
+
* SPDX-License-Identifier: AGPL-3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { instanceSymbol } from "../../../constants.mjs";
|
|
16
|
+
import {
|
|
17
|
+
assembleMethodSymbol,
|
|
18
|
+
CustomElement,
|
|
19
|
+
registerCustomElement,
|
|
20
|
+
} from "../../../dom/customelement.mjs";
|
|
21
|
+
import { FilterControlsDefaultsStyleSheet } from "../stylesheet/filter-controls-defaults.mjs";
|
|
22
|
+
import { FilterStyleSheet } from "../stylesheet/filter.mjs";
|
|
23
|
+
import { AbstractBase } from "./abstract-base.mjs";
|
|
24
|
+
|
|
25
|
+
export { DateTimeFilter };
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* local symbol
|
|
29
|
+
* @private
|
|
30
|
+
* @type {symbol}
|
|
31
|
+
*/
|
|
32
|
+
const inputElementSymbol = Symbol("inputElement");
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The Filter component is used to show and handle the filter values.
|
|
36
|
+
*
|
|
37
|
+
* @copyright Volker Schukai
|
|
38
|
+
* @summary The FilterDateTime component is used to show and handle datetime values.
|
|
39
|
+
*/
|
|
40
|
+
class DateTimeFilter extends AbstractBase {
|
|
41
|
+
/**
|
|
42
|
+
* This method is called by the `instanceof` operator.
|
|
43
|
+
* @return {symbol}
|
|
44
|
+
*/
|
|
45
|
+
static get [instanceSymbol]() {
|
|
46
|
+
return Symbol.for("@schukai/monster/components/filter/date-time@@instance");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
|
51
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
52
|
+
*
|
|
53
|
+
* The individual configuration values can be found in the table.
|
|
54
|
+
*
|
|
55
|
+
* @property {Object} templates Template definitions
|
|
56
|
+
* @property {string} templates.main Main template
|
|
57
|
+
* @property {object} datasource The datasource
|
|
58
|
+
* @property {boolean} autoLoad If true, the datasource is called immediately after the control is created.
|
|
59
|
+
*/
|
|
60
|
+
get defaults() {
|
|
61
|
+
return Object.assign({}, super.defaults, {
|
|
62
|
+
templates: {
|
|
63
|
+
main: getTemplate(),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @return {string}
|
|
71
|
+
*/
|
|
72
|
+
static getTag() {
|
|
73
|
+
return "monster-filter-date-time";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @return {FilterButton}
|
|
79
|
+
*/
|
|
80
|
+
[assembleMethodSymbol]() {
|
|
81
|
+
super[assembleMethodSymbol]();
|
|
82
|
+
|
|
83
|
+
initControlReferences.call(this);
|
|
84
|
+
initEventHandler.call(this);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @return Array<CSSStyleSheet>
|
|
89
|
+
*/
|
|
90
|
+
static getCSSStyleSheet() {
|
|
91
|
+
return [FilterControlsDefaultsStyleSheet, FilterStyleSheet];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
96
|
+
*
|
|
97
|
+
* @param {*} value
|
|
98
|
+
*/
|
|
99
|
+
set value(value) {
|
|
100
|
+
this[inputElementSymbol].value = value;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @return {*}
|
|
105
|
+
*/
|
|
106
|
+
get value() {
|
|
107
|
+
return this[inputElementSymbol].value;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @private
|
|
113
|
+
* @return {DateTimeFilter}
|
|
114
|
+
*/
|
|
115
|
+
function initControlReferences() {
|
|
116
|
+
if (!this.shadowRoot) {
|
|
117
|
+
throw new Error("no shadow-root is defined");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
this[inputElementSymbol] = this.shadowRoot.querySelector(
|
|
121
|
+
"[data-monster-role=query]",
|
|
122
|
+
);
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
function initEventHandler() {}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @private
|
|
133
|
+
* @return {string}
|
|
134
|
+
*/
|
|
135
|
+
function getTemplate() {
|
|
136
|
+
// language=HTML
|
|
137
|
+
return `
|
|
138
|
+
<div data-monster-role="control" part="control">
|
|
139
|
+
<slot></slot>
|
|
140
|
+
<input type="datetime-local" name="query" data-monster-role="query" data-monster-attributes="value path:query">
|
|
141
|
+
</div>
|
|
142
|
+
`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
registerCustomElement(DateTimeFilter);
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
|
|
3
|
+
* Node module: @schukai/monster
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
|
|
6
|
+
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
|
|
7
|
+
*
|
|
8
|
+
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
|
|
9
|
+
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
|
|
10
|
+
* For more information about purchasing a commercial license, please contact Volker Schukai.
|
|
11
|
+
*
|
|
12
|
+
* SPDX-License-Identifier: AGPL-3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { instanceSymbol } from "../../../constants.mjs";
|
|
16
|
+
import {
|
|
17
|
+
assembleMethodSymbol,
|
|
18
|
+
CustomElement,
|
|
19
|
+
registerCustomElement,
|
|
20
|
+
} from "../../../dom/customelement.mjs";
|
|
21
|
+
import { FilterControlsDefaultsStyleSheet } from "../stylesheet/filter-controls-defaults.mjs";
|
|
22
|
+
import { FilterStyleSheet } from "../stylesheet/filter.mjs";
|
|
23
|
+
import { AbstractBase } from "./abstract-base.mjs";
|
|
24
|
+
|
|
25
|
+
export { DateFilter };
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* local symbol
|
|
29
|
+
* @private
|
|
30
|
+
* @type {symbol}
|
|
31
|
+
*/
|
|
32
|
+
const inputElementSymbol = Symbol("inputElement");
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The Filter component is used to show and handle the filter values.
|
|
36
|
+
*
|
|
37
|
+
* @copyright Volker Schukai
|
|
38
|
+
* @summary The FilterDate component is used to show and handle date values.
|
|
39
|
+
*/
|
|
40
|
+
class DateFilter extends AbstractBase {
|
|
41
|
+
/**
|
|
42
|
+
* This method is called by the `instanceof` operator.
|
|
43
|
+
* @return {symbol}
|
|
44
|
+
*/
|
|
45
|
+
static get [instanceSymbol]() {
|
|
46
|
+
return Symbol.for("@schukai/monster/components/filter/date@@instance");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
|
51
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
52
|
+
*
|
|
53
|
+
* The individual configuration values can be found in the table.
|
|
54
|
+
*
|
|
55
|
+
* @property {Object} templates Template definitions
|
|
56
|
+
* @property {string} templates.main Main template
|
|
57
|
+
* @property {object} datasource The datasource
|
|
58
|
+
* @property {boolean} autoLoad If true, the datasource is called immediately after the control is created.
|
|
59
|
+
*/
|
|
60
|
+
get defaults() {
|
|
61
|
+
return Object.assign({}, super.defaults, {
|
|
62
|
+
templates: {
|
|
63
|
+
main: getTemplate(),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @return {string}
|
|
71
|
+
*/
|
|
72
|
+
static getTag() {
|
|
73
|
+
return "monster-filter-date";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @return {FilterButton}
|
|
79
|
+
*/
|
|
80
|
+
[assembleMethodSymbol]() {
|
|
81
|
+
super[assembleMethodSymbol]();
|
|
82
|
+
|
|
83
|
+
initControlReferences.call(this);
|
|
84
|
+
initEventHandler.call(this);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @return Array<CSSStyleSheet>
|
|
89
|
+
*/
|
|
90
|
+
static getCSSStyleSheet() {
|
|
91
|
+
return [FilterControlsDefaultsStyleSheet, FilterStyleSheet];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
96
|
+
*
|
|
97
|
+
* @param {*} value
|
|
98
|
+
*/
|
|
99
|
+
set value(value) {
|
|
100
|
+
this[inputElementSymbol].value = value;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @return {*}
|
|
105
|
+
*/
|
|
106
|
+
get value() {
|
|
107
|
+
return this[inputElementSymbol].value;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @private
|
|
113
|
+
* @return {DateFilter}
|
|
114
|
+
*/
|
|
115
|
+
function initControlReferences() {
|
|
116
|
+
if (!this.shadowRoot) {
|
|
117
|
+
throw new Error("no shadow-root is defined");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
this[inputElementSymbol] = this.shadowRoot.querySelector(
|
|
121
|
+
"[data-monster-role=query]",
|
|
122
|
+
);
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
function initEventHandler() {}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @private
|
|
133
|
+
* @return {string}
|
|
134
|
+
*/
|
|
135
|
+
function getTemplate() {
|
|
136
|
+
// language=HTML
|
|
137
|
+
return `
|
|
138
|
+
<div data-monster-role="control" part="control">
|
|
139
|
+
<slot></slot>
|
|
140
|
+
<input type="date" name="query" data-monster-role="query" data-monster-attributes="value path:query">
|
|
141
|
+
</div>
|
|
142
|
+
`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
registerCustomElement(DateFilter);
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
|
|
3
|
+
* Node module: @schukai/monster
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
|
|
6
|
+
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
|
|
7
|
+
*
|
|
8
|
+
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
|
|
9
|
+
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
|
|
10
|
+
* For more information about purchasing a commercial license, please contact Volker Schukai.
|
|
11
|
+
*
|
|
12
|
+
* SPDX-License-Identifier: AGPL-3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { instanceSymbol } from "../../../constants.mjs";
|
|
16
|
+
import {
|
|
17
|
+
assembleMethodSymbol,
|
|
18
|
+
registerCustomElement,
|
|
19
|
+
} from "../../../dom/customelement.mjs";
|
|
20
|
+
import { FilterControlsDefaultsStyleSheet } from "../stylesheet/filter-controls-defaults.mjs";
|
|
21
|
+
import { FilterStyleSheet } from "../stylesheet/filter.mjs";
|
|
22
|
+
import { AbstractBase } from "./abstract-base.mjs";
|
|
23
|
+
import { getLocaleOfDocument } from "../../../dom/locale.mjs";
|
|
24
|
+
import "../../form/input-group.mjs";
|
|
25
|
+
|
|
26
|
+
export { TextOperator };
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* local symbol
|
|
30
|
+
* @private
|
|
31
|
+
* @type {symbol}
|
|
32
|
+
*/
|
|
33
|
+
const operatorElementSymbol = Symbol("operatorElement");
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* local symbol
|
|
37
|
+
* @private
|
|
38
|
+
* @type {symbol}
|
|
39
|
+
*/
|
|
40
|
+
const inputElementSymbol = Symbol("inputElement");
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The Filter component is used to show and handle the filter values.
|
|
44
|
+
*
|
|
45
|
+
* @copyright Volker Schukai
|
|
46
|
+
* @summary The FilterTextOperator component combines operator and query input.
|
|
47
|
+
*/
|
|
48
|
+
class TextOperator extends AbstractBase {
|
|
49
|
+
/**
|
|
50
|
+
* This method is called by the `instanceof` operator.
|
|
51
|
+
* @return {symbol}
|
|
52
|
+
*/
|
|
53
|
+
static get [instanceSymbol]() {
|
|
54
|
+
return Symbol.for("@schukai/monster/components/filter/text-operator@@instance");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
|
59
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
60
|
+
*
|
|
61
|
+
* The individual configuration values can be found in the table.
|
|
62
|
+
*
|
|
63
|
+
* @property {Object} templates Template definitions
|
|
64
|
+
* @property {string} templates.main Main template
|
|
65
|
+
* @property {Object} labels Text labels
|
|
66
|
+
*/
|
|
67
|
+
get defaults() {
|
|
68
|
+
return Object.assign({}, super.defaults, {
|
|
69
|
+
templates: {
|
|
70
|
+
main: getTemplate(),
|
|
71
|
+
},
|
|
72
|
+
labels: getTranslations(),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @return {string}
|
|
79
|
+
*/
|
|
80
|
+
static getTag() {
|
|
81
|
+
return "monster-filter-text-operator";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @return {FilterButton}
|
|
87
|
+
*/
|
|
88
|
+
[assembleMethodSymbol]() {
|
|
89
|
+
super[assembleMethodSymbol]();
|
|
90
|
+
|
|
91
|
+
initControlReferences.call(this);
|
|
92
|
+
updateOptions.call(this);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @return Array<CSSStyleSheet>
|
|
97
|
+
*/
|
|
98
|
+
static getCSSStyleSheet() {
|
|
99
|
+
return [FilterControlsDefaultsStyleSheet, FilterStyleSheet];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
104
|
+
*
|
|
105
|
+
* @param {*} value
|
|
106
|
+
*/
|
|
107
|
+
set value(value) {
|
|
108
|
+
const parsed = parseValue(value);
|
|
109
|
+
this[operatorElementSymbol].value = parsed.operator;
|
|
110
|
+
this[inputElementSymbol].value = parsed.query;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @return {*}
|
|
115
|
+
*/
|
|
116
|
+
get value() {
|
|
117
|
+
const query = `${this[inputElementSymbol].value || ""}`.trim();
|
|
118
|
+
if (!query) {
|
|
119
|
+
return "";
|
|
120
|
+
}
|
|
121
|
+
return `${this[operatorElementSymbol].value}${query}`;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @private
|
|
127
|
+
* @returns {Object}
|
|
128
|
+
*/
|
|
129
|
+
function getTranslations() {
|
|
130
|
+
const locale = getLocaleOfDocument();
|
|
131
|
+
switch (locale.language) {
|
|
132
|
+
case "de":
|
|
133
|
+
return {
|
|
134
|
+
contains: "Enthält",
|
|
135
|
+
equals: "Gleich",
|
|
136
|
+
notEqual: "Ungleich",
|
|
137
|
+
startsWith: "Beginnt mit",
|
|
138
|
+
endsWith: "Endet mit",
|
|
139
|
+
};
|
|
140
|
+
case "es":
|
|
141
|
+
return {
|
|
142
|
+
contains: "Contiene",
|
|
143
|
+
equals: "Igual",
|
|
144
|
+
notEqual: "Distinto",
|
|
145
|
+
startsWith: "Empieza con",
|
|
146
|
+
endsWith: "Termina con",
|
|
147
|
+
};
|
|
148
|
+
case "zh":
|
|
149
|
+
return {
|
|
150
|
+
contains: "包含",
|
|
151
|
+
equals: "等于",
|
|
152
|
+
notEqual: "不等于",
|
|
153
|
+
startsWith: "开头为",
|
|
154
|
+
endsWith: "结尾为",
|
|
155
|
+
};
|
|
156
|
+
case "hi":
|
|
157
|
+
return {
|
|
158
|
+
contains: "शामिल है",
|
|
159
|
+
equals: "समान",
|
|
160
|
+
notEqual: "समान नहीं",
|
|
161
|
+
startsWith: "से शुरू",
|
|
162
|
+
endsWith: "पर समाप्त",
|
|
163
|
+
};
|
|
164
|
+
case "bn":
|
|
165
|
+
return {
|
|
166
|
+
contains: "অন্তর্ভুক্ত",
|
|
167
|
+
equals: "সমান",
|
|
168
|
+
notEqual: "সমান নয়",
|
|
169
|
+
startsWith: "দিয়ে শুরু",
|
|
170
|
+
endsWith: "দিয়ে শেষ",
|
|
171
|
+
};
|
|
172
|
+
case "pt":
|
|
173
|
+
return {
|
|
174
|
+
contains: "Contém",
|
|
175
|
+
equals: "Igual",
|
|
176
|
+
notEqual: "Diferente",
|
|
177
|
+
startsWith: "Começa com",
|
|
178
|
+
endsWith: "Termina com",
|
|
179
|
+
};
|
|
180
|
+
case "ru":
|
|
181
|
+
return {
|
|
182
|
+
contains: "Содержит",
|
|
183
|
+
equals: "Равно",
|
|
184
|
+
notEqual: "Не равно",
|
|
185
|
+
startsWith: "Начинается с",
|
|
186
|
+
endsWith: "Заканчивается на",
|
|
187
|
+
};
|
|
188
|
+
case "ja":
|
|
189
|
+
return {
|
|
190
|
+
contains: "含む",
|
|
191
|
+
equals: "等しい",
|
|
192
|
+
notEqual: "等しくない",
|
|
193
|
+
startsWith: "で始まる",
|
|
194
|
+
endsWith: "で終わる",
|
|
195
|
+
};
|
|
196
|
+
case "pa":
|
|
197
|
+
return {
|
|
198
|
+
contains: "ਸ਼ਾਮਲ ਹੈ",
|
|
199
|
+
equals: "ਬਰਾਬਰ",
|
|
200
|
+
notEqual: "ਬਰਾਬਰ ਨਹੀਂ",
|
|
201
|
+
startsWith: "ਨਾਲ ਸ਼ੁਰੂ",
|
|
202
|
+
endsWith: "ਨਾਲ ਖਤਮ",
|
|
203
|
+
};
|
|
204
|
+
case "mr":
|
|
205
|
+
return {
|
|
206
|
+
contains: "समाविष्ट",
|
|
207
|
+
equals: "समान",
|
|
208
|
+
notEqual: "समान नाही",
|
|
209
|
+
startsWith: "ने सुरू",
|
|
210
|
+
endsWith: "ने समाप्त",
|
|
211
|
+
};
|
|
212
|
+
case "fr":
|
|
213
|
+
return {
|
|
214
|
+
contains: "Contient",
|
|
215
|
+
equals: "Égal",
|
|
216
|
+
notEqual: "Différent",
|
|
217
|
+
startsWith: "Commence par",
|
|
218
|
+
endsWith: "Se termine par",
|
|
219
|
+
};
|
|
220
|
+
case "it":
|
|
221
|
+
return {
|
|
222
|
+
contains: "Contiene",
|
|
223
|
+
equals: "Uguale",
|
|
224
|
+
notEqual: "Diverso",
|
|
225
|
+
startsWith: "Inizia con",
|
|
226
|
+
endsWith: "Finisce con",
|
|
227
|
+
};
|
|
228
|
+
case "nl":
|
|
229
|
+
return {
|
|
230
|
+
contains: "Bevat",
|
|
231
|
+
equals: "Gelijk",
|
|
232
|
+
notEqual: "Niet gelijk",
|
|
233
|
+
startsWith: "Begint met",
|
|
234
|
+
endsWith: "Eindigt met",
|
|
235
|
+
};
|
|
236
|
+
case "sv":
|
|
237
|
+
return {
|
|
238
|
+
contains: "Innehåller",
|
|
239
|
+
equals: "Lika med",
|
|
240
|
+
notEqual: "Inte lika",
|
|
241
|
+
startsWith: "Börjar med",
|
|
242
|
+
endsWith: "Slutar med",
|
|
243
|
+
};
|
|
244
|
+
case "pl":
|
|
245
|
+
return {
|
|
246
|
+
contains: "Zawiera",
|
|
247
|
+
equals: "Równe",
|
|
248
|
+
notEqual: "Nie równe",
|
|
249
|
+
startsWith: "Zaczyna się od",
|
|
250
|
+
endsWith: "Kończy się na",
|
|
251
|
+
};
|
|
252
|
+
case "da":
|
|
253
|
+
return {
|
|
254
|
+
contains: "Indeholder",
|
|
255
|
+
equals: "Lig med",
|
|
256
|
+
notEqual: "Ikke lig med",
|
|
257
|
+
startsWith: "Starter med",
|
|
258
|
+
endsWith: "Slutter med",
|
|
259
|
+
};
|
|
260
|
+
case "fi":
|
|
261
|
+
return {
|
|
262
|
+
contains: "Sisältää",
|
|
263
|
+
equals: "Yhtä kuin",
|
|
264
|
+
notEqual: "Ei yhtä kuin",
|
|
265
|
+
startsWith: "Alkaa",
|
|
266
|
+
endsWith: "Päättyy",
|
|
267
|
+
};
|
|
268
|
+
case "no":
|
|
269
|
+
return {
|
|
270
|
+
contains: "Inneholder",
|
|
271
|
+
equals: "Lik",
|
|
272
|
+
notEqual: "Ikke lik",
|
|
273
|
+
startsWith: "Starter med",
|
|
274
|
+
endsWith: "Slutter med",
|
|
275
|
+
};
|
|
276
|
+
case "cs":
|
|
277
|
+
return {
|
|
278
|
+
contains: "Obsahuje",
|
|
279
|
+
equals: "Rovno",
|
|
280
|
+
notEqual: "Nerovno",
|
|
281
|
+
startsWith: "Začíná na",
|
|
282
|
+
endsWith: "Končí na",
|
|
283
|
+
};
|
|
284
|
+
default:
|
|
285
|
+
case "en":
|
|
286
|
+
return {
|
|
287
|
+
contains: "Contains",
|
|
288
|
+
equals: "Equals",
|
|
289
|
+
notEqual: "Not equal",
|
|
290
|
+
startsWith: "Starts with",
|
|
291
|
+
endsWith: "Ends with",
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* @private
|
|
298
|
+
* @return {TextOperator}
|
|
299
|
+
*/
|
|
300
|
+
function initControlReferences() {
|
|
301
|
+
if (!this.shadowRoot) {
|
|
302
|
+
throw new Error("no shadow-root is defined");
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
this[operatorElementSymbol] = this.shadowRoot.querySelector(
|
|
306
|
+
"[data-monster-role=operator]",
|
|
307
|
+
);
|
|
308
|
+
this[inputElementSymbol] = this.shadowRoot.querySelector(
|
|
309
|
+
"[data-monster-role=query]",
|
|
310
|
+
);
|
|
311
|
+
return this;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* @private
|
|
316
|
+
* @return {void}
|
|
317
|
+
*/
|
|
318
|
+
function updateOptions() {
|
|
319
|
+
const labels = this.getOption("labels");
|
|
320
|
+
const currentValue = this[operatorElementSymbol].value;
|
|
321
|
+
|
|
322
|
+
const operators = [
|
|
323
|
+
{ value: ":", label: labels.contains },
|
|
324
|
+
{ value: "=", label: labels.equals },
|
|
325
|
+
{ value: "!=", label: labels.notEqual },
|
|
326
|
+
{ value: "^=", label: labels.startsWith },
|
|
327
|
+
{ value: "$=", label: labels.endsWith },
|
|
328
|
+
];
|
|
329
|
+
|
|
330
|
+
this[operatorElementSymbol].innerHTML = "";
|
|
331
|
+
for (const operator of operators) {
|
|
332
|
+
const option = document.createElement("option");
|
|
333
|
+
option.value = operator.value;
|
|
334
|
+
option.textContent = operator.label;
|
|
335
|
+
this[operatorElementSymbol].append(option);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (currentValue) {
|
|
339
|
+
this[operatorElementSymbol].value = currentValue;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* @private
|
|
345
|
+
* @param {string} value
|
|
346
|
+
* @return {{operator: string, query: string}}
|
|
347
|
+
*/
|
|
348
|
+
function parseValue(value) {
|
|
349
|
+
if (!value) {
|
|
350
|
+
return { operator: ":", query: "" };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const operators = ["!=", "<>", "^=", "$=", "=", ":"];
|
|
354
|
+
for (const op of operators) {
|
|
355
|
+
if (value.startsWith(op)) {
|
|
356
|
+
return { operator: op === "<>" ? "!=" : op, query: value.slice(op.length) };
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return { operator: ":", query: value };
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* @private
|
|
365
|
+
* @return {string}
|
|
366
|
+
*/
|
|
367
|
+
function getTemplate() {
|
|
368
|
+
// language=HTML
|
|
369
|
+
return `
|
|
370
|
+
<div data-monster-role="control" part="control">
|
|
371
|
+
<slot></slot>
|
|
372
|
+
<monster-input-group>
|
|
373
|
+
<select slot="prefix" data-monster-role="operator" name="operator"></select>
|
|
374
|
+
<input type="search" data-monster-role="query" name="query" data-monster-attributes="value path:query">
|
|
375
|
+
</monster-input-group>
|
|
376
|
+
</div>
|
|
377
|
+
`;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
registerCustomElement(TextOperator);
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
|
|
3
|
+
* Node module: @schukai/monster
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
|
|
6
|
+
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
|
|
7
|
+
*
|
|
8
|
+
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
|
|
9
|
+
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
|
|
10
|
+
* For more information about purchasing a commercial license, please contact Volker Schukai.
|
|
11
|
+
*
|
|
12
|
+
* SPDX-License-Identifier: AGPL-3.0
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { instanceSymbol } from "../../../constants.mjs";
|
|
16
|
+
import {
|
|
17
|
+
assembleMethodSymbol,
|
|
18
|
+
CustomElement,
|
|
19
|
+
registerCustomElement,
|
|
20
|
+
} from "../../../dom/customelement.mjs";
|
|
21
|
+
import { FilterControlsDefaultsStyleSheet } from "../stylesheet/filter-controls-defaults.mjs";
|
|
22
|
+
import { FilterStyleSheet } from "../stylesheet/filter.mjs";
|
|
23
|
+
import { AbstractBase } from "./abstract-base.mjs";
|
|
24
|
+
|
|
25
|
+
export { TimeFilter };
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* local symbol
|
|
29
|
+
* @private
|
|
30
|
+
* @type {symbol}
|
|
31
|
+
*/
|
|
32
|
+
const inputElementSymbol = Symbol("inputElement");
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The Filter component is used to show and handle the filter values.
|
|
36
|
+
*
|
|
37
|
+
* @copyright Volker Schukai
|
|
38
|
+
* @summary The FilterTime component is used to show and handle time values.
|
|
39
|
+
*/
|
|
40
|
+
class TimeFilter extends AbstractBase {
|
|
41
|
+
/**
|
|
42
|
+
* This method is called by the `instanceof` operator.
|
|
43
|
+
* @return {symbol}
|
|
44
|
+
*/
|
|
45
|
+
static get [instanceSymbol]() {
|
|
46
|
+
return Symbol.for("@schukai/monster/components/filter/time@@instance");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
|
|
51
|
+
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
|
|
52
|
+
*
|
|
53
|
+
* The individual configuration values can be found in the table.
|
|
54
|
+
*
|
|
55
|
+
* @property {Object} templates Template definitions
|
|
56
|
+
* @property {string} templates.main Main template
|
|
57
|
+
* @property {object} datasource The datasource
|
|
58
|
+
* @property {boolean} autoLoad If true, the datasource is called immediately after the control is created.
|
|
59
|
+
*/
|
|
60
|
+
get defaults() {
|
|
61
|
+
return Object.assign({}, super.defaults, {
|
|
62
|
+
templates: {
|
|
63
|
+
main: getTemplate(),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* @return {string}
|
|
71
|
+
*/
|
|
72
|
+
static getTag() {
|
|
73
|
+
return "monster-filter-time";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
*
|
|
78
|
+
* @return {FilterButton}
|
|
79
|
+
*/
|
|
80
|
+
[assembleMethodSymbol]() {
|
|
81
|
+
super[assembleMethodSymbol]();
|
|
82
|
+
|
|
83
|
+
initControlReferences.call(this);
|
|
84
|
+
initEventHandler.call(this);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* @return Array<CSSStyleSheet>
|
|
89
|
+
*/
|
|
90
|
+
static getCSSStyleSheet() {
|
|
91
|
+
return [FilterControlsDefaultsStyleSheet, FilterStyleSheet];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
|
|
96
|
+
*
|
|
97
|
+
* @param {*} value
|
|
98
|
+
*/
|
|
99
|
+
set value(value) {
|
|
100
|
+
this[inputElementSymbol].value = value;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @return {*}
|
|
105
|
+
*/
|
|
106
|
+
get value() {
|
|
107
|
+
return this[inputElementSymbol].value;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* @private
|
|
113
|
+
* @return {TimeFilter}
|
|
114
|
+
*/
|
|
115
|
+
function initControlReferences() {
|
|
116
|
+
if (!this.shadowRoot) {
|
|
117
|
+
throw new Error("no shadow-root is defined");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
this[inputElementSymbol] = this.shadowRoot.querySelector(
|
|
121
|
+
"[data-monster-role=query]",
|
|
122
|
+
);
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
function initEventHandler() {}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @private
|
|
133
|
+
* @return {string}
|
|
134
|
+
*/
|
|
135
|
+
function getTemplate() {
|
|
136
|
+
// language=HTML
|
|
137
|
+
return `
|
|
138
|
+
<div data-monster-role="control" part="control">
|
|
139
|
+
<slot></slot>
|
|
140
|
+
<input type="time" name="query" data-monster-role="query" data-monster-attributes="value path:query">
|
|
141
|
+
</div>
|
|
142
|
+
`;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
registerCustomElement(TimeFilter);
|
|
@@ -25,7 +25,7 @@ try {
|
|
|
25
25
|
FilterControlsDefaultsStyleSheet.insertRule(
|
|
26
26
|
`
|
|
27
27
|
@layer filtercontrolsdefaults {
|
|
28
|
-
[data-monster-role=control]{box-sizing:border-box;outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}input,meter,progress,select,textarea{accent-color:var(--monster-color-secondary-2);background-color:var(--monster-bg-color-primary-1);border-color:var(--monster-theme-control-border-color);border-radius:var(--monster-theme-control-border-radius);border-style:var(--monster-theme-control-border-style);border-width:var(--monster-theme-control-border-width);box-sizing:border-box;color:var(--monster-color-primary-1);font-family:inherit;font-size:100%;margin:0;outline:none}input,select,textarea{height:-moz-fit-content;height:fit-content;padding:.4rem .6rem}textarea{min-height:6rem;resize:vertical}input[type=color]{height:2rem;margin:0;padding:.1rem;width:2rem}input:hover:not([type=radio]):not([type=checkbox]):not([type=range]),select:hover,textarea:hover{box-shadow:var(--monster-box-shadow-2);transition:background .8s,color .25s .0833333333s}input:focus,select:focus,textarea:focus{outline:1px dashed var(--monster-color-selection-3);outline-offset:3px}:host{height:100%;width:100%}div[data-monster-role=control]{display:flex;height:100%;position:relative}div[data-monster-role=control] .form-container{margin:0 auto;max-width:600px}:is(div[data-monster-role=control] .form-container) .form-group{margin-bottom:.2rem}:is(:is(div[data-monster-role=control] .form-container) .form-group) input[type=number]{text-align:right;width:5rem}:is(:is(div[data-monster-role=control] .form-container) .form-group) input[type=number]::-webkit-inner-spin-button,:is(:is(div[data-monster-role=control] .form-container) .form-group) input[type=number]::-webkit-outer-spin-button{margin-left:10px}:is(:is(div[data-monster-role=control] .form-container) .form-group) input[type=radio]{accent-color:var(--monster-bg-color-primary-3)}[data-monster-role=popper]{position:absolute}
|
|
28
|
+
[data-monster-role=control]{box-sizing:border-box;outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:host{box-sizing:border-box;display:block}div[data-monster-role=popper]{align-content:center;background:var(--monster-bg-color-primary-1);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);box-sizing:border-box;color:var(--monster-color-primary-1);display:none;justify-content:space-between;left:0;padding:1.1em;position:absolute;top:0;width:-moz-max-content;width:max-content;z-index:var(--monster-z-index-modal)}div[data-monster-role=popper] div[data-monster-role=arrow]{background:var(--monster-bg-color-primary-1);height:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);pointer-events:none;position:absolute;width:calc(max(var(--monster-popper-witharrrow-distance), -1 * var(--monster-popper-witharrrow-distance))*2);z-index:-1}input,meter,progress,select,textarea{accent-color:var(--monster-color-secondary-2);background-color:var(--monster-bg-color-primary-1);border-color:var(--monster-theme-control-border-color);border-radius:var(--monster-theme-control-border-radius);border-style:var(--monster-theme-control-border-style);border-width:var(--monster-theme-control-border-width);box-sizing:border-box;color:var(--monster-color-primary-1);font-family:inherit;font-size:100%;margin:0;outline:none}input,select,textarea{height:-moz-fit-content;height:fit-content;padding:.4rem .6rem}textarea{min-height:6rem;resize:vertical}input[type=color]{height:2rem;margin:0;padding:.1rem;width:2rem}input:hover:not([type=radio]):not([type=checkbox]):not([type=range]),select:hover,textarea:hover{box-shadow:var(--monster-box-shadow-2);transition:background .8s,color .25s .0833333333s}input:focus,select:focus,textarea:focus{outline:1px dashed var(--monster-color-selection-3);outline-offset:3px}:host{height:100%;width:100%}div[data-monster-role=control]{display:flex;height:100%;position:relative}div[data-monster-role=control] .form-container{margin:0 auto;max-width:600px}:is(div[data-monster-role=control] .form-container) .form-group{margin-bottom:.2rem}:is(:is(div[data-monster-role=control] .form-container) .form-group) input[type=number]{text-align:right;width:5rem}:is(:is(div[data-monster-role=control] .form-container) .form-group) input[type=number]::-webkit-inner-spin-button,:is(:is(div[data-monster-role=control] .form-container) .form-group) input[type=number]::-webkit-outer-spin-button{margin-left:10px}:is(:is(div[data-monster-role=control] .form-container) .form-group) input[type=radio]{accent-color:var(--monster-bg-color-primary-3)}[data-monster-role=popper]{position:absolute}@media (prefers-color-scheme:dark){input[type=date],input[type=time],input[type=datetime-local]{color-scheme:dark}input[type=date]::-webkit-calendar-picker-indicator,input[type=time]::-webkit-calendar-picker-indicator,input[type=datetime-local]::-webkit-calendar-picker-indicator{-webkit-filter:invert(1)!important;filter:invert(1)!important;opacity:.85}}
|
|
29
29
|
}`,
|
|
30
30
|
0,
|
|
31
31
|
);
|
|
@@ -190,6 +190,7 @@ const pricingCacheSymbol = Symbol("pricingCache");
|
|
|
190
190
|
* @example /examples/components/form/buy-box-basic Basic buy box
|
|
191
191
|
*
|
|
192
192
|
* @summary Product buy box control with variants, quantity, pricing, and add-to-cart.
|
|
193
|
+
* @since 4.65.0
|
|
193
194
|
* @fires monster-buy-box-change
|
|
194
195
|
* @fires monster-buy-box-valid
|
|
195
196
|
* @fires monster-buy-box-invalid
|
|
@@ -114,6 +114,7 @@ const initGuardSymbol = Symbol("initGuard");
|
|
|
114
114
|
* @example /examples/components/form/variant-select-remote Remote data
|
|
115
115
|
*
|
|
116
116
|
* @summary A control to pick valid variant combinations (e.g., color/size).
|
|
117
|
+
* @since 4.64.0
|
|
117
118
|
* @fires monster-variant-select-change
|
|
118
119
|
* @fires monster-variant-select-valid
|
|
119
120
|
* @fires monster-variant-select-invalid
|
package/source/monster.mjs
CHANGED
|
@@ -89,7 +89,12 @@ export * from "./components/host/call-button.mjs";
|
|
|
89
89
|
export * from "./components/host/details.mjs";
|
|
90
90
|
export * from "./components/host/constants.mjs";
|
|
91
91
|
export * from "./components/datatable/filter/input.mjs";
|
|
92
|
+
export * from "./components/datatable/filter/date.mjs";
|
|
93
|
+
export * from "./components/datatable/filter/date-presets.mjs";
|
|
92
94
|
export * from "./components/datatable/filter/date-range.mjs";
|
|
95
|
+
export * from "./components/datatable/filter/date-time.mjs";
|
|
96
|
+
export * from "./components/datatable/filter/time.mjs";
|
|
97
|
+
export * from "./components/datatable/filter/text-operator.mjs";
|
|
93
98
|
export * from "./components/datatable/filter/abstract-base.mjs";
|
|
94
99
|
export * from "./components/datatable/filter/settings.mjs";
|
|
95
100
|
export * from "./components/datatable/filter/range.mjs";
|