150 lines
5.4 KiB
Plaintext
150 lines
5.4 KiB
Plaintext
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;
|
|
}
|
|
}
|