import { PlusOutlined } from '@ant-design/icons'; import { Button, Table } from 'antd'; import { ColumnsType, ExpandableConfig, SorterResult, } from 'antd/lib/table/interface'; import { Layout, Spinner, usePlugin, useValue } from 'flipper-plugin'; import React, { useEffect, useState } from 'react'; import { plugin } from '..'; import InfiniteScroll from 'react-infinite-scroller'; import { InspectionDataType } from './RealmDataInspector'; import { renderValue } from '../utils/Renderer'; import { ColumnTitle } from './ColumnTitle'; import { DropdownPropertyType, MenuItemGenerator, PlainRealmObject, DeserializedRealmObject, SortedObjectSchema, RealmObjectReference } from '../CommonTypes'; import { ClickableText } from './ClickableText'; export type ColumnType = { optional: boolean; name: string; objectType?: string; type: string; isPrimaryKey: boolean; }; type DataTableProps = { objects: DeserializedRealmObject[]; schemas: SortedObjectSchema[]; currentSchema: SortedObjectSchema; sortingDirection: 'ascend' | 'descend' | null; sortingColumn: string | null; generateMenuItems?: MenuItemGenerator; style?: Record; dropdownProp: DropdownPropertyType; setdropdownProp: React.Dispatch>; scrollX: number; scrollY: number; enableSort: boolean; hasMore: boolean; totalObjects?: number; fetchMore: () => void; setNewInspectionData: ( inspectionData: InspectionDataType, wipeStacks?: boolean, ) => void; clickAction?: (object: DeserializedRealmObject) => void; getObject: (object: RealmObjectReference, objectSchemaName: string) => Promise; }; // Receives a schema and returns column objects for the table. const schemaObjectToColumns = ( schema: SortedObjectSchema, ): ColumnType[] => { return schema.order.map((propertyName) => { const obj = schema.properties[propertyName]; const isPrimaryKey = obj.name === schema.primaryKey; return { name: obj.name, optional: obj.optional, objectType: obj.objectType, type: obj.type, isPrimaryKey: isPrimaryKey, }; }); }; export const DataTable = (dataTableProps: DataTableProps) => { const { objects, schemas, currentSchema, generateMenuItems, setdropdownProp, dropdownProp, scrollX, scrollY, setNewInspectionData, enableSort, hasMore, totalObjects = 0, fetchMore = () => undefined, clickAction, getObject, } = dataTableProps; const instance = usePlugin(plugin); const state = useValue(instance.state); const sortableTypes = new Set([ 'string', 'int', 'uuid', 'date', 'decimal128', 'decimal', 'float', 'bool', ]); const [rowExpansionProp, setRowExpansionProp] = useState({ expandedRowRender: () => { return <>; }, showExpandColumn: false, } as ExpandableConfig); /** Hook to close the nested Table when clicked outside of it. */ useEffect(() => { const closeNestedTable = () => { setRowExpansionProp({ ...rowExpansionProp }); }; document.body.addEventListener('click', closeNestedTable); return () => document.body.removeEventListener('click', closeNestedTable); }, []); if (!currentSchema) { return Please select schema.; } if (currentSchema.embedded) { return Embedded objects cannot be queried. Please view them from their parent schema or select a different schema.; } if (!schemas || !schemas.length) { return No schemas found. Check selected Realm.; } /** Definition of antd-specific columns. This constant is passed to the antd table as a property. */ const antdColumns:ColumnsType = schemaObjectToColumns(currentSchema).map((column) => { const property: Realm.CanonicalObjectSchemaProperty = currentSchema.properties[column.name]; const linkedSchema = schemas.find( (schema) => property && schema.name === property.objectType, ); /* A function that is applied for every cell to specify what to render in each cell on top of the pure value specified in the 'dataSource' property of the antd table.*/ const render = (value: PlainRealmObject | RealmObjectReference, row: DeserializedRealmObject) => { /** Apply the renderValue function on the value in the cell to create a standard cell. */ const cellValue = renderValue(value, property, schemas, { downloadData: instance.downloadData, inspectValue: (value: any) => { setNewInspectionData({ data: { [`${currentSchema.name}.${column.name}`]: value}, view: "property", isReference: false, }, true) } }); /** Render buttons to expand the row and a clickable text if the cell contains a linked or embedded Realm object. */ if (value !== null && linkedSchema && property.type === 'object') { const isEmbedded = linkedSchema.embedded; return ( {/* Embedded objects cannot be queried in the row. */ !isEmbedded &&