import * as React from "react" ; import { Collection , I18NService , IComponents , ListSmart , QueryBodyType , XRouter , XUI_COMPONENTS_TOKEN , } from "@bluelibs/x-ui" ; import { ColumnsType , TablePaginationConfig , TableProps } from "antd/lib/table" ; import { Button , Dropdown , Menu , Popconfirm } from "antd" ; import { Constructor , Inject } from "@bluelibs/core" ; import * as moment from "moment" ; const AntTableContext = React . createContext ( null ) ; export abstract class AntTableSmart < T = any > extends ListSmart < T > { @ Inject ( ( ) => XRouter ) router : XRouter ; @ Inject ( XUI_COMPONENTS_TOKEN ) UIComponents : IComponents ; @ Inject ( ( ) => I18NService ) i18n : I18NService ; abstract collectionClass : Constructor < Collection < T > > ; abstract getBody ( ) ; abstract getColumns ( ) ; static getContext ( ) { return AntTableContext ; } getTableProps ( ) { const columns = this . getColumns ( ) ; const props = { dataSource : this . state . documents , columns , loading : this . state . isLoading , pagination : this . getUIPaginationConfig ( ) , onChange : this . onTableChange . bind ( this ) , rowKey : ( item ) => item . _id , } ; if ( columns . length > 6 + 1 ) { props . scroll = { x : columns . length * 200 , } ; } return props ; } onTableChange ( filters , pagination , sorter ) { if ( sorter . field ) { let field = Array . isArray ( sorter . field ) ? sorter . field . join ( "." ) : sorter . field ; if ( this . getSortMap ( ) [ field ] ) { field = this . getSortMap ( ) [ field ] ; } this . updateSort ( field , sorter . order === "descend" ? - 1 : 1 ) ; } } /**
     * This is used so you can map certain fields to certain sorts. For example you only get the dataIndex specified.
     */ getSortMap ( ) { return { } ; } returns getFilterMap ( ) { return { } ; } param model param actions returns generateActions ( model , actions ) { const menu = ( < Menu > { actions . items . map ( ( item ) => { const props = { key : item . label , onClick : undefined , } ; if ( item . icon ) { props . icon = item . icon ; } let children = item . label ; if ( item . confirm ) { children = ( < Popconfirm title = { item . confirm } onConfirm = { ( ) => { item . action ( model ) ; } } > { item . label } < /Popconfirm>); } else { props . onClick = ( ) => item . action ( model ) ; } return < Menu . Item { ... props } > { children } < /Menu.Item>; } ) } < /Menu>); return ( < Dropdown overlay = { menu } > < Button icon = { actions . icon } > { actions . label } < /Button> < /Dropdown>); } getUIPaginationConfig ( ) { const options = { position : [ "bottomCenter" ] , defaultCurrent : this . state . currentPage , pageSize : this . state . perPage , onChange : ( page ) => { this . setCurrentPage ( page ) ; } , total : this . state . totalCount , } ; return options ; } getRouter ( ) { return this . container . get ( XRouter ) ; } param filters setFlexibleFilters ( filters ) { const $and = this . extractFilters ( filters ) ; if ( $and . length === 0 ) { this . setFilters ( { } ) ; } else { this . setFilters ( { $and , } ) ; } } protected extractFilters ( filters , keyPrefix = "" ) { const $and = [ ] ; const filterMap = this . getFilterMap ( ) ; const push = ( key , value ) => { $and . push ( { [ keyPrefix + key ] : value , } ) ; } ; for ( const key in filters ) { const value = filters [ key ] ; if ( value === undefined || value === null || ( Array . isArray ( value ) && value . length === 0 ) ) { continue ; } if ( filterMap [ key ] ) { push ( filterMap [ key ] , filters [ key ] ) ; continue ; } if ( Array . isArray ( value ) ) { if ( moment . isMoment ( value [ 0 ] ) ) { push ( key , { $gte : value [ 0 ] . startOf ( "day" ) . toDate ( ) , $lte : value [ 1 ] . endOf ( "day" ) . toDate ( ) , } ) ; } if ( typeof value [ 0 ] === "number" ) { push ( key , { $gte : value [ 0 ] , $lte : value [ 1 ] , } ) ; } push ( key , { $in : filters [ key ] , } ) ; } else { if ( typeof filters [ key ] === "string" ) { if ( filters [ key ] !== "" ) { push ( key , new RegExp ( filters [ key ] , "i" ) ) ; } } else { if ( typeof filters [ key ] === "object" ) { const objectFilters = this . extractFilters ( filters [ key ] , key + "." ) ; if ( objectFilters . length ) { $and . push ( ... objectFilters ) ; } } else { push ( key , { $in : Array . isArray ( filters [ key ] ) ? filters [ key ] : [ filters [ key ] ] , } ) ; } } } } return $and ; } } export type AntListActionsType < T > = { label : string ; icon ? : React . ReactElement ; items : AntListActionsItemType < T > [ ] ; } ; export type AntListActionsItemType < T > = { label : string ; icon ? : React . ReactElement ; /**
     * This can ask for confirmation to proceed to action
     */ confirm ? : string ; action : ( model : T ) => any ; } ;