Skip to content

Commit

Permalink
Merge a72b1e0 into a4ff972
Browse files Browse the repository at this point in the history
  • Loading branch information
TheZoker committed Jan 22, 2024
2 parents a4ff972 + a72b1e0 commit a8c9fe7
Show file tree
Hide file tree
Showing 7 changed files with 339 additions and 191 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,55 +24,65 @@
*/
import React, { useMemo } from 'react';
import {
Categorization,
Category,
Categorization,
deriveLabelForUISchemaElement,
Translator,
isVisible,
} from '@jsonforms/core';
import { isCategorization } from './tester';
import { AjvProps } from '../../util';

const getCategoryClassName = (
category: Category,
selectedCategory: Category
): string => (selectedCategory === category ? 'selected' : '');

export interface CategorizationProps {
categorization: Categorization;
elements: (Category | Categorization)[];
selectedCategory: Category;
depth: number;
data: any;
onSelect: any;
subcategoriesClassName: string;
groupClassName: string;
t: Translator;
}

export const CategorizationList = ({
categorization,
selectedCategory,
elements,
data,
depth,
onSelect,
subcategoriesClassName,
groupClassName,
t,
}: CategorizationProps) => {
ajv,
}: CategorizationProps & AjvProps) => {
const filteredElements = useMemo(() => {
return elements.filter((category: Category | Categorization) =>
isVisible(category, data, undefined, ajv)
);
}, [elements, data, ajv]);

const categoryLabels = useMemo(
() =>
categorization.elements.map((cat) =>
deriveLabelForUISchemaElement(cat, t)
),
[categorization, t]
() => filteredElements.map((cat) => deriveLabelForUISchemaElement(cat, t)),
[filteredElements, t]
);

return (
<ul className={subcategoriesClassName}>
{categorization.elements.map((category, idx) => {
{filteredElements.map((category, idx) => {
if (isCategorization(category)) {
return (
<li key={categoryLabels[idx]} className={groupClassName}>
<span>{categoryLabels[idx]}</span>
<CategorizationList
categorization={category}
selectedCategory={selectedCategory}
elements={category.elements}
data={data}
ajv={ajv}
depth={depth + 1}
onSelect={onSelect}
subcategoriesClassName={subcategoriesClassName}
Expand All @@ -85,7 +95,7 @@ export const CategorizationList = ({
return (
<li
key={categoryLabels[idx]}
onClick={onSelect(category)}
onClick={onSelect(idx)}
className={getCategoryClassName(category, selectedCategory)}
>
<span>{categoryLabels[idx]}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,89 +22,102 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
import React from 'react';
import React, { useState } from 'react';
import type { Categorization, Category, LayoutProps } from '@jsonforms/core';
import {
RendererComponent,
TranslateProps,
withJsonFormsLayoutProps,
withTranslateProps,
} from '@jsonforms/react';
import { CategorizationList } from './CategorizationList';
import { SingleCategory } from './SingleCategory';
import { isCategorization } from './tester';
import { withVanillaControlProps } from '../../util';
import type { VanillaRendererProps } from '../../index';
import { withAjvProps, withVanillaControlProps } from '../../util';
import type { AjvProps, VanillaRendererProps } from '../../util';

export interface CategorizationState {
selectedCategory: Category;
}

class CategorizationRenderer extends RendererComponent<
LayoutProps & VanillaRendererProps & TranslateProps,
CategorizationState
> {
onCategorySelected = (category: Category) => () => {
return this.setState({ selectedCategory: category });
};
interface CategorizationProps {
selected?: number;
onChange?(selected: number, prevSelected: number): void;
}

/**
* @inheritDoc
*/
render() {
const { uischema, visible, getStyleAsClassName, t } = this.props;
const categorization = uischema as Categorization;
const classNames = getStyleAsClassName('categorization');
const masterClassNames = getStyleAsClassName('categorization.master');
const detailClassNames = getStyleAsClassName('categorization.detail');
const selectedCategory = this.findCategory(categorization);
const subcategoriesClassName = getStyleAsClassName(
'category.subcategories'
);
const groupClassName = getStyleAsClassName('category.group');
export const CategorizationRenderer = ({
data,
uischema,
schema,
path,
selected,
t,
visible,
getStyleAsClassName,
onChange,
ajv,
}: LayoutProps &
VanillaRendererProps &
TranslateProps &
CategorizationProps &
AjvProps) => {
const categorization = uischema as Categorization;
const elements = categorization.elements as (Category | Categorization)[];
const classNames = getStyleAsClassName('categorization');
const masterClassNames = getStyleAsClassName('categorization.master');
const detailClassNames = getStyleAsClassName('categorization.detail');
const subcategoriesClassName = getStyleAsClassName('category.subcategories');
const groupClassName = getStyleAsClassName('category.group');

return (
<div
className={classNames}
hidden={visible === null || visible === undefined ? false : !visible}
>
<div className={masterClassNames}>
<CategorizationList
categorization={categorization}
selectedCategory={selectedCategory}
depth={0}
onSelect={this.onCategorySelected}
subcategoriesClassName={subcategoriesClassName}
groupClassName={groupClassName}
t={t}
/>
</div>
<div className={detailClassNames}>
<SingleCategory
category={selectedCategory}
schema={this.props.schema}
path={this.props.path}
/>
</div>
</div>
);
}
const [previousCategorization, setPreviousCategorization] =
useState<Categorization>(uischema as Categorization);
const [activeCategory, setActiveCategory] = useState<number>(selected ?? 0);

private findCategory(categorization: Categorization): Category {
const category = categorization.elements[0];
const safeCategory =
activeCategory >= categorization.elements.length ? 0 : activeCategory;

if (this.state && this.state.selectedCategory) {
return this.state.selectedCategory;
}
if (categorization !== previousCategorization) {
setActiveCategory(0);
setPreviousCategorization(categorization);
}

if (isCategorization(category)) {
return this.findCategory(category);
const onCategorySelected = (categoryIndex: number) => () => {
if (onChange) {
return onChange(categoryIndex, safeCategory);
}
return setActiveCategory(categoryIndex);
};

return category;
}
}
return (
<div
className={classNames}
hidden={visible === null || visible === undefined ? false : !visible}
>
<div className={masterClassNames}>
<CategorizationList
elements={elements}
selectedCategory={elements[safeCategory] as Category}
data={data}
ajv={ajv}
depth={0}
onSelect={onCategorySelected}
subcategoriesClassName={subcategoriesClassName}
groupClassName={groupClassName}
t={t}
/>
</div>
<div className={detailClassNames}>
<SingleCategory
category={elements[safeCategory] as Category}
schema={schema}
path={path}
key={safeCategory}
/>
</div>
</div>
);
};

export default withVanillaControlProps(
withTranslateProps(withJsonFormsLayoutProps(CategorizationRenderer))
export default withAjvProps(
withVanillaControlProps(
withTranslateProps(withJsonFormsLayoutProps(CategorizationRenderer))
)
);
110 changes: 1 addition & 109 deletions packages/vanilla-renderers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,89 +22,6 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
import { RankedTester } from '@jsonforms/core';

import {
BooleanCell,
booleanCellTester,
DateCell,
dateCellTester,
dateTimeCellTester,
EnumCell,
enumCellTester,
IntegerCell,
integerCellTester,
NumberCell,
numberCellTester,
SliderCell,
sliderCellTester,
TextAreaCell,
textAreaCellTester,
TextCell,
textCellTester,
TimeCell,
timeCellTester,
} from './cells';

import {
InputControl,
inputControlTester,
RadioGroupControl,
radioGroupControlTester,
OneOfRadioGroupControl,
oneOfRadioGroupControlTester,
} from './controls';

import {
ArrayControl,
arrayControlTester,
Categorization,
categorizationTester,
LabelRenderer,
labelRendererTester,
TableArrayControl,
tableArrayControlTester,
} from './complex';

import {
GroupLayout,
groupTester,
HorizontalLayout,
horizontalLayoutTester,
VerticalLayout,
verticalLayoutTester,
} from './layouts';
import DateTimeCell from './cells/DateTimeCell';

export interface WithClassname {
className?: string;
}

/**
* Additional renderer props specific to vanilla renderers.
*/
export interface VanillaRendererProps extends WithClassname {
classNames?: { [className: string]: string };
/**
* Returns all classes associated with the given style.
* @param {string} string the style name
* @param args any additional args necessary to calculate the classes
* @returns {string[]} array of class names
*/
getStyle?(string: string, ...args: any[]): string[];

/**
* Returns all classes associated with the given style as a single class name.
* @param {string} string the style name
* @param args any additional args necessary to calculate the classes
* @returns {string[]} array of class names
*/
getStyleAsClassName?(string: string, ...args: any[]): string;
}

export interface WithChildren {
children: any;
}

export * from './actions';
export * from './controls';
Expand All @@ -114,29 +31,4 @@ export * from './layouts';
export * from './reducers';
export * from './util';
export * from './styles';

export const vanillaRenderers: { tester: RankedTester; renderer: any }[] = [
{ tester: inputControlTester, renderer: InputControl },
{ tester: radioGroupControlTester, renderer: RadioGroupControl },
{ tester: oneOfRadioGroupControlTester, renderer: OneOfRadioGroupControl },
{ tester: arrayControlTester, renderer: ArrayControl },
{ tester: labelRendererTester, renderer: LabelRenderer },
{ tester: categorizationTester, renderer: Categorization },
{ tester: tableArrayControlTester, renderer: TableArrayControl },
{ tester: groupTester, renderer: GroupLayout },
{ tester: verticalLayoutTester, renderer: VerticalLayout },
{ tester: horizontalLayoutTester, renderer: HorizontalLayout },
];

export const vanillaCells: { tester: RankedTester; cell: any }[] = [
{ tester: booleanCellTester, cell: BooleanCell },
{ tester: dateCellTester, cell: DateCell },
{ tester: dateTimeCellTester, cell: DateTimeCell },
{ tester: enumCellTester, cell: EnumCell },
{ tester: integerCellTester, cell: IntegerCell },
{ tester: numberCellTester, cell: NumberCell },
{ tester: sliderCellTester, cell: SliderCell },
{ tester: textAreaCellTester, cell: TextAreaCell },
{ tester: textCellTester, cell: TextCell },
{ tester: timeCellTester, cell: TimeCell },
];
export * from './renderers';
Loading

0 comments on commit a8c9fe7

Please sign in to comment.