import { EditorProperty } from "@iplusplus/y-model" import React, { useCallback, useContext } from "react" import { DataGrid, DataGridProps, GridColDef, GridRenderEditCellParams, GridRowModel } from "@mui/x-data-grid" import { Tooltip, Typography } from "@mui/material" import { EditorContextProps } from "../editor-context/types" import { PropertyGridValues } from "./types" import { EditorContext } from "../editor-context/EditorContext" // function createProcessRowUpdate(onNewValueSubmit: (prop: EditorProperty, newValue: unknown) => void) { // return (newRow: GridRowModel, oldRow: GridRowModel) => // new Promise((resolve) => { // const p = oldRow.v.property as EditorProperty; // const v = p.valueType; // if (v.dataTypeName === "number") { // const newValue = parseFloat(newRow.value); // if (isNaN(newValue)) { // resolve(oldRow) // } // else { // onNewValueSubmit(p, newValue) // resolve({ ...oldRow, value: newValue }) // } // } else { // onNewValueSubmit(p, newRow.value) // resolve(newRow) // } // }) // } function processRowUpdate2( onNewValueSubmit: (prop: EditorProperty, newValue: unknown) => void, newRow: GridRowModel, oldRow: GridRowModel, ) { return new Promise(resolve => { const p = oldRow.v.property as EditorProperty const v = p.valueType if (v.dataTypeName === "number") { const newValue = parseFloat(newRow.value) if (isNaN(newValue)) { resolve(oldRow) } else { onNewValueSubmit(p, newValue) resolve({ ...oldRow, value: newValue }) } } else { onNewValueSubmit(p, newRow.value) resolve(newRow) } }) } function getColumns(context: EditorContextProps): GridColDef[] { const renderEditCell = (params: GridRenderEditCellParams) => { // console.log("renderEditCell", params) const p = params.row.v.property as EditorProperty const render = context.editCellRenderBuilder(p) return render!(params) } const renderCell: GridColDef["renderCell"] = params => { // console.log("renderEditCell", params) //console.log(params.value) const p = params.row.v.property as EditorProperty const render = context.cellRenderBuilder(p) return render!(params) } const renderNameCell: GridColDef["renderCell"] = params => { // console.log("renderEditCell", params) const p = params.row.v.property as EditorProperty const descr = p.valueType.getDescription() const ele = {p.title} if (descr) { return {ele} } return ele } return [ { field: "name", headerName: "属性名", // width: 180, display: "flex", flex: 2, maxWidth: 200, sortable: false, renderCell: renderNameCell, }, { field: "value", headerName: "值", type: "string", editable: true, align: "left", headerAlign: "left", flex: 3, maxWidth: 1200, sortable: false, renderEditCell, renderCell, }, ] } export type PropertyGridProps = { values: PropertyGridValues onNewValueSubmit: (prop: EditorProperty, newValue: unknown) => void onEditStateNotify?: (isInEdit: boolean) => void disableEditFields?: string[] } export const PropertyGrid = React.memo(function ({ values, onNewValueSubmit, onEditStateNotify, disableEditFields, }: PropertyGridProps) { const processRowUpdate = useCallback( (newRow: GridRowModel, oldRow: GridRowModel) => processRowUpdate2(onNewValueSubmit, newRow, oldRow), [onNewValueSubmit], ) const rows = values.map(v => { return { v: v, id: v.property.name, name: v.property.title, value: v.value, } }) const editorStateNotify = (isInEdit: boolean) => { if (onEditStateNotify) { onEditStateNotify(isInEdit) } } const context = useContext(EditorContext) const columns = getColumns(context) const isCellEditable: DataGridProps["isCellEditable"] = params => { return disableEditFields === undefined || disableEditFields.indexOf(params.row.v.property.name as string) === -1 } return ( editorStateNotify(true)} onCellEditStop={() => editorStateNotify(false)} isCellEditable={isCellEditable} density="compact" showCellVerticalBorder > ) })