digitaform-preview-react
Version:
A comprehensive React form preview component library with form controls,responsive design
1,393 lines (1,311 loc) • 498 kB
JavaScript
import React, { forwardRef, createElement, useState, useEffect, useCallback, useMemo, useRef, useLayoutEffect, createContext, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { createPortal } from 'react-dom';
var jsxRuntime = {exports: {}};
var reactJsxRuntime_production = {};
/**
* @license React
* react-jsx-runtime.production.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var hasRequiredReactJsxRuntime_production;
function requireReactJsxRuntime_production () {
if (hasRequiredReactJsxRuntime_production) return reactJsxRuntime_production;
hasRequiredReactJsxRuntime_production = 1;
var REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),
REACT_FRAGMENT_TYPE = Symbol.for("react.fragment");
function jsxProd(type, config, maybeKey) {
var key = null;
void 0 !== maybeKey && (key = "" + maybeKey);
void 0 !== config.key && (key = "" + config.key);
if ("key" in config) {
maybeKey = {};
for (var propName in config)
"key" !== propName && (maybeKey[propName] = config[propName]);
} else maybeKey = config;
config = maybeKey.ref;
return {
$$typeof: REACT_ELEMENT_TYPE,
type: type,
key: key,
ref: void 0 !== config ? config : null,
props: maybeKey
};
}
reactJsxRuntime_production.Fragment = REACT_FRAGMENT_TYPE;
reactJsxRuntime_production.jsx = jsxProd;
reactJsxRuntime_production.jsxs = jsxProd;
return reactJsxRuntime_production;
}
var reactJsxRuntime_development = {};
/**
* @license React
* react-jsx-runtime.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var hasRequiredReactJsxRuntime_development;
function requireReactJsxRuntime_development () {
if (hasRequiredReactJsxRuntime_development) return reactJsxRuntime_development;
hasRequiredReactJsxRuntime_development = 1;
"production" !== process.env.NODE_ENV &&
(function () {
function getComponentNameFromType(type) {
if (null == type) return null;
if ("function" === typeof type)
return type.$$typeof === REACT_CLIENT_REFERENCE
? null
: type.displayName || type.name || null;
if ("string" === typeof type) return type;
switch (type) {
case REACT_FRAGMENT_TYPE:
return "Fragment";
case REACT_PROFILER_TYPE:
return "Profiler";
case REACT_STRICT_MODE_TYPE:
return "StrictMode";
case REACT_SUSPENSE_TYPE:
return "Suspense";
case REACT_SUSPENSE_LIST_TYPE:
return "SuspenseList";
case REACT_ACTIVITY_TYPE:
return "Activity";
}
if ("object" === typeof type)
switch (
("number" === typeof type.tag &&
console.error(
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
),
type.$$typeof)
) {
case REACT_PORTAL_TYPE:
return "Portal";
case REACT_CONTEXT_TYPE:
return type.displayName || "Context";
case REACT_CONSUMER_TYPE:
return (type._context.displayName || "Context") + ".Consumer";
case REACT_FORWARD_REF_TYPE:
var innerType = type.render;
type = type.displayName;
type ||
((type = innerType.displayName || innerType.name || ""),
(type = "" !== type ? "ForwardRef(" + type + ")" : "ForwardRef"));
return type;
case REACT_MEMO_TYPE:
return (
(innerType = type.displayName || null),
null !== innerType
? innerType
: getComponentNameFromType(type.type) || "Memo"
);
case REACT_LAZY_TYPE:
innerType = type._payload;
type = type._init;
try {
return getComponentNameFromType(type(innerType));
} catch (x) {}
}
return null;
}
function testStringCoercion(value) {
return "" + value;
}
function checkKeyStringCoercion(value) {
try {
testStringCoercion(value);
var JSCompiler_inline_result = !1;
} catch (e) {
JSCompiler_inline_result = !0;
}
if (JSCompiler_inline_result) {
JSCompiler_inline_result = console;
var JSCompiler_temp_const = JSCompiler_inline_result.error;
var JSCompiler_inline_result$jscomp$0 =
("function" === typeof Symbol &&
Symbol.toStringTag &&
value[Symbol.toStringTag]) ||
value.constructor.name ||
"Object";
JSCompiler_temp_const.call(
JSCompiler_inline_result,
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
JSCompiler_inline_result$jscomp$0
);
return testStringCoercion(value);
}
}
function getTaskName(type) {
if (type === REACT_FRAGMENT_TYPE) return "<>";
if (
"object" === typeof type &&
null !== type &&
type.$$typeof === REACT_LAZY_TYPE
)
return "<...>";
try {
var name = getComponentNameFromType(type);
return name ? "<" + name + ">" : "<...>";
} catch (x) {
return "<...>";
}
}
function getOwner() {
var dispatcher = ReactSharedInternals.A;
return null === dispatcher ? null : dispatcher.getOwner();
}
function UnknownOwner() {
return Error("react-stack-top-frame");
}
function hasValidKey(config) {
if (hasOwnProperty.call(config, "key")) {
var getter = Object.getOwnPropertyDescriptor(config, "key").get;
if (getter && getter.isReactWarning) return !1;
}
return void 0 !== config.key;
}
function defineKeyPropWarningGetter(props, displayName) {
function warnAboutAccessingKey() {
specialPropKeyWarningShown ||
((specialPropKeyWarningShown = !0),
console.error(
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
displayName
));
}
warnAboutAccessingKey.isReactWarning = !0;
Object.defineProperty(props, "key", {
get: warnAboutAccessingKey,
configurable: !0
});
}
function elementRefGetterWithDeprecationWarning() {
var componentName = getComponentNameFromType(this.type);
didWarnAboutElementRef[componentName] ||
((didWarnAboutElementRef[componentName] = !0),
console.error(
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
));
componentName = this.props.ref;
return void 0 !== componentName ? componentName : null;
}
function ReactElement(type, key, props, owner, debugStack, debugTask) {
var refProp = props.ref;
type = {
$$typeof: REACT_ELEMENT_TYPE,
type: type,
key: key,
props: props,
_owner: owner
};
null !== (void 0 !== refProp ? refProp : null)
? Object.defineProperty(type, "ref", {
enumerable: !1,
get: elementRefGetterWithDeprecationWarning
})
: Object.defineProperty(type, "ref", { enumerable: !1, value: null });
type._store = {};
Object.defineProperty(type._store, "validated", {
configurable: !1,
enumerable: !1,
writable: !0,
value: 0
});
Object.defineProperty(type, "_debugInfo", {
configurable: !1,
enumerable: !1,
writable: !0,
value: null
});
Object.defineProperty(type, "_debugStack", {
configurable: !1,
enumerable: !1,
writable: !0,
value: debugStack
});
Object.defineProperty(type, "_debugTask", {
configurable: !1,
enumerable: !1,
writable: !0,
value: debugTask
});
Object.freeze && (Object.freeze(type.props), Object.freeze(type));
return type;
}
function jsxDEVImpl(
type,
config,
maybeKey,
isStaticChildren,
debugStack,
debugTask
) {
var children = config.children;
if (void 0 !== children)
if (isStaticChildren)
if (isArrayImpl(children)) {
for (
isStaticChildren = 0;
isStaticChildren < children.length;
isStaticChildren++
)
validateChildKeys(children[isStaticChildren]);
Object.freeze && Object.freeze(children);
} else
console.error(
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
);
else validateChildKeys(children);
if (hasOwnProperty.call(config, "key")) {
children = getComponentNameFromType(type);
var keys = Object.keys(config).filter(function (k) {
return "key" !== k;
});
isStaticChildren =
0 < keys.length
? "{key: someKey, " + keys.join(": ..., ") + ": ...}"
: "{key: someKey}";
didWarnAboutKeySpread[children + isStaticChildren] ||
((keys =
0 < keys.length ? "{" + keys.join(": ..., ") + ": ...}" : "{}"),
console.error(
'A props object containing a "key" prop is being spread into JSX:\n let props = %s;\n <%s {...props} />\nReact keys must be passed directly to JSX without using spread:\n let props = %s;\n <%s key={someKey} {...props} />',
isStaticChildren,
children,
keys,
children
),
(didWarnAboutKeySpread[children + isStaticChildren] = !0));
}
children = null;
void 0 !== maybeKey &&
(checkKeyStringCoercion(maybeKey), (children = "" + maybeKey));
hasValidKey(config) &&
(checkKeyStringCoercion(config.key), (children = "" + config.key));
if ("key" in config) {
maybeKey = {};
for (var propName in config)
"key" !== propName && (maybeKey[propName] = config[propName]);
} else maybeKey = config;
children &&
defineKeyPropWarningGetter(
maybeKey,
"function" === typeof type
? type.displayName || type.name || "Unknown"
: type
);
return ReactElement(
type,
children,
maybeKey,
getOwner(),
debugStack,
debugTask
);
}
function validateChildKeys(node) {
isValidElement(node)
? node._store && (node._store.validated = 1)
: "object" === typeof node &&
null !== node &&
node.$$typeof === REACT_LAZY_TYPE &&
("fulfilled" === node._payload.status
? isValidElement(node._payload.value) &&
node._payload.value._store &&
(node._payload.value._store.validated = 1)
: node._store && (node._store.validated = 1));
}
function isValidElement(object) {
return (
"object" === typeof object &&
null !== object &&
object.$$typeof === REACT_ELEMENT_TYPE
);
}
var React$1 = React,
REACT_ELEMENT_TYPE = Symbol.for("react.transitional.element"),
REACT_PORTAL_TYPE = Symbol.for("react.portal"),
REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"),
REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"),
REACT_PROFILER_TYPE = Symbol.for("react.profiler"),
REACT_CONSUMER_TYPE = Symbol.for("react.consumer"),
REACT_CONTEXT_TYPE = Symbol.for("react.context"),
REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"),
REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"),
REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"),
REACT_MEMO_TYPE = Symbol.for("react.memo"),
REACT_LAZY_TYPE = Symbol.for("react.lazy"),
REACT_ACTIVITY_TYPE = Symbol.for("react.activity"),
REACT_CLIENT_REFERENCE = Symbol.for("react.client.reference"),
ReactSharedInternals =
React$1.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,
hasOwnProperty = Object.prototype.hasOwnProperty,
isArrayImpl = Array.isArray,
createTask = console.createTask
? console.createTask
: function () {
return null;
};
React$1 = {
react_stack_bottom_frame: function (callStackForError) {
return callStackForError();
}
};
var specialPropKeyWarningShown;
var didWarnAboutElementRef = {};
var unknownOwnerDebugStack = React$1.react_stack_bottom_frame.bind(
React$1,
UnknownOwner
)();
var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));
var didWarnAboutKeySpread = {};
reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE;
reactJsxRuntime_development.jsx = function (type, config, maybeKey) {
var trackActualOwner =
1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
return jsxDEVImpl(
type,
config,
maybeKey,
!1,
trackActualOwner
? Error("react-stack-top-frame")
: unknownOwnerDebugStack,
trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
);
};
reactJsxRuntime_development.jsxs = function (type, config, maybeKey) {
var trackActualOwner =
1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;
return jsxDEVImpl(
type,
config,
maybeKey,
!0,
trackActualOwner
? Error("react-stack-top-frame")
: unknownOwnerDebugStack,
trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask
);
};
})();
return reactJsxRuntime_development;
}
if (process.env.NODE_ENV === 'production') {
jsxRuntime.exports = requireReactJsxRuntime_production();
} else {
jsxRuntime.exports = requireReactJsxRuntime_development();
}
var jsxRuntimeExports = jsxRuntime.exports;
class ConditionalLogicService {
constructor() { }
static getInstance() {
if (!ConditionalLogicService.instance) {
ConditionalLogicService.instance = new ConditionalLogicService();
}
return ConditionalLogicService.instance;
}
/**
* Get all available components in the form for conditional logic
* @param formSchema - The current form schema containing all components
* @param excludeComponentId - Optional component ID to exclude from the list
* @returns Array of available components with their metadata
*/
getAvailableComponentsForConditional(formSchema, excludeComponentId) {
if (!formSchema || !Array.isArray(formSchema)) {
return [];
}
const availableComponents = formSchema
.filter(component => !excludeComponentId || component.id !== excludeComponentId)
.map(component => {
const mappedComponent = {
id: component.id,
label: component.basic?.label || component.id,
type: component.name,
key: component.id // Using id as key for consistency
};
return mappedComponent;
})
.sort((a, b) => a.label.localeCompare(b.label));
return availableComponents;
}
// Get applicable operators for a specific component type
getApplicableOperators(componentType) {
switch (componentType) {
case 'text-input':
case 'email-input':
case 'textarea':
return [
'equals',
'notEquals',
'contains',
'notContains',
'isEmpty',
'isNotEmpty'
];
case 'number-input':
return [
'equals',
'notEquals',
'greaterThan',
'lessThan',
'greaterThanOrEqual',
'lessThanOrEqual',
'isEmpty',
'isNotEmpty'
];
case 'select':
case 'radio':
case 'segment':
return [
'equals',
'notEquals',
'isEmpty',
'isNotEmpty'
];
case 'checkbox':
return [
'contains',
'notContains',
'isEmpty',
'isNotEmpty'
];
case 'date-picker':
case 'datetime-picker':
return [
'equals',
'notEquals',
'greaterThan',
'lessThan',
'greaterThanOrEqual',
'lessThanOrEqual',
'isEmpty',
'isNotEmpty'
];
default:
return [
'equals',
'notEquals',
'isEmpty',
'isNotEmpty'
];
}
}
// Validate conditional logic
validateConditionalLogic(conditional, formSchema) {
const errors = [];
if (!conditional) {
return { isValid: true, errors: [] };
}
// Validate action
if (!['show', 'hide', 'always'].includes(conditional.action)) {
errors.push('Invalid conditional action');
}
// Validate when condition
if (!['all', 'any'].includes(conditional.when)) {
errors.push('Invalid when condition');
}
// Validate conditions
if (!conditional.conditions || conditional.conditions.length === 0) {
errors.push('At least one condition is required');
}
else {
conditional.conditions.forEach((condition, index) => {
// Validate condition component exists
const component = formSchema.find(comp => comp.id === condition.when);
if (!component) {
errors.push(`Condition ${index + 1}: Component not found`);
return;
}
// Validate operator is applicable for component type
const applicableOperators = this.getApplicableOperators(component.name);
if (!applicableOperators.includes(condition.operator)) {
errors.push(`Condition ${index + 1}: Operator not applicable for component type`);
}
// Validate condition value
if (!this.isValidConditionValue(condition.value, component.name, condition.operator)) {
errors.push(`Condition ${index + 1}: Invalid condition value`);
}
});
}
return {
isValid: errors.length === 0,
errors
};
}
/**
* Evaluate whether a component should be shown based on conditional logic
* @param conditional - The conditional logic to evaluate
* @param formSchema - The current form schema
* @param formValues - Current form values (component values)
* @returns Evaluation result with details
*/
evaluateConditionalLogic(conditional, formSchema, formValues) {
// If action is 'always', always show the component
if (conditional.action === 'always') {
return {
shouldShow: true,
evaluatedConditions: []
};
}
if (!conditional || !conditional.conditions || conditional.conditions.length === 0) {
return {
shouldShow: true,
evaluatedConditions: []
};
}
const evaluatedConditions = conditional.conditions.map(condition => {
const componentValue = this.getComponentValue(condition.when, formSchema, formValues);
const result = this.evaluateCondition(condition, componentValue);
return {
condition,
result,
componentValue
};
});
const shouldShow = this.determineFinalResult(conditional, evaluatedConditions);
return {
shouldShow,
evaluatedConditions
};
}
/**
* Get the current value of a component
* @param componentId - The component ID to get value for
* @param formSchema - The current form schema
* @param formValues - Current form values
* @returns The component value or undefined if not found
*/
getComponentValue(componentId, formSchema, formValues) {
// First check if we have a direct form value
if (formValues && formValues[componentId] !== undefined) {
return formValues[componentId];
}
// Fallback to component's default value
const component = formSchema.find(comp => comp.id === componentId);
if (component) {
return component.basic.defaultValue;
}
return undefined;
}
/**
* Evaluate a single condition
* @param condition - The condition to evaluate
* @param componentValue - The current value of the component
* @returns Boolean result of the condition evaluation
*/
evaluateCondition(condition, componentValue) {
const { operator, value } = condition;
// Handle checkbox-specific evaluation
if (value === 'checked' || value === 'notChecked') {
return this.evaluateCheckboxCondition(componentValue, value);
}
switch (operator) {
case 'equals':
return this.isEqual(componentValue, value);
case 'notEquals':
return !this.isEqual(componentValue, value);
case 'isEmpty':
return this.isEmpty(componentValue);
case 'isNotEmpty':
return !this.isEmpty(componentValue);
case 'contains':
return this.contains(componentValue, value);
case 'notContains':
return !this.contains(componentValue, value);
case 'greaterThan':
return this.isGreaterThan(componentValue, value);
case 'lessThan':
return this.isLessThan(componentValue, value);
case 'greaterThanOrEqual':
return this.isGreaterThanOrEqual(componentValue, value);
case 'lessThanOrEqual':
return this.isLessThanOrEqual(componentValue, value);
default:
return false;
}
}
/**
* Evaluate checkbox-specific conditions (checked/notChecked)
* @param componentValue - The current value of the checkbox component
* @param expectedValue - Either 'checked' or 'notChecked'
* @returns Boolean result of the checkbox condition evaluation
*/
evaluateCheckboxCondition(componentValue, expectedValue) {
// Determine if checkbox is checked based on component value
const isChecked = this.isCheckboxChecked(componentValue);
if (expectedValue === 'checked') {
return isChecked;
}
else if (expectedValue === 'notChecked') {
return !isChecked;
}
return false;
}
/**
* Determine if a checkbox component is checked based on its value
* @param componentValue - The current value of the checkbox component
* @returns Boolean indicating if checkbox is checked
*/
isCheckboxChecked(componentValue) {
if (componentValue === null || componentValue === undefined) {
return false;
}
// Handle boolean values
if (typeof componentValue === 'boolean') {
return componentValue;
}
// Handle string values
if (typeof componentValue === 'string') {
return componentValue.toLowerCase() === 'true' || componentValue === '1';
}
// Handle array values (for multi-select checkboxes)
if (Array.isArray(componentValue)) {
return componentValue.length > 0;
}
// Handle numeric values
if (typeof componentValue === 'number') {
return componentValue > 0;
}
// Default to false for any other type
return false;
}
/**
* Determine final result based on 'when' condition (all/any) and action (show/hide)
* @param conditional - The conditional logic configuration
* @param evaluatedConditions - Array of evaluated conditions
* @returns Final boolean result
*/
determineFinalResult(conditional, evaluatedConditions) {
// First determine if conditions are met
let conditionsMet;
if (conditional.when === 'all') {
conditionsMet = evaluatedConditions.every(condition => condition.result);
}
else if (conditional.when === 'any') {
conditionsMet = evaluatedConditions.some(condition => condition.result);
}
else {
conditionsMet = false;
}
// Then apply the action to determine final visibility
let finalResult;
if (conditional.action === 'show') {
// Show when conditions are met
finalResult = conditionsMet;
}
else if (conditional.action === 'hide') {
// Hide when conditions are met (inverse of show)
finalResult = !conditionsMet;
}
else if (conditional.action === 'always') {
// Always show
finalResult = true;
}
else {
// Default to showing if no action specified
finalResult = true;
}
return finalResult;
}
// Helper methods for condition evaluation
isEqual(a, b) {
if (a === b)
return true;
if (a == null || b == null)
return false;
// Handle arrays
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length)
return false;
return a.every((val, index) => this.isEqual(val, b[index]));
}
// Handle objects
if (typeof a === 'object' && typeof b === 'object') {
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length)
return false;
return keysA.every(key => this.isEqual(a[key], b[key]));
}
return false;
}
isEmpty(value) {
if (value == null || value === undefined)
return true;
if (typeof value === 'string')
return value.trim() === '';
if (Array.isArray(value))
return value.length === 0;
if (typeof value === 'object')
return Object.keys(value).length === 0;
return false;
}
contains(container, searchValue) {
if (container == null || searchValue == null)
return false;
if (typeof container === 'string') {
return container.toLowerCase().includes(String(searchValue).toLowerCase());
}
if (Array.isArray(container)) {
return container.some(item => this.isEqual(item, searchValue));
}
return false;
}
isGreaterThan(a, b) {
const numA = Number(a);
const numB = Number(b);
return !isNaN(numA) && !isNaN(numB) && numA > numB;
}
isLessThan(a, b) {
const numA = Number(a);
const numB = Number(b);
return !isNaN(numA) && !isNaN(numB) && numA < numB;
}
isGreaterThanOrEqual(a, b) {
const numA = Number(a);
const numB = Number(b);
return !isNaN(numA) && !isNaN(numB) && numA >= numB;
}
isLessThanOrEqual(a, b) {
const numA = Number(a);
const numB = Number(b);
return !isNaN(numA) && !isNaN(numB) && numA <= numB;
}
// Validate condition value
isValidConditionValue(value, componentType, operator) {
if (value === null || value === undefined) {
return ['isEmpty', 'isNotEmpty'].includes(operator);
}
switch (componentType) {
case 'number-input':
return !isNaN(Number(value)) || ['isEmpty', 'isNotEmpty'].includes(operator);
case 'date-picker':
case 'datetime-picker':
return !isNaN(Date.parse(value)) || ['isEmpty', 'isNotEmpty'].includes(operator);
case 'checkbox':
return Array.isArray(value) || typeof value === 'string' || typeof value === 'number';
default:
return true;
}
}
// Create default conditional logic
createDefaultConditionalLogic() {
return {
action: 'show',
when: 'all',
conditions: []
};
}
// Get operator display text
getOperatorDisplayText(operator) {
const operatorTexts = {
'equals': 'Is Equal To',
'notEquals': 'Is Not Equal To',
'contains': 'Contains',
'notContains': 'Does Not Contain',
'isEmpty': 'Is Empty',
'isNotEmpty': 'Is Not Empty',
'greaterThan': 'Is Greater Than',
'lessThan': 'Is Less Than',
'greaterThanOrEqual': 'Is Greater Than Or Equal To',
'lessThanOrEqual': 'Is Less Than Or Equal To'
};
return operatorTexts[operator] || operator;
}
// Get action display text
getActionDisplayText(action) {
const actionTexts = {
show: 'Show this field when',
hide: 'Hide this field when',
always: 'Always show this field'
};
return actionTexts[action] || action;
}
// Get conditional logic summary text
getConditionalLogicSummary(conditional, formSchema) {
if (!conditional || conditional.conditions.length === 0) {
return 'No conditions';
}
if (conditional.action === 'always') {
return 'Always show';
}
const actionText = this.getActionDisplayText(conditional.action);
const conditionTexts = conditional.conditions.map(condition => {
const component = formSchema.find(comp => comp.id === condition.when);
const componentLabel = component?.basic.label || 'Unknown component';
const operatorText = this.getOperatorDisplayText(condition.operator);
const valueText = this.formatConditionValue(condition.value);
return `${componentLabel} ${operatorText} ${valueText}`;
});
const operatorText = conditional.when === 'all' ? ' and ' : ' or ';
return `${actionText} ${conditionTexts.join(operatorText)}`;
}
// Format condition value for display
formatConditionValue(value) {
if (value === null || value === undefined) {
return 'empty';
}
if (Array.isArray(value)) {
return `[${value.join(', ')}]`;
}
if (typeof value === 'string') {
return `"${value}"`;
}
return String(value);
}
}
// Export singleton instance
const conditionalLogicService = ConditionalLogicService.getInstance();
const DfFormErrorMsg = ({ validationErrors, fieldId, touchedFields, formSubmitted, properties, localValidation, isTouched: localIsTouched, mode, }) => {
const getErrorMessage = () => {
// Only show error messages in test mode
if (mode !== 'test') {
return '';
}
// Check if field is touched or form is submitted
const isTouched = localIsTouched || touchedFields[fieldId] || formSubmitted;
if (!isTouched) {
return '';
}
// Prioritize local validation - if local validation is valid, don't show any errors
if (localValidation && localValidation.isValid) {
return '';
}
// Show local validation errors if validation failed
if (localValidation && !localValidation.isValid && Object.keys(localValidation.errors).length > 0) {
const errorKeys = Object.keys(localValidation.errors);
if (errorKeys.length > 0) {
const firstError = errorKeys[0];
return getDefaultErrorMessage(firstError);
}
}
// Only check external validation errors if local validation doesn't exist or is not valid
const fieldErrors = validationErrors[fieldId];
if (fieldErrors && typeof fieldErrors === 'string' && fieldErrors.trim() !== '') {
// For date/time components, check if we should use mode-specific message
const componentName = properties.name || '';
const isDateTimeComponent = componentName === 'date-picker' || componentName === 'datetime-picker';
if (isDateTimeComponent && fieldErrors.includes('valid date')) {
const dateTimeMode = properties.basic?.dateTimeMode || (componentName === 'datetime-picker' ? 'datetime' : 'date');
if (dateTimeMode === 'time') {
return 'Please select a valid time';
}
else if (dateTimeMode === 'datetime') {
return 'Please select a valid date and time';
}
}
return fieldErrors;
}
return '';
};
const getDefaultErrorMessage = (errorType) => {
const fieldLabel = properties.basic.label || 'This field';
// Check if there's a custom validation message
const customMessage = properties.validation.customValidationMessage;
if (customMessage) {
return customMessage;
}
// For date/time components, check dateTimeMode for appropriate error messages
const componentName = properties.name || '';
const isDateTimeComponent = componentName === 'date-picker' || componentName === 'datetime-picker';
const dateTimeMode = isDateTimeComponent ? (properties.basic?.dateTimeMode || (componentName === 'datetime-picker' ? 'datetime' : 'date')) : null;
switch (errorType) {
case 'required':
return `${fieldLabel} is required`;
case 'invalidDate':
// Show mode-specific error messages for date/time components
if (dateTimeMode === 'time') {
return 'Please select a valid time';
}
else if (dateTimeMode === 'datetime') {
return 'Please select a valid date and time';
}
else if (dateTimeMode === 'date') {
return 'Please select a valid date';
}
return `${fieldLabel} is invalid`;
case 'minLength':
const minLength = properties.validation.minLength;
return `${fieldLabel} must be at least ${minLength} characters long`;
case 'maxLength':
const maxLength = properties.validation.maxLength;
return `${fieldLabel} must be no more than ${maxLength} characters long`;
case 'min':
const min = properties.validation.min;
return `${fieldLabel} must be at least ${min}`;
case 'max':
const max = properties.validation.max;
return `${fieldLabel} must be no more than ${max}`;
case 'pattern':
return `${fieldLabel} format is invalid`;
case 'email':
return `${fieldLabel} must be a valid email address`;
default:
return `${fieldLabel} is invalid`;
}
};
const errorMessage = getErrorMessage();
if (!errorMessage) {
return null;
}
return (jsxRuntimeExports.jsx("div", { className: "form-error-msg", children: errorMessage }));
};
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
var defaultAttributes$1 = {
xmlns: "http://www.w3.org/2000/svg",
width: 24,
height: 24,
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: 2,
strokeLinecap: "round",
strokeLinejoin: "round"
};
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().trim();
const createLucideIcon = (iconName, iconNode) => {
const Component = forwardRef(
({ color = "currentColor", size = 24, strokeWidth = 2, absoluteStrokeWidth, className = "", children, ...rest }, ref) => createElement(
"svg",
{
ref,
...defaultAttributes$1,
width: size,
height: size,
stroke: color,
strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
className: ["lucide", `lucide-${toKebabCase(iconName)}`, className].join(" "),
...rest
},
[
...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),
...Array.isArray(children) ? children : [children]
]
)
);
Component.displayName = `${iconName}`;
return Component;
};
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const AlertTriangle = createLucideIcon("AlertTriangle", [
[
"path",
{
d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z",
key: "c3ski4"
}
],
["path", { d: "M12 9v4", key: "juzpu7" }],
["path", { d: "M12 17h.01", key: "p32p05" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Bold = createLucideIcon("Bold", [
["path", { d: "M14 12a4 4 0 0 0 0-8H6v8", key: "v2sylx" }],
["path", { d: "M15 20a4 4 0 0 0 0-8H6v8Z", key: "1ef5ya" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Calendar = createLucideIcon("Calendar", [
["rect", { width: "18", height: "18", x: "3", y: "4", rx: "2", ry: "2", key: "eu3xkr" }],
["line", { x1: "16", x2: "16", y1: "2", y2: "6", key: "m3sa8f" }],
["line", { x1: "8", x2: "8", y1: "2", y2: "6", key: "18kwsl" }],
["line", { x1: "3", x2: "21", y1: "10", y2: "10", key: "xt86sb" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Check = createLucideIcon("Check", [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const ChevronDown = createLucideIcon("ChevronDown", [
["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const ChevronRight = createLucideIcon("ChevronRight", [
["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Grid3x3 = createLucideIcon("Grid3x3", [
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
["path", { d: "M3 9h18", key: "1pudct" }],
["path", { d: "M3 15h18", key: "5xshup" }],
["path", { d: "M9 3v18", key: "fh3hqa" }],
["path", { d: "M15 3v18", key: "14nvp0" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const GripVertical = createLucideIcon("GripVertical", [
["circle", { cx: "9", cy: "12", r: "1", key: "1vctgf" }],
["circle", { cx: "9", cy: "5", r: "1", key: "hp0tcf" }],
["circle", { cx: "9", cy: "19", r: "1", key: "fkjjf6" }],
["circle", { cx: "15", cy: "12", r: "1", key: "1tmaij" }],
["circle", { cx: "15", cy: "5", r: "1", key: "19l28e" }],
["circle", { cx: "15", cy: "19", r: "1", key: "f4zoj3" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Image$1 = createLucideIcon("Image", [
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Italic = createLucideIcon("Italic", [
["line", { x1: "19", x2: "10", y1: "4", y2: "4", key: "15jd3p" }],
["line", { x1: "14", x2: "5", y1: "20", y2: "20", key: "bu0au3" }],
["line", { x1: "15", x2: "9", y1: "4", y2: "20", key: "uljnxc" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const ListOrdered = createLucideIcon("ListOrdered", [
["line", { x1: "10", x2: "21", y1: "6", y2: "6", key: "76qw6h" }],
["line", { x1: "10", x2: "21", y1: "12", y2: "12", key: "16nom4" }],
["line", { x1: "10", x2: "21", y1: "18", y2: "18", key: "u3jurt" }],
["path", { d: "M4 6h1v4", key: "cnovpq" }],
["path", { d: "M4 10h2", key: "16xx2s" }],
["path", { d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1", key: "m9a95d" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const List = createLucideIcon("List", [
["line", { x1: "8", x2: "21", y1: "6", y2: "6", key: "7ey8pc" }],
["line", { x1: "8", x2: "21", y1: "12", y2: "12", key: "rjfblc" }],
["line", { x1: "8", x2: "21", y1: "18", y2: "18", key: "c3b1m8" }],
["line", { x1: "3", x2: "3.01", y1: "6", y2: "6", key: "1g7gq3" }],
["line", { x1: "3", x2: "3.01", y1: "12", y2: "12", key: "1pjlvk" }],
["line", { x1: "3", x2: "3.01", y1: "18", y2: "18", key: "28t2mc" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Loader2 = createLucideIcon("Loader2", [
["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const MapPin = createLucideIcon("MapPin", [
["path", { d: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z", key: "2oe9fu" }],
["circle", { cx: "12", cy: "10", r: "3", key: "ilqhr7" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const MessageSquare = createLucideIcon("MessageSquare", [
["path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z", key: "1lielz" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Navigation = createLucideIcon("Navigation", [
["polygon", { points: "3 11 22 2 13 21 11 13 3 11", key: "1ltx0t" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const PenSquare = createLucideIcon("PenSquare", [
["path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7", key: "1qinfi" }],
["path", { d: "M18.5 2.5a2.12 2.12 0 0 1 3 3L12 15l-4 1 1-4Z", key: "w2jsv5" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Table = createLucideIcon("Table", [
["path", { d: "M12 3v18", key: "108xh3" }],
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
["path", { d: "M3 9h18", key: "1pudct" }],
["path", { d: "M3 15h18", key: "5xshup" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const Trash2 = createLucideIcon("Trash2", [
["path", { d: "M3 6h18", key: "d0wm0j" }],
["path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6", key: "4alrt4" }],
["path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2", key: "v07s0e" }],
["line", { x1: "10", x2: "10", y1: "11", y2: "17", key: "1uufr5" }],
["line", { x1: "14", x2: "14", y1: "11", y2: "17", key: "xtxkd" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const User = createLucideIcon("User", [
["path", { d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2", key: "975kel" }],
["circle", { cx: "12", cy: "7", r: "4", key: "17ys0d" }]
]);
/**
* @license lucide-react v0.294.0 - ISC
*
* This source code is licensed under the ISC license.
* See the LICENSE file in the root directory of this source tree.
*/
const X = createLucideIcon("X", [
["path", { d: "M18 6 6 18", key: "1bl5f8" }],
["path", { d: "m6 6 12 12", key: "d8bk6v" }]
]);
class HttpService {
constructor() {
// Token will be retrieved dynamically for each request
}
handleError(url, error, showToast = true) {
// Check if this is an authentication error that should trigger logout
// if (authInterceptorService.handleApiError(error)) {
// Don't show toast for auth errors as user will be redirected
// throw error?.error || error;
// }
// Show toast notification for API errors
if (showToast) {
let errorMessage = 'An error occurred';
// Try to extract meaningful error message
if (error?.error?.Response?.[0]?.ReturnMessage) {
errorMessage = error.error.Response[0].ReturnMessage;
}
else if (error?.error?.message) {
errorMessage = error.error.message;
}
else if (error?.message) {
errorMessage = error.message;
}
else if (typeof error === 'string') {
errorMessage = error;
}
// Don't show duplicate toasts for JSON parsing errors
if (!errorMessage.includes('JSON') && !errorMessage.includes('HTML')) ;
}
throw error?.error || error;
}
getHeaders(includeAuth = true) {
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json, text/plain, */*',
'Origin': window.location.origin,
'Referer': window.location.href,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'cross-site',
};
return headers;
}
/**
* Builds HTTP query parameters from an object, excluding undefined values.
* This prevents empty parameters from being sent to the API, which can
* cause unintended filtering behavior (e.g., search= vs no search param).
*
* @param baseParams - Object containing parameter key-value pairs
* @returns URLSearchParams object with only defined values
*/
getHttpParams(params) {
const searchParams = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
searchParams.append(key, value.toString());
}
});
return searchParams;
}
buildUrl(url, params) {
if (params && Object.keys(params).length > 0) {
const searchParams = this.getHttpParams(params);
return `${url}?${searchParams.toString()}`;
}
return url;
}
async get(url, options = {}) {
try {
const fullUrl = this.buildUrl(url, options.params);
c