Skip to content

Commit

Permalink
optimize ErrorBoundary multi type support #68
Browse files Browse the repository at this point in the history
  • Loading branch information
elbakerino committed Mar 13, 2022
1 parent 608cbdb commit 336d372
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 53 deletions.
13 changes: 5 additions & 8 deletions packages/ds-material/src/widgetsBinding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,15 @@ import { pluginStack } from './pluginStack'
import { WidgetRenderer } from '@ui-schema/ui-schema/WidgetRenderer'
import { validators } from '@ui-schema/ui-schema/Validators/validators'
import { CardRenderer, FormGroup, LabelBox } from '@ui-schema/ds-material/Widgets'
import { WidgetProps, WidgetsBindingFactory, WidgetType, WithScalarValue } from '@ui-schema/ui-schema'
import { ErrorFallbackProps, WidgetProps, WidgetsBindingFactory, WidgetType, WithScalarValue } from '@ui-schema/ui-schema'
import { InfoRendererProps } from '@ui-schema/ds-material/Component/InfoRenderer'
import { List } from 'immutable'

const MyFallbackComponent: React.ComponentType<{
error: any | null
type?: string
widget?: string
}> = ({type, widget}) => (
const MyFallbackComponent: React.ComponentType<ErrorFallbackProps> = ({type, widget}) => (
<div>
<p><strong>System Error in Widget!</strong></p>
<p><strong>Type:</strong> {type}</p>
<p><strong>Widget:</strong> {widget}</p>
<p><strong>Type:</strong> {List.isList(type) ? type.join(', ') : (type || '-')}</p>
<p><strong>Widget:</strong> {widget || '-'}</p>
</div>
)

Expand Down
23 changes: 10 additions & 13 deletions packages/ui-schema/src/PluginStack/PluginStackErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from 'react'
import { WidgetsBindingComponents } from '@ui-schema/ui-schema/WidgetsBinding'
import { ErrorFallbackProps } from '@ui-schema/ui-schema/WidgetsBinding'
import { StoreKeys } from '@ui-schema/ui-schema/UIStore'
import { List } from 'immutable'

export class PluginStackErrorBoundary extends React.Component<{
FallbackComponent: WidgetsBindingComponents['ErrorFallback']
type: string | undefined
FallbackComponent: React.ComponentType<ErrorFallbackProps>
type: string | List<string> | undefined
widget: string | undefined
storeKeys: StoreKeys
}> {
Expand All @@ -23,16 +24,12 @@ export class PluginStackErrorBoundary extends React.Component<{
render() {
if (this.state.error) {
const FallbackComponent = this.props.FallbackComponent
if (FallbackComponent) {
return <FallbackComponent
error={this.state.error}
type={this.props.type}
widget={this.props.widget}
storeKeys={this.props.storeKeys}
/>
}
// todo: multi type support #68
return 'error-' + this.props.type + (this.props.widget ? '-' + this.props.widget : '')
return <FallbackComponent
error={this.state.error}
type={this.props.type}
widget={this.props.widget}
storeKeys={this.props.storeKeys}
/>
}
return this.props.children
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export const VirtualArrayRenderer = (
key={i}
schema={
List.isList(schema.get('items')) ?
schema.get('items').get(i)
: schema.get('items')
schema.get('items').get(i) :
schema.get('items')
}
parentSchema={schema}
storeKeys={storeKeys.push(i)}
Expand Down
33 changes: 19 additions & 14 deletions packages/ui-schema/src/WidgetRenderer/WidgetRenderer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import {useImmutable} from '@ui-schema/ui-schema/Utils';
import {widgetMatcher} from '@ui-schema/ui-schema/widgetMatcher';
import {List} from 'immutable';

export const WidgetRenderer = (
{
Expand All @@ -9,10 +10,6 @@ export const WidgetRenderer = (
WidgetOverride,
errors,
onErrors,
// todo: concept in validation
// we do not want `parentSchema` to be passed to the final widget for performance reasons
// eslint-disable-next-line no-unused-vars
//parentSchema,
// we do not want `requiredList` to be passed to the final widget for performance reasons
// eslint-disable-next-line no-unused-vars
requiredList,
Expand All @@ -23,26 +20,34 @@ export const WidgetRenderer = (
},
) => {
const {schema, widgets, isVirtual} = props;
const type = schema.get('type');
const widgetName = schema.get('widget');
const currentErrors = useImmutable(errors)

React.useEffect(() => onErrors && onErrors(currentErrors), [onErrors, currentErrors])

let Widget = widgetMatcher({
isVirtual,
WidgetOverride,
const schemaType = schema.get('type');
const widgetName = schema.get('widget');
const Widget = widgetMatcher({
isVirtual: isVirtual,
WidgetOverride: WidgetOverride,
widgetName: widgetName,
schemaType: type,
widgets,
schemaType: schemaType,
widgets: widgets,
});

const extractValue = !isVirtual && (type === 'array' || type === 'object')
const noExtractValue = !isVirtual && (
schemaType === 'array' || schemaType === 'object' ||
(
List.isList(schemaType) && (
schemaType.indexOf('array') !== -1 ||
schemaType.indexOf('object') !== -1
)
)
)
return Widget ?
<Widget
{...props}
value={extractValue ? undefined : value}
internalValue={extractValue ? undefined : internalValue}
value={noExtractValue ? undefined : value}
internalValue={noExtractValue ? undefined : internalValue}
errors={currentErrors}
/> : null;
};
15 changes: 9 additions & 6 deletions packages/ui-schema/src/WidgetsBinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { WidgetType } from '@ui-schema/ui-schema/Widget'
import { WidgetRendererProps } from '@ui-schema/ui-schema/WidgetRenderer'
import { PluginSimple } from '@ui-schema/ui-schema/PluginSimpleStack/PluginSimple'
import { StoreKeys } from '@ui-schema/ui-schema/UIStore'
import { List } from 'immutable'

export interface GroupRendererProps {
storeKeys: StoreKeys
Expand All @@ -17,13 +18,15 @@ export interface GroupRendererProps {
spacing?: number
}

export interface ErrorFallbackProps {
error: any | null
storeKeys: StoreKeys
type?: string | List<string>
widget?: string
}

export interface WidgetsBindingComponents {
ErrorFallback?: React.ComponentType<{
error: any | null
storeKeys: StoreKeys
type?: string
widget?: string
}>
ErrorFallback?: React.ComponentType<ErrorFallbackProps>
// wraps the whole generator
RootRenderer: React.ComponentType<any>
// wraps any `object` that has no custom widget
Expand Down
18 changes: 8 additions & 10 deletions packages/ui-schema/src/widgetMatcher/widgetMatcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,14 @@ export function widgetMatcher<W extends WidgetsBindingFactory<{}, WidgetsBinding
schemaType,
widgets,
NoWidget: NoWidgetCustom,
}:
{
isVirtual: boolean
//WidgetOverride?: PluginStackProps['WidgetOverride']
WidgetOverride?: WidgetOverrideType<{}, {}, W>
widgetName: string | undefined
schemaType: SchemaTypesType
widgets: W
NoWidget?: React.ComponentType<NoWidgetProps>
}
}: {
isVirtual: boolean
WidgetOverride?: WidgetOverrideType<{}, {}, W>
widgetName: string | undefined
schemaType: SchemaTypesType
widgets: W
NoWidget?: React.ComponentType<NoWidgetProps>
}
): WidgetType<{}, W> | null {
const NoW = NoWidgetCustom || NoWidget
let Widget: WidgetType<{}, W> | null = null
Expand Down

0 comments on commit 336d372

Please sign in to comment.