@nethserver/ns8-ui-lib 2.0.0 → 2.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nethserver/ns8-ui-lib",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Vue.js library for NethServer 8 UI",
5
5
  "keywords": [
6
6
  "nethserver",
@@ -313,6 +313,11 @@ import Close16 from "@carbon/icons-vue/es/close/16";
313
313
  import ChevronRight16 from "@carbon/icons-vue/es/chevron--right/16";
314
314
  import UtilService from "../lib-mixins/util.js";
315
315
  import LottieService from "../lib-mixins/lottie.js";
316
+ import StorageService from "../lib-mixins/storage.js";
317
+
318
+ // localStorage entry holding the page sizes chosen by the user, grouped by
319
+ // page sizes set (e.g. {"10,25,50,100": 50}) or by pageSizeStorageKey prop
320
+ const PAGE_SIZES_STORAGE_KEY = "nsDataTablePageSizes";
316
321
 
317
322
  export default {
318
323
  name: "NsDataTable",
@@ -329,7 +334,7 @@ export default {
329
334
  ChevronRight16,
330
335
  NsPagination,
331
336
  },
332
- mixins: [UtilService, LottieService],
337
+ mixins: [UtilService, LottieService, StorageService],
333
338
  props: {
334
339
  actionBarAriaLabel: { type: String, default: "Table Action Bar" },
335
340
  collapseAllAriaLabel: { type: String, default: "Collapse all rows" },
@@ -343,6 +348,11 @@ export default {
343
348
  type: Array,
344
349
  default: () => [10, 25, 50, 100],
345
350
  },
351
+ // remember the page size chosen by the user in localStorage
352
+ persistPageSize: { type: Boolean, default: true },
353
+ // key used to store the page size; tables with the same key share the same page size.
354
+ // If empty, tables are grouped by their page sizes set
355
+ pageSizeStorageKey: { type: String, default: "" },
346
356
  rowSize: {
347
357
  type: String,
348
358
  default: "standard",
@@ -395,6 +405,7 @@ export default {
395
405
  pageStart: 0,
396
406
  pageNumber: 0,
397
407
  pageLength: 0,
408
+ selectedPageSize: null,
398
409
  };
399
410
  },
400
411
  watch: {
@@ -404,8 +415,12 @@ export default {
404
415
  filteredRows: function () {
405
416
  this.$emit("updatePage", this.tablePage);
406
417
  },
418
+ pageSizeGroup: function () {
419
+ this.selectedPageSize = this.getStoredPageSize();
420
+ },
407
421
  },
408
422
  created() {
423
+ this.selectedPageSize = this.getStoredPageSize();
409
424
  this.filterRows();
410
425
  },
411
426
  computed: {
@@ -413,12 +428,38 @@ export default {
413
428
  if (this.pageSizes.length) {
414
429
  return {
415
430
  numberOfItems: this.filteredRows.length,
416
- pageSizes: this.pageSizes,
431
+ pageSizes: this.paginationPageSizes,
417
432
  };
418
433
  } else {
419
434
  return false;
420
435
  }
421
436
  },
437
+ isPageSizePersisted() {
438
+ return (
439
+ this.persistPageSize &&
440
+ this.pageSizes.length > 1 &&
441
+ this.pageSizes.every((size) => typeof size === "number")
442
+ );
443
+ },
444
+ pageSizeGroup() {
445
+ if (!this.isPageSizePersisted) {
446
+ return "";
447
+ }
448
+ return this.pageSizeStorageKey || this.pageSizes.join(",");
449
+ },
450
+ paginationPageSizes() {
451
+ if (
452
+ this.selectedPageSize === null ||
453
+ !this.pageSizes.includes(this.selectedPageSize)
454
+ ) {
455
+ return this.pageSizes;
456
+ }
457
+ // preselect page size in NsPagination
458
+ return this.pageSizes.map((size) => ({
459
+ value: size,
460
+ selected: size === this.selectedPageSize,
461
+ }));
462
+ },
422
463
  tablePage() {
423
464
  if (this.pageSizes.length) {
424
465
  return this.filteredRows.slice(
@@ -526,7 +567,56 @@ export default {
526
567
  return searchResults;
527
568
  }
528
569
  },
570
+ readStoredPageSizes() {
571
+ try {
572
+ const storedPageSizes = this.getFromStorage(PAGE_SIZES_STORAGE_KEY);
573
+
574
+ if (
575
+ storedPageSizes &&
576
+ typeof storedPageSizes === "object" &&
577
+ !Array.isArray(storedPageSizes)
578
+ ) {
579
+ return storedPageSizes;
580
+ }
581
+ } catch (e) {
582
+ // corrupted value or storage not available
583
+ }
584
+ return {};
585
+ },
586
+ getStoredPageSize() {
587
+ if (!this.pageSizeGroup) {
588
+ return null;
589
+ }
590
+ const pageSize = this.readStoredPageSizes()[this.pageSizeGroup];
591
+
592
+ if (this.pageSizes.includes(pageSize)) {
593
+ return pageSize;
594
+ }
595
+ return null;
596
+ },
597
+ storePageSize(pageSize) {
598
+ if (!this.pageSizeGroup) {
599
+ return;
600
+ }
601
+ const storedPageSizes = this.readStoredPageSizes();
602
+ storedPageSizes[this.pageSizeGroup] = pageSize;
603
+
604
+ try {
605
+ this.saveToStorage(PAGE_SIZES_STORAGE_KEY, storedPageSizes);
606
+ } catch (e) {
607
+ // storage not available or full
608
+ }
609
+ },
529
610
  paginateTable(ev) {
611
+ if (
612
+ this.isPageSizePersisted &&
613
+ this.pageLength !== 0 &&
614
+ ev.length !== this.pageLength
615
+ ) {
616
+ // page size changed by the user
617
+ this.selectedPageSize = ev.length;
618
+ this.storePageSize(ev.length);
619
+ }
530
620
  this.pageStart = ev.start - 1;
531
621
  this.pageNumber = ev.page;
532
622
  this.pageLength = ev.length;
@@ -0,0 +1,14 @@
1
+ <!--
2
+ Copyright (C) 2026 Nethesis S.r.l.
3
+ SPDX-License-Identifier: GPL-3.0-or-later
4
+ -->
5
+ <template>
6
+ <path
7
+ id="network--3"
8
+ d="M30,30H22V22h8Zm-6-2h4V24H24Z
9
+ M20,27H8A6,6,0,0,1,8,15h2v2H8a4,4,0,0,0,0,8H20Z
10
+ M20,20H12V12h8Zm-6-2h4V14H14Z
11
+ M24,17H22V15h2a4,4,0,0,0,0-8H12V5H24a6,6,0,0,1,0,12Z
12
+ M10,10H2V2h8ZM4,8H8V4H4Z"
13
+ />
14
+ </template>