@schukai/monster
Version:
Monster is a simple library for creating fast, robust and lightweight websites.
448 lines (422 loc) • 10.8 kB
JavaScript
/**
* Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
* Node module: @schukai/monster
*
* This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact Volker Schukai.
*
* SPDX-License-Identifier: AGPL-3.0
*/
import { instanceSymbol } from "../../../constants.mjs";
import {
assembleMethodSymbol,
registerCustomElement,
} from "../../../dom/customelement.mjs";
import { CustomControl } from "../../../dom/customcontrol.mjs";
import { FilterControlsDefaultsStyleSheet } from "../stylesheet/filter-controls-defaults.mjs";
import { FilterStyleSheet } from "../stylesheet/filter.mjs";
import { getLocaleOfDocument } from "../../../dom/locale.mjs";
export { DatePresets };
/**
* local symbol
* @private
* @type {symbol}
*/
const selectElementSymbol = Symbol("selectElement");
/**
* The FilterDatePresets component provides pre-defined date ranges.
*
* @fragments /fragments/components/datatable/filter/date-presets
*
* @example /examples/components/datatable/filter-controls Filter controls
*
* @copyright Volker Schukai
* @summary The FilterDatePresets component provides quick date presets.
*/
class DatePresets extends CustomControl {
/**
* This method is called by the `instanceof` operator.
* @return {symbol}
*/
static get [instanceSymbol]() {
return Symbol.for(
"@schukai/monster/components/filter/date-presets@@instance",
);
}
/**
* To set the options via the HTML tag, the attribute `data-monster-options` must be used.
* @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
*
* The individual configuration values can be found in the table.
*
* @property {Object} templates Template definitions
* @property {string} templates.main Main template
* @property {Object} labels Text labels
*/
get defaults() {
return Object.assign({}, super.defaults, {
templates: {
main: getTemplate(),
},
labels: getTranslations(),
});
}
/**
*
* @return {string}
*/
static getTag() {
return "monster-filter-date-presets";
}
/**
*
* @return {FilterButton}
*/
[assembleMethodSymbol]() {
super[assembleMethodSymbol]();
initControlReferences.call(this);
updateOptions.call(this);
}
/**
* @return Array<CSSStyleSheet>
*/
static getCSSStyleSheet() {
return [FilterControlsDefaultsStyleSheet, FilterStyleSheet];
}
/**
* This is a method of [internal api](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals)
*
* @param {*} value
*/
set value(value) {
this[selectElementSymbol].value = value;
}
/**
* @return {*}
*/
get value() {
return this[selectElementSymbol].value;
}
}
/**
* @private
* @returns {Object}
*/
function getTranslations() {
const locale = getLocaleOfDocument();
switch (locale.language) {
case "de":
return {
any: "Beliebig",
today: "Heute",
yesterday: "Gestern",
last7: "Letzte 7 Tage",
last30: "Letzte 30 Tage",
thisMonth: "Dieser Monat",
lastMonth: "Letzter Monat",
};
case "es":
return {
any: "Cualquiera",
today: "Hoy",
yesterday: "Ayer",
last7: "Últimos 7 días",
last30: "Últimos 30 días",
thisMonth: "Este mes",
lastMonth: "Mes pasado",
};
case "zh":
return {
any: "不限",
today: "今天",
yesterday: "昨天",
last7: "最近7天",
last30: "最近30天",
thisMonth: "本月",
lastMonth: "上个月",
};
case "hi":
return {
any: "कोई भी",
today: "आज",
yesterday: "कल",
last7: "पिछले 7 दिन",
last30: "पिछले 30 दिन",
thisMonth: "इस माह",
lastMonth: "पिछला माह",
};
case "bn":
return {
any: "যেকোনো",
today: "আজ",
yesterday: "গতকাল",
last7: "শেষ ৭ দিন",
last30: "শেষ ৩০ দিন",
thisMonth: "এই মাস",
lastMonth: "গত মাস",
};
case "pt":
return {
any: "Qualquer",
today: "Hoje",
yesterday: "Ontem",
last7: "Últimos 7 dias",
last30: "Últimos 30 dias",
thisMonth: "Este mês",
lastMonth: "Mês passado",
};
case "ru":
return {
any: "Любой",
today: "Сегодня",
yesterday: "Вчера",
last7: "Последние 7 дней",
last30: "Последние 30 дней",
thisMonth: "Этот месяц",
lastMonth: "Прошлый месяц",
};
case "ja":
return {
any: "指定なし",
today: "今日",
yesterday: "昨日",
last7: "過去7日",
last30: "過去30日",
thisMonth: "今月",
lastMonth: "先月",
};
case "pa":
return {
any: "ਕੋਈ ਵੀ",
today: "ਅੱਜ",
yesterday: "ਕੱਲ੍ਹ",
last7: "ਪਿਛਲੇ 7 ਦਿਨ",
last30: "ਪਿਛਲੇ 30 ਦਿਨ",
thisMonth: "ਇਸ ਮਹੀਨੇ",
lastMonth: "ਪਿਛਲਾ ਮਹੀਨਾ",
};
case "mr":
return {
any: "कोणतेही",
today: "आज",
yesterday: "काल",
last7: "मागील 7 दिवस",
last30: "मागील 30 दिवस",
thisMonth: "हा महिना",
lastMonth: "मागील महिना",
};
case "fr":
return {
any: "Tout",
today: "Aujourd'hui",
yesterday: "Hier",
last7: "7 derniers jours",
last30: "30 derniers jours",
thisMonth: "Ce mois",
lastMonth: "Mois dernier",
};
case "it":
return {
any: "Qualsiasi",
today: "Oggi",
yesterday: "Ieri",
last7: "Ultimi 7 giorni",
last30: "Ultimi 30 giorni",
thisMonth: "Questo mese",
lastMonth: "Mese scorso",
};
case "nl":
return {
any: "Elke",
today: "Vandaag",
yesterday: "Gisteren",
last7: "Laatste 7 dagen",
last30: "Laatste 30 dagen",
thisMonth: "Deze maand",
lastMonth: "Vorige maand",
};
case "sv":
return {
any: "Alla",
today: "Idag",
yesterday: "Igår",
last7: "Senaste 7 dagar",
last30: "Senaste 30 dagar",
thisMonth: "Denna månad",
lastMonth: "Förra månaden",
};
case "pl":
return {
any: "Dowolny",
today: "Dzisiaj",
yesterday: "Wczoraj",
last7: "Ostatnie 7 dni",
last30: "Ostatnie 30 dni",
thisMonth: "Ten miesiąc",
lastMonth: "Poprzedni miesiąc",
};
case "da":
return {
any: "Alle",
today: "I dag",
yesterday: "I går",
last7: "Seneste 7 dage",
last30: "Seneste 30 dage",
thisMonth: "Denne måned",
lastMonth: "Sidste måned",
};
case "fi":
return {
any: "Kaikki",
today: "Tänään",
yesterday: "Eilen",
last7: "Viimeiset 7 päivää",
last30: "Viimeiset 30 päivää",
thisMonth: "Tämä kuukausi",
lastMonth: "Edellinen kuukausi",
};
case "no":
return {
any: "Alle",
today: "I dag",
yesterday: "I går",
last7: "Siste 7 dager",
last30: "Siste 30 dager",
thisMonth: "Denne måneden",
lastMonth: "Forrige måned",
};
case "cs":
return {
any: "Libovolný",
today: "Dnes",
yesterday: "Včera",
last7: "Posledních 7 dní",
last30: "Posledních 30 dní",
thisMonth: "Tento měsíc",
lastMonth: "Minulý měsíc",
};
default:
case "en":
return {
any: "Any",
today: "Today",
yesterday: "Yesterday",
last7: "Last 7 days",
last30: "Last 30 days",
thisMonth: "This month",
lastMonth: "Last month",
};
}
}
/**
* @private
* @return {DatePresets}
*/
function initControlReferences() {
if (!this.shadowRoot) {
throw new Error("no shadow-root is defined");
}
this[selectElementSymbol] = this.shadowRoot.querySelector(
"[data-monster-role=query]",
);
return this;
}
/**
* @private
* @return {void}
*/
function updateOptions() {
const labels = this.getOption("labels");
const currentValue = this[selectElementSymbol].value;
const presets = buildPresets(labels);
this[selectElementSymbol].innerHTML = "";
for (const preset of presets) {
const option = document.createElement("option");
option.value = preset.value;
option.textContent = preset.label;
this[selectElementSymbol].append(option);
}
if (currentValue) {
this[selectElementSymbol].value = currentValue;
}
}
/**
* @private
* @param {Object} labels
* @return {Array<{label: string, value: string}>}
*/
function buildPresets(labels) {
const today = new Date();
const todayString = formatDate(today);
const yesterday = formatDate(addDays(today, -1));
const last7 = buildRange(addDays(today, -6), today);
const last30 = buildRange(addDays(today, -29), today);
const thisMonthStart = new Date(today.getFullYear(), today.getMonth(), 1);
const thisMonthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0);
const lastMonthStart = new Date(today.getFullYear(), today.getMonth() - 1, 1);
const lastMonthEnd = new Date(today.getFullYear(), today.getMonth(), 0);
return [
{ label: labels.any, value: "" },
{ label: labels.today, value: todayString },
{ label: labels.yesterday, value: yesterday },
{ label: labels.last7, value: last7 },
{ label: labels.last30, value: last30 },
{
label: labels.thisMonth,
value: buildRange(thisMonthStart, thisMonthEnd),
},
{
label: labels.lastMonth,
value: buildRange(lastMonthStart, lastMonthEnd),
},
];
}
/**
* @private
* @param {Date} date
* @return {string}
*/
function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
/**
* @private
* @param {Date} from
* @param {Date} to
* @return {string}
*/
function buildRange(from, to) {
return `${formatDate(from)} - ${formatDate(to)}`;
}
/**
* @private
* @param {Date} date
* @param {number} amount
* @return {Date}
*/
function addDays(date, amount) {
const d = new Date(date);
d.setDate(d.getDate() + amount);
return d;
}
/**
* @private
* @return {string}
*/
function getTemplate() {
// language=HTML
return `
<div data-monster-role="control" part="control">
<slot></slot>
<select name="query" data-monster-role="query" data-monster-attributes="value path:query"></select>
</div>
`;
}
registerCustomElement(DatePresets);