import { writable, derived } from 'svelte/store'; export default class Context { rowsPerPage; pageNumber; triggerChange; globalSearch; filters; rawRows; filteredRows; rows; rowCount; pages; pagesWithEllipsis; pageCount; sorted; constructor(data, params) { this.rowsPerPage = writable(params.rowsPerPage); this.pageNumber = writable(1); this.triggerChange = writable(0); this.globalSearch = writable({ value: null, scope: null }); this.filters = writable([]); this.rawRows = writable(data); this.filteredRows = this.createFilteredRows(); this.rows = this.createPaginatedRows(); this.rowCount = this.createRowCount(); this.pages = this.createPages(); this.pagesWithEllipsis = this.createPagesWithEllipsis(); this.pageCount = this.createPageCount(); this.sorted = writable({ identifier: null, direction: null, fn: null }); } createFilteredRows() { return derived([this.rawRows, this.globalSearch, this.filters], ([$rawRows, $globalSearch, $filters]) => { if ($globalSearch.value) { $rawRows = $rawRows.filter(row => { const scope = $globalSearch.scope ?? Object.keys(row); return scope.some(key => { if (row[key]) { return this.stringMatch(row[key], $globalSearch.value); } return ''; }); }); this.pageNumber.set(1); this.triggerChange.update(store => { return store + 1; }); } if ($filters.length > 0) { $filters.forEach(localFilter => { return $rawRows = $rawRows.filter(row => { const entry = localFilter.filterBy(row); return this.stringMatch(entry, localFilter.value); }); }); this.pageNumber.set(1); this.triggerChange.update(store => { return store + 1; }); } return $rawRows; }); } createPaginatedRows() { return derived([this.filteredRows, this.rowsPerPage, this.pageNumber], ([$filteredRows, $rowsPerPage, $pageNumber]) => { if (!$rowsPerPage) { return $filteredRows; } this.triggerChange.update(store => { return store + 1; }); return $filteredRows.slice(($pageNumber - 1) * $rowsPerPage, $pageNumber * $rowsPerPage); }); } createRowCount() { return derived([this.filteredRows, this.pageNumber, this.rowsPerPage], ([$filteredRows, $pageNumber, $rowsPerPage]) => { const total = $filteredRows.length; if (!$rowsPerPage) { return { total: total, start: 1, end: total }; } return { total: total, start: ($pageNumber * $rowsPerPage - $rowsPerPage) + 1, end: Math.min(($pageNumber * $rowsPerPage), $filteredRows.length), }; }); } createPages() { return derived([this.rowsPerPage, this.filteredRows], ([$rowsPerPage, $filteredRows]) => { if (!$rowsPerPage) { return [1]; } const pages = Array.from(Array(Math.ceil($filteredRows.length / $rowsPerPage))); return pages.map((row, i) => { return i + 1; }); }); } createPagesWithEllipsis() { return derived([this.pages, this.pageNumber], ([$pages, $pageNumber]) => { if ($pages.length <= 7) { return $pages; } const ellipse = null; const firstPage = 1; const lastPage = $pages.length; if ($pageNumber <= 4) { return [ ...$pages.slice(0, 5), ellipse, lastPage, ]; } else if ($pageNumber < $pages.length - 3) { return [ firstPage, ellipse, ...$pages.slice($pageNumber - 2, $pageNumber + 1), ellipse, lastPage ]; } else { return [ firstPage, ellipse, ...$pages.slice($pages.length - 5, $pages.length) ]; } }); } createPageCount() { return derived([this.pages], ([$pages]) => { return $pages.length; }); } stringMatch(entry, value) { if (typeof entry === 'string' || !entry) { return String(entry) .toLowerCase() .normalize("NFD") .replace(/[\u0300-\u036f]/g, "") .indexOf(value .toString() .toLowerCase() .normalize("NFD") .replace(/[\u0300-\u036f]/g, "")) > -1; } else if (typeof entry === 'object') { return Object.keys(entry).some(k => { return this.stringMatch(entry[k], value); }); } return String(entry).indexOf(String(value)) > -1; } }