UNPKG

@dewesoft-web/grid2

Version:

Dewesoft WebUI Grid

289 lines (225 loc) 7.28 kB
import { observable, action, computed } from "mobx"; import { CellModel } from "./CellModel"; import { ColumnModel } from "./ColumnModel"; import { EventEmitter } from "./EventEmitter"; import { CellEvent } from "./CellModel"; import { EventArguments } from "@dewesoft-web/ui/events"; import { Row, SortDirecton } from "../types"; export enum RowEvent { IndexChanged, VisibleChanged, ReadOnlyChanged, SelectedChanged, CellValueChanged, RowCellChanged, CellChanged, } export interface RowCells { [col : string] : CellModel; } export class RowModel extends EventEmitter<RowEvent> { @observable cells : RowCells; @observable selected : boolean; @observable first : boolean; @observable last : boolean; @observable readOnly : boolean; @observable scrollVisible : boolean; @observable searchVisible : boolean; @observable visible : boolean; index : number; @observable displayIndex : number; columns : ColumnModel[]; virtualize : boolean; constructor(index : number, displayIndex : number, rowInfo : Row, columns : ColumnModel[], virtualize : boolean) { super(); this.virtualize = virtualize; this.index = index; this.displayIndex = displayIndex; this.cells = {}; for (const col of columns) { this.cells[col.property] = new CellModel(rowInfo.data[col.property], col, this); } for (const prop of Object.keys(rowInfo.data)) { if (!this.cells[prop]) { this.cells[prop] = new CellModel(rowInfo.data[prop], prop, this); } } this.columns = columns; this.readOnly = rowInfo.readOnly === true; this.selected = false; this.first = false; this.last = false; this.scrollVisible = !virtualize; this.searchVisible = true; this.visible = rowInfo.visible !== false; this.select = this.select.bind(this); } onInitialized() { } @computed get isVisible() { return this.scrollVisible && this.searchVisible && this.visible; } @action selectCustom(first : boolean, last : boolean) { // this.selected = true; this.setSelected(true); this.first = first; this.last = last; } @action select(noEvent? : boolean) { // this.selected = true; this.setSelected(true, noEvent); this.first = true; this.last = true; } @action deselect(noEvent? : boolean) { // this.selected = false; this.setSelected(false, noEvent); this.first = false; this.last = false; } @action setSelected(select : boolean, noEvent? : boolean) { if (noEvent !== true && this.selected !== select) { this.triggerEvent(RowEvent.SelectedChanged, { selected: select }); } this.selected = select; } triggerSelected() { this.triggerEvent(RowEvent.SelectedChanged, { selected: this.selected }); } edit(col : ColumnModel) : CellModel { // const cell = this.cells.find((cell) => cell.column === col); const cell = this.cells[col.property]; if (cell) { cell.startEditing(); } return cell; } setValue(value : any, col : ColumnModel) { // const cell = this.cells.find((cell) => cell.column === col); const cell = this.cells[col.property]; if (cell) { cell.setValue(value); } } resetFilter() { this.searchVisible = true; for (const col of this.columns) { this.cells[col.property].filter = ""; } } @action contains(filter : string) : boolean { if (filter === "") { this.resetFilter(); return true; } this.searchVisible = false; // console.group(`Row ${this.index}`); for (const col of this.columns) { if (this.cells[col.property].contains(filter)) { this.searchVisible = true; } } // console.groupEnd(); return this.searchVisible; } compare(ascending : boolean, column : string, other : RowModel) { if (this.cells[column].data < other.cells[column].data) { return ascending ? -1 : 1; } else if (this.cells[column].data > other.cells[column].data) { return ascending ? 1 : -1; } return 0; } serialize() { const keys = Object.keys(this.cells); const numKeys = keys.length; const cells = new Array(numKeys); for (let i = 0; i < numKeys; i++) { cells[i] = this.cells[keys[i]].serialize(); } return { cells: cells, selected: this.selected, readOnly: this.readOnly, visible: this.isVisible, index: this.index }; } onCellChanged(cell : CellModel, event : CellEvent, args : EventArguments) { // console.log(`RowData[${this.index}]{${cell.column.property}} ${CellEvent[event]} => ${JSON.stringify(args)}`); this.triggerEvent(RowEvent.CellChanged, { column: cell.column.property, cellEvent: event, args: args }); } addColumnData() { for (const col of this.columns) { if (!this.cells[col.property]) { this.cells[col.property] = new CellModel(null, col, this); } } } removeColumnData(columnProp : string) { this.cells[columnProp] = undefined; } private cppCellChanged(col : string, cellEvent : CellEvent, args) { if (this.cells[col]) { this.cells[col].handleEvent(cellEvent, args); } else { console.warn("No such row cell: " + col); } } handleEvent(event : RowEvent, args : any[]) { switch (event) { case RowEvent.IndexChanged: break; case RowEvent.VisibleChanged: this.visible = args[0]; break; case RowEvent.SelectedChanged: if (args[0]) { this.select(true); } else { this.deselect(false); } break; case RowEvent.CellValueChanged: break; case RowEvent.RowCellChanged: break; case RowEvent.CellChanged: { const [col, cellEvent, cellArgs] = args; this.cppCellChanged(col, cellEvent, cellArgs); } break; case RowEvent.ReadOnlyChanged: this.readOnly = args[0]; break; default: break; } } }