Skip to content

Commit

Permalink
Merge pull request #14 from Jaspersoft/wrap-texfield-ic
Browse files Browse the repository at this point in the history
Wrapping Text Field IC with Base Input Control
  • Loading branch information
ecanchev-jaspersoft authored Jul 2, 2024
2 parents da449aa + c8455df commit 7f53868
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 135 deletions.
33 changes: 28 additions & 5 deletions packages/jv-input-controls/src/InputControls.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react'
import { BoolICType } from './controls/BooleanInputControl'
import { createRoot } from 'react-dom/client'
import { TextFieldICType } from './controls/SingleValueTextInputControl';
import BasePanel from './panels/BasePanel'
import { InputControlCollection } from './controls/BaseInputControl';

Expand All @@ -11,9 +12,23 @@ export interface InputControlConfig {
tenant: string,
};

export interface InputControlUserConfig {
bool?: {
type: BoolICType
},
singleValueText?: {
type: TextFieldICType
},
singleValueNumber?: {
type: 'number'
}
}

export interface InputControlPanelConfig {
booleanStyle?: BoolICType,
//text?: TextICType,
success?: (success: { code: number; message: string }) => void,
error?: (error: { code: number; message: string }) => void,
exclude?: string[],
config?: InputControlUserConfig
}

const defaultInputControlConfig: InputControlConfig = {
Expand Down Expand Up @@ -59,10 +74,18 @@ export class InputControls {
return this.controlStructure;
}

public renderControlPanel = (uri: string, container: HTMLElement, config?: InputControlPanelConfig) => {
public renderControlPanel = (uri: string, container: HTMLElement, icPanelDef?: InputControlPanelConfig) => {
this.fillControlStructure(uri, (controls: InputControlCollection) => {
const icRoot = createRoot(container);
icRoot.render(<BasePanel controls={controls} booleanStyle={config?.booleanStyle} />);
try {
const icRoot = createRoot(container);
// TODO: we have to consider the exclude/include property from the icPanelDef before providing the controls prop
icRoot.render(<BasePanel controls={controls} config={icPanelDef?.config} />);
if (icPanelDef?.success) {
icPanelDef?.success.call(null, { code: 200, message: 'Controls rendered successfully' });
}
} catch (e) {
icPanelDef?.error && icPanelDef?.error.call(null, { code: 500, message: 'An error occurred when rendering the controls' });
}
});
}

Expand Down
54 changes: 0 additions & 54 deletions packages/jv-input-controls/src/controls/BaseInputControl.ts

This file was deleted.

63 changes: 60 additions & 3 deletions packages/jv-input-controls/src/controls/BaseInputControl.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,64 @@
import * as React from 'react'
import { useState } from 'react';
import { BaseInputControlProps } from '../controls/BaseInputControl'
import { useState, useEffect } from 'react';

export type ICType = string | 'bool' | 'singleValueText' | 'singleValueNumber' | 'singleValueDate' | 'singleValueDatetime' | 'singleValueTime' | 'singleSelect' | 'singleSelectRadio' | 'multiSelect' | 'multiSelectCheckbox' | undefined;

export interface ICOption {
selected?: boolean;
label?: string;
value?: string;
}

export interface ICState {
id: string;
uri: string;
value: string;
error?: string;
totalCount?: string;
options?: ICOption[];
}

export interface ICValidationRule {
errorMessage?: string;
}

export type ICDataTypeType = string | 'date' | 'datetime' | 'time' | 'text' | 'number' | undefined;

export interface ICDataType {
type?: ICDataTypeType;
pattern?: string;
maxValue?: string;
strictMax?: boolean;
minValue?: string;
strictMin?: boolean;
maxLength?: number;
}

export interface BaseInputControlProps {
children?: React.JSX.Element[] | React.JSX.Element;
id: string;
type: ICType;
label: string;
mandatory: boolean;
readOnly: boolean;
visible: boolean;
uri?: string;
state?: ICState;
validationRules?: ICValidationRule;
dataType?: ICDataType;

masterDependencies?: string[];
slaveDependencies?: string[];
}

export interface InputControlCollection {
inputControl: BaseInputControlProps[];
}

const CONTAINER_CLASS = 'jv-uInputControl-container';
const INVISIBLE_CLASS = 'jv-uVisibility-hide';
const MANDATORY_CLASS = 'jv-uMandatory';
const READ_ONLY_CLASS = 'jv-uReadOnly';

export default function BaseInputControl(props: BaseInputControlProps) {

Expand All @@ -14,10 +68,13 @@ export default function BaseInputControl(props: BaseInputControlProps) {
let activeClasses: string[] = [CONTAINER_CLASS];
if (!props.visible) activeClasses.push(INVISIBLE_CLASS);
if (props.mandatory) activeClasses.push(MANDATORY_CLASS);
if (props.readOnly) activeClasses.push(READ_ONLY_CLASS);
setAdditionalCssClasses(activeClasses);
}

getClasses();
useEffect(() => {
getClasses();
}, []);

return (
<div className={additionalCssClasses.join(' ')}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { TextField as JVTextField } from '@jaspersoft/jv-ui-components/material-ui/TextField/TextField';
import { ChangeEvent, useState } from 'react';
import { BaseInputControlProps } from './BaseInputControl';
import BaseInputControl, { BaseInputControlProps } from './BaseInputControl';

export type TextFieldICType = 'textField';

export interface TextFieldICProps extends BaseInputControlProps {
defaultValue?: string;
Expand Down Expand Up @@ -36,15 +38,17 @@ export const SingleValueTextInputControl = (props: TextFieldICProps) => {
cssClasses += ' jv-uVisibility-hide';
}
const isRequiredError = mandatory && currentValue.trim().length === 0;
return <JVTextField variant={props.variant || 'outlined'}
value={currentValue}
size={theSize}
onChange={defaultOnChangeHandler}
className={cssClasses}
InputProps={inputProps}
required={mandatory}
error={isRequiredError}
{...remainingProps}
/>;
return <BaseInputControl {...{ ...remainingProps, mandatory, readOnly, visible }}>
<JVTextField variant={props.variant || 'outlined'}
value={currentValue}
size={theSize}
onChange={defaultOnChangeHandler}
className={cssClasses}
InputProps={inputProps}
required={mandatory}
error={isRequiredError}
{...remainingProps}
/>
</BaseInputControl>;
};

25 changes: 23 additions & 2 deletions packages/jv-input-controls/src/panels/BasePanel.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import * as React from 'react'
import BooleanInputControl from '../controls/BooleanInputControl'
import { SingleValueTextInputControl } from '../controls/SingleValueTextInputControl';
import { InputControlUserConfig } from '../InputControls';

export interface BasePanelProps {
controls: any,
booleanStyle?: 'checkbox' | 'switch',
config?: InputControlUserConfig
}

export default function BasePanel(props: BasePanelProps): React.JSX.Element {
const buildControl = (control: any) => {
if (control.type === 'bool') {
return (
<BooleanInputControl
key={control.id}
id={control.id}
readOnly={control.readOnly}
visible={control.visible}
Expand All @@ -19,7 +22,25 @@ export default function BasePanel(props: BasePanelProps): React.JSX.Element {
uri={control.uri}
label={control.label}

styleType={props.booleanStyle}
styleType={props.config?.bool?.type}
/>
);
}
if (control.type === 'singleValueText') {
let inputTypeText = props.config?.singleValueText?.type || 'text';
if (inputTypeText === 'textField') {
inputTypeText = 'text';
}
return (
<SingleValueTextInputControl
key={control.id}
id={control.id}
label={control.label}
value={control.state.value}
type={inputTypeText}
readOnly={control.readOnly}
visible={control.visible}
mandatory={control.mandatory}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const requiredProps = {
type: 'singleValueText',
};

const getTextIC = (options?: object): JSX.Element => {
const getTextIC = (options?: object): React.JSX.Element => {
return (
<SingleValueTextInputControl {...{ ...requiredProps, ...options }} />
);
Expand Down
38 changes: 4 additions & 34 deletions packages/test-app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import InputControls from '@jaspersoft/jv-input-controls';
import { Authentication, VisualizeFactory, visualizejsLoader, VisualizeType } from '@jaspersoft/jv-tools';
import { useEffect, useState } from 'react';

import {
visualizejsLoader,
Authentication,
VisualizeFactory,
VisualizeType
} from '@jaspersoft/jv-tools';
import MuiTest from './Mui-test.js';
import ControlPanel, { ConfigInputControl } from './controls/ControlPanel.js';
import ControlPanel from './controls/ControlPanel.js';

export interface AppConfig {
title: string,
Expand All @@ -24,33 +17,11 @@ const reportUri = '/public/viz/Adhoc/Ad_Hoc_View_All_filters_Report';

const visualizeUrl = 'https://mobiledemo.jaspersoft.com/jasperserver-pro/client/visualize.js';

const DEFAULT_CONFIG: ConfigInputControl = {
container: '#containerID',
success: (success: { code: number; message: string }) => {
console.log('success => ', success);
},
error: (error: { code: number; message: string }) => {
console.log('error => ', error);
},
exclude: [],
config: {
bool: {
type: 'checkbox'
},
singleValueText: {
type: 'textField'
},
singleValueNumber: {
type: 'number'
}
}
};

export default function App(props: AppConfig) {
const [controlStruct, setControlStruct] = useState({});
const [visualizeFactoryContainer, setVisualizeFactoryContainer] = useState(null as { viz: VisualizeFactory } | null);
const [vContainer, setVContainer] = useState(null as { v: VisualizeType } | null);
const [plugin, setPlugin] = useState();
const [plugin, setPlugin] = useState<InputControls>();

useEffect(() => {
const loadVisualize = visualizejsLoader(visualizeUrl);
Expand Down Expand Up @@ -94,8 +65,7 @@ export default function App(props: AppConfig) {
<h1> {props.title || 'Title Goes Here'}</h1>
<div id="controlBox">
<ControlPanel title={reportUri}
controlData={controlStruct}
icGeneralConfig={DEFAULT_CONFIG}/>
controlData={controlStruct}/>
</div>
</div>
);
Expand Down
Loading

0 comments on commit 7f53868

Please sign in to comment.