move react projects to own folder
This commit is contained in:
@@ -0,0 +1,366 @@
|
||||
import * as FluentUI from '@fluentui/react';
|
||||
import type { IElixFormsComponentFormState } from './IElixFormsComponentFormState';
|
||||
import type { IElixFormsComponentProperties } from './IElixFormsComponentProperties';
|
||||
import { ElixFormsElement } from './ElixFormsElement';
|
||||
import { QueryParamHelper } from './QueryParamHelper';
|
||||
import { Component, type FormEvent, type JSX, useState } from 'react';
|
||||
import React from 'react';
|
||||
import type { IElixFormsComponentCustomFormFieldFactory } from './IElixFormsComponentCustomFormFieldFactory';
|
||||
import type { ElixFormsCheckboxOption, ElixFormsDropdownOption, ElixFormsRadioOption } from './ElixFormsTypes';
|
||||
|
||||
export default abstract class ElixFormsComponentAbstract extends Component<IElixFormsComponentProperties, IElixFormsComponentFormState> {
|
||||
constructor(props: IElixFormsComponentProperties) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
formData: {}
|
||||
};
|
||||
|
||||
// const [formData, setFormData] = useState({});
|
||||
// const handleAnyInputChange = (name: string) => (event: any, valueOrOption: any) => { //ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement> | SyntheticEvent<HTMLElement, Event>
|
||||
// let value: any = null;
|
||||
// // Fluent UI Dropdown passes (event, option)
|
||||
// if (valueOrOption && valueOrOption.key !== undefined) {
|
||||
// value = valueOrOption.key;
|
||||
// }
|
||||
// // Fluent UI TextField passes (event, newValue)
|
||||
// else if (typeof valueOrOption === "string") {
|
||||
// value = valueOrOption;
|
||||
// }
|
||||
// // Fluent UI Checkbox passes (event, checked)
|
||||
// else if (typeof valueOrOption === "boolean") {
|
||||
// value = valueOrOption;
|
||||
// }
|
||||
// // Native HTML inputs
|
||||
// else if (event?.target) {
|
||||
// value = event.target.type === "checkbox"
|
||||
// ? event.target.checked
|
||||
// : event.target.value;
|
||||
// }
|
||||
// setFormData(prev => ({
|
||||
// ...prev,
|
||||
// [name]: value
|
||||
// }));
|
||||
// console.log(`Input ${name} changed to ${value}. Current form data:`, JSON.stringify(formData));
|
||||
// };
|
||||
}
|
||||
|
||||
private checkboxValues = new Map<string, number[]>();
|
||||
|
||||
private mandatoryFormFieldNames: string[] = [
|
||||
"RWE2_MODULE_ID",
|
||||
"RWE2_REQUEST_ID",
|
||||
"custom-workflow-back-url",
|
||||
"custom-workflow-generic-id",
|
||||
"custom-workflow-current-tabrel-genid",
|
||||
"custom-workflow-source-field",
|
||||
"crc",
|
||||
"MODULE_TESTMODE_KEY",
|
||||
"ELANG"
|
||||
];
|
||||
|
||||
private createMandatoryFormFields(queryParams: URLSearchParams) : JSX.Element {
|
||||
const hiddenInputs: JSX.Element[] = [];
|
||||
|
||||
// Create a hidden input for each mandatory Elix parameter
|
||||
this.mandatoryFormFieldNames.forEach(paramName => {
|
||||
const value = queryParams.get(paramName) ?? "";
|
||||
// Create the input element
|
||||
hiddenInputs.push(this.createHiddenInput(paramName));
|
||||
});
|
||||
|
||||
return <>{hiddenInputs}</>;
|
||||
}
|
||||
|
||||
private createAdditionalFormFields() : React.ReactElement {
|
||||
const schema = JSON.parse(this.props.additionalFieldsJson || "[]");
|
||||
|
||||
return (
|
||||
<>
|
||||
{schema.map((field: { key: React.Key | null | undefined; }) => (
|
||||
<div key={field.key}>
|
||||
{this.renderField(field)}
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
public createCustomFormFields(callback: (formFieldFactory: IElixFormsComponentCustomFormFieldFactory) => JSX.Element = () => <></>): JSX.Element {
|
||||
const formFieldFactory = {
|
||||
createBooleanInput: (name: string, label: string, required: boolean = false) =>
|
||||
this.createBooleanInput(name, label, required),
|
||||
createCheckboxInput: (name: string, label: string, options: Array<ElixFormsCheckboxOption>) =>
|
||||
this.createCheckboxInput(name, label, options),
|
||||
createDropdownInput: (name: string, label: string, options: Array<ElixFormsDropdownOption>, required: boolean = false) =>
|
||||
this.createDropdownInput(name, label, options, required),
|
||||
createHiddenInput: (name: string) =>
|
||||
this.createHiddenInput(name),
|
||||
createNumberInput: (name: string, label: string, required: boolean = false) =>
|
||||
this.createNumberInput(name, label, required),
|
||||
createRadioInput: (name: string, label: string, options: Array<ElixFormsRadioOption>, required: boolean = false) =>
|
||||
this.createRadioInput(name, label, options, required),
|
||||
createTextInput: (name: string, label: string, required: boolean = false) =>
|
||||
this.createTextInput(name, label, required),
|
||||
createTextAreaInput: (name: string, label: string, required: boolean = false) =>
|
||||
this.createTextAreaInput(name, label, required),
|
||||
};
|
||||
|
||||
return callback(formFieldFactory);
|
||||
}
|
||||
|
||||
public override render(): React.ReactElement<IElixFormsComponentProperties> {
|
||||
const {
|
||||
description,
|
||||
isDarkTheme,
|
||||
environmentMessage,
|
||||
hasTeamsContext,
|
||||
userDisplayName,
|
||||
additionalFieldsJson,
|
||||
customFormFieldsConfiguration
|
||||
} = this.props;
|
||||
|
||||
const queryParams = new URLSearchParams(window.location.search);
|
||||
|
||||
return (
|
||||
<section>
|
||||
{/* className={`${styles.elixFormsReact} ${hasTeamsContext ? styles.teams : ''}`} */}
|
||||
<div>{environmentMessage}</div>
|
||||
<div>{description}</div>
|
||||
<form action="https://procedure.unipr.it/rwe2/ComeBackToElixAndSave" method="post">
|
||||
{this.createMandatoryFormFields(queryParams)}
|
||||
{this.createAdditionalFormFields()}
|
||||
{this.createCustomFormFields(customFormFieldsConfiguration)}
|
||||
<input type="submit" value="Submit"/>
|
||||
</form>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
private createCheckboxInput(paramName: string, label: string, values: Array<ElixFormsCheckboxOption>) : JSX.Element {
|
||||
const checkedValues = QueryParamHelper.getCheckedFromQuery(paramName);
|
||||
|
||||
if (!this.checkboxValues.get(paramName)) {
|
||||
this.checkboxValues.set(paramName, checkedValues);
|
||||
}
|
||||
|
||||
const checkboxes: React.ReactElement[] = [];
|
||||
const stackTokens = { childrenGap: 10 };
|
||||
|
||||
values.forEach((entry, entryIndex) => {
|
||||
const id = `${paramName}_${entryIndex}`;
|
||||
checkboxes.push(
|
||||
<FluentUI.Checkbox title={label} key={id} id={id} label={entry.label} required={entry.required ?? false} defaultChecked={checkedValues.indexOf(entryIndex) !== -1} className='isiportalPartialAdminCheckboxFieldItem'
|
||||
onChange={(event, checked) => {
|
||||
const currentCheckboxValues = this.checkboxValues.get(paramName)!;
|
||||
const checkboxIndex = currentCheckboxValues.indexOf(entryIndex);
|
||||
if (checked && checkboxIndex === -1) {
|
||||
currentCheckboxValues.push(entryIndex);
|
||||
} else if (!checked && checkboxIndex !== -1) {
|
||||
currentCheckboxValues.splice(checkboxIndex, 1);
|
||||
}
|
||||
this.state.formData[paramName] = currentCheckboxValues.join(',').trim() ?? '';
|
||||
//this.setState({ formData: { ...this.state.formData, [paramName]: currentCheckboxValues.join(',').trim() ?? '' } }, () =>
|
||||
console.log(`Checkbox ${id} changed to ${checked}. Current values for ${paramName}: ${this.state.formData[paramName]}`);
|
||||
//);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
return new ElixFormsElement(
|
||||
<><FluentUI.Label htmlFor={paramName}>{label}</FluentUI.Label></>,
|
||||
<><FluentUI.Stack tokens={stackTokens}>
|
||||
{checkboxes}
|
||||
</FluentUI.Stack>
|
||||
<input type='hidden' id={paramName} name={paramName} value={this.state.formData[paramName] ?? ''} />
|
||||
</>
|
||||
).render();
|
||||
}
|
||||
|
||||
private createRadioInput(paramName: string, label: string, values: Array<ElixFormsRadioOption>, required: boolean = false) : JSX.Element {
|
||||
const radioValue = QueryParamHelper.getOptionFromQuery(paramName);
|
||||
const radios: FluentUI.IChoiceGroupOption[] = [];
|
||||
|
||||
values.forEach((entry, _) => {
|
||||
const id = `${paramName}_${entry.value}`;
|
||||
radios.push(
|
||||
{
|
||||
key: id,
|
||||
text: entry.label,
|
||||
id: id,
|
||||
name: paramName,
|
||||
value: entry.value,
|
||||
className: 'isiportalPartialAdminFormFieldRadio'
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return new ElixFormsElement(
|
||||
<></>,
|
||||
<FluentUI.ChoiceGroup
|
||||
name={paramName}
|
||||
label={label}
|
||||
options={radios}
|
||||
required={required}
|
||||
defaultSelectedKey={`${paramName}_${radioValue}`}
|
||||
onChange={(event, option) => {
|
||||
const value = option?.value ?? '';
|
||||
this.setState({ formData: { ...this.state.formData, [paramName]: value } }, () =>
|
||||
console.log(`Radio ${option?.id} changed to ${value}. Current value for ${paramName}: ${this.state.formData[paramName]}`)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
).render();
|
||||
}
|
||||
|
||||
private createBooleanInput(paramName: string, label: string, required: boolean = false) : JSX.Element {
|
||||
const boolValue = QueryParamHelper.getOptionFromQuery(paramName);
|
||||
const radios: FluentUI.IChoiceGroupOption[] = [];
|
||||
|
||||
[{ "value": "true", "label": "Sì" }, { "value": "false", "label": "No" }].forEach((val) => {
|
||||
const id = `${paramName}_${val.value}`;
|
||||
radios.push(
|
||||
{
|
||||
key: id,
|
||||
text: val.label,
|
||||
id: id,
|
||||
name: paramName,
|
||||
value: val.value,
|
||||
className: 'isiportalPartialAdminFormFieldRadio'
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return new ElixFormsElement(
|
||||
<></>,
|
||||
<FluentUI.ChoiceGroup
|
||||
name={paramName}
|
||||
label={label}
|
||||
options={radios}
|
||||
required={required}
|
||||
defaultSelectedKey={`${paramName}_${boolValue}`}
|
||||
onChange={(event, option) => {
|
||||
const value = option?.value ?? '';
|
||||
this.setState({ formData: { ...this.state.formData, [paramName]: value } }, () =>
|
||||
console.log(`Boolean ${option?.id} changed to ${value}. Current value for ${paramName}: ${this.state.formData[paramName]}`)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
).render();
|
||||
}
|
||||
|
||||
private createTextAreaInput(paramName: string, label: string, required: boolean = false) : JSX.Element {
|
||||
const textareaValue = QueryParamHelper.getDecodedTextFromQuery(paramName) ?? "";
|
||||
return new ElixFormsElement(
|
||||
<FluentUI.Label htmlFor={paramName}>{label}</FluentUI.Label>,
|
||||
<FluentUI.TextField id={paramName} name={paramName} defaultValue={textareaValue} multiline rows={4} required={required} className='isiportalPartialAdminFormFieldMultiLineText'
|
||||
onChange={(event, value) => {
|
||||
this.setState({ formData: { ...this.state.formData, [paramName]: value } }, () =>
|
||||
console.log(`TextArea ${paramName} changed to ${value}. Current value for ${paramName}: ${this.state.formData[paramName]}`)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
).render();
|
||||
}
|
||||
|
||||
private createTextInput(paramName: string, label: string, required: boolean = false) : JSX.Element {
|
||||
const textValue = QueryParamHelper.getDecodedTextFromQuery(paramName) ?? "";
|
||||
return new ElixFormsElement(
|
||||
<FluentUI.Label htmlFor={paramName}>{label}</FluentUI.Label>,
|
||||
<FluentUI.TextField id={paramName} name={paramName} defaultValue={textValue} required={required} className='isiportalPartialAdminFormFieldSingleLineText'
|
||||
onChange={(event, value) => {
|
||||
this.setState({ formData: { ...this.state.formData, [paramName]: value } }, () =>
|
||||
console.log(`TextInput ${paramName} changed to ${value}. Current value for ${paramName}: ${this.state.formData[paramName]}`)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
).render();
|
||||
}
|
||||
|
||||
private createHiddenInput(paramName: string) : JSX.Element {
|
||||
const textValue = QueryParamHelper.getDecodedTextFromQuery(paramName) ?? "";
|
||||
return <><input type='text' id={paramName} name={paramName} defaultValue={textValue} /><br/></>;
|
||||
}
|
||||
|
||||
private createNumberInput(paramName: string, label: string, required: boolean = false) : JSX.Element {
|
||||
const textValue = QueryParamHelper.getDecodedTextFromQuery(paramName) ?? "";
|
||||
return new ElixFormsElement(
|
||||
<FluentUI.Label htmlFor={paramName}>{label}</FluentUI.Label>,
|
||||
<FluentUI.TextField id={paramName} name={paramName} defaultValue={textValue} type="number" required={required} className='isiportalPartialAdminFormFieldSingleLineText'
|
||||
onChange={(event, value) => {
|
||||
this.setState({ formData: { ...this.state.formData, [paramName]: value } }, () =>
|
||||
console.log(`NumberInput ${paramName} changed to ${value}. Current value for ${paramName}: ${this.state.formData[paramName]}`)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
).render();
|
||||
}
|
||||
|
||||
private createDropdownInput(paramName: string, label: string, values: Array<ElixFormsDropdownOption>, required: boolean = false): JSX.Element {
|
||||
const selectedValue = QueryParamHelper.getOptionFromQuery(paramName);
|
||||
const options: FluentUI.IDropdownOption[] = [];
|
||||
|
||||
values.forEach(entry => {
|
||||
const id = `${paramName}_${entry.value}`;
|
||||
options.push(
|
||||
{
|
||||
key: id,
|
||||
text: entry.label
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return new ElixFormsElement(
|
||||
<FluentUI.Label htmlFor={paramName}>{label}</FluentUI.Label>,
|
||||
<FluentUI.Dropdown
|
||||
id={paramName}
|
||||
options={options}
|
||||
selectedKey={selectedValue?.toString()}
|
||||
placeholder='---'
|
||||
required={required}
|
||||
className='isiportalPartialAdminFormFieldSelect'
|
||||
onChange={(event, value) => {
|
||||
this.setState({ formData: { ...this.state.formData, [paramName]: value } }, () =>
|
||||
console.log(`Dropdown ${paramName} changed to ${value}. Current value for ${paramName}: ${this.state.formData[paramName]}`)
|
||||
);
|
||||
}}
|
||||
/>
|
||||
).render();
|
||||
}
|
||||
|
||||
private renderField(field: any): JSX.Element {
|
||||
//const value = this.state.formData[field.key] || "";
|
||||
|
||||
switch (field.type) {
|
||||
case "text":
|
||||
return this.createTextInput(field.key, field.label, field.required ?? false);
|
||||
|
||||
case "textarea":
|
||||
return this.createTextAreaInput(field.key, field.label, field.required ?? false);
|
||||
|
||||
case "radio":
|
||||
return this.createRadioInput(field.key, field.label,
|
||||
new Array<ElixFormsRadioOption>().concat(...field.options.map((o: any) => [[o.value, o.label]])),
|
||||
field.required ?? false);
|
||||
|
||||
case "boolean":
|
||||
return this.createBooleanInput(field.key, field.label, field.required ?? false);
|
||||
|
||||
case "checkbox":
|
||||
return this.createCheckboxInput(field.key, field.label,
|
||||
new Array<ElixFormsCheckboxOption>().concat(...field.options.map((o: any) => [[o.value, o.label, o.required ?? false]])));
|
||||
|
||||
case "number":
|
||||
return this.createNumberInput(field.key, field.label, field.required ?? false);
|
||||
|
||||
case "dropdown":
|
||||
return this.createDropdownInput(field.key, field.label,
|
||||
new Array<ElixFormsDropdownOption>().concat(...field.options.map((o: any) => [[o.value, o.label]])),
|
||||
field.required ?? false);
|
||||
|
||||
default:
|
||||
return <></>;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user