{"version":3,"file":"Table-BkGR684J.js","sources":["../../Client/legacy/Components/FormGroups/Table.tsx"],"sourcesContent":["import { Svg } from '@legacy/Components/Svg';\r\nimport * as React from 'react';\r\nimport { Col, Row } from 'react-bootstrap';\r\nimport InfiniteScroll from '../InfiniteScroll';\r\nimport { Tooltip, TooltipSize } from '../Tooltip';\r\n\r\nexport interface TableParams {\r\n    /** The index from where rows should be returned. */\r\n    start: number;\r\n\r\n    /** The number of rows to return. */\r\n    count: number;\r\n\r\n    /** The search string used filter out results. */\r\n    search: string;\r\n}\r\n\r\nexport interface ITableFormGroupProps<TModel> {\r\n    /** The method used to retrieve data that will be shown in the table. */\r\n    get: (params: TableParams) => Promise<TModel[]> | TModel[];\r\n\r\n    /** The method used to generate the row JSX element. */\r\n    row: (model: TModel, index: number) => JSX.Element;\r\n\r\n    /** The list of headers to show at the top of the table. */\r\n    headers: (string | JSX.Element)[];\r\n\r\n    /** The number of rows to show in each page of the table. Defaults to 100. */\r\n    pageSize?: number;\r\n\r\n    /** An optional CSS class name for the component. */\r\n    className?: string;\r\n\r\n    /** An optional flag indicating whether search is enabled. */\r\n    search?: boolean;\r\n\r\n    /** An optional action element to place above the table. */\r\n    action?: JSX.Element;\r\n\r\n    /** An optional number of milliseconds for search debouncing. Defaults to 200. */\r\n    searchDebounce?: number;\r\n\r\n    /** An optional placeholder string for the search input field. */\r\n    searchPlaceholder?: string;\r\n\r\n    /** An optional value for the first page's size. Defaults to pageSize. */\r\n    initialPageSize?: number;\r\n\r\n    /** An optional label for when no data is available. */\r\n    missingDataLabel?: string;\r\n\r\n    /** An optional callback method fired when models are retrieved. */\r\n    onModelsRetrieved?: () => TModel[];\r\n\r\n    /** An optional callback method fired if an error occurrs while retrieving models. */\r\n    onError?: (error: Error) => void;\r\n\r\n    /** An optional flag indicating whether data should be pulled on mount. If enabled, no data will be requested\r\n     * from the API. Calling `update` directly will trigger the data retrieval. Defaults to false.\r\n     */\r\n    skipInitialUpdate?: boolean;\r\n}\r\n\r\ninterface ITableFormGroupState {\r\n    search: string;\r\n}\r\n\r\nexport class TableFormGroup<TModel> extends React.Component<ITableFormGroupProps<TModel>, ITableFormGroupState> {\r\n    searchDebounce: any;\r\n    infiniteScroll: InfiniteScroll;\r\n\r\n    constructor(props) {\r\n        super(props);\r\n\r\n        this.state = {\r\n            search: '',\r\n        };\r\n    }\r\n\r\n    render() {\r\n        const p = this.props;\r\n        return (\r\n            <div className={`form-group-table-cp form-group-cp ${this.props.className || ''}`}>\r\n                {(p.search || p.action) && (\r\n                    <Row className='row-spacing-cp'>\r\n                        {p.search && (\r\n                            <Col lg={4} md={6} sm={12} xs={12}>\r\n                                <div className='form-group-table-search-cp'>\r\n                                    <input\r\n                                        className='form-group-input-cp'\r\n                                        placeholder={p.searchPlaceholder}\r\n                                        value={this.state.search}\r\n                                        onChange={e => this.search(e.target.value)}\r\n                                    />\r\n                                    <Svg\r\n                                        path='/images/outline-search.svg'\r\n                                        className='form-group-table-search-icon-cp'\r\n                                        alt='Search to filter the table data'\r\n                                    />\r\n                                </div>\r\n                            </Col>\r\n                        )}\r\n                        {p.action && (\r\n                            <Col lg={3} md={4} sm={12} xs={12} lgOffset={p.search ? 5 : 0} mdOffset={p.search ? 2 : 0}>\r\n                                {p.action}\r\n                            </Col>\r\n                        )}\r\n                    </Row>\r\n                )}\r\n\r\n                <Row className={p.search || p.action ? 'row-spacing-cp' : ''}>\r\n                    <Col xs={12}>\r\n                        <div className='scroll-right-cp'>\r\n                            Scroll right to view more info\r\n                            <Svg\r\n                                className='scroll-right-svg-cp'\r\n                                path='/images/arrow-right.svg'\r\n                                alt='Scroll right to view more table data'\r\n                            />\r\n                        </div>\r\n                        <div className={`table-wrapper-cp ${p.search || p.action ? 'table-wrapper-search-cp' : ''}`}>\r\n                            <table>\r\n                                <thead>\r\n                                    <tr>\r\n                                        {p.headers.map((h, i) => (\r\n                                            <th key={h && typeof h === 'string' ? (h as string) : i}>{h}</th>\r\n                                        ))}\r\n                                    </tr>\r\n                                </thead>\r\n\r\n                                <tbody>\r\n                                    <InfiniteScroll\r\n                                        ref={c => {\r\n                                            this.infiniteScroll = c as InfiniteScroll;\r\n                                        }}\r\n                                        count={p.pageSize || 100}\r\n                                        initialCount={p.initialPageSize}\r\n                                        get={async (start: number, count: number) =>\r\n                                            await this.onDataRequired(start, count)\r\n                                        }\r\n                                        build={(model: TModel, index: number) => p.row(model, index)}\r\n                                        loading={\r\n                                            <tr key='loading-row'>\r\n                                                <td colSpan={p.headers.length} className='no-data-cp'>\r\n                                                    <div className='infinite-scroll-loader-cp'></div>\r\n                                                </td>\r\n                                            </tr>\r\n                                        }\r\n                                        missingData={\r\n                                            <tr key='missing-data-row'>\r\n                                                <td colSpan={p.headers.length} className='no-data-cp'>\r\n                                                    {this.props.missingDataLabel || 'No data available'}\r\n                                                </td>\r\n                                            </tr>\r\n                                        }\r\n                                        skipInitialUpdate={this.props.skipInitialUpdate}\r\n                                    />\r\n                                </tbody>\r\n                            </table>\r\n                        </div>\r\n                    </Col>\r\n                </Row>\r\n            </div>\r\n        );\r\n    }\r\n\r\n    refresh() {\r\n        this.infiniteScroll.refresh();\r\n    }\r\n\r\n    update(force?: boolean) {\r\n        this.infiniteScroll.update(force);\r\n    }\r\n\r\n    getModels(): TModel[] {\r\n        return this.infiniteScroll.getModels();\r\n    }\r\n\r\n    setModels(models: TModel[]) {\r\n        this.infiniteScroll.setModels(models);\r\n    }\r\n\r\n    search(search: string) {\r\n        if (this.searchDebounce) clearTimeout(this.searchDebounce);\r\n\r\n        this.setState({ search });\r\n        this.searchDebounce = setTimeout(() => {\r\n            this.infiniteScroll.update(true);\r\n        }, this.props.searchDebounce || 200);\r\n    }\r\n\r\n    private async onDataRequired(start: number, count: number) {\r\n        const params = {\r\n            start,\r\n            count,\r\n            search: this.state.search,\r\n        } as TableParams;\r\n\r\n        let models: TModel[] = [];\r\n        try {\r\n            models = await this.props.get(params);\r\n        } catch (e) {\r\n            if (this.props.onError) this.props.onError(e);\r\n        }\r\n        return models;\r\n    }\r\n}\r\n\r\ninterface ITableRowButtonProps {\r\n    id: string;\r\n    onClick: () => void;\r\n    path: string;\r\n    tooltip: string;\r\n    className?: string;\r\n}\r\n\r\nexport class TableRowButton extends React.Component<ITableRowButtonProps> {\r\n    render() {\r\n        const p = JSON.parse(JSON.stringify(this.props));\r\n        return (\r\n            <Tooltip message={this.props.tooltip} size={TooltipSize.Fill} wrapperClassName={p.className}>\r\n                <Svg {...p} onClick={this.props.onClick} alt={p.tooltip} className='table-row-button-cp' />\r\n            </Tooltip>\r\n        );\r\n    }\r\n}\r\n"],"names":["TableFormGroup","React.Component","props","__publicField","p","jsxs","Row","jsx","Col","e","Svg","h","i","InfiniteScroll","c","start","count","model","index","force","models","search","params"],"mappings":"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"}