@formio/js 5.0.0-rc.73 → 5.0.0-rc.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/formio.embed.js +1 -1
- package/dist/formio.embed.min.js +1 -1
- package/dist/formio.embed.min.js.LICENSE.txt +1 -1
- package/dist/formio.form.js +9 -9
- package/dist/formio.form.min.js +1 -1
- package/dist/formio.form.min.js.LICENSE.txt +1 -1
- package/dist/formio.full.js +10 -10
- package/dist/formio.full.min.js +1 -1
- package/dist/formio.full.min.js.LICENSE.txt +1 -1
- package/dist/formio.js +4 -4
- package/dist/formio.min.js +1 -1
- package/dist/formio.min.js.LICENSE.txt +1 -1
- package/dist/formio.utils.js +2 -2
- package/dist/formio.utils.min.js +1 -1
- package/dist/formio.utils.min.js.LICENSE.txt +1 -1
- package/lib/cjs/CDN.js +1 -2
- package/lib/cjs/Form.js +2 -2
- package/lib/cjs/Wizard.js +1 -1
- package/lib/cjs/components/day/Day.d.ts +2 -2
- package/lib/cjs/components/day/Day.js +3 -3
- package/lib/cjs/components/form/fixtures/index.d.ts +2 -1
- package/lib/cjs/components/form/fixtures/index.js +3 -1
- package/lib/cjs/components/form/fixtures/nestedWizardForm.d.ts +771 -0
- package/lib/cjs/components/form/fixtures/nestedWizardForm.js +765 -0
- package/lib/cjs/components/time/Time.form.js +2 -2
- package/lib/cjs/translations/en.d.ts +1 -0
- package/lib/cjs/translations/en.js +1 -0
- package/lib/mjs/CDN.js +1 -2
- package/lib/mjs/Form.js +2 -2
- package/lib/mjs/Wizard.js +1 -1
- package/lib/mjs/components/day/Day.d.ts +2 -2
- package/lib/mjs/components/day/Day.js +3 -3
- package/lib/mjs/components/form/fixtures/index.d.ts +2 -1
- package/lib/mjs/components/form/fixtures/index.js +2 -1
- package/lib/mjs/components/form/fixtures/nestedWizardForm.d.ts +771 -0
- package/lib/mjs/components/form/fixtures/nestedWizardForm.js +763 -0
- package/lib/mjs/components/time/Time.form.js +2 -2
- package/lib/mjs/translations/en.d.ts +1 -0
- package/lib/mjs/translations/en.js +1 -0
- package/package.json +2 -2
package/dist/formio.utils.js
CHANGED
@@ -565,7 +565,7 @@ eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _argument
|
|
565
565
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
566
566
|
|
567
567
|
"use strict";
|
568
|
-
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateMultipleInfo = exports.validateMultipleSync = exports.validateMultiple = exports.shouldValidate = exports.emptyValueIsArray = exports.isEligible = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst error_1 = __webpack_require__(/*! ../../../error */ \"./node_modules/@formio/core/lib/error/index.js\");\nconst isEligible = (component) => {\n // TODO: would be nice if this was type safe\n switch (component.type) {\n case 'hidden':\n case 'address':\n if (!component.multiple) {\n return false;\n }\n return true;\n case 'textarea':\n if (!component.as ||\n component.as !== 'json') {\n return false;\n }\n return true;\n // TODO: For backwards compatibility, skip multiple validation for select components until we can investigate\n // how this validation might break existing forms\n case 'select':\n return false;\n default:\n return true;\n }\n};\nexports.isEligible = isEligible;\nconst emptyValueIsArray = (component) => {\n // TODO: How do we infer the data model of the compoennt given only its JSON? For now, we have to hardcode component types\n switch (component.type) {\n case 'datagrid':\n case 'editgrid':\n case 'tagpad':\n case 'sketchpad':\n case 'datatable':\n case 'dynamicWizard':\n case 'file':\n return true;\n case 'select':\n return !!component.multiple;\n case 'tags':\n return component.storeas !== 'string';\n default:\n return false;\n }\n};\nexports.emptyValueIsArray = emptyValueIsArray;\nconst shouldValidate = (context) => {\n const { component } = context;\n if (!(0, exports.isEligible)(component)) {\n return false;\n }\n return true;\n};\nexports.shouldValidate = shouldValidate;\nconst validateMultiple = (context) => __awaiter(void 0, void 0, void 0, function* () {\n return (0, exports.validateMultipleSync)(context);\n});\nexports.validateMultiple = validateMultiple;\nconst validateMultipleSync = (context) => {\n var _a;\n const { component, value } = context;\n // Skip multiple validation if the component tells us to\n if (!(0, exports.isEligible)(component)) {\n return null;\n }\n const shouldBeArray = !!component.multiple;\n const isRequired = !!((_a = component.validate) === null || _a === void 0 ? void 0 : _a.required);\n const isArray = Array.isArray(value);\n if (shouldBeArray) {\n if (isArray) {\n return isRequired\n ? value.length > 0\n ? null\n : new error_1.FieldError('array_nonempty', Object.assign(Object.assign({}, context), { setting: true }))\n : null;\n }\n else {\n const error = new error_1.FieldError('array', Object.assign(Object.assign({}, context), { setting: true }));\n // Null/undefined is ok if this value isn't required; anything else should fail\n return (0, lodash_1.isNil)(value) ? (isRequired ? error : null) : error;\n }\n }\n else {\n const canBeArray = (0, exports.emptyValueIsArray)(component);\n if (!canBeArray && isArray) {\n return new error_1.FieldError('nonarray', Object.assign(Object.assign({}, context), { setting: false }));\n }\n return null;\n }\n};\nexports.validateMultipleSync = validateMultipleSync;\nexports.validateMultipleInfo = {\n name: 'validateMultiple',\n process: exports.validateMultiple,\n fullValue: true,\n processSync: exports.validateMultipleSync,\n shouldProcess: exports.shouldValidate,\n};\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/process/validation/rules/validateMultiple.js?");
|
568
|
+
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateMultipleInfo = exports.validateMultipleSync = exports.validateMultiple = exports.shouldValidate = exports.emptyValueIsArray = exports.isEligible = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst error_1 = __webpack_require__(/*! ../../../error */ \"./node_modules/@formio/core/lib/error/index.js\");\nconst isEligible = (component) => {\n // TODO: would be nice if this was type safe\n switch (component.type) {\n case 'hidden':\n case 'address':\n if (!component.multiple) {\n return false;\n }\n return true;\n case 'textarea':\n if (!component.as ||\n component.as !== 'json' ||\n (component.as === 'json' && !component.multiple)) {\n return false;\n }\n return true;\n // TODO: For backwards compatibility, skip multiple validation for select components until we can investigate\n // how this validation might break existing forms\n case 'select':\n return false;\n default:\n return true;\n }\n};\nexports.isEligible = isEligible;\nconst emptyValueIsArray = (component) => {\n // TODO: How do we infer the data model of the compoennt given only its JSON? For now, we have to hardcode component types\n switch (component.type) {\n case 'datagrid':\n case 'editgrid':\n case 'tagpad':\n case 'sketchpad':\n case 'datatable':\n case 'dynamicWizard':\n case 'file':\n return true;\n case 'select':\n return !!component.multiple;\n case 'tags':\n return component.storeas !== 'string';\n default:\n return false;\n }\n};\nexports.emptyValueIsArray = emptyValueIsArray;\nconst shouldValidate = (context) => {\n const { component } = context;\n if (!(0, exports.isEligible)(component)) {\n return false;\n }\n return true;\n};\nexports.shouldValidate = shouldValidate;\nconst validateMultiple = (context) => __awaiter(void 0, void 0, void 0, function* () {\n return (0, exports.validateMultipleSync)(context);\n});\nexports.validateMultiple = validateMultiple;\nconst validateMultipleSync = (context) => {\n var _a;\n const { component, value } = context;\n // Skip multiple validation if the component tells us to\n if (!(0, exports.isEligible)(component)) {\n return null;\n }\n const shouldBeArray = !!component.multiple;\n const isRequired = !!((_a = component.validate) === null || _a === void 0 ? void 0 : _a.required);\n const isArray = Array.isArray(value);\n if (shouldBeArray) {\n if (isArray) {\n return isRequired\n ? value.length > 0\n ? null\n : new error_1.FieldError('array_nonempty', Object.assign(Object.assign({}, context), { setting: true }))\n : null;\n }\n else {\n const error = new error_1.FieldError('array', Object.assign(Object.assign({}, context), { setting: true }));\n // Null/undefined is ok if this value isn't required; anything else should fail\n return (0, lodash_1.isNil)(value) ? (isRequired ? error : null) : error;\n }\n }\n else {\n const canBeArray = (0, exports.emptyValueIsArray)(component);\n if (!canBeArray && isArray) {\n return new error_1.FieldError('nonarray', Object.assign(Object.assign({}, context), { setting: false }));\n }\n return null;\n }\n};\nexports.validateMultipleSync = validateMultipleSync;\nexports.validateMultipleInfo = {\n name: 'validateMultiple',\n process: exports.validateMultiple,\n fullValue: true,\n processSync: exports.validateMultipleSync,\n shouldProcess: exports.shouldValidate,\n};\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/process/validation/rules/validateMultiple.js?");
|
569
569
|
|
570
570
|
/***/ }),
|
571
571
|
|
@@ -1335,7 +1335,7 @@ eval("\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexpo
|
|
1335
1335
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
1336
1336
|
|
1337
1337
|
"use strict";
|
1338
|
-
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.isComponentDataEmpty = exports.getEmptyValue = exports.findComponent = exports.applyFormChanges = exports.generateFormChange = exports.getStrings = exports.getValue = exports.escapeRegExCharacters = exports.formatAsCurrency = exports.parseFloatExt = exports.hasCondition = exports.removeComponent = exports.findComponents = exports.searchComponents = exports.getComponent = exports.matchComponent = exports.isLayoutComponent = exports.getComponentActualValue = exports.getComponentData = exports.eachComponentAsync = exports.eachComponent = exports.componentInfo = exports.getContextualRowData = exports.getContextualRowPath = exports.getComponentKey = exports.eachComponentData = exports.eachComponentDataAsync = exports.componentFormPath = exports.componentDataPath = exports.componentPath = exports.isComponentNestedDataType = exports.isComponentModelType = exports.getComponentPath = exports.getComponentAbsolutePath = exports.getModelType = exports.MODEL_TYPES = exports.uniqueName = exports.guid = exports.flattenComponents = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst fast_json_patch_1 = __webpack_require__(/*! fast-json-patch */ \"./node_modules/fast-json-patch/index.mjs\");\nconst Evaluator_1 = __webpack_require__(/*! ./Evaluator */ \"./node_modules/@formio/core/lib/utils/Evaluator.js\");\n/**\n * Flatten the form components for data manipulation.\n *\n * @param {Object} components\n * The components to iterate.\n * @param {Boolean} includeAll\n * Whether or not to include layout components.\n *\n * @returns {Object}\n * The flattened components map.\n */\nfunction flattenComponents(components, includeAll = false) {\n const flattened = {};\n eachComponent(components, (component, path) => {\n flattened[path] = component;\n }, includeAll);\n return flattened;\n}\nexports.flattenComponents = flattenComponents;\nfunction guid() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\nexports.guid = guid;\n/**\n * Make a filename guaranteed to be unique.\n * @param name\n * @param template\n * @param evalContext\n * @returns {string}\n */\nfunction uniqueName(name, template, evalContext) {\n template = template || \"{{fileName}}-{{guid}}\";\n //include guid in template anyway, to prevent overwriting issue if filename matches existing file\n if (!template.includes(\"{{guid}}\")) {\n template = `${template}-{{guid}}`;\n }\n const parts = name.split(\".\");\n let fileName = parts.slice(0, parts.length - 1).join(\".\");\n const extension = parts.length > 1 ? `.${(0, lodash_1.last)(parts)}` : \"\";\n //allow only 100 characters from original name to avoid issues with filename length restrictions\n fileName = fileName.substr(0, 100);\n evalContext = Object.assign(evalContext || {}, {\n fileName,\n guid: guid(),\n });\n //only letters, numbers, dots, dashes, underscores and spaces are allowed. Anything else will be replaced with dash\n const uniqueName = `${Evaluator_1.Evaluator.interpolate(template, evalContext)}${extension}`.replace(/[^0-9a-zA-Z.\\-_ ]/g, \"-\");\n return uniqueName;\n}\nexports.uniqueName = uniqueName;\nexports.MODEL_TYPES = {\n array: [\n 'datagrid',\n 'editgrid',\n 'datatable',\n 'dynamicWizard',\n 'tagpad'\n ],\n dataObject: [\n 'form'\n ],\n object: [\n 'container',\n 'address'\n ],\n map: [\n 'datamap'\n ],\n content: [\n 'htmlelement',\n 'content'\n ],\n layout: [\n 'table',\n 'tabs',\n 'well',\n 'columns',\n 'fieldset',\n 'panel',\n 'tabs'\n ],\n};\nfunction getModelType(component) {\n if (isComponentNestedDataType(component)) {\n if (isComponentModelType(component, 'dataObject')) {\n return 'dataObject';\n }\n if (isComponentModelType(component, 'array')) {\n return 'array';\n }\n if (isComponentModelType(component, 'map')) {\n return 'map';\n }\n return 'object';\n }\n if ((component.input === false) || isComponentModelType(component, 'layout')) {\n return 'inherit';\n }\n if (getComponentKey(component)) {\n return 'value';\n }\n return 'inherit';\n}\nexports.getModelType = getModelType;\nfunction getComponentAbsolutePath(component) {\n let paths = [component.path];\n while (component.parent) {\n component = component.parent;\n // We only need to do this for nested forms because they reset the data contexts for the children.\n if (isComponentModelType(component, 'dataObject')) {\n paths[paths.length - 1] = `data.${paths[paths.length - 1]}`;\n paths.push(component.path);\n }\n }\n return paths.reverse().join('.');\n}\nexports.getComponentAbsolutePath = getComponentAbsolutePath;\nfunction getComponentPath(component, path) {\n const key = getComponentKey(component);\n if (!key) {\n return path;\n }\n if (!path) {\n return key;\n }\n if (path.match(new RegExp(`${key}$`))) {\n return path;\n }\n return (getModelType(component) === 'inherit') ? `${path}.${key}` : path;\n}\nexports.getComponentPath = getComponentPath;\nfunction isComponentModelType(component, modelType) {\n return component.modelType === modelType || exports.MODEL_TYPES[modelType].includes(component.type);\n}\nexports.isComponentModelType = isComponentModelType;\nfunction isComponentNestedDataType(component) {\n return component.tree || isComponentModelType(component, 'array') ||\n isComponentModelType(component, 'dataObject') ||\n isComponentModelType(component, 'object') ||\n isComponentModelType(component, 'map');\n}\nexports.isComponentNestedDataType = isComponentNestedDataType;\nfunction componentPath(component, parentPath) {\n parentPath = component.parentPath || parentPath;\n const key = getComponentKey(component);\n if (!key) {\n // If the component does not have a key, then just always return the parent path.\n return parentPath || '';\n }\n return parentPath ? `${parentPath}.${key}` : key;\n}\nexports.componentPath = componentPath;\nconst componentDataPath = (component, parentPath, path) => {\n parentPath = component.parentPath || parentPath;\n path = path || componentPath(component, parentPath);\n // See if we are a nested component.\n if (component.components && Array.isArray(component.components)) {\n if (isComponentModelType(component, 'dataObject')) {\n return `${path}.data`;\n }\n if (isComponentModelType(component, 'array')) {\n return `${path}[0]`;\n }\n if (isComponentNestedDataType(component)) {\n return path;\n }\n return parentPath;\n }\n return path;\n};\nexports.componentDataPath = componentDataPath;\nconst componentFormPath = (component, parentPath, path) => {\n parentPath = component.parentPath || parentPath;\n path = path || componentPath(component, parentPath);\n if (isComponentModelType(component, 'dataObject')) {\n return `${path}.data`;\n }\n if (isComponentNestedDataType(component)) {\n return path;\n }\n return parentPath;\n};\nexports.componentFormPath = componentFormPath;\n// Async each component data.\nconst eachComponentDataAsync = (components_1, data_1, fn_1, ...args_1) => __awaiter(void 0, [components_1, data_1, fn_1, ...args_1], void 0, function* (components, data, fn, path = \"\", index, parent, includeAll = false) {\n if (!components || !data) {\n return;\n }\n return yield eachComponentAsync(components, (component, compPath, componentComponents, compParent) => __awaiter(void 0, void 0, void 0, function* () {\n const row = getContextualRowData(component, compPath, data);\n if ((yield fn(component, data, row, compPath, componentComponents, index, compParent)) === true) {\n return true;\n }\n if (isComponentNestedDataType(component)) {\n const value = (0, lodash_1.get)(data, compPath, data);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, `${compPath}[${i}]`, i, component, includeAll);\n }\n return true;\n }\n else if ((0, lodash_1.isEmpty)(row) && !includeAll) {\n // Tree components may submit empty objects; since we've already evaluated the parent tree/layout component, we won't worry about constituent elements\n return true;\n }\n if (isComponentModelType(component, 'dataObject')) {\n // No need to bother processing all the children data if there is no data for this form.\n if ((0, lodash_1.has)(data, component.path)) {\n // For nested forms, we need to reset the \"data\" and \"path\" objects for all of the children components, and then re-establish the data when it is done.\n const childPath = (0, exports.componentDataPath)(component, path, compPath);\n const childData = (0, lodash_1.get)(data, childPath, null);\n yield (0, exports.eachComponentDataAsync)(component.components, childData, fn, '', index, component, includeAll);\n (0, lodash_1.set)(data, childPath, childData);\n }\n }\n else {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, (0, exports.componentDataPath)(component, path, compPath), index, component, includeAll);\n }\n return true;\n }\n return false;\n }), true, path, parent);\n});\nexports.eachComponentDataAsync = eachComponentDataAsync;\nconst eachComponentData = (components, data, fn, path = \"\", index, parent, includeAll = false) => {\n if (!components || !data) {\n return;\n }\n return eachComponent(components, (component, compPath, componentComponents, compParent) => {\n const row = getContextualRowData(component, compPath, data);\n if (fn(component, data, row, compPath, componentComponents, index, compParent) === true) {\n return true;\n }\n if (isComponentNestedDataType(component)) {\n const value = (0, lodash_1.get)(data, compPath, data);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n (0, exports.eachComponentData)(component.components, data, fn, `${compPath}[${i}]`, i, component, includeAll);\n }\n return true;\n }\n else if ((0, lodash_1.isEmpty)(row) && !includeAll) {\n // Tree components may submit empty objects; since we've already evaluated the parent tree/layout component, we won't worry about constituent elements\n return true;\n }\n if (isComponentModelType(component, 'dataObject')) {\n // No need to bother processing all the children data if there is no data for this form.\n if ((0, lodash_1.has)(data, component.path)) {\n // For nested forms, we need to reset the \"data\" and \"path\" objects for all of the children components, and then re-establish the data when it is done.\n const childPath = (0, exports.componentDataPath)(component, path, compPath);\n const childData = (0, lodash_1.get)(data, childPath, {});\n (0, exports.eachComponentData)(component.components, childData, fn, '', index, component, includeAll);\n (0, lodash_1.set)(data, childPath, childData);\n }\n }\n else {\n (0, exports.eachComponentData)(component.components, data, fn, (0, exports.componentDataPath)(component, path, compPath), index, component, includeAll);\n }\n return true;\n }\n return false;\n }, true, path, parent);\n};\nexports.eachComponentData = eachComponentData;\nfunction getComponentKey(component) {\n if (component.type === 'checkbox' &&\n component.inputType === 'radio' &&\n component.name) {\n return component.name;\n }\n return component.key;\n}\nexports.getComponentKey = getComponentKey;\nfunction getContextualRowPath(component, path) {\n return path.replace(new RegExp(`\\.?${getComponentKey(component)}$`), '');\n}\nexports.getContextualRowPath = getContextualRowPath;\nfunction getContextualRowData(component, path, data) {\n const rowPath = getContextualRowPath(component, path);\n return rowPath ? (0, lodash_1.get)(data, rowPath, null) : data;\n}\nexports.getContextualRowData = getContextualRowData;\nfunction componentInfo(component) {\n const hasColumns = component.columns && Array.isArray(component.columns);\n const hasRows = component.rows && Array.isArray(component.rows);\n const hasComps = component.components && Array.isArray(component.components);\n const isContent = isComponentModelType(component, 'content');\n const isLayout = isComponentModelType(component, 'layout');\n const isInput = !component.hasOwnProperty('input') || !!component.input;\n return {\n hasColumns,\n hasRows,\n hasComps,\n layout: hasColumns || hasRows || (hasComps && !isInput) || isLayout || isContent,\n iterable: hasColumns || hasRows || hasComps || isContent,\n };\n}\nexports.componentInfo = componentInfo;\n/**\n * Iterate through each component within a form.\n *\n * @param {Object} components\n * The components to iterate.\n * @param {Function} fn\n * The iteration function to invoke for each component.\n * @param {Boolean} includeAll\n * Whether or not to include layout components.\n * @param {String} path\n * The current data path of the element. Example: data.user.firstName\n * @param {Object} parent\n * The parent object.\n */\nfunction eachComponent(components, fn, includeAll, path, parent) {\n if (!components)\n return;\n path = path || \"\";\n components.forEach((component) => {\n if (!component) {\n return;\n }\n const info = componentInfo(component);\n let noRecurse = false;\n // Keep track of parent references.\n if (parent) {\n // Ensure we don't create infinite JSON structures.\n Object.defineProperty(component, 'parent', {\n enumerable: false,\n writable: true,\n value: JSON.parse(JSON.stringify(parent))\n });\n Object.defineProperty(component.parent, 'parent', {\n enumerable: false,\n writable: true,\n value: parent.parent\n });\n Object.defineProperty(component.parent, 'path', {\n enumerable: false,\n writable: true,\n value: parent.path\n });\n delete component.parent.components;\n delete component.parent.componentMap;\n delete component.parent.columns;\n delete component.parent.rows;\n }\n Object.defineProperty(component, 'path', {\n enumerable: false,\n writable: true,\n value: componentPath(component, path)\n });\n if (includeAll || component.tree || !info.layout) {\n noRecurse = fn(component, component.path, components, parent);\n }\n if (!noRecurse) {\n if (info.hasColumns) {\n component.columns.forEach((column) => eachComponent(column.components, fn, includeAll, path, parent ? component : null));\n }\n else if (info.hasRows) {\n component.rows.forEach((row) => {\n if (Array.isArray(row)) {\n row.forEach((column) => eachComponent(column.components, fn, includeAll, path, parent ? component : null));\n }\n });\n }\n else if (info.hasComps) {\n eachComponent(component.components, fn, includeAll, (0, exports.componentFormPath)(component, path, component.path), parent ? component : null);\n }\n }\n });\n}\nexports.eachComponent = eachComponent;\n// Async each component.\nfunction eachComponentAsync(components_2, fn_1) {\n return __awaiter(this, arguments, void 0, function* (components, fn, includeAll = false, path = \"\", parent) {\n var _a, _b;\n if (!components)\n return;\n for (let i = 0; i < components.length; i++) {\n if (!components[i]) {\n continue;\n }\n let component = components[i];\n const info = componentInfo(component);\n // Keep track of parent references.\n if (parent) {\n // Ensure we don't create infinite JSON structures.\n Object.defineProperty(component, 'parent', {\n enumerable: false,\n writable: true,\n value: JSON.parse(JSON.stringify(parent))\n });\n Object.defineProperty(component.parent, 'parent', {\n enumerable: false,\n writable: true,\n value: parent.parent\n });\n Object.defineProperty(component.parent, 'path', {\n enumerable: false,\n writable: true,\n value: parent.path\n });\n delete component.parent.components;\n delete component.parent.componentMap;\n delete component.parent.columns;\n delete component.parent.rows;\n }\n Object.defineProperty(component, 'path', {\n enumerable: false,\n writable: true,\n value: componentPath(component, path)\n });\n if (includeAll || component.tree || !info.layout) {\n if (yield fn(component, component.path, components, parent)) {\n continue;\n }\n }\n if (info.hasColumns) {\n for (let j = 0; j < component.columns.length; j++) {\n yield eachComponentAsync((_a = component.columns[j]) === null || _a === void 0 ? void 0 : _a.components, fn, includeAll, path, parent ? component : null);\n }\n }\n else if (info.hasRows) {\n for (let j = 0; j < component.rows.length; j++) {\n let row = component.rows[j];\n if (Array.isArray(row)) {\n for (let k = 0; k < row.length; k++) {\n yield eachComponentAsync((_b = row[k]) === null || _b === void 0 ? void 0 : _b.components, fn, includeAll, path, parent ? component : null);\n }\n }\n }\n }\n else if (info.hasComps) {\n yield eachComponentAsync(component.components, fn, includeAll, (0, exports.componentFormPath)(component, path, component.path), parent ? component : null);\n }\n }\n });\n}\nexports.eachComponentAsync = eachComponentAsync;\n// Provided components, data, and a key, this will return the components data.\nfunction getComponentData(components, data, path) {\n const compData = { component: null, data: null };\n (0, exports.eachComponentData)(components, data, (component, data, row, compPath) => {\n if (compPath === path) {\n compData.component = component;\n compData.data = row;\n return true;\n }\n });\n return compData;\n}\nexports.getComponentData = getComponentData;\nfunction getComponentActualValue(component, compPath, data, row) {\n var _a;\n // The compPath here will NOT contain the indexes for DataGrids and EditGrids.\n //\n // a[0].b[2].c[3].d\n //\n // Because of this, we will need to determine our parent component path (not data path),\n // and find the \"row\" based comp path.\n //\n // a[0].b[2].c[3].d => a.b.c.d\n //\n let parentInputComponent = null;\n let parent = component;\n while (((_a = parent === null || parent === void 0 ? void 0 : parent.parent) === null || _a === void 0 ? void 0 : _a.path) && !parentInputComponent) {\n parent = parent.parent;\n if (parent.input) {\n parentInputComponent = parent;\n }\n }\n if (parentInputComponent) {\n const parentCompPath = parentInputComponent.path.replace(/\\[[0-9]+\\]/g, '');\n compPath = compPath.replace(parentCompPath, '');\n compPath = (0, lodash_1.trim)(compPath, '. ');\n }\n let value = null;\n if (row) {\n value = (0, lodash_1.get)(row, compPath);\n }\n if (data && (0, lodash_1.isNil)(value)) {\n value = (0, lodash_1.get)(data, compPath);\n }\n if ((0, lodash_1.isNil)(value) || ((0, lodash_1.isObject)(value) && (0, lodash_1.isEmpty)(value))) {\n value = '';\n }\n return value;\n}\nexports.getComponentActualValue = getComponentActualValue;\n/**\n * Determine if a component is a layout component or not.\n *\n * @param {Object} component\n * The component to check.\n *\n * @returns {Boolean}\n * Whether or not the component is a layout component.\n */\nfunction isLayoutComponent(component) {\n return Boolean((component.columns && Array.isArray(component.columns)) ||\n (component.rows && Array.isArray(component.rows)) ||\n (component.components && Array.isArray(component.components)));\n}\nexports.isLayoutComponent = isLayoutComponent;\n/**\n * Matches if a component matches the query.\n *\n * @param component\n * @param query\n * @return {boolean}\n */\nfunction matchComponent(component, query) {\n if ((0, lodash_1.isString)(query)) {\n return (component.key === query) || (component.path === query);\n }\n else {\n let matches = false;\n (0, lodash_1.forOwn)(query, (value, key) => {\n matches = ((0, lodash_1.get)(component, key) === value);\n if (!matches) {\n return false;\n }\n });\n return matches;\n }\n}\nexports.matchComponent = matchComponent;\n/**\n * Get a component by its key\n *\n * @param {Object} components - The components to iterate.\n * @param {String|Object} key - The key of the component to get, or a query of the component to search.\n * @param {boolean} includeAll - Whether or not to include layout components.\n * @returns {Component} - The component that matches the given key, or undefined if not found.\n */\nfunction getComponent(components, key, includeAll = false) {\n let result;\n eachComponent(components, (component, path) => {\n if ((path === key) || (component.path === key) || (component.input && (component.key === key))) {\n result = component;\n return true;\n }\n }, includeAll);\n return result;\n}\nexports.getComponent = getComponent;\n/**\n * Finds a component provided a query of properties of that component.\n *\n * @param components\n * @param query\n * @return {*}\n */\nfunction searchComponents(components, query) {\n const results = [];\n eachComponent(components, (component) => {\n if (matchComponent(component, query)) {\n results.push(component);\n }\n }, true);\n return results;\n}\nexports.searchComponents = searchComponents;\n/**\n * Deprecated version of findComponents. Renamed to searchComponents.\n * @param {import('@formio/core').Component[]} components - The components to find components within.\n * @param {object} query - The query to use when searching for the components.\n * @returns {import('@formio/core').Component[]} - The result of the component that is found.\n */\nfunction findComponents(components, query) {\n console.warn('formio.js/utils findComponents is deprecated. Use searchComponents instead.');\n return searchComponents(components, query);\n}\nexports.findComponents = findComponents;\n/**\n * Remove a component by path.\n *\n * @param components\n * @param path\n */\nfunction removeComponent(components, path) {\n // Using _.unset() leave a null value. Use Array splice instead.\n // @ts-ignore\n var index = path.pop();\n if (path.length !== 0) {\n components = (0, lodash_1.get)(components, path);\n }\n components.splice(index, 1);\n}\nexports.removeComponent = removeComponent;\n/**\n * Returns if this component has a conditional statement.\n *\n * @param component - The component JSON schema.\n *\n * @returns {boolean} - TRUE - This component has a conditional, FALSE - No conditional provided.\n */\nfunction hasCondition(component) {\n return Boolean((component.customConditional) ||\n (component.conditional && (component.conditional.when ||\n component.conditional.json ||\n component.conditional.conjunction)));\n}\nexports.hasCondition = hasCondition;\n/**\n * Extension of standard #parseFloat(value) function, that also clears input string.\n *\n * @param {any} value\n * The value to parse.\n *\n * @returns {Number}\n * Parsed value.\n */\nfunction parseFloatExt(value) {\n return parseFloat((0, lodash_1.isString)(value)\n ? value.replace(/[^\\de.+-]/gi, '')\n : value);\n}\nexports.parseFloatExt = parseFloatExt;\n/**\n * Formats provided value in way how Currency component uses it.\n *\n * @param {any} value\n * The value to format.\n *\n * @returns {String}\n * Value formatted for Currency component.\n */\nfunction formatAsCurrency(value) {\n const parsedValue = parseFloatExt(value);\n if (isNaN(parsedValue)) {\n return '';\n }\n const parts = (0, lodash_1.round)(parsedValue, 2)\n .toString()\n .split('.');\n parts[0] = (0, lodash_1.chunk)(Array.from(parts[0]).reverse(), 3)\n .reverse()\n .map((part) => part\n .reverse()\n .join(''))\n .join(',');\n parts[1] = (0, lodash_1.pad)(parts[1], 2, '0');\n return parts.join('.');\n}\nexports.formatAsCurrency = formatAsCurrency;\n/**\n * Escapes RegEx characters in provided String value.\n *\n * @param {String} value\n * String for escaping RegEx characters.\n * @returns {string}\n * String with escaped RegEx characters.\n */\nfunction escapeRegExCharacters(value) {\n return value.replace(/[-[\\]/{}()*+?.\\\\^$|]/g, '\\\\$&');\n}\nexports.escapeRegExCharacters = escapeRegExCharacters;\n/**\n * Get the value for a component key, in the given submission.\n *\n * @param {Object} submission\n * A submission object to search.\n * @param {String} key\n * A for components API key to search for.\n */\nfunction getValue(submission, key) {\n const search = (data) => {\n if ((0, lodash_1.isPlainObject)(data)) {\n if ((0, lodash_1.has)(data, key)) {\n return (0, lodash_1.get)(data, key);\n }\n let value = null;\n (0, lodash_1.forOwn)(data, (prop) => {\n const result = search(prop);\n if (!(0, lodash_1.isNil)(result)) {\n value = result;\n return false;\n }\n });\n return value;\n }\n else {\n return null;\n }\n };\n return search(submission.data);\n}\nexports.getValue = getValue;\n/**\n * Iterate over all components in a form and get string values for translation.\n * @param form\n */\nfunction getStrings(form) {\n const properties = ['label', 'title', 'legend', 'tooltip', 'description', 'placeholder', 'prefix', 'suffix', 'errorLabel', 'content', 'html'];\n const strings = [];\n eachComponent(form.components, (component) => {\n properties.forEach(property => {\n if (component.hasOwnProperty(property) && component[property]) {\n strings.push({\n key: component.key,\n type: component.type,\n property,\n string: component[property]\n });\n }\n });\n if ((!component.dataSrc || component.dataSrc === 'values') && component.hasOwnProperty('values') && Array.isArray(component.values) && component.values.length) {\n component.values.forEach((value, index) => {\n strings.push({\n key: component.key,\n property: `value[${index}].label`,\n string: component.values[index].label\n });\n });\n }\n // Hard coded values from Day component\n if (component.type === 'day') {\n [\n 'day',\n 'month',\n 'year',\n 'Day',\n 'Month',\n 'Year',\n 'january',\n 'february',\n 'march',\n 'april',\n 'may',\n 'june',\n 'july',\n 'august',\n 'september',\n 'october',\n 'november',\n 'december'\n ].forEach(string => {\n strings.push({\n key: component.key,\n property: 'day',\n string,\n });\n });\n if (component.fields.day.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.day.placeholder',\n string: component.fields.day.placeholder,\n });\n }\n if (component.fields.month.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.month.placeholder',\n string: component.fields.month.placeholder,\n });\n }\n if (component.fields.year.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.year.placeholder',\n string: component.fields.year.placeholder,\n });\n }\n }\n if (component.type === 'editgrid') {\n const string = component.addAnother || 'Add Another';\n if (component.addAnother) {\n strings.push({\n key: component.key,\n property: 'addAnother',\n string,\n });\n }\n }\n if (component.type === 'select') {\n [\n 'loading...',\n 'Type to search'\n ].forEach(string => {\n strings.push({\n key: component.key,\n property: 'select',\n string,\n });\n });\n }\n }, true);\n return strings;\n}\nexports.getStrings = getStrings;\n// ?????????????????????????\n// questionable section\nfunction generateFormChange(type, data) {\n let change;\n switch (type) {\n case 'add':\n change = {\n op: 'add',\n key: data.component.key,\n container: data.parent.key, // Parent component\n path: data.path, // Path to container within parent component.\n index: data.index, // Index of component in parent container.\n component: data.component\n };\n break;\n case 'edit':\n change = {\n op: 'edit',\n key: data.originalComponent.key,\n patches: (0, fast_json_patch_1.compare)(data.originalComponent, data.component)\n };\n // Don't save if nothing changed.\n if (!change.patches.length) {\n change = null;\n }\n break;\n case 'remove':\n change = {\n op: 'remove',\n key: data.component.key,\n };\n break;\n }\n return change;\n}\nexports.generateFormChange = generateFormChange;\nfunction applyFormChanges(form, changes) {\n const failed = [];\n changes.forEach(function (change) {\n var found = false;\n switch (change.op) {\n case 'add':\n var newComponent = change.component;\n // Find the container to set the component in.\n findComponent(form.components, change.container, null, function (parent) {\n if (!change.container) {\n parent = form;\n }\n // A move will first run an add so remove any existing components with matching key before inserting.\n findComponent(form.components, change.key, null, function (component, path) {\n // If found, use the existing component. (If someone else edited it, the changes would be here)\n newComponent = component;\n removeComponent(form.components, path);\n });\n found = true;\n var container = (0, lodash_1.get)(parent, change.path);\n container.splice(change.index, 0, newComponent);\n });\n break;\n case 'remove':\n findComponent(form.components, change.key, null, function (component, path) {\n found = true;\n const oldComponent = (0, lodash_1.get)(form.components, path);\n if (oldComponent.key !== component.key) {\n path.pop();\n }\n removeComponent(form.components, path);\n });\n break;\n case 'edit':\n findComponent(form.components, change.key, null, function (component, path) {\n found = true;\n try {\n const oldComponent = (0, lodash_1.get)(form.components, path);\n const newComponent = (0, fast_json_patch_1.applyPatch)(component, change.patches).newDocument;\n if (oldComponent.key !== newComponent.key) {\n path.pop();\n }\n (0, lodash_1.set)(form.components, path, newComponent);\n }\n catch (err) {\n failed.push(change);\n }\n });\n break;\n case 'move':\n break;\n }\n if (!found) {\n failed.push(change);\n }\n });\n return {\n form,\n failed\n };\n}\nexports.applyFormChanges = applyFormChanges;\n/**\n* This function will find a component in a form and return the component AND THE PATH to the component in the form.\n* Path to the component is stored as an array of nested components and their indexes.The Path is being filled recursively\n* when you iterating through the nested structure.\n* If the component is not found the callback won't be called and function won't return anything.\n*\n* @param components\n* @param key\n* @param fn\n* @param path\n* @returns {*}\n*/\nfunction findComponent(components, key, path, fn) {\n if (!components)\n return;\n path = path || [];\n if (!key) {\n return fn(components);\n }\n components.forEach(function (component, index) {\n var newPath = path.slice();\n // Add an index of the component it iterates through in nested structure\n newPath.push(index);\n if (!component)\n return;\n if (component.hasOwnProperty('columns') && Array.isArray(component.columns)) {\n newPath.push('columns');\n component.columns.forEach(function (column, index) {\n var colPath = newPath.slice();\n colPath.push(index);\n colPath.push('components');\n findComponent(column.components, key, colPath, fn);\n });\n }\n if (component.hasOwnProperty('rows') && Array.isArray(component.rows)) {\n newPath.push('rows');\n component.rows.forEach(function (row, index) {\n var rowPath = newPath.slice();\n rowPath.push(index);\n row.forEach(function (column, index) {\n var colPath = rowPath.slice();\n colPath.push(index);\n colPath.push('components');\n findComponent(column.components, key, colPath, fn);\n });\n });\n }\n if (component.hasOwnProperty('components') && Array.isArray(component.components)) {\n newPath.push('components');\n findComponent(component.components, key, newPath, fn);\n }\n if (component.key === key) {\n //Final callback if the component is found\n fn(component, newPath, components);\n }\n });\n}\nexports.findComponent = findComponent;\nconst isCheckboxComponent = (component) => component.type === 'checkbox';\nconst isDataGridComponent = (component) => component.type === 'datagrid';\nconst isEditGridComponent = (component) => component.type === 'editgrid';\nconst isDataTableComponent = (component) => component.type === 'datatable';\nconst hasChildComponents = (component) => component.components != null;\nconst isDateTimeComponent = (component) => component.type === 'datetime';\nconst isSelectBoxesComponent = (component) => component.type === 'selectboxes';\nconst isTextAreaComponent = (component) => component.type === 'textarea';\nconst isTextFieldComponent = (component) => component.type === 'textfield';\nfunction getEmptyValue(component) {\n switch (component.type) {\n case 'textarea':\n case 'textfield':\n case 'time':\n case 'datetime':\n case 'day':\n return '';\n case 'datagrid':\n case 'editgrid':\n return [];\n default:\n return null;\n }\n}\nexports.getEmptyValue = getEmptyValue;\nconst replaceBlanks = (value) => {\n const nbsp = '<p> </p>';\n const br = '<p><br></p>';\n const brNbsp = '<p><br> </p>';\n const regExp = new RegExp(`^${nbsp}|${nbsp}$|^${br}|${br}$|^${brNbsp}|${brNbsp}$`, 'g');\n return typeof value === 'string' ? value.replace(regExp, '').trim() : value;\n};\nfunction trimBlanks(value) {\n if (!value) {\n return value;\n }\n if (Array.isArray(value)) {\n value = value.map((val) => replaceBlanks(val));\n }\n else {\n value = replaceBlanks(value);\n }\n return value;\n}\nfunction isValueEmpty(component, value) {\n const compValueIsEmptyArray = ((0, lodash_1.isArray)(value) && value.length === 1) ? (0, lodash_1.isEqual)(value[0], getEmptyValue(component)) : false;\n return value == null || value === '' || ((0, lodash_1.isArray)(value) && value.length === 0) || compValueIsEmptyArray;\n}\nfunction isComponentDataEmpty(component, data, path) {\n var _a;\n const value = (0, lodash_1.get)(data, path);\n if (isCheckboxComponent(component)) {\n return isValueEmpty(component, value) || value === false;\n }\n else if (isDataGridComponent(component) || isEditGridComponent(component) || isDataTableComponent(component) || hasChildComponents(component)) {\n if ((_a = component.components) === null || _a === void 0 ? void 0 : _a.length) {\n let childrenEmpty = true;\n // wrap component in an array to let eachComponentData handle introspection to child components (e.g. this will be different\n // for data grids versus nested forms, etc.)\n (0, exports.eachComponentData)([component], data, (thisComponent, data, row, path, components, index) => {\n if (component.key === thisComponent.key)\n return;\n if (!isComponentDataEmpty(thisComponent, data, path)) {\n childrenEmpty = false;\n }\n });\n return isValueEmpty(component, value) || childrenEmpty;\n }\n return isValueEmpty(component, value);\n }\n else if (isDateTimeComponent(component)) {\n return isValueEmpty(component, value) || value.toString() === 'Invalid date';\n }\n else if (isSelectBoxesComponent(component)) {\n let selectBoxEmpty = true;\n for (const key in value) {\n if (value[key]) {\n selectBoxEmpty = false;\n break;\n }\n }\n return isValueEmpty(component, value) || selectBoxEmpty;\n }\n else if (isTextAreaComponent(component)) {\n const isPlain = !component.wysiwyg && !component.editor;\n return isPlain ? typeof value === 'string' ? isValueEmpty(component, value.trim()) : isValueEmpty(component, value) : isValueEmpty(component, trimBlanks(value));\n }\n else if (isTextFieldComponent(component)) {\n if (component.allowMultipleMasks && !!component.inputMasks && !!component.inputMasks.length) {\n return isValueEmpty(component, value) || (component.multiple ? value.length === 0 : (!value.maskName || !value.value));\n }\n return isValueEmpty(component, value === null || value === void 0 ? void 0 : value.toString().trim());\n }\n return isValueEmpty(component, value);\n}\nexports.isComponentDataEmpty = isComponentDataEmpty;\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil.js?");
|
1338
|
+
eval("\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.isComponentDataEmpty = exports.getEmptyValue = exports.findComponent = exports.applyFormChanges = exports.generateFormChange = exports.getStrings = exports.getValue = exports.escapeRegExCharacters = exports.formatAsCurrency = exports.parseFloatExt = exports.hasCondition = exports.removeComponent = exports.findComponents = exports.searchComponents = exports.getComponent = exports.matchComponent = exports.isLayoutComponent = exports.getComponentActualValue = exports.getComponentData = exports.eachComponentAsync = exports.eachComponent = exports.componentInfo = exports.getContextualRowData = exports.getContextualRowPath = exports.getComponentKey = exports.eachComponentData = exports.eachComponentDataAsync = exports.componentFormPath = exports.componentDataPath = exports.componentPath = exports.isComponentNestedDataType = exports.isComponentModelType = exports.getComponentPath = exports.getComponentAbsolutePath = exports.getModelType = exports.MODEL_TYPES = exports.uniqueName = exports.guid = exports.flattenComponents = void 0;\nconst lodash_1 = __webpack_require__(/*! lodash */ \"./node_modules/lodash/lodash.js\");\nconst fast_json_patch_1 = __webpack_require__(/*! fast-json-patch */ \"./node_modules/fast-json-patch/index.mjs\");\nconst Evaluator_1 = __webpack_require__(/*! ./Evaluator */ \"./node_modules/@formio/core/lib/utils/Evaluator.js\");\n/**\n * Flatten the form components for data manipulation.\n *\n * @param {Object} components\n * The components to iterate.\n * @param {Boolean} includeAll\n * Whether or not to include layout components.\n *\n * @returns {Object}\n * The flattened components map.\n */\nfunction flattenComponents(components, includeAll = false) {\n const flattened = {};\n eachComponent(components, (component, path) => {\n flattened[path] = component;\n }, includeAll);\n return flattened;\n}\nexports.flattenComponents = flattenComponents;\nfunction guid() {\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\nexports.guid = guid;\n/**\n * Make a filename guaranteed to be unique.\n * @param name\n * @param template\n * @param evalContext\n * @returns {string}\n */\nfunction uniqueName(name, template, evalContext) {\n template = template || \"{{fileName}}-{{guid}}\";\n //include guid in template anyway, to prevent overwriting issue if filename matches existing file\n if (!template.includes(\"{{guid}}\")) {\n template = `${template}-{{guid}}`;\n }\n const parts = name.split(\".\");\n let fileName = parts.slice(0, parts.length - 1).join(\".\");\n const extension = parts.length > 1 ? `.${(0, lodash_1.last)(parts)}` : \"\";\n //allow only 100 characters from original name to avoid issues with filename length restrictions\n fileName = fileName.substr(0, 100);\n evalContext = Object.assign(evalContext || {}, {\n fileName,\n guid: guid(),\n });\n //only letters, numbers, dots, dashes, underscores and spaces are allowed. Anything else will be replaced with dash\n const uniqueName = `${Evaluator_1.Evaluator.interpolate(template, evalContext)}${extension}`.replace(/[^0-9a-zA-Z.\\-_ ]/g, \"-\");\n return uniqueName;\n}\nexports.uniqueName = uniqueName;\nexports.MODEL_TYPES = {\n array: [\n 'datagrid',\n 'editgrid',\n 'datatable',\n 'dynamicWizard',\n 'tagpad'\n ],\n dataObject: [\n 'form'\n ],\n object: [\n 'container',\n 'address'\n ],\n map: [\n 'datamap'\n ],\n content: [\n 'htmlelement',\n 'content'\n ],\n layout: [\n 'table',\n 'tabs',\n 'well',\n 'columns',\n 'fieldset',\n 'panel',\n 'tabs'\n ],\n};\nfunction getModelType(component) {\n if (isComponentNestedDataType(component)) {\n if (isComponentModelType(component, 'dataObject')) {\n return 'dataObject';\n }\n if (isComponentModelType(component, 'array')) {\n return 'array';\n }\n if (isComponentModelType(component, 'map')) {\n return 'map';\n }\n return 'object';\n }\n if ((component.input === false) || isComponentModelType(component, 'layout')) {\n return 'inherit';\n }\n if (getComponentKey(component)) {\n return 'value';\n }\n return 'inherit';\n}\nexports.getModelType = getModelType;\nfunction getComponentAbsolutePath(component) {\n let paths = [component.path];\n while (component.parent) {\n component = component.parent;\n // We only need to do this for nested forms because they reset the data contexts for the children.\n if (isComponentModelType(component, 'dataObject')) {\n paths[paths.length - 1] = `data.${paths[paths.length - 1]}`;\n paths.push(component.path);\n }\n }\n return paths.reverse().join('.');\n}\nexports.getComponentAbsolutePath = getComponentAbsolutePath;\nfunction getComponentPath(component, path) {\n const key = getComponentKey(component);\n if (!key) {\n return path;\n }\n if (!path) {\n return key;\n }\n if (path.match(new RegExp(`${key}$`))) {\n return path;\n }\n return (getModelType(component) === 'inherit') ? `${path}.${key}` : path;\n}\nexports.getComponentPath = getComponentPath;\nfunction isComponentModelType(component, modelType) {\n return component.modelType === modelType || exports.MODEL_TYPES[modelType].includes(component.type);\n}\nexports.isComponentModelType = isComponentModelType;\nfunction isComponentNestedDataType(component) {\n return component.tree || isComponentModelType(component, 'array') ||\n isComponentModelType(component, 'dataObject') ||\n isComponentModelType(component, 'object') ||\n isComponentModelType(component, 'map');\n}\nexports.isComponentNestedDataType = isComponentNestedDataType;\nfunction componentPath(component, parentPath) {\n parentPath = component.parentPath || parentPath;\n const key = getComponentKey(component);\n if (!key) {\n // If the component does not have a key, then just always return the parent path.\n return parentPath || '';\n }\n return parentPath ? `${parentPath}.${key}` : key;\n}\nexports.componentPath = componentPath;\nconst componentDataPath = (component, parentPath, path) => {\n parentPath = component.parentPath || parentPath;\n path = path || componentPath(component, parentPath);\n // See if we are a nested component.\n if (component.components && Array.isArray(component.components)) {\n if (isComponentModelType(component, 'dataObject')) {\n return `${path}.data`;\n }\n if (isComponentModelType(component, 'array')) {\n return `${path}[0]`;\n }\n if (isComponentNestedDataType(component)) {\n return path;\n }\n return parentPath;\n }\n return path;\n};\nexports.componentDataPath = componentDataPath;\nconst componentFormPath = (component, parentPath, path) => {\n parentPath = component.parentPath || parentPath;\n path = path || componentPath(component, parentPath);\n if (isComponentModelType(component, 'dataObject')) {\n return `${path}.data`;\n }\n if (isComponentNestedDataType(component)) {\n return path;\n }\n return parentPath;\n};\nexports.componentFormPath = componentFormPath;\n// Async each component data.\nconst eachComponentDataAsync = (components_1, data_1, fn_1, ...args_1) => __awaiter(void 0, [components_1, data_1, fn_1, ...args_1], void 0, function* (components, data, fn, path = \"\", index, parent, includeAll = false) {\n if (!components || !data) {\n return;\n }\n return yield eachComponentAsync(components, (component, compPath, componentComponents, compParent) => __awaiter(void 0, void 0, void 0, function* () {\n const row = getContextualRowData(component, compPath, data);\n if ((yield fn(component, data, row, compPath, componentComponents, index, compParent)) === true) {\n return true;\n }\n if (isComponentNestedDataType(component)) {\n const value = (0, lodash_1.get)(data, compPath, data);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, `${compPath}[${i}]`, i, component, includeAll);\n }\n return true;\n }\n else if ((0, lodash_1.isEmpty)(row) && !includeAll) {\n // Tree components may submit empty objects; since we've already evaluated the parent tree/layout component, we won't worry about constituent elements\n return true;\n }\n if (isComponentModelType(component, 'dataObject')) {\n // No need to bother processing all the children data if there is no data for this form.\n if ((0, lodash_1.has)(data, component.path)) {\n // For nested forms, we need to reset the \"data\" and \"path\" objects for all of the children components, and then re-establish the data when it is done.\n const childPath = (0, exports.componentDataPath)(component, path, compPath);\n const childData = (0, lodash_1.get)(data, childPath, null);\n yield (0, exports.eachComponentDataAsync)(component.components, childData, fn, '', index, component, includeAll);\n (0, lodash_1.set)(data, childPath, childData);\n }\n }\n else {\n yield (0, exports.eachComponentDataAsync)(component.components, data, fn, (0, exports.componentDataPath)(component, path, compPath), index, component, includeAll);\n }\n return true;\n }\n return false;\n }), true, path, parent);\n});\nexports.eachComponentDataAsync = eachComponentDataAsync;\nconst eachComponentData = (components, data, fn, path = \"\", index, parent, includeAll = false) => {\n if (!components || !data) {\n return;\n }\n return eachComponent(components, (component, compPath, componentComponents, compParent) => {\n const row = getContextualRowData(component, compPath, data);\n if (fn(component, data, row, compPath, componentComponents, index, compParent) === true) {\n return true;\n }\n if (isComponentNestedDataType(component)) {\n const value = (0, lodash_1.get)(data, compPath, data);\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n (0, exports.eachComponentData)(component.components, data, fn, `${compPath}[${i}]`, i, component, includeAll);\n }\n return true;\n }\n else if ((0, lodash_1.isEmpty)(row) && !includeAll) {\n // Tree components may submit empty objects; since we've already evaluated the parent tree/layout component, we won't worry about constituent elements\n return true;\n }\n if (isComponentModelType(component, 'dataObject')) {\n // No need to bother processing all the children data if there is no data for this form.\n if ((0, lodash_1.has)(data, component.path)) {\n // For nested forms, we need to reset the \"data\" and \"path\" objects for all of the children components, and then re-establish the data when it is done.\n const childPath = (0, exports.componentDataPath)(component, path, compPath);\n const childData = (0, lodash_1.get)(data, childPath, {});\n (0, exports.eachComponentData)(component.components, childData, fn, '', index, component, includeAll);\n (0, lodash_1.set)(data, childPath, childData);\n }\n }\n else {\n (0, exports.eachComponentData)(component.components, data, fn, (0, exports.componentDataPath)(component, path, compPath), index, component, includeAll);\n }\n return true;\n }\n return false;\n }, true, path, parent);\n};\nexports.eachComponentData = eachComponentData;\nfunction getComponentKey(component) {\n if (component.type === 'checkbox' &&\n component.inputType === 'radio' &&\n component.name) {\n return component.name;\n }\n return component.key;\n}\nexports.getComponentKey = getComponentKey;\nfunction getContextualRowPath(component, path) {\n return path.replace(new RegExp(`\\.?${getComponentKey(component)}$`), '');\n}\nexports.getContextualRowPath = getContextualRowPath;\nfunction getContextualRowData(component, path, data) {\n const rowPath = getContextualRowPath(component, path);\n return rowPath ? (0, lodash_1.get)(data, rowPath, null) : data;\n}\nexports.getContextualRowData = getContextualRowData;\nfunction componentInfo(component) {\n const hasColumns = component.columns && Array.isArray(component.columns);\n const hasRows = component.rows && Array.isArray(component.rows);\n const hasComps = component.components && Array.isArray(component.components);\n const isContent = isComponentModelType(component, 'content');\n const isLayout = isComponentModelType(component, 'layout');\n const isInput = !component.hasOwnProperty('input') || !!component.input;\n return {\n hasColumns,\n hasRows,\n hasComps,\n layout: hasColumns || hasRows || (hasComps && !isInput) || isLayout || isContent,\n iterable: hasColumns || hasRows || hasComps || isContent,\n };\n}\nexports.componentInfo = componentInfo;\n/**\n * Iterate through each component within a form.\n *\n * @param {Object} components\n * The components to iterate.\n * @param {Function} fn\n * The iteration function to invoke for each component.\n * @param {Boolean} includeAll\n * Whether or not to include layout components.\n * @param {String} path\n * The current data path of the element. Example: data.user.firstName\n * @param {Object} parent\n * The parent object.\n */\nfunction eachComponent(components, fn, includeAll, path, parent) {\n if (!components)\n return;\n path = path || \"\";\n components.forEach((component) => {\n if (!component) {\n return;\n }\n const info = componentInfo(component);\n let noRecurse = false;\n // Keep track of parent references.\n if (parent) {\n // Ensure we don't create infinite JSON structures.\n Object.defineProperty(component, 'parent', {\n enumerable: false,\n writable: true,\n value: JSON.parse(JSON.stringify(parent))\n });\n Object.defineProperty(component.parent, 'parent', {\n enumerable: false,\n writable: true,\n value: parent.parent\n });\n Object.defineProperty(component.parent, 'path', {\n enumerable: false,\n writable: true,\n value: parent.path\n });\n delete component.parent.components;\n delete component.parent.componentMap;\n delete component.parent.columns;\n delete component.parent.rows;\n }\n Object.defineProperty(component, 'path', {\n enumerable: false,\n writable: true,\n value: componentPath(component, path)\n });\n if (includeAll || component.tree || !info.layout) {\n noRecurse = fn(component, component.path, components, parent);\n }\n if (!noRecurse) {\n if (info.hasColumns) {\n component.columns.forEach((column) => eachComponent(column.components, fn, includeAll, path, parent ? component : null));\n }\n else if (info.hasRows) {\n component.rows.forEach((row) => {\n if (Array.isArray(row)) {\n row.forEach((column) => eachComponent(column.components, fn, includeAll, path, parent ? component : null));\n }\n });\n }\n else if (info.hasComps) {\n eachComponent(component.components, fn, includeAll, (0, exports.componentFormPath)(component, path, component.path), parent ? component : null);\n }\n }\n });\n}\nexports.eachComponent = eachComponent;\n// Async each component.\nfunction eachComponentAsync(components_2, fn_1) {\n return __awaiter(this, arguments, void 0, function* (components, fn, includeAll = false, path = \"\", parent) {\n var _a, _b;\n if (!components)\n return;\n for (let i = 0; i < components.length; i++) {\n if (!components[i]) {\n continue;\n }\n let component = components[i];\n const info = componentInfo(component);\n // Keep track of parent references.\n if (parent) {\n // Ensure we don't create infinite JSON structures.\n Object.defineProperty(component, 'parent', {\n enumerable: false,\n writable: true,\n value: JSON.parse(JSON.stringify(parent))\n });\n Object.defineProperty(component.parent, 'parent', {\n enumerable: false,\n writable: true,\n value: parent.parent\n });\n Object.defineProperty(component.parent, 'path', {\n enumerable: false,\n writable: true,\n value: parent.path\n });\n delete component.parent.components;\n delete component.parent.componentMap;\n delete component.parent.columns;\n delete component.parent.rows;\n }\n Object.defineProperty(component, 'path', {\n enumerable: false,\n writable: true,\n value: componentPath(component, path)\n });\n if (includeAll || component.tree || !info.layout) {\n if (yield fn(component, component.path, components, parent)) {\n continue;\n }\n }\n if (info.hasColumns) {\n for (let j = 0; j < component.columns.length; j++) {\n yield eachComponentAsync((_a = component.columns[j]) === null || _a === void 0 ? void 0 : _a.components, fn, includeAll, path, parent ? component : null);\n }\n }\n else if (info.hasRows) {\n for (let j = 0; j < component.rows.length; j++) {\n let row = component.rows[j];\n if (Array.isArray(row)) {\n for (let k = 0; k < row.length; k++) {\n yield eachComponentAsync((_b = row[k]) === null || _b === void 0 ? void 0 : _b.components, fn, includeAll, path, parent ? component : null);\n }\n }\n }\n }\n else if (info.hasComps) {\n yield eachComponentAsync(component.components, fn, includeAll, (0, exports.componentFormPath)(component, path, component.path), parent ? component : null);\n }\n }\n });\n}\nexports.eachComponentAsync = eachComponentAsync;\n// Provided components, data, and a key, this will return the components data.\nfunction getComponentData(components, data, path) {\n const compData = { component: null, data: null };\n (0, exports.eachComponentData)(components, data, (component, data, row, compPath) => {\n if (compPath === path) {\n compData.component = component;\n compData.data = row;\n return true;\n }\n });\n return compData;\n}\nexports.getComponentData = getComponentData;\nfunction getComponentActualValue(component, compPath, data, row) {\n var _a;\n // The compPath here will NOT contain the indexes for DataGrids and EditGrids.\n //\n // a[0].b[2].c[3].d\n //\n // Because of this, we will need to determine our parent component path (not data path),\n // and find the \"row\" based comp path.\n //\n // a[0].b[2].c[3].d => a.b.c.d\n //\n let parentInputComponent = null;\n let parent = component;\n while (((_a = parent === null || parent === void 0 ? void 0 : parent.parent) === null || _a === void 0 ? void 0 : _a.path) && !parentInputComponent) {\n parent = parent.parent;\n if (parent.input) {\n parentInputComponent = parent;\n }\n }\n if (parentInputComponent) {\n const parentCompPath = parentInputComponent.path.replace(/\\[[0-9]+\\]/g, '');\n compPath = compPath.replace(parentCompPath, '');\n compPath = (0, lodash_1.trim)(compPath, '. ');\n }\n let value = null;\n if (row) {\n value = (0, lodash_1.get)(row, compPath);\n }\n if (data && (0, lodash_1.isNil)(value)) {\n value = (0, lodash_1.get)(data, compPath);\n }\n if ((0, lodash_1.isNil)(value) || ((0, lodash_1.isObject)(value) && (0, lodash_1.isEmpty)(value))) {\n value = '';\n }\n return value;\n}\nexports.getComponentActualValue = getComponentActualValue;\n/**\n * Determine if a component is a layout component or not.\n *\n * @param {Object} component\n * The component to check.\n *\n * @returns {Boolean}\n * Whether or not the component is a layout component.\n */\nfunction isLayoutComponent(component) {\n return Boolean((component.columns && Array.isArray(component.columns)) ||\n (component.rows && Array.isArray(component.rows)) ||\n (component.components && Array.isArray(component.components)));\n}\nexports.isLayoutComponent = isLayoutComponent;\n/**\n * Matches if a component matches the query.\n *\n * @param component\n * @param query\n * @return {boolean}\n */\nfunction matchComponent(component, query) {\n if ((0, lodash_1.isString)(query)) {\n return (component.key === query) || (component.path === query);\n }\n else {\n let matches = false;\n (0, lodash_1.forOwn)(query, (value, key) => {\n matches = ((0, lodash_1.get)(component, key) === value);\n if (!matches) {\n return false;\n }\n });\n return matches;\n }\n}\nexports.matchComponent = matchComponent;\n/**\n * Get a component by its key\n *\n * @param {Object} components - The components to iterate.\n * @param {String|Object} key - The key of the component to get, or a query of the component to search.\n * @param {boolean} includeAll - Whether or not to include layout components.\n * @returns {Component} - The component that matches the given key, or undefined if not found.\n */\nfunction getComponent(components, key, includeAll = false) {\n let result;\n eachComponent(components, (component, path) => {\n if ((path === key) || (component.path === key) || (component.input && (component.key === key))) {\n result = component;\n return true;\n }\n }, includeAll);\n return result;\n}\nexports.getComponent = getComponent;\n/**\n * Finds a component provided a query of properties of that component.\n *\n * @param components\n * @param query\n * @return {*}\n */\nfunction searchComponents(components, query) {\n const results = [];\n eachComponent(components, (component) => {\n if (matchComponent(component, query)) {\n results.push(component);\n }\n }, true);\n return results;\n}\nexports.searchComponents = searchComponents;\n/**\n * Deprecated version of findComponents. Renamed to searchComponents.\n * @param {import('@formio/core').Component[]} components - The components to find components within.\n * @param {object} query - The query to use when searching for the components.\n * @returns {import('@formio/core').Component[]} - The result of the component that is found.\n */\nfunction findComponents(components, query) {\n console.warn('formio.js/utils findComponents is deprecated. Use searchComponents instead.');\n return searchComponents(components, query);\n}\nexports.findComponents = findComponents;\n/**\n * Remove a component by path.\n *\n * @param components\n * @param path\n */\nfunction removeComponent(components, path) {\n // Using _.unset() leave a null value. Use Array splice instead.\n // @ts-ignore\n var index = path.pop();\n if (path.length !== 0) {\n components = (0, lodash_1.get)(components, path);\n }\n components.splice(index, 1);\n}\nexports.removeComponent = removeComponent;\n/**\n * Returns if this component has a conditional statement.\n *\n * @param component - The component JSON schema.\n *\n * @returns {boolean} - TRUE - This component has a conditional, FALSE - No conditional provided.\n */\nfunction hasCondition(component) {\n return Boolean((component.customConditional) ||\n (component.conditional && (component.conditional.when ||\n component.conditional.json ||\n (component.conditional.conjunction && (0, lodash_1.isBoolean)(component.conditional.show) && !(0, lodash_1.isEmpty)(component.conditional.conditions)))));\n}\nexports.hasCondition = hasCondition;\n/**\n * Extension of standard #parseFloat(value) function, that also clears input string.\n *\n * @param {any} value\n * The value to parse.\n *\n * @returns {Number}\n * Parsed value.\n */\nfunction parseFloatExt(value) {\n return parseFloat((0, lodash_1.isString)(value)\n ? value.replace(/[^\\de.+-]/gi, '')\n : value);\n}\nexports.parseFloatExt = parseFloatExt;\n/**\n * Formats provided value in way how Currency component uses it.\n *\n * @param {any} value\n * The value to format.\n *\n * @returns {String}\n * Value formatted for Currency component.\n */\nfunction formatAsCurrency(value) {\n const parsedValue = parseFloatExt(value);\n if (isNaN(parsedValue)) {\n return '';\n }\n const parts = (0, lodash_1.round)(parsedValue, 2)\n .toString()\n .split('.');\n parts[0] = (0, lodash_1.chunk)(Array.from(parts[0]).reverse(), 3)\n .reverse()\n .map((part) => part\n .reverse()\n .join(''))\n .join(',');\n parts[1] = (0, lodash_1.pad)(parts[1], 2, '0');\n return parts.join('.');\n}\nexports.formatAsCurrency = formatAsCurrency;\n/**\n * Escapes RegEx characters in provided String value.\n *\n * @param {String} value\n * String for escaping RegEx characters.\n * @returns {string}\n * String with escaped RegEx characters.\n */\nfunction escapeRegExCharacters(value) {\n return value.replace(/[-[\\]/{}()*+?.\\\\^$|]/g, '\\\\$&');\n}\nexports.escapeRegExCharacters = escapeRegExCharacters;\n/**\n * Get the value for a component key, in the given submission.\n *\n * @param {Object} submission\n * A submission object to search.\n * @param {String} key\n * A for components API key to search for.\n */\nfunction getValue(submission, key) {\n const search = (data) => {\n if ((0, lodash_1.isPlainObject)(data)) {\n if ((0, lodash_1.has)(data, key)) {\n return (0, lodash_1.get)(data, key);\n }\n let value = null;\n (0, lodash_1.forOwn)(data, (prop) => {\n const result = search(prop);\n if (!(0, lodash_1.isNil)(result)) {\n value = result;\n return false;\n }\n });\n return value;\n }\n else {\n return null;\n }\n };\n return search(submission.data);\n}\nexports.getValue = getValue;\n/**\n * Iterate over all components in a form and get string values for translation.\n * @param form\n */\nfunction getStrings(form) {\n const properties = ['label', 'title', 'legend', 'tooltip', 'description', 'placeholder', 'prefix', 'suffix', 'errorLabel', 'content', 'html'];\n const strings = [];\n eachComponent(form.components, (component) => {\n properties.forEach(property => {\n if (component.hasOwnProperty(property) && component[property]) {\n strings.push({\n key: component.key,\n type: component.type,\n property,\n string: component[property]\n });\n }\n });\n if ((!component.dataSrc || component.dataSrc === 'values') && component.hasOwnProperty('values') && Array.isArray(component.values) && component.values.length) {\n component.values.forEach((value, index) => {\n strings.push({\n key: component.key,\n property: `value[${index}].label`,\n string: component.values[index].label\n });\n });\n }\n // Hard coded values from Day component\n if (component.type === 'day') {\n [\n 'day',\n 'month',\n 'year',\n 'Day',\n 'Month',\n 'Year',\n 'january',\n 'february',\n 'march',\n 'april',\n 'may',\n 'june',\n 'july',\n 'august',\n 'september',\n 'october',\n 'november',\n 'december'\n ].forEach(string => {\n strings.push({\n key: component.key,\n property: 'day',\n string,\n });\n });\n if (component.fields.day.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.day.placeholder',\n string: component.fields.day.placeholder,\n });\n }\n if (component.fields.month.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.month.placeholder',\n string: component.fields.month.placeholder,\n });\n }\n if (component.fields.year.placeholder) {\n strings.push({\n key: component.key,\n property: 'fields.year.placeholder',\n string: component.fields.year.placeholder,\n });\n }\n }\n if (component.type === 'editgrid') {\n const string = component.addAnother || 'Add Another';\n if (component.addAnother) {\n strings.push({\n key: component.key,\n property: 'addAnother',\n string,\n });\n }\n }\n if (component.type === 'select') {\n [\n 'loading...',\n 'Type to search'\n ].forEach(string => {\n strings.push({\n key: component.key,\n property: 'select',\n string,\n });\n });\n }\n }, true);\n return strings;\n}\nexports.getStrings = getStrings;\n// ?????????????????????????\n// questionable section\nfunction generateFormChange(type, data) {\n let change;\n switch (type) {\n case 'add':\n change = {\n op: 'add',\n key: data.component.key,\n container: data.parent.key, // Parent component\n path: data.path, // Path to container within parent component.\n index: data.index, // Index of component in parent container.\n component: data.component\n };\n break;\n case 'edit':\n change = {\n op: 'edit',\n key: data.originalComponent.key,\n patches: (0, fast_json_patch_1.compare)(data.originalComponent, data.component)\n };\n // Don't save if nothing changed.\n if (!change.patches.length) {\n change = null;\n }\n break;\n case 'remove':\n change = {\n op: 'remove',\n key: data.component.key,\n };\n break;\n }\n return change;\n}\nexports.generateFormChange = generateFormChange;\nfunction applyFormChanges(form, changes) {\n const failed = [];\n changes.forEach(function (change) {\n var found = false;\n switch (change.op) {\n case 'add':\n var newComponent = change.component;\n // Find the container to set the component in.\n findComponent(form.components, change.container, null, function (parent) {\n if (!change.container) {\n parent = form;\n }\n // A move will first run an add so remove any existing components with matching key before inserting.\n findComponent(form.components, change.key, null, function (component, path) {\n // If found, use the existing component. (If someone else edited it, the changes would be here)\n newComponent = component;\n removeComponent(form.components, path);\n });\n found = true;\n var container = (0, lodash_1.get)(parent, change.path);\n container.splice(change.index, 0, newComponent);\n });\n break;\n case 'remove':\n findComponent(form.components, change.key, null, function (component, path) {\n found = true;\n const oldComponent = (0, lodash_1.get)(form.components, path);\n if (oldComponent.key !== component.key) {\n path.pop();\n }\n removeComponent(form.components, path);\n });\n break;\n case 'edit':\n findComponent(form.components, change.key, null, function (component, path) {\n found = true;\n try {\n const oldComponent = (0, lodash_1.get)(form.components, path);\n const newComponent = (0, fast_json_patch_1.applyPatch)(component, change.patches).newDocument;\n if (oldComponent.key !== newComponent.key) {\n path.pop();\n }\n (0, lodash_1.set)(form.components, path, newComponent);\n }\n catch (err) {\n failed.push(change);\n }\n });\n break;\n case 'move':\n break;\n }\n if (!found) {\n failed.push(change);\n }\n });\n return {\n form,\n failed\n };\n}\nexports.applyFormChanges = applyFormChanges;\n/**\n* This function will find a component in a form and return the component AND THE PATH to the component in the form.\n* Path to the component is stored as an array of nested components and their indexes.The Path is being filled recursively\n* when you iterating through the nested structure.\n* If the component is not found the callback won't be called and function won't return anything.\n*\n* @param components\n* @param key\n* @param fn\n* @param path\n* @returns {*}\n*/\nfunction findComponent(components, key, path, fn) {\n if (!components)\n return;\n path = path || [];\n if (!key) {\n return fn(components);\n }\n components.forEach(function (component, index) {\n var newPath = path.slice();\n // Add an index of the component it iterates through in nested structure\n newPath.push(index);\n if (!component)\n return;\n if (component.hasOwnProperty('columns') && Array.isArray(component.columns)) {\n newPath.push('columns');\n component.columns.forEach(function (column, index) {\n var colPath = newPath.slice();\n colPath.push(index);\n colPath.push('components');\n findComponent(column.components, key, colPath, fn);\n });\n }\n if (component.hasOwnProperty('rows') && Array.isArray(component.rows)) {\n newPath.push('rows');\n component.rows.forEach(function (row, index) {\n var rowPath = newPath.slice();\n rowPath.push(index);\n row.forEach(function (column, index) {\n var colPath = rowPath.slice();\n colPath.push(index);\n colPath.push('components');\n findComponent(column.components, key, colPath, fn);\n });\n });\n }\n if (component.hasOwnProperty('components') && Array.isArray(component.components)) {\n newPath.push('components');\n findComponent(component.components, key, newPath, fn);\n }\n if (component.key === key) {\n //Final callback if the component is found\n fn(component, newPath, components);\n }\n });\n}\nexports.findComponent = findComponent;\nconst isCheckboxComponent = (component) => component.type === 'checkbox';\nconst isDataGridComponent = (component) => component.type === 'datagrid';\nconst isEditGridComponent = (component) => component.type === 'editgrid';\nconst isDataTableComponent = (component) => component.type === 'datatable';\nconst hasChildComponents = (component) => component.components != null;\nconst isDateTimeComponent = (component) => component.type === 'datetime';\nconst isSelectBoxesComponent = (component) => component.type === 'selectboxes';\nconst isTextAreaComponent = (component) => component.type === 'textarea';\nconst isTextFieldComponent = (component) => component.type === 'textfield';\nfunction getEmptyValue(component) {\n switch (component.type) {\n case 'textarea':\n case 'textfield':\n case 'time':\n case 'datetime':\n case 'day':\n return '';\n case 'datagrid':\n case 'editgrid':\n return [];\n default:\n return null;\n }\n}\nexports.getEmptyValue = getEmptyValue;\nconst replaceBlanks = (value) => {\n const nbsp = '<p> </p>';\n const br = '<p><br></p>';\n const brNbsp = '<p><br> </p>';\n const regExp = new RegExp(`^${nbsp}|${nbsp}$|^${br}|${br}$|^${brNbsp}|${brNbsp}$`, 'g');\n return typeof value === 'string' ? value.replace(regExp, '').trim() : value;\n};\nfunction trimBlanks(value) {\n if (!value) {\n return value;\n }\n if (Array.isArray(value)) {\n value = value.map((val) => replaceBlanks(val));\n }\n else {\n value = replaceBlanks(value);\n }\n return value;\n}\nfunction isValueEmpty(component, value) {\n const compValueIsEmptyArray = ((0, lodash_1.isArray)(value) && value.length === 1) ? (0, lodash_1.isEqual)(value[0], getEmptyValue(component)) : false;\n return value == null || value === '' || ((0, lodash_1.isArray)(value) && value.length === 0) || compValueIsEmptyArray;\n}\nfunction isComponentDataEmpty(component, data, path) {\n var _a;\n const value = (0, lodash_1.get)(data, path);\n if (isCheckboxComponent(component)) {\n return isValueEmpty(component, value) || value === false;\n }\n else if (isDataGridComponent(component) || isEditGridComponent(component) || isDataTableComponent(component) || hasChildComponents(component)) {\n if ((_a = component.components) === null || _a === void 0 ? void 0 : _a.length) {\n let childrenEmpty = true;\n // wrap component in an array to let eachComponentData handle introspection to child components (e.g. this will be different\n // for data grids versus nested forms, etc.)\n (0, exports.eachComponentData)([component], data, (thisComponent, data, row, path, components, index) => {\n if (component.key === thisComponent.key)\n return;\n if (!isComponentDataEmpty(thisComponent, data, path)) {\n childrenEmpty = false;\n }\n });\n return isValueEmpty(component, value) || childrenEmpty;\n }\n return isValueEmpty(component, value);\n }\n else if (isDateTimeComponent(component)) {\n return isValueEmpty(component, value) || value.toString() === 'Invalid date';\n }\n else if (isSelectBoxesComponent(component)) {\n let selectBoxEmpty = true;\n for (const key in value) {\n if (value[key]) {\n selectBoxEmpty = false;\n break;\n }\n }\n return isValueEmpty(component, value) || selectBoxEmpty;\n }\n else if (isTextAreaComponent(component)) {\n const isPlain = !component.wysiwyg && !component.editor;\n return isPlain ? typeof value === 'string' ? isValueEmpty(component, value.trim()) : isValueEmpty(component, value) : isValueEmpty(component, trimBlanks(value));\n }\n else if (isTextFieldComponent(component)) {\n if (component.allowMultipleMasks && !!component.inputMasks && !!component.inputMasks.length) {\n return isValueEmpty(component, value) || (component.multiple ? value.length === 0 : (!value.maskName || !value.value));\n }\n return isValueEmpty(component, value === null || value === void 0 ? void 0 : value.toString().trim());\n }\n return isValueEmpty(component, value);\n}\nexports.isComponentDataEmpty = isComponentDataEmpty;\n\n\n//# sourceURL=webpack://Formio/./node_modules/@formio/core/lib/utils/formUtil.js?");
|
1339
1339
|
|
1340
1340
|
/***/ }),
|
1341
1341
|
|