@davebaol/angular-formio-editor
Version:
Angular component integrating Form.io builder and renderer with a json editor
1,286 lines (1,272 loc) • 83.5 kB
JavaScript
import { __values, __extends, __decorate } from 'tslib';
import { Input, ViewChild, Component as Component$1, EventEmitter, Output, NgModule } from '@angular/core';
import { BsModalService, ModalModule } from 'ngx-bootstrap/modal';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { FormioModule } from 'angular-formio';
import { AlertModule } from 'ngx-bootstrap/alert';
import JsonEditor from 'jsoneditor';
var _this = this;
/*
This is heavily inspired by https://github.com/schnittstabil/merge-options
*/
var _a = Object.prototype, hasOwnProperty = _a.hasOwnProperty, toString = _a.toString;
var propertyIsEnumerable = Object.propertyIsEnumerable;
var globalThis = this;
var defaultMergeOpts = { ignoreUndefined: false };
var isPlainObject = function (value) {
if (toString.call(value) !== '[object Object]') {
return false;
}
var prototype = Object.getPrototypeOf(value);
return prototype === null || prototype === Object.prototype;
};
var ɵ0 = isPlainObject;
var defineProperty = function (obj, name, value) {
Object.defineProperty(obj, name, {
value: value,
writable: true,
enumerable: true,
configurable: true
});
};
var ɵ1 = defineProperty;
var getEnumerableOwnPropertyKeys = function (value) {
var e_1, _a;
var keys = [];
for (var key in value) {
if (hasOwnProperty.call(value, key)) {
keys.push(key);
}
}
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(value);
try {
for (var symbols_1 = __values(symbols), symbols_1_1 = symbols_1.next(); !symbols_1_1.done; symbols_1_1 = symbols_1.next()) {
var symbol = symbols_1_1.value;
if (propertyIsEnumerable.call(value, symbol)) {
keys.push(symbol);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (symbols_1_1 && !symbols_1_1.done && (_a = symbols_1.return)) _a.call(symbols_1);
}
finally { if (e_1) throw e_1.error; }
}
}
return keys;
};
var ɵ2 = getEnumerableOwnPropertyKeys;
var clone = function (value) {
if (Array.isArray(value)) {
return cloneArray(value);
}
if (isPlainObject(value)) {
return clonePlainObject(value);
}
return value;
};
var cloneArray = function (array) {
var result = array.slice(0, 0);
getEnumerableOwnPropertyKeys(array).forEach(function (key) {
defineProperty(result, key, clone(array[key]));
});
return result;
};
var ɵ3 = cloneArray;
var clonePlainObject = function (obj) {
var result = Object.getPrototypeOf(obj) === null ? Object.create(null) : {};
getEnumerableOwnPropertyKeys(obj).forEach(function (key) {
defineProperty(result, key, clone(obj[key]));
});
return result;
};
var ɵ4 = clonePlainObject;
var mergeKeys = function (merged, source, keys, config) {
keys.forEach(function (key) {
if (typeof source[key] === 'undefined' && config.ignoreUndefined) {
return;
}
// Do not recurse into prototype chain of merged
if (key in merged && merged[key] !== Object.getPrototypeOf(merged)) {
defineProperty(merged, key, _merge(merged[key], source[key], config));
}
else {
defineProperty(merged, key, clone(source[key]));
}
});
return merged;
};
var ɵ5 = mergeKeys;
// tslint:disable-next-line:variable-name
var _merge = function (merged, source, config) {
if (!isPlainObject(source) || !isPlainObject(merged)) {
return clone(source);
}
return mergeKeys(merged, source, getEnumerableOwnPropertyKeys(source), config);
};
var ɵ6 = _merge;
var merge = function () {
var e_2, _a;
var options = [];
for (var _i = 0; _i < arguments.length; _i++) {
options[_i] = arguments[_i];
}
var config = _merge(clone(defaultMergeOpts), (_this !== globalThis && _this) || {}, defaultMergeOpts);
var merged = { _: {} };
try {
for (var options_1 = __values(options), options_1_1 = options_1.next(); !options_1_1.done; options_1_1 = options_1.next()) {
var option = options_1_1.value;
if (option === undefined) {
continue;
}
if (!isPlainObject(option)) {
throw new TypeError('`' + option + '` is not a plain Object');
}
merged = _merge(merged, { _: option }, config);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (options_1_1 && !options_1_1.done && (_a = options_1.return)) _a.call(options_1);
}
finally { if (e_2) throw e_2.error; }
}
return merged._;
};
var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
// -------------------------------
// SCHEMAS
// -------------------------------
var Schema = /** @class */ (function () {
function Schema(component) {
this.component = component;
this.conditions = [];
this.required = false;
this.dataType = {};
if (component && component.formioComponent) {
if (component.formioComponent.conditional) {
// Add non-empty condition from the component
var cnd = component.formioComponent.conditional;
if (typeof cnd.show === 'boolean' && cnd.when) {
// console.log(component.formioComponent.type, "Pushing condition")
var c = { show: cnd.show, when: cnd.when, eq: cnd.eq };
c.key = this.generateSingleConditionKey(c);
this.conditions.push(c);
}
}
if (component.formioComponent.validate) {
this.required = component.formioComponent.validate.required;
}
}
}
/*private*/ Schema.prototype.generateSingleConditionKey = function (condition) {
return JSON.stringify(condition);
};
/*private*/ Schema.prototype.generateConditionsKey = function () {
return JSON.stringify(this.conditions, function (k, v) { return k === 'key' ? undefined : v; });
};
Schema.prototype.prepareConditions = function () {
// Ensure the array has unique conditions
this.conditions = this.conditions.sort(function (c1, c2) { return c1.key.compare(c2.key); })
.filter(function (x, i, a) { return i === 0 || x.key !== a[i - 1].key; });
this.conditions.key = this.generateConditionsKey();
};
Schema.prototype.shrink = function () {
for (var k in this.properties) {
if (hasOwnProperty$1.call(this.properties, k)) {
var propSchema = this.properties[k];
if (propSchema instanceof MergeableObjectSchema && propSchema.component && propSchema.component.shrinkable()) {
// console.log('Shrink', propSchema.component.formioComponent.type);
propSchema.shrink();
delete this.properties[k]; // Remove shribkable schema from parent
this.merge(propSchema); // merge its properties and conditions with parent
}
}
}
return this;
};
// Subclasses overriding this method MUST call super.toJsonSchema()
Schema.prototype.toJsonSchema = function () {
return Object.assign({}, this.dataType);
};
return Schema;
}());
var ObjectSchema = /** @class */ (function (_super) {
__extends(ObjectSchema, _super);
function ObjectSchema(component) {
var _this = _super.call(this, component) || this;
_this.dataType.type = 'object';
_this.properties = {};
return _this;
}
ObjectSchema.prototype.addProperty = function (name, schema, required) {
this.properties[name] = schema;
schema.required = required;
return this;
};
ObjectSchema.prototype.toJsonSchema = function () {
var jsonSchema = _super.prototype.toJsonSchema.call(this);
jsonSchema.properties = {};
var required = [];
var condPropMap = {};
var conditionsMap = {};
for (var pk in this.properties) {
if (hasOwnProperty$1.call(this.properties, pk)) {
var childSchema = this.properties[pk];
if (childSchema.conditions.length === 0) {
if (childSchema.required) {
required.push(pk);
}
jsonSchema.properties[pk] = childSchema.toJsonSchema();
continue;
}
childSchema.prepareConditions();
var ck = childSchema.conditions.key;
conditionsMap[ck] = childSchema.conditions;
if (!(ck in condPropMap)) {
condPropMap[ck] = {};
}
condPropMap[ck][pk] = childSchema;
}
}
// Add required to jsonSchema if not empty
if (required.length > 0) {
jsonSchema.required = required;
}
// Generate allOf from conditional properties
var allOf = [];
for (var ck in condPropMap) {
if (hasOwnProperty$1.call(condPropMap, ck)) {
var conds = conditionsMap[ck];
var _if = {
properties: conds.reduce(function (acc, c) {
acc[c.when] = c.show ? { const: c.eq } : { not: { const: c.eq } };
return acc;
}, {})
};
var then = { required: [], properties: {} };
for (var pk in condPropMap[ck]) {
if (hasOwnProperty$1.call(condPropMap[ck], pk)) {
var childSchema = condPropMap[ck][pk];
if (childSchema.required) {
then.required.push(pk);
}
then.properties[pk] = childSchema.toJsonSchema();
}
}
// Remove empty required
if (then.required.length === 0) {
delete then.required;
}
// Add if/then to allOf
allOf.push({ if: _if, then: then });
}
}
// Add allOf to jsonSchema if not empty
if (allOf.length > 0) {
jsonSchema.allOf = allOf;
}
return jsonSchema;
};
return ObjectSchema;
}(Schema));
var MergeableObjectSchema = /** @class */ (function (_super) {
__extends(MergeableObjectSchema, _super);
function MergeableObjectSchema(component) {
return _super.call(this, component) || this;
}
MergeableObjectSchema.prototype.merge = function () {
var sources = [];
for (var _i = 0; _i < arguments.length; _i++) {
sources[_i] = arguments[_i];
}
var targetProps = this.properties;
for (var i = 0, len = sources.length; i < len; i++) {
var source = sources[i];
if (source instanceof MergeableObjectSchema) {
// merge properties
var sourceProps = source.properties;
for (var key in sourceProps) {
if (hasOwnProperty$1.call(sourceProps, key)) {
// Append source schema conditions to the conditions of its sub-schemas
Array.prototype.push.apply(sourceProps[key].conditions, source.conditions);
// Merge properties recursively
if (targetProps[key] && sourceProps[key] instanceof MergeableObjectSchema) {
targetProps[key].merge(sourceProps[key]);
}
else {
targetProps[key] = sourceProps[key];
}
}
}
}
}
return this;
};
return MergeableObjectSchema;
}(ObjectSchema));
var ArraySchema = /** @class */ (function (_super) {
__extends(ArraySchema, _super);
function ArraySchema(component, items) {
var _this = _super.call(this, component) || this;
_this.dataType.type = 'array';
_this.dataType.items = items;
return _this;
}
ArraySchema.prototype.toJsonSchema = function () {
var jsonSchema = _super.prototype.toJsonSchema.call(this);
jsonSchema.items = this.dataType.items.toJsonSchema();
return jsonSchema;
};
return ArraySchema;
}(Schema));
var PrimitiveSchema = /** @class */ (function (_super) {
__extends(PrimitiveSchema, _super);
function PrimitiveSchema(component, type) {
var _this = _super.call(this, component) || this;
_this.dataType.type = type;
return _this;
}
return PrimitiveSchema;
}(Schema));
var BooleanSchema = /** @class */ (function (_super) {
__extends(BooleanSchema, _super);
function BooleanSchema(component) {
return _super.call(this, component, 'boolean') || this;
}
return BooleanSchema;
}(PrimitiveSchema));
var NumberSchema = /** @class */ (function (_super) {
__extends(NumberSchema, _super);
function NumberSchema(component) {
var _this = _super.call(this, component, 'number') || this;
if (component && component.formioComponent && component.formioComponent.validate) {
var validate = component.formioComponent.validate;
if (validate.min || typeof validate.min === 'number')
_this.dataType.minimum = Number(validate.min);
if (validate.max || typeof validate.max === 'number')
_this.dataType.maximum = Number(validate.max);
if (validate.integer)
_this.dataType.type = 'integer';
}
return _this;
}
return NumberSchema;
}(PrimitiveSchema));
var StringSchema = /** @class */ (function (_super) {
__extends(StringSchema, _super);
function StringSchema(component) {
var _this = _super.call(this, component, 'string') || this;
if (component && component.formioComponent && component.formioComponent.validate) {
var validate = component.formioComponent.validate;
if (validate.minLength)
_this.dataType.minLength = Number(validate.minLength);
if (validate.maxLength)
_this.dataType.maxLength = Number(validate.maxLength);
if (validate.pattern)
_this.dataType.pattern = validate.pattern;
}
return _this;
}
return StringSchema;
}(PrimitiveSchema));
var EnumSchema = /** @class */ (function (_super) {
__extends(EnumSchema, _super);
function EnumSchema(component, values) {
var _this = _super.call(this, component) || this;
_this.dataType.enum = values;
return _this;
}
return EnumSchema;
}(Schema));
// -------------------------------
// COMPONENT BASE CLASSES
// -------------------------------
var Component = /** @class */ (function () {
function Component(formioComponent) {
this.formioComponent = formioComponent;
}
Component.prototype.schema = function () {
throw new Error('Subclasses of \'Component\' have to implement the method \'schema\'!');
};
// Layout components are view-only components. From resource perspective, they are to be
// shrinked, because they don't have any value neither implicit nor expressed by user.
// So they don't contribute to the underlying resource because their 'API key' does not
// match any field inside the resource itself.
// Howewer, shrink process propagates component's condition (show/when/eq) to child components.
Component.prototype.shrinkable = function () {
return !(this.formioComponent && this.formioComponent.input);
};
return Component;
}());
var AtomicComponent = /** @class */ (function (_super) {
__extends(AtomicComponent, _super);
function AtomicComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
AtomicComponent.prototype.schema = function () {
var schema = this.baseSchema();
if (this.formioComponent.multiple) {
if (this.formioComponent.validate && !this.formioComponent.validate.required) {
// With multiple values enabled the component can generate null items if required is false
schema.dataType = { anyOf: [schema.dataType, { type: 'null' }] };
}
return new ArraySchema(this, schema);
}
return schema;
};
AtomicComponent.prototype.baseSchema = function () {
throw new Error('Subclasses of \'AtomicComponent\' have to implement the method \'baseSchema\'!');
};
AtomicComponent.prototype.isDefaultCastToString = function () {
return false; // cast defaults to 'auto'
};
AtomicComponent.prototype.cast = function (val, to) {
switch (to) {
case 'boolean':
return val.toLowerCase() === 'true';
case 'number':
return Number(val);
case 'object':
return JSON.parse(val);
case 'string':
return val;
case 'auto':
default: // Either autotype or string
if (to !== 'auto' && this.isDefaultCastToString())
return val;
if (val === "true")
return true;
if (val === "false")
return false;
if (val === "")
return val;
var v = Number(val);
return isNaN(v) ? val : v;
}
};
return AtomicComponent;
}(Component));
var CompoundComponent = /** @class */ (function (_super) {
__extends(CompoundComponent, _super);
function CompoundComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
CompoundComponent.prototype.schema = function () {
var schema = new MergeableObjectSchema(this);
this.childrenSchema(schema);
return schema.shrink();
};
/*prorected*/ CompoundComponent.prototype.children = function () {
return this.formioComponent.components;
};
// Subclasses can override this method to provide a default class
// for children that don't have a type
/*prorected*/ CompoundComponent.prototype.defaultChildClass = function () {
return undefined;
};
/*prorected*/ CompoundComponent.prototype.childrenSchema = function (parentSchema) {
var children = this.children();
for (var i = 0, len = children.length; i < len; i++) {
var c = children[i];
// console.log(this.formioComponent.type, 'child', c)
var type = MAP[c.type] || this.defaultChildClass();
if (type) {
var schema = new (type)(c).schema();
var required = c.validate && c.validate.required;
// Dotted key means nested schema
var keyParts = c.key.split('.');
for (var j = keyParts.length - 1; j > 0; j--) {
schema = new MergeableObjectSchema(undefined).addProperty(keyParts[j], schema, required);
}
parentSchema.merge(new MergeableObjectSchema(undefined).addProperty(keyParts[0], schema, required));
}
else {
// console.log(this.formioComponent.type, ": skipping child with unknown type", c.type);
}
}
return parentSchema;
};
return CompoundComponent;
}(Component));
// -------------------------------
// ABSTRACT COMPONENT CLASSES
// -------------------------------
var StringComponent = /** @class */ (function (_super) {
__extends(StringComponent, _super);
function StringComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
StringComponent.prototype.baseSchema = function () {
return new StringSchema(this);
};
return StringComponent;
}(AtomicComponent));
var EnumComponent = /** @class */ (function (_super) {
__extends(EnumComponent, _super);
function EnumComponent(formioComponent) {
var additionalValuesIfNotRequired = [];
for (var _i = 1; _i < arguments.length; _i++) {
additionalValuesIfNotRequired[_i - 1] = arguments[_i];
}
var _this = _super.call(this, formioComponent) || this;
_this.additionalValuesIfNotRequired = additionalValuesIfNotRequired;
return _this;
}
// This is needed because different components take values from different path
EnumComponent.prototype.values = function () {
throw new Error('Subclasses of \'EnumComponent\' have to implement the method \'values\'!');
};
EnumComponent.prototype.baseSchema = function () {
var _this = this;
var values = this.values().map(function (v) { return _this.cast(v.value, _this.formioComponent.dataType); });
if (this.formioComponent && this.formioComponent.validate && !this.formioComponent.validate.required) {
Array.prototype.push.apply(values, this.additionalValuesIfNotRequired);
}
return new EnumSchema(this, values);
};
return EnumComponent;
}(AtomicComponent));
// -------------------------------
// BASIC COMPONENTS
// -------------------------------
var CheckboxComponent = /** @class */ (function (_super) {
__extends(CheckboxComponent, _super);
function CheckboxComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
CheckboxComponent.prototype.baseSchema = function () {
return new BooleanSchema(this);
};
return CheckboxComponent;
}(AtomicComponent));
var NumberComponent = /** @class */ (function (_super) {
__extends(NumberComponent, _super);
function NumberComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
NumberComponent.prototype.baseSchema = function () {
return new NumberSchema(this);
};
return NumberComponent;
}(AtomicComponent));
var PasswordComponent = /** @class */ (function (_super) {
__extends(PasswordComponent, _super);
function PasswordComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return PasswordComponent;
}(StringComponent));
var RadioComponent = /** @class */ (function (_super) {
__extends(RadioComponent, _super);
function RadioComponent(formioComponent) {
// Empty string and null are valid values if the component is not required
return _super.call(this, formioComponent, '', null) || this;
}
RadioComponent.prototype.values = function () {
return this.formioComponent.values;
};
return RadioComponent;
}(EnumComponent));
var SelectComponent = /** @class */ (function (_super) {
__extends(SelectComponent, _super);
function SelectComponent(formioComponent) {
// Empty string and null are valid values if the component is not required
return _super.call(this, formioComponent, '', null) || this;
}
SelectComponent.prototype.values = function () {
return this.formioComponent.data.values;
};
SelectComponent.prototype.schema = function () {
var schema = _super.prototype.schema.call(this);
// If multiple values are enabled ensure uniqueness
if (schema instanceof ArraySchema) {
schema.dataType.uniqueItems = true;
}
return schema;
};
SelectComponent.prototype.isDefaultCastToString = function () {
return true; // cast defaults to 'string'
};
return SelectComponent;
}(EnumComponent));
var SelectBoxesComponent = /** @class */ (function (_super) {
__extends(SelectBoxesComponent, _super);
function SelectBoxesComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
SelectBoxesComponent.prototype.baseSchema = function () {
var schema = new ObjectSchema(this);
schema.dataType.additionalProperties = false;
var values = this.formioComponent.values
.forEach(function (v) { return schema.addProperty(v.value, new BooleanSchema(undefined), true); });
if (this.formioComponent.validate && !this.formioComponent.validate.required) {
// This is needed for compatibility.
// Formio adds a boolean property with name "" when the component is not required.
// The property itself must not be required
schema.addProperty('', new BooleanSchema(undefined), false);
}
return schema;
};
return SelectBoxesComponent;
}(AtomicComponent));
var TextAreaComponent = /** @class */ (function (_super) {
__extends(TextAreaComponent, _super);
function TextAreaComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return TextAreaComponent;
}(StringComponent));
var TextFieldComponent = /** @class */ (function (_super) {
__extends(TextFieldComponent, _super);
function TextFieldComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return TextFieldComponent;
}(StringComponent));
// -------------------------------
// ADVANCED COMPONENTS
// -------------------------------
var DateTimeComponent = /** @class */ (function (_super) {
__extends(DateTimeComponent, _super);
function DateTimeComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return DateTimeComponent;
}(StringComponent));
var EmailComponent = /** @class */ (function (_super) {
__extends(EmailComponent, _super);
function EmailComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return EmailComponent;
}(StringComponent));
var UrlComponent = /** @class */ (function (_super) {
__extends(UrlComponent, _super);
function UrlComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return UrlComponent;
}(StringComponent));
var TagsComponent = /** @class */ (function (_super) {
__extends(TagsComponent, _super);
function TagsComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
TagsComponent.prototype.schema = function () {
return this.formioComponent.storeas === 'array' ?
new ArraySchema(this, this.baseSchema())
: this.baseSchema();
};
TagsComponent.prototype.baseSchema = function () {
return new StringSchema(this);
};
return TagsComponent;
}(AtomicComponent));
// -------------------------------
// LAYOUT COMPONENTS
// -------------------------------
var ColumnsComponent = /** @class */ (function (_super) {
__extends(ColumnsComponent, _super);
function ColumnsComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
// Determines children from columns.
// Children are calculated lazily and cached into this instance.
ColumnsComponent.prototype.children = function () {
var _this = this;
if (!this.components) {
this.components = [];
this.formioComponent.columns.forEach(function (col) { return Array.prototype.push.apply(_this.components, col.components); });
}
return this.components;
};
return ColumnsComponent;
}(CompoundComponent));
var ContentComponent = /** @class */ (function (_super) {
__extends(ContentComponent, _super);
function ContentComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
ContentComponent.prototype.children = function () {
return []; // This component never has children
};
return ContentComponent;
}(CompoundComponent));
var FieldSetComponent = /** @class */ (function (_super) {
__extends(FieldSetComponent, _super);
function FieldSetComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return FieldSetComponent;
}(CompoundComponent));
var PanelComponent = /** @class */ (function (_super) {
__extends(PanelComponent, _super);
function PanelComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return PanelComponent;
}(CompoundComponent));
var TableComponent = /** @class */ (function (_super) {
__extends(TableComponent, _super);
function TableComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
// Determines children from table's rows and columns.
// Children are calculated lazily and cached into this instance.
TableComponent.prototype.children = function () {
var _this = this;
if (!this.components) {
this.components = [];
this.formioComponent.rows.forEach(function (row) {
row.forEach(function (col) { return Array.prototype.push.apply(_this.components, col.components); });
});
}
return this.components;
};
return TableComponent;
}(CompoundComponent));
var TabsComponent = /** @class */ (function (_super) {
__extends(TabsComponent, _super);
function TabsComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
/*prorected*/ TabsComponent.prototype.defaultChildClass = function () {
return CompoundComponent; // Needed because children don't have a type :(
};
return TabsComponent;
}(CompoundComponent));
var WellComponent = /** @class */ (function (_super) {
__extends(WellComponent, _super);
function WellComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return WellComponent;
}(CompoundComponent));
// -------------------------------
// DATA COMPONENTS
// -------------------------------
var EditGridComponent = /** @class */ (function (_super) {
__extends(EditGridComponent, _super);
function EditGridComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
EditGridComponent.prototype.schema = function () {
return new ArraySchema(this, _super.prototype.schema.call(this));
};
return EditGridComponent;
}(CompoundComponent));
// -------------------------------
// FORM COMPONENT
// -------------------------------
var FormComponent = /** @class */ (function (_super) {
__extends(FormComponent, _super);
function FormComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return FormComponent;
}(CompoundComponent));
var MAP = {
editgrid: EditGridComponent,
checkbox: CheckboxComponent,
columns: ColumnsComponent,
content: ContentComponent,
datetime: DateTimeComponent,
email: EmailComponent,
fieldset: FieldSetComponent,
number: NumberComponent,
password: PasswordComponent,
panel: PanelComponent,
radio: RadioComponent,
select: SelectComponent,
selectboxes: SelectBoxesComponent,
table: TableComponent,
tabs: TabsComponent,
tags: TagsComponent,
textarea: TextAreaComponent,
textfield: TextFieldComponent,
url: UrlComponent,
well: WellComponent
};
function generateFormJsonSchema(form) {
return new FormComponent(form).schema().toJsonSchema();
}
// tslint:disable:object-literal-key-quotes quotemark semicolon
var schema = {
"title": "Form",
"description": "Object containing a form.io form",
"type": "object",
"required": ["components"],
"properties": {
"display": {
"title": "Display mode",
"description": "The given name.",
"enum": ["form", "wizard"]
},
"components": {
"$ref": "components"
}
}
};
// tslint:disable:object-literal-key-quotes quotemark semicolon
var components = {
"title": "Component List",
"description": "The list of all components",
"type": "array",
"items": {
"$ref": "component"
}
};
// tslint:disable:object-literal-key-quotes quotemark semicolon
var componentStrict = {
"title": "Component",
"description": "Object containing a form.io component",
"type": "object",
"required": ["type", "key", "input"],
"properties": {
"type": {
"title": "Component Type",
"description": "The type of this component",
"type": "string"
},
"key": {
"title": "Component Key",
"description": "The API key for this component",
"type": "string"
},
"label": {
"title": "Component Label",
"description": "The HTML label to give this component",
"type": "string"
},
"placeholder": {
"title": "Component Placeholder",
"description": "The text to show in the input before they type",
"type": "string"
},
"input": {
"title": "User Input?",
"description": "Determines if this is an input from the user",
"type": "boolean"
},
"tableView": {
"title": "Component TableView",
"description": "Determines if this field will show in the data tables output",
"type": "boolean"
},
"multiple": {
"title": "Component Multiple",
"description": "If this field should collect multiple values, creating an array of values",
"type": "boolean"
},
"protected": {
"title": "Component Protected",
"description": "If the value of this field should be shown to the end user via API once it is saved",
"type": "boolean"
},
"prefix": {
"title": "Component Prefix",
"description": "The prefix text to put in front of the input",
"type": "string"
},
"suffix": {
"title": "Component Suffix",
"description": "The suffix text to put after the input",
"type": "string"
},
"defaultValue": {
"title": "Default Value",
"description": "The default value to provide to this component. Its type depends on the specific component"
},
"clearOnHide": {
"title": "Clear on Hide",
"description": "If the value of this field should be cleared when it is conditionally hidden",
"type": "boolean"
},
"unique": {
"title": "Unique",
"description": "Validates if this field should be unique amongst other submissions in the same form",
"type": "boolean"
},
"persistent": {
"title": "Persistent",
"description": "Determines if the value of this field should be saved as persistent",
"type": "boolean"
},
"hidden": {
"title": "Hidden",
"description": "Determines if this field should be hidden from view by default. This can be overridden with the conditionals.",
"type": "boolean"
},
"validate": {
"title": "Validate",
"description": "Determines validation criteria for this component.",
"type": "object",
"properties": {
"required": {
"title": "Required",
"description": "Specifies if the field is required.",
"type": "boolean"
},
"minLength": {
"title": "Min Lenngth",
"description": "For text input, this checks the minimum length of text for valid input.",
"type": ["number", "string"]
},
"maxLength": {
"title": "Max Lenngth",
"description": "For text input, this checks the maximum length of text for valid input.",
"type": ["number", "string"]
},
"pattern": {
"title": "Pattern",
"description": "For text input, this checks the text agains a Regular expression pattern.",
"type": "string"
},
"custom": {
"title": "Custom",
"description": "A custom javascript based validation or a JSON object for using JSON Logic.",
"type": ["string", "object"]
}
}
},
"conditional": {
"$ref": "conditional"
},
"errors": {
"title": "Errors",
"description": "Allows customizable errors to be displayed for each component when an error occurs.",
"type": "object",
"properties": {
"required": {
"title": "Required",
"description": "Error message for error 'required'.",
"type": "string"
},
"min": {
"title": "Min",
"description": "Error message for error 'min'.",
"type": "string"
},
"max": {
"title": "Min",
"description": "Error message for error 'max'.",
"type": "string"
},
"minLength": {
"title": "Min Length",
"description": "Error message for error 'minLength'.",
"type": "string"
},
"maxLength": {
"title": "Max Length",
"description": "Error message for error 'maxLength'.",
"type": "string"
},
"invalid_email": {
"title": "Invalid Email",
"description": "Error message for error 'invalid_email'.",
"type": "string"
},
"invalid_date": {
"title": "Invalid Date",
"description": "Error message for error 'invalid_date'.",
"type": "string"
},
"pattern": {
"title": "Pattern",
"description": "Error message for error 'pattern'.",
"type": "string"
},
"custom": {
"title": "Custom",
"description": "Error message for error 'custom'.",
"type": ["string", "object"]
}
}
},
"logic": {
"title": "Logic",
"description": "Allows changing the component definition in reaction to data entered in a form. For example, changing a field to required, disabled or hidden when a value is entered.",
"type": "array",
"items": {
"$ref": "logic"
}
}
},
"allOf": [
{
"if": { "properties": { "type": { "const": "columns" } } },
"then": { "$ref": "columns" }
},
{
"if": { "properties": { "type": { "const": "table" } } },
"then": { "$ref": "table" }
},
{
"if": { "properties": { "type": { "const": "tabs" } } },
"then": { "$ref": "tabs" },
"else": {
"properties": {
"components": {
"$ref": "components"
}
}
}
}
]
};
var componentLoose = Object.assign({}, componentStrict, { required: ['type'] });
// tslint:disable:object-literal-key-quotes quotemark semicolon
var logic = {
"title": "Logic",
"description": "...",
"type": "object",
"required": ["trigger", "actions"],
"properties": {
"trigger": {
"$ref": "trigger"
},
"actions": {
"title": "Actions",
"description": "The actions to perform when the logic is triggered",
"type": "array",
"items": {
"$ref": "action"
}
}
}
};
// tslint:disable:object-literal-key-quotes quotemark semicolon
var trigger = {
"title": "Trigger",
"description": "Determines when the logic should be triggered",
"type": "object",
"required": ["type"],
"properties": {
"type": {
"title": "Type",
"description": "The type of the trigger.",
"enum": ["simple", "javascript", "json", "event"]
}
},
"allOf": [
{
"if": {
"properties": { "type": { "const": "simple" } }
},
"then": {
"required": ["simple"],
"properties": {
"simple": {
"title": "Simple",
"description": "Defines a simple trigger.",
"required": ["when", "eq", "show"],
"type": "object",
"properties": {
"when": {
"title": "When",
"description": "The trigger field key.",
"type": "string"
},
"eq": {
"title": "Eq",
"description": "The value to equal.",
"type": "string"
},
"show": {
"title": "Show",
"description": "Whether to trigger or not when the value is equal.",
"type": "boolean"
}
}
}
}
}
},
{
"if": {
"properties": { "type": { "const": "javascript" } }
},
"then": {
"required": ["javascript"],
"properties": {
"javascript": {
"title": "Javascript",
"description": "Javascript logic.",
"type": "string"
}
}
}
},
{
"if": {
"properties": { "type": { "const": "json" } }
},
"then": {
"required": ["json"],
"properties": {
"json": {
"title": "Json",
"description": "JSON Logic object that returns true or false.",
"type": "object"
}
}
}
},
{
"if": {
"properties": { "type": { "const": "event" } }
},
"then": {
"required": ["event"],
"properties": {
"event": {
"title": "Event",
"description": "The name of the event that will trigger this logic.",
"type": "string"
}
}
}
}
]
};
// tslint:disable:object-literal-key-quotes quotemark semicolon
var action = {
"title": "Action",
"description": "An action to perform when the logic is triggered",
"required": ["type"],
"type": "object",
"properties": {
"type": {
"title": "Type",
"description": "The type of the action.",
"enum": ["property", "value"]
}
},
"allOf": [
{
"if": {
"properties": { "type": { "const": "property" } }
},
"then": {
"properties": {
"property": {
"title": "Property",
"description": "The property action.",
"required": ["type", "value"],
"type": "object",
"properties": {
"type": {
"title": "Property",
"description": "The type of the property action (either 'boolean' or 'string').",
"enum": ["boolean", "string"]
},
"value": {
"title": "Value",
"description": "The path to the property on the component definition.",
"type": "string"
}
}
}
},
"allOf": [
{
"if": {
"properties": { "type": { "const": "boolean" } }
},
"then": {
"properties": {
"state": {
"title": "Boolean State",
"description": "Used if the type of the property action is boolean.",
"type": "boolean"
}
}
}
},
{
"if": {
"properties": { "type": { "const": "string" } }
},
"then": {
"properties": {
"text": {
"title": "String Text",
"description": "Used if the type of the property action is string.",
"type": "string"
}
}
}
}
]
}
},
{
"if": {
"properties": { "type": { "const": "value" } }
},
"then": {
"properties": {
"value": {
"title": "Value",
"description": "The javascript that returns the new value. It Will be evaluated with available variables of row, data, component and result (returned from trigger).",
"type": "string"
}
}
}
}
]
};
// tslint:disable:object-literal-key-quotes quotemark semicolon
var conditional = {
"title": "Conditional",
"description": "Determines when this component should be added to the form for both processing and input.",
"type": "object",
"properties": {
"show": {
"$ref": "show",
},
"when": {
"title": "When",
"description": "The field API key that it should compare its value against to determine if the condition is triggered.",
"type": ["string", "null"]
},
"eq": {
"title": "Eq",
"description": "The value that should be checked against the comparison component.",
"type": "string"
},
"json": {
"title": "Json",
"description": "The JSON Logic to determine if this component is conditionally available.",
"type": "string"
}
}
};
// tslint:disable:object-literal-key-quotes quotemark semicolon
var showStrict = {
"title": "Show",
"description": "If the field should show if the condition is true.",
"type": ["boolean", "null"]
};
// tslint:disable:object-literal-key-quotes quotemark semicolon
var showLoose = {
"title": "Show",
"description": "If the field should show if the condition is true.",
"enum": [true, false, "true", "false", "", null]
};
// tslint:disable:object-literal-key-quotes quotemark semicolon
var columns = {
"required": ["columns"],
"not": { "required": ["components"] },
"properties": {
"columns": {
"type": "array",
"items": {
"required": ["components"],