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

core.factory.FactoryProvider.jsx Maven / Gradle / Ivy

The newest version!
import React, { Component, Children } from 'react'
import PropTypes from 'prop-types'
import first from 'lodash/first'
import each from 'lodash/each'
import isObject from 'lodash/isObject'
import isArray from 'lodash/isArray'
import isString from 'lodash/isString'
import values from 'lodash/values'

import { withErrorBoundary } from '../error/withErrorBoundary'

import factoryConfigShape from './factoryConfigShape'
import { NotFoundFactory } from './NotFoundFactory'
import { FactoryContext } from './context'

const ignoreList = ['dataProvider', 'action', 'actions']

export class FactoryProvider extends Component {
    getChildContext() {
        const { contextMethods } = this.state

        return contextMethods
    }

    constructor(props, context) {
        super(props, context)
        this.factories = props.config
        this.getComponent = this.getComponent.bind(this)
        this.resolveProps = this.resolveProps.bind(this)
        this.componentCache = new WeakMap()
        this.state = {
            contextMethods: {
                factories: this.factories,
                getComponent: this.getComponent,
                resolveProps: this.resolveProps,
            },
        }
    }

    withBoundary = (component = null) => {
        if (this.componentCache.has(component)) {
            return this.componentCache.get(component)
        }

        const WithErrorBoundary = withErrorBoundary(component)

        this.componentCache.set(component, WithErrorBoundary)

        return WithErrorBoundary
    }

    getComponent(src, level) {
        if (level && this.factories[level]?.[src]) {
            return this.withBoundary(this.factories[level][src])
        }
        const factories = []

        each(this.factories, (group) => {
            if (group && group[src]) {
                const comp = this.withBoundary(group[src])

                factories.push(comp)
            }
        })

        return first(factories)
    }

    resolveProps(
        props,
        defaultComponent = NotFoundFactory,
        paramName = 'component',
    ) {
        const obj = {}

        if (isObject(props)) {
            Object.keys(props).forEach((key) => {
                if (isObject(props[key]) && !ignoreList.includes(key)) {
                    obj[key] = this.resolveProps(props[key], defaultComponent, paramName)
                } else if (key === 'src') {
                    obj[paramName] = this.getComponent(props[key], null) || defaultComponent
                } else {
                    obj[key] = props[key]
                }
            })

            return isArray(props) ? values(obj) : obj
        }

        if (isString(props)) {
            return this.getComponent(props) || defaultComponent
        }

        return props
    }

    render() {
        const { children } = this.props
        const { contextMethods } = this.state

        return (
            
                {Children.only(children)}
            
        )
    }
}

FactoryProvider.propTypes = {
    config: factoryConfigShape.isRequired,
    children: PropTypes.element.isRequired,
}

FactoryProvider.childContextTypes = {
    factories: factoryConfigShape.isRequired,
    getComponent: PropTypes.func,
    resolveProps: PropTypes.func,
}

export default FactoryProvider




© 2015 - 2024 Weber Informatics LLC | Privacy Policy