UNPKG

@siberiaweb/components

Version:
272 lines (271 loc) 9.65 kB
import CustomGrid from "../custom-grid/CustomGrid"; import * as moment from "moment"; /** * Сетка. * * @template TRecord Тип записи. */ export default class Grid extends CustomGrid { /** * Конструктор. */ constructor() { super(); /** * Изначальный порядок записей в наборе данных для восстановления сортировки по умолчанию. */ this.dataSetInitialOrder = new Map(); /** * Обработчик сортировки набора данных. */ this.onSortDataSet = null; } /** * Функция обратного вызова для сортировки неопределенных значений. * * @param a Первое значение. * @param b Второе значение. * @param sortOrder Порядок сортировки. */ sortNullsCallback(a, b, sortOrder) { if ((a === null) && (b !== null)) { return sortOrder === "asc" ? -1 : 1; } if ((a !== null) && (b === null)) { return sortOrder === "asc" ? 1 : -1; } return 0; } /** * Функция обратного вызова для восстановления порядка следования записей. * * @param a Первая запись. * @param b Вторая запись. */ sortDefaultCallback(a, b) { let indexA = this.dataSetInitialOrder.get(a); let indexB = this.dataSetInitialOrder.get(b); if ((indexA !== undefined) && (indexB !== undefined)) { return indexA - indexB; } return 0; } /** * Функция обратного вызова для сортировки логических значений. * * @param a Первая запись. * @param b Вторая запись. * @param col Столбец. */ sortBooleanCallback(a, b, col) { if (col.sortOrder === "none") { return this.sortDefaultCallback(a, b); } let booleanA = this.getFieldValue(col, a); let booleanB = this.getFieldValue(col, b); if ((booleanA === null) || (booleanB === null)) { return this.sortNullsCallback(booleanA, booleanB, col.sortOrder); } if (booleanA === booleanB) { return 0; } if (booleanA) { return col.sortOrder === "asc" ? 1 : -1; } return col.sortOrder === "desc" ? -1 : 1; } /** * Функция обратного вызова для сортировки чисел. * * @param a Первая запись. * @param b Вторая запись. * @param col Столбец. */ sortNumberCallback(a, b, col) { if (col.sortOrder === "none") { return this.sortDefaultCallback(a, b); } let numberA = this.getFieldValue(col, a); let numberB = this.getFieldValue(col, b); if ((numberA === null) || (numberB === null)) { return this.sortNullsCallback(numberA, numberB, col.sortOrder); } return col.sortOrder === "asc" ? numberA - numberB : numberB - numberA; } /** * Функция обратного вызова для сортировки дат. * * @param a Первая запись. * @param b Вторая запись. * @param col Столбец. */ sortDateCallback(a, b, col) { if (col.sortOrder === "none") { return this.sortDefaultCallback(a, b); } let dateA = this.getFieldValue(col, a); let dateB = this.getFieldValue(col, b); if ((dateA === null) || (dateB === null)) { return this.sortNullsCallback(dateA, dateB, col.sortOrder); } return col.sortOrder === "asc" ? dateA.getTime() - dateB.getTime() : dateB.getTime() - dateA.getTime(); } /** * Функция обратного вызова для сортировки дат, представленных в виде строки. * * @param a Первая запись. * @param b Вторая запись. * @param col Столбец. * @param pattern Шаблон даты. */ sortDateStringCallback(a, b, col, pattern) { if (col.sortOrder === "none") { return this.sortDefaultCallback(a, b); } let dateA = this.getFieldValue(col, a); let dateB = this.getFieldValue(col, b); if ((dateA === null) || (dateB === null)) { return this.sortNullsCallback(dateA, dateB, col.sortOrder); } let momentA = moment(dateA, pattern); let momentB = moment(dateB, pattern); return col.sortOrder === "asc" ? momentA.toDate().getTime() - momentB.toDate().getTime() : momentB.toDate().getTime() - momentA.toDate().getTime(); } /** * Функция обратного вызова для сортировки текста. * * @param a Первая запись. * @param b Вторая запись. * @param col Столбец. */ sortTextCallback(a, b, col) { if (col.sortOrder === "none") { return this.sortDefaultCallback(a, b); } let valueA = this.getFieldValue(col, a); let valueB = this.getFieldValue(col, b); if ((valueA === null) || (valueB === null)) { return this.sortNullsCallback(valueA, valueB, col.sortOrder); } if (valueA < valueB) { return col.sortOrder === "asc" ? -1 : 1; } if (valueA > valueB) { return col.sortOrder === "asc" ? 1 : -1; } return 0; } /** * Сортировка набора данных. * * @param col Столбец. */ sortDataSet(col) { if ((this.onSortDataSet !== null) && this.onSortDataSet(this.getDataSet(), col)) { return; } switch (col.fieldType) { case "boolean": this.getDataSet().sort((a, b) => { return this.sortBooleanCallback(a, b, col); }); break; case "date": this.getDataSet().sort((a, b) => { return this.sortDateCallback(a, b, col); }); break; case "date-string": let pattern = col.pattern; this.getDataSet().sort((a, b) => { return pattern === null ? this.sortTextCallback(a, b, col) : this.sortDateStringCallback(a, b, col, pattern); }); break; case "number": this.getDataSet().sort((a, b) => { return this.sortNumberCallback(a, b, col); }); break; default: this.getDataSet().sort((a, b) => { return this.sortTextCallback(a, b, col); }); break; } } /** * @override */ sort(col) { super.sort(col); if (col.sortDisabled) { return; } this.sortDataSet(col); if (!this.scrollTopAfterSortDisabled) { this.scrollTop = 0; } this.renderBody(true); } /** * @override */ setDataSet(dataSet) { super.setDataSet(dataSet); this.dataSetInitialOrder.clear(); for (let i = 0; i < this.getDataSet().length; i++) { this.dataSetInitialOrder.set(this.getDataSet()[i], i); } if (this.sortCol !== null) { this.sort(this.sortCol); } } /** * @override */ addDataSet(dataSet) { let length = this.getDataSet().length; super.addDataSet(dataSet); for (let i = length; i < this.getDataSet().length; i++) { this.dataSetInitialOrder.set(this.getDataSet()[i], i); } } /** * @override */ addRecord(record) { super.addRecord(record); this.dataSetInitialOrder.set(record, this.getDataSet().length - 1); } /** * @override */ removeRecord(record) { super.removeRecord(record); this.dataSetInitialOrder.delete(record); } /** * Получение признака отключения прокрутки в начало сетки после сортировки. */ get scrollTopAfterSortDisabled() { return this.hasAttribute(Grid.ATTR_SCROLL_TOP_AFTER_SORT_DISABLED); } /** * Установка признака отключения прокрутки в начало сетки после сортировки. * * @param value Значение. */ set scrollTopAfterSortDisabled(value) { this.toggleAttribute(Grid.ATTR_SCROLL_TOP_AFTER_SORT_DISABLED, value); } } /** * Наименование компонента. */ Grid.COMPONENT_NAME = "sw-grid"; /** * Отключение прокрутки в начало таблицы после сортировки. */ Grid.ATTR_SCROLL_TOP_AFTER_SORT_DISABLED = "scroll-top-after-sort-disabled";