move react projects to own folder
This commit is contained in:
Generated
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "common",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "common",
|
||||
"version": "0.0.1",
|
||||
"license": "ISC"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "common",
|
||||
"version": "0.0.1",
|
||||
"description": "Common components to build elixForms custom pages",
|
||||
"license": "ISC",
|
||||
"author": "",
|
||||
"type": "commonjs",
|
||||
"main": "index.js"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
@import '~@fluentui/react/dist/sass/References.scss';
|
||||
|
||||
.elixFormsComponent {
|
||||
overflow: hidden;
|
||||
padding: 1em;
|
||||
color: "[theme:bodyText, default: #323130]";
|
||||
color: var(--bodyText);
|
||||
&.teams {
|
||||
font-family: $ms-font-family-fallbacks;
|
||||
}
|
||||
}
|
||||
|
||||
.welcome {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.welcomeImage {
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
}
|
||||
|
||||
.links {
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: "[theme:link, default:#03787c]";
|
||||
color: var(--link); // note: CSS Custom Properties support is limited to modern browsers only
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
color: "[theme:linkHovered, default: #014446]";
|
||||
color: var(--linkHovered); // note: CSS Custom Properties support is limited to modern browsers only
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//import * as React from 'react';
|
||||
import ElixFormsComponentAbstract from './ElixFormsComponentAbstract';
|
||||
|
||||
export default class ElixFormsComponent extends ElixFormsComponentAbstract {
|
||||
// public override createCustomFormFields(): React.ReactElement {
|
||||
// // const textTest = this.CreateTextInput("COL0018", "TEXT INPUT");
|
||||
// // const checkTest = this.CreateCheckboxInput("COL0090", "CHECKBOX INPUT", new Map<number, string>([ [1, "Option 1"], [2, "Option 2"], [3, "Option 3"] ]));
|
||||
// // const radioTest = this.CreateRadioInput("COL0091", "RADIO INPUT", new Map<number, string>([ [1, "Option 1"], [2, "Option 2"], [3, "Option 3"] ]));
|
||||
// // const boolTest = this.CreateBooleanInput("COL0092", "BOOLEAN INPUT");
|
||||
// // const textareaTest = this.CreateTextAreaInput("COL0093", "TEXTAREA INPUT");
|
||||
|
||||
// return (<></>);
|
||||
// }
|
||||
}
|
||||
|
||||
export { ElixFormsComponent as ElixFormsReact };
|
||||
@@ -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 <></>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import React, { type JSX } from "react";
|
||||
|
||||
// Class to encapsulate the label and input elements
|
||||
export class ElixFormsElement {
|
||||
label: JSX.Element;
|
||||
input: JSX.Element;
|
||||
separator: string;
|
||||
constructor(labelElement: React.ReactElement, inputElement: React.ReactElement, separator: string = "")
|
||||
{
|
||||
if (!labelElement || !inputElement) {
|
||||
throw new Error("labelElement and inputElement are required.");
|
||||
}
|
||||
|
||||
this.label = labelElement;
|
||||
this.input = inputElement;
|
||||
this.separator = separator;
|
||||
}
|
||||
|
||||
// Optional: render both elements together
|
||||
render() : JSX.Element {
|
||||
return (<><div className="iuFieldContainer">
|
||||
<div className="attrDisplay_left attrDisplay_label"><div className="iuLabelContainer"><div className="attrDisplay_center"><div className="attrDisplay_middle">
|
||||
{this.label}{this.separator}
|
||||
</div></div><div className="iuClearContainer"> </div></div></div>
|
||||
<div className="attrDisplay_right attrDisplay_input"><div className="iuInputContainer iuTypeString"><div className="attrDisplay_center"><div className="attrDisplay_middle">
|
||||
{this.input}
|
||||
</div></div><div className="iuClearContainer"> </div></div></div>
|
||||
</div></>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export type ElixFormsCheckboxOption = { value: number, label: string, required?: boolean };
|
||||
export type ElixFormsDropdownOption = { value: number, label: string };
|
||||
export type ElixFormsRadioOption = { value: number, label: string };
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { JSX } from "react";
|
||||
import type { ElixFormsCheckboxOption, ElixFormsDropdownOption, ElixFormsRadioOption } from "./ElixFormsTypes";
|
||||
|
||||
export type IElixFormsComponentCustomFormFieldFactory = {
|
||||
createBooleanInput: (name: string, label: string, required?: boolean) => JSX.Element;
|
||||
createCheckboxInput: (name: string, label: string, options: Array<ElixFormsCheckboxOption>) => JSX.Element;
|
||||
createDropdownInput: (name: string, label: string, options: Array<ElixFormsDropdownOption>, required?: boolean) => JSX.Element;
|
||||
createHiddenInput: (name: string) => JSX.Element;
|
||||
createNumberInput: (name: string, label: string, required?: boolean) => JSX.Element;
|
||||
createRadioInput: (name: string, label: string, options: Array<ElixFormsRadioOption>, required?: boolean) => JSX.Element;
|
||||
createTextInput: (name: string, label: string, required?: boolean) => JSX.Element;
|
||||
createTextAreaInput: (name: string, label: string, required?: boolean) => JSX.Element;
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface IElixFormsComponentFormState {
|
||||
formData: { [key: string]: any; };
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { JSX } from "react";
|
||||
import type { IElixFormsComponentCustomFormFieldFactory } from "./IElixFormsComponentCustomFormFieldFactory";
|
||||
|
||||
export interface IElixFormsComponentProperties {
|
||||
description: string;
|
||||
isDarkTheme: boolean;
|
||||
environmentMessage: string;
|
||||
hasTeamsContext: boolean;
|
||||
userDisplayName: string;
|
||||
additionalFieldsJson?: string;
|
||||
customFormFieldsConfiguration?: (formFieldFactory: IElixFormsComponentCustomFormFieldFactory) => JSX.Element;
|
||||
}
|
||||
|
||||
// Additional Fields JSON Schema
|
||||
/* // To test, just copy-paste the following JSON in the "Additional Fields JSON" property of the web part. Remember to remove comments before pasting.
|
||||
[
|
||||
{
|
||||
"key": "field1",
|
||||
"type": "text",
|
||||
"label": "Field 1",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"key": "field2",
|
||||
"type": "checkbox",
|
||||
"label": "Field 2",
|
||||
"options": [
|
||||
{ "value": 1, "label": "Checkbox Option 1" },
|
||||
{ "value": 2, "label": "Checkbox Option 2" },
|
||||
{ "value": 3, "label": "Checkbox Option 3" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "field3",
|
||||
"type": "radio",
|
||||
"label": "Field 3",
|
||||
"required": true,
|
||||
"options": [
|
||||
{ "value": 1, "label": "Radio Option 1" },
|
||||
{ "value": 2, "label": "Radio Option 2" },
|
||||
{ "value": 3, "label": "Radio Option 3" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "field4",
|
||||
"type": "boolean",
|
||||
"label": "Field 4"
|
||||
},
|
||||
{
|
||||
"key": "field5",
|
||||
"type": "textarea",
|
||||
"label": "Field 5",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"key": "field6",
|
||||
"type": "number",
|
||||
"label": "Field 6"
|
||||
},
|
||||
{
|
||||
"key": "field7",
|
||||
"type": "dropdown",
|
||||
"label": "Field 7",
|
||||
"required": true,
|
||||
"options": [
|
||||
{ "value": 1, "label": "Dropdown Option 1" },
|
||||
{ "value": 2, "label": "Dropdown Option 2" },
|
||||
{ "value": 3, "label": "Dropdown Option 3" }
|
||||
]
|
||||
}
|
||||
]
|
||||
*/
|
||||
@@ -0,0 +1,41 @@
|
||||
export class QueryParamHelper {
|
||||
public static getCheckedFromQuery(paramName: string): number[] {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const values = params.get(paramName) ?? "";
|
||||
|
||||
console.debug(`getCheckedFromQuery(${paramName}) = ${values}`);
|
||||
|
||||
return values.split(',')
|
||||
.map(Number)
|
||||
.filter(n => !isNaN(n));
|
||||
}
|
||||
|
||||
public static getOptionFromQuery(paramName: string): number | undefined {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const num = Number.parseInt(params.get(paramName) ?? "-1");
|
||||
|
||||
console.debug(`getOptionFromQuery(${paramName}) = ${num}`);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
public static getBooleanFromQuery(paramName: string): boolean | undefined {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const boolValue = params.get(paramName) === undefined || params.get(paramName) === null ? undefined :
|
||||
params.get(paramName)?.toLowerCase() === "true" ? true : false;
|
||||
|
||||
console.debug(`getBooleanFromQuery(${paramName}) = ${boolValue}`);
|
||||
|
||||
return boolValue;
|
||||
}
|
||||
|
||||
public static getDecodedTextFromQuery(paramName: string): string | undefined {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const textValue = params.get(paramName) === undefined || params.get(paramName) === null ? undefined :
|
||||
decodeURIComponent(params.get(paramName) as string);
|
||||
|
||||
console.debug(`getDecodedTextFromQuery(${paramName}) = ${textValue}`);
|
||||
|
||||
return textValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"module": "ESNext",
|
||||
"target": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"jsx": "react-jsx",
|
||||
"isolatedModules": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"skipLibCheck": true,
|
||||
},
|
||||
"include": [
|
||||
"**/*"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user