All Downloads are FREE. Search and download functionalities are using the official Maven repository.

components.widgets.StandardWidget.tsx Maven / Gradle / Ivy

There is a newer version: 7.28.2
Show newest version
import React, { Children, useCallback, useMemo, ReactNode, CSSProperties, memo } from 'react'
import classNames from 'classnames'
import { connect } from 'react-redux'
import { createStructuredSelector } from 'reselect'
import { isEmpty } from 'lodash'
import { SpinnerType } from '@i-novus/n2o-components/lib/layouts/Spinner/Spinner'

import Toolbar, { ToolbarProps } from '../buttons/Toolbar'
import { Spinner } from '../snippets/Spinner/Spinner'
import { dataSourceError } from '../../ducks/datasource/selectors'
import { ErrorContainer } from '../../core/error/Container'
import { State } from '../../ducks/State'
import { type ErrorContainerProps } from '../../core/error/types'
import { Model } from '../../ducks/models/selectors'

import { WidgetFilters, type Props as WidgetFiltersProps } from './WidgetFilters'

export enum PLACES {
    top = 'top',
    left = 'left',
    right = 'right',
    center = 'center',
    topLeft = 'topLeft',
    topRight = 'topRight',
    topCenter = 'topCenter',
    bottomLeft = 'bottomLeft',
    bottomRight = 'bottomRight',
    bottomCenter = 'bottomCenter',
}

export interface Props {
    widgetId: string
    toolbar: Record
    filter?: { filterPlace: PLACES, filterFieldsets: WidgetFiltersProps['fieldsets'] }
    fetchData?: WidgetFiltersProps['fetchData']
    datasource: string
    pagination?: Record
    disabled?: boolean
    className?: string
    style?: CSSProperties
    children: ReactNode
    loading: boolean
    error: ErrorContainerProps['error']
    activeModel?: Model | Model[]
}

/**
 * Виджет таблица
 * @reactProps {string} widgetId - id виджета
 * @reactProps {Object} toolbar
 * @reactProps {Object} filter
 * @reactProps {boolean} disabled - флаг активности
 * @reactProps {node} children - элемент потомок компонента StandardWidget
 */
const StandardWidget = memo(({
    widgetId,
    fetchData,
    datasource,
    disabled,
    className,
    style,
    children,
    loading,
    error,
    filter = {} as never,
    toolbar = {},
    pagination = {},
}: Props) => {
    const renderToolbar = useCallback((place) => {
        const paginationComponent = pagination[place]
        const currentToolbar = toolbar[place]
        const toolbarClassNames = classNames(
            'd-flex',
            'flex-column',
            'n2o-standard-widget-layout-toolbar-wrapper',
            `n2o-standard-widget-layout-toolbar--${place.toLowerCase().replace(/(bottom)|(top)/, '')}`,
            {
                'flex-column-reverse': place.includes(PLACES.top),
            },
        )

        return (
            currentToolbar || paginationComponent ? (
                
{paginationComponent} {currentToolbar ? : null}
) : null ) }, [pagination, toolbar, widgetId]) const filterComponent = ( ) const { topToolbars, bottomToolbars } = useMemo(() => ({ topToolbars: [ renderToolbar(PLACES.topLeft), renderToolbar(PLACES.topCenter), renderToolbar(PLACES.topRight), ].filter(Boolean), bottomToolbars: [ renderToolbar(PLACES.bottomLeft), renderToolbar(PLACES.bottomCenter), renderToolbar(PLACES.bottomRight), ].filter(Boolean), }), [renderToolbar]) const classes = classNames([ className, 'n2o-standard-widget-layout', { 'n2o-disabled': disabled }, ]) const errorComponent = isEmpty(error) ? null : const childrenWithError = Children.map(children, (child) => { if (React.isValidElement(child)) { return React.cloneElement(child, { errorComponent } as never) } return child }) return (
{filter.filterPlace === PLACES.left ? (
{filterComponent}
) : null}
{filter.filterPlace === PLACES.top ? (
{filterComponent}
) : null} {topToolbars.length ? (
{topToolbars}
) : null}
{childrenWithError}
{bottomToolbars.length ? (
{bottomToolbars}
) : null}
{filter.filterPlace === PLACES.right ? (
{filterComponent}
) : null}
) }) const mapStateToProps = createStructuredSelector({ // @ts-ignore TODO объеденить типы ErrorContainerProps['error'] и dataSourceError, убрать as never error: (state: State, { datasource }: Props) => { if (state.datasource[datasource]) { return dataSourceError(datasource)(state) } return null }, }) // @ts-ignore TODO объеденить типы ErrorContainerProps['error'] и dataSourceError, убрать as never export default connect(mapStateToProps)(StandardWidget)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy