I am trying to implement a custom categorization rendere and I need to parse the errors of each category. I am aware that I can use getSubErrorsAt
to do that. The function needs the instance path and schema as input.
The schema is available to me, the instance path on the other hand is undefined when I try to get it from my props.
Here is my renderer.
import React, { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
Categorization,
Category,
getSubErrorsAt,
isVisible,
RankedTester,
rankWith,
StatePropsOfLayout,
uiTypeIs,
} from '@jsonforms/core';
import {
MaterialLayoutRenderer,
MaterialLayoutRendererProps,
} from '@jsonforms/material-renderers';
import {
JsonFormsStateContext,
useJsonForms,
withJsonFormsLayoutProps,
} from '@jsonforms/react';
import { BottomSheetOptions } from '@linckr/ui-react';
import { Box, Hidden } from '@mui/material';
import { SubtaskButton } from '../../../../screens/taskForm/partials/SubtaskButton';
import { SelectRenderInput } from '../../components/SelectRenderInput';
const CategorizationRenderer = ({
uischema,
schema,
path,
visible,
renderers,
data,
cells,
}: StatePropsOfLayout) => {
const [activeCategory, setActiveCategory] = useState<number>(0);
const [openCategories, setOpenCategories] = useState(false);
const {
core,
config: { submitForm },
}: JsonFormsStateContext = useJsonForms();
const { ajv, errors } = core || {};
const { t } = useTranslation();
const categorization = uischema as Categorization;
const categories = useMemo(
() =>
categorization.elements.filter((category: Category | Categorization) => {
if (category.type !== 'Category' || !ajv) {
return false;
}
return isVisible(category, data, '', ajv);
}),
[categorization.elements, ajv, data],
);
const activeCategoryIsLast = activeCategory + 1 === categories.length;
const handleCategoryChange = (step?: number) => {
const nextStep = step || step === 0 ? step : activeCategory + 1;
setActiveCategory(nextStep);
};
const childProps: MaterialLayoutRendererProps = {
elements: categorization.elements[activeCategory].elements,
schema,
path,
direction: 'column',
visible,
renderers,
cells,
};
const bottomSheetOptions = categories.map((category, idx) => {
return {
value: `${idx}`,
label: `${idx + 1}/${categories.length} - ${category.label}`,
};
});
return (
<Box
display='flex'
flexDirection='column'
justifyContent='space-between'
height='100%'
>
<Hidden xsUp={!visible}>
<Box>
<Box
sx={{
width: '100%',
display: 'flex',
justifyContent: 'center',
py: 2,
}}
>
<SelectRenderInput
title={`${activeCategory + 1}/${categories.length} ${
categories[activeCategory].label
}`}
onButtonClick={() => setOpenCategories(true)}
/>
</Box>
<MaterialLayoutRenderer {...childProps} />
</Box>
</Hidden>
<BottomSheetOptions
items={bottomSheetOptions}
close={() => setOpenCategories(false)}
isOpen={openCategories}
onSelect={(value: string) => setActiveCategory(Number(value))}
title={uischema.options?.title}
selectedValue={`${activeCategory}`}
/>
{submitForm && (
<SubtaskButton
label={t(activeCategoryIsLast ? 'main.submit' : 'main.next')}
isLoading={false}
onClick={() =>
activeCategoryIsLast ? submitForm() : handleCategoryChange()
}
/>
)}
</Box>
);
};
const categorizationRendererTester: RankedTester = rankWith(
6,
uiTypeIs('Categorization'),
);
export default {
tester: categorizationRendererTester,
renderer: withJsonFormsLayoutProps(CategorizationRenderer),
};
the path
prop is undefined. The renderer is imported into a renderers array which is then passed to the JsonForms component. Note that I import the default export, which is the wrapped renderer and not the raw renderer.