import { BasePage } from "./base-page"; import { DataSource, DataControlField, CustomField, GridViewCell, GridViewEditableCell, BoundField, GridViewCellControl, createGridView, boundField, BoundFieldParams, dateTimeField, CheckboxListFieldParams, checkboxListField } from "maishu-wuzhui-helper"; import * as React from "react"; import { createItemDialog, Dialog } from "./item-dialog"; import * as ReactDOM from "react-dom"; import { InputControl, InputControlProps } from "./inputs/input-control"; import { PageDataSource } from "./page-data-source"; import { PageProps } from "maishu-chitu-react"; import { buttonOnClick, confirm } from "maishu-ui-toolkit"; interface BoundInputControlProps extends InputControlProps { boundField: BoundField } /** 数据绑定列控件 */ class BoundFieldControl extends InputControl>{ control: GridViewCellControl; cell: GridViewEditableCell; private _value; constructor(props: BoundFieldControl["props"]) { super(props); this.state = {}; } get value() { return this._value; } set value(value) { this._value = value; if (this.control != null) this.control.value = value; } render() { console.assert(this.state != null); return { if (this.control != null) { return; } this.control = this.props.boundField.createControl(); this.control.element.setAttribute("name", this.props.dataField as string); this.control.value = this._value; this.control.element.onchange = () => { this._value = this.control.value; } e.appendChild(this.control.element); }}> } } export interface DataListPageState { tableSize?: { width: number, height: number } } export abstract class DataListPage extends BasePage { /** 操作列宽度 */ protected CommandColumnWidth = 140; protected ScrollBarWidth = 18; abstract dataSource: DataSource; abstract columns: DataControlField[]; protected itemName?: string; //============================================ // protected protected pageSize?: number = 15; protected headerFixed = false; /** 是否显示命令字段 */ protected showCommandColumn = true; /** 对显示的数据进行转换 */ protected translate?: (items: T[]) => T[]; //============================================ protected deleteConfirmText: (dataItem: T) => string; private itemTable: HTMLTableElement; private dialog: Dialog; private commandColumn: CustomField; constructor(props: P) { super(props); window.addEventListener("resize", () => { let height = window.innerHeight - 160; let width = window.innerWidth - 80; let firstMenuPanel = document.getElementsByClassName("first")[0] as HTMLElement; let secondMenuPanel = document.getElementsByClassName("second")[0] as HTMLElement; if (firstMenuPanel) { width = width - firstMenuPanel.offsetWidth; } if (secondMenuPanel) { width = width - secondMenuPanel.offsetWidth; } let tableSize: DataListPageState["tableSize"]; if (this.state != null) { tableSize = this.state.tableSize; } if (tableSize == null || tableSize.height != height || tableSize.width != width) { this.setState({ tableSize: { width, height } }); } }) } calcTableSize() { let height = window.innerHeight - 160; let width = window.innerWidth - 40; let firstMenuPanel = document.getElementsByClassName("first")[0] as HTMLElement; let secondMenuPanel = document.getElementsByClassName("second")[0] as HTMLElement; if (firstMenuPanel) { width = width - firstMenuPanel.offsetWidth; } if (secondMenuPanel) { width = width - secondMenuPanel.offsetWidth; } return { width, height }; } componentDidMount() { this.columns = this.columns || []; if (this.showCommandColumn) { let it = this; this.commandColumn = new CustomField({ headerText: "操作", headerStyle: { textAlign: "center", width: `${this.CommandColumnWidth}px` }, itemStyle: { textAlign: "center", width: `${this.CommandColumnWidth}px` }, createItemCell(dataItem: T, cellElement) { let cell = new GridViewCell(cellElement); ReactDOM.render(<> {it.leftCommands(dataItem)} {it.editButton(dataItem)} {it.deleteButton(dataItem)} {it.rightCommands(dataItem)} , cell.element); return cell; } }); } createGridView({ element: this.itemTable, dataSource: this.dataSource, columns: this.commandColumn ? [...this.columns, this.commandColumn] : this.columns, pageSize: this.pageSize, translate: this.translate, showHeader: this.headerFixed != true, }) } renderEditor(): React.ReactElement { return <> {this.columns.filter(o => o instanceof BoundField && o.readOnly != true).map((col, i) =>
} dataField={(col as BoundField).dataField} validateRules={(col as BoundField).validateRules} />
)} } protected renderToolbarRight() { let editor = this.renderEditor(); if (editor == null) { return []; } this.dialog = createItemDialog(this.dataSource, this.itemName, editor); let addButton = this.addButton(); let searchInput = this.searchControl(); return [searchInput, addButton,]; } /** 获取页面添加按钮 */ protected addButton() { let button = this.dataSource.canInsert ? : null; return button; } /** 获取页面编辑按钮 */ protected editButton(dataItem: T) { if (!this.dataSource.canUpdate) return null; let ps = this.dataSource as PageDataSource; let options = ps.options || {} as typeof ps.options; let itemCanUpdate = options.itemCanUpdate || (() => true); return } /** 获取页面删除按钮 */ protected deleteButton(dataItem: T) { if (!this.dataSource.canDelete) return; let ps = this.dataSource as PageDataSource; let options = ps.options || {} as typeof ps.options; let itemCanDelete = options.itemCanDelete || (() => true); return } /** 执行编辑操作 */ protected executeEdit(dataItem: T) { this.dialog.show(dataItem); } /** 执行删除操作 */ protected executeDelete(dataItem: T) { if (this.deleteConfirmText) { let message = this.deleteConfirmText(dataItem); return new Promise((resolve, reject) => { confirm({ title: "请确认", message, confirm: async () => { return this.dataSource.delete(dataItem) .then(r => resolve(r)) .catch(err => reject(err)) }, cancle: async () => { resolve({}); } }) }) } return this.dataSource.delete(dataItem); } /** 获取页面搜索栏 */ protected searchControl() { let dataSource = this.dataSource as PageDataSource; let search = dataSource.options ? dataSource.options.search : null; let searchInput = search ? <> : null; return searchInput; } protected rightCommands(dataItem: T): JSX.Element[] { return []; } protected leftCommands(dataItem: T): JSX.Element[] { return []; } render() { let tableSize = this.state ? this.state.tableSize : this.calcTableSize(); if (this.headerFixed) { let columns = this.columns || []; return <>
{columns.map((col, i) => )} {this.commandColumn ? : null}
{ if (!e) return; if (!col.itemStyle) return; e.style.width = col.itemStyle["width"]; if (this.commandColumn == null && i == columns.length - 1) { e.style.width = `calc(${e.style.width} + ${this.ScrollBarWidth}px)` } }}>{col.headerText} {this.commandColumn.headerText}
this.itemTable = e || this.itemTable}>
} return this.itemTable = e || this.itemTable}>
} boundField(params: BoundFieldParams) { return boundField(params); } dateTimeField(params: BoundFieldParams) { return dateTimeField(params); } checkboxListField(params: CheckboxListFieldParams): BoundField { return checkboxListField(params) } }