@optionfactory/ful 4.0.6 → 4.0.8

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/dist/ful.mjs CHANGED
@@ -2400,15 +2400,33 @@ class SortButton extends ParsedElement {
2400
2400
 
2401
2401
  class Pagination extends ParsedElement {
2402
2402
  static observed = ["total:number", "current:number"];
2403
+ static l10n = {
2404
+ en: {
2405
+ 'showing': 'Page {0} of {1}',
2406
+ 'navigation': "Page navigation",
2407
+ 'previous': "Previous",
2408
+ 'next': "Next",
2409
+ },
2410
+ it: {
2411
+ 'showing': 'Pagina {0} di {1}',
2412
+ 'navigation': "Navigazione pagine",
2413
+ 'previous': "Precedente",
2414
+ 'next': "Successivo",
2415
+ }
2416
+ }
2417
+ static config = {
2418
+ prevIcon: 'bi bi-chevron-left',
2419
+ nextIcon: 'bi bi-chevron-right',
2420
+ reloadIcon: 'bi bi-arrow-clockwise',
2421
+ }
2403
2422
  static template = `
2404
- <nav aria-label="Page navigation" class="user-select-none">
2423
+ <nav data-tpl-aria-label="#l10n:t('navigation')" class="user-select-none">
2405
2424
  <ul class="pagination">
2406
- <li class="page-item ms-auto me-2" data-tpl-if="paginationLabel"> Showing page {{ curr.label }} of {{ total }}</li>
2407
- <li class="page-item ms-auto me-2" data-tpl-if="!paginationLabel"></li>
2408
- <li class="page-item reload me-2"><a role="button"><i class="bi bi-arrow-clockwise"></i></a></li>
2425
+ <li class="page-item ms-auto me-2 pagination-index"> {{ #l10n:t('showing', curr.label, total) }}</li>
2426
+ <li class="page-item reload me-2"><a role="button"><i data-tpl-class="config.reloadIcon"></i></a></li>
2409
2427
  <li class="page-item prev">
2410
- <a data-tpl-class="prev.enabled?'page-link':'page-link disabled'" aria-label="Previous" role="button" data-tpl-data-page="prev.index">
2411
- <i aria-hidden="true" class="bi bi-chevron-left"></i>
2428
+ <a data-tpl-class="prev.enabled?'page-link':'page-link disabled'" data-tpl-aria-label="#l10n:t('previous')" role="button" data-tpl-data-page="prev.index">
2429
+ <i aria-hidden="true" data-tpl-class="config.prevIcon"></i>
2412
2430
  </a>
2413
2431
  </li>
2414
2432
  <li class="page-item" data-tpl-each="pages" data-tpl-var="page">
@@ -2417,18 +2435,16 @@ class Pagination extends ParsedElement {
2417
2435
  </a>
2418
2436
  </li>
2419
2437
  <li class="page-item next">
2420
- <a data-tpl-class="next.enabled?'page-link':'page-link disabled'" aria-label="Next" role="button" data-tpl-data-page="next.index">
2421
- <i aria-hidden="true" class="bi bi-chevron-right"></i>
2438
+ <a data-tpl-class="next.enabled?'page-link':'page-link disabled'" data-tpl-aria-label="#l10n:t('next')" role="button" data-tpl-data-page="next.index">
2439
+ <i aria-hidden="true" data-tpl-class="config.nextIcon"></i>
2422
2440
  </a>
2423
2441
  </li>
2424
2442
  </ul>
2425
2443
  </nav>
2426
2444
  `;
2427
- #paginationLabel;
2428
2445
  #total = 0;
2429
2446
  #current = 0;
2430
2447
  render({ observed }) {
2431
- this.#paginationLabel = this.hasAttribute('pagination-label');
2432
2448
  this.update(observed.current ?? 0, observed.total ?? 0);
2433
2449
  this.addEventListener('click', (/** @type any */evt) => {
2434
2450
  const el = evt.target.closest('a');
@@ -2464,8 +2480,7 @@ class Pagination extends ParsedElement {
2464
2480
  pages.push({ index: n, label: n + 1 });
2465
2481
  }
2466
2482
  }
2467
- const paginationLabel = this.#paginationLabel;
2468
- this.template().withOverlay({ total, prev, curr, next, pages, paginationLabel }).renderTo(this);
2483
+ this.template().withOverlay({ total, prev, curr, next, pages }).renderTo(this);
2469
2484
  }
2470
2485
  get total() {
2471
2486
  return this.#total;
@@ -2557,6 +2572,21 @@ class TableLoader{
2557
2572
 
2558
2573
  class Table extends ParsedElement {
2559
2574
  static slots = true;
2575
+ static l10n = {
2576
+ en: {
2577
+ 'notloaded': 'Start searching to see results.',
2578
+ 'error': 'Error while loading data:',
2579
+ 'nodata': 'No elements found.',
2580
+ },
2581
+ it: {
2582
+ 'notloaded': 'Avvia la ricerca per visualizzare i risultati.',
2583
+ 'error': 'Errore nel caricamento dei dati:',
2584
+ 'nodata': 'Nessun elemento trovato.',
2585
+ }
2586
+ }
2587
+ static conf = {
2588
+ sortIcon: '',
2589
+ }
2560
2590
  static template = `
2561
2591
  <ful-form data-tpl-if="slots.filters">
2562
2592
  {{{{ slots.filters }}}}
@@ -2578,7 +2608,7 @@ class Table extends ParsedElement {
2578
2608
  <td data-tpl-colspan="schema.length" class="text-center align-middle p-4">
2579
2609
  <i class="bi bi-search" style="font-size: 40px; color: #BDC3CA"></i>
2580
2610
  <p class="mt-3 mb-0" style="color: #BDC3CA">
2581
- Avvia la ricerca per visualizzare i risultati...
2611
+ {{ #l10n:t('notloaded') }}
2582
2612
  </p>
2583
2613
  </td>
2584
2614
  </tr>
@@ -2594,7 +2624,7 @@ class Table extends ParsedElement {
2594
2624
  <tr>
2595
2625
  <td data-tpl-colspan="schema.length" class="text-center align-middle p-4">
2596
2626
  <div class="alert alert-danger">
2597
- <p>Errore nel caricamento della tabella:</p>
2627
+ <p>{{ #l10n:t('error') }}</p>
2598
2628
  <p class="mb-0" data-ref="feedback-error"></p>
2599
2629
  </div>
2600
2630
  </td>
@@ -2611,7 +2641,7 @@ class Table extends ParsedElement {
2611
2641
  row: `
2612
2642
  <tr data-tpl-if="pageResponse.data.length == 0">
2613
2643
  <td data-tpl-colspan="schema.length" class="text-center align-middle p-4">
2614
- Nessun elemento trovato.
2644
+ {{ #l10n:t('nodata') }}
2615
2645
  </td>
2616
2646
  </tr>
2617
2647
  <tr data-tpl-each="pageResponse.data" data-tpl-var="row">
@@ -2760,7 +2790,7 @@ class InstantFilter extends ParsedElement {
2760
2790
  render({ slots }) {
2761
2791
  const label = Fragments.toHtml(slots.default.cloneNode(true)).trim().length === 0 ? null : slots.default;
2762
2792
  const name = this.getAttribute("name");
2763
- const fragment = this.template().withOverlay({ label, name }).render(this);
2793
+ const fragment = this.template().withOverlay({ slots, label, name }).render();
2764
2794
  this.#operator = fragment.querySelector('[data-ref=operator]');
2765
2795
  this.#value1 = fragment.querySelector('[data-ref=value1]');
2766
2796
  this.#value2 = fragment.querySelector('[data-ref=value2]');
@@ -2856,7 +2886,7 @@ class LocalDateFilter extends ParsedElement {
2856
2886
  render({ slots }) {
2857
2887
  const label = Fragments.toHtml(slots.default.cloneNode(true)).trim().length === 0 ? null : slots.default;
2858
2888
  const name = this.getAttribute("name");
2859
- const fragment = this.template().withOverlay({ label, name }).render(this);
2889
+ const fragment = this.template().withOverlay({ slots, label, name }).render();
2860
2890
  this.#operator = fragment.querySelector('[data-ref=operator]');
2861
2891
  this.#value1 = fragment.querySelector('[data-ref=value1]');
2862
2892
  this.#value2 = fragment.querySelector('[data-ref=value2]');
@@ -2881,7 +2911,7 @@ class LocalDateFilter extends ParsedElement {
2881
2911
  get value() {
2882
2912
  const operator = this.#operator.getAttribute('value');
2883
2913
  const values = operator == 'BETWEEN' ? [this.#value1.value, this.#value2.value] : [this.#value1.value];
2884
- return values.some(v => v === '') ? undefined : [operator, "ISO_8601", ...values];
2914
+ return values.some(v => v === '') ? undefined : [operator, ...values];
2885
2915
  }
2886
2916
  set value(v) {
2887
2917
  if (v === null || v === undefined) {
@@ -2946,7 +2976,7 @@ class TextFilter extends ParsedElement {
2946
2976
  render({ slots }) {
2947
2977
  const label = Fragments.toHtml(slots.default.cloneNode(true)).trim().length === 0 ? null : slots.default;
2948
2978
  const name = this.getAttribute("name");
2949
- const fragment = this.template().withOverlay({ label, name }).render(this);
2979
+ const fragment = this.template().withOverlay({ slots, label, name }).render();
2950
2980
  this.#operator = fragment.querySelector('[data-ref=operator]');
2951
2981
  this.#value = fragment.querySelector('[data-ref=value]');
2952
2982
  this.#fieldError = fragment.querySelector('ful-field-error');
@@ -3008,6 +3038,17 @@ class Plugin {
3008
3038
  .withRedirectOnUnauthorized("/")
3009
3039
  .build();
3010
3040
  registry
3041
+ .defineModule("l10n", {
3042
+ t: function (k, ...args) {
3043
+ const format = this.l10n[this.language][k] ?? this.l10n['en'][k] ?? k;
3044
+ if (args.length === 0) {
3045
+ return format;
3046
+ }
3047
+ return format.replace(/{(\d+)}/g, (m, is) => {
3048
+ return args[Number(is)];
3049
+ });
3050
+ }
3051
+ })
3011
3052
  .defineComponent('http-client', httpClient)
3012
3053
  .defineElement('ful-spinner', Spinner)
3013
3054
  .defineElement('ful-form', Form)
@@ -3029,7 +3070,10 @@ class Plugin {
3029
3070
  .defineElement('ful-dropdown', Dropdown)
3030
3071
  .defineComponent("loaders:select", SelectLoader)
3031
3072
  .defineComponent("loaders:form", FormLoader)
3032
- .defineComponent("loaders:table", TableLoader);
3073
+ .defineComponent("loaders:table", TableLoader)
3074
+ .defineOverlay({
3075
+ language: navigator?.language?.split("-")?.[0] ?? "en"
3076
+ });
3033
3077
  }
3034
3078
  }
3035
3079