/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
import ClayModal from 'clay-modal';
import {FormBuilderBase} from 'dynamic-data-mapping-form-builder/js/components/FormBuilder/FormBuilder.es';
import withActionableFields from 'dynamic-data-mapping-form-builder/js/components/FormBuilder/withActionableFields.es';
import withClickableFields from 'dynamic-data-mapping-form-builder/js/components/FormBuilder/withClickableFields.es';
import withEditablePageHeader from 'dynamic-data-mapping-form-builder/js/components/FormBuilder/withEditablePageHeader.es';
import withMoveableFields from 'dynamic-data-mapping-form-builder/js/components/FormBuilder/withMoveableFields.es';
import withMultiplePages from 'dynamic-data-mapping-form-builder/js/components/FormBuilder/withMultiplePages.es';
import withResizeableColumns from 'dynamic-data-mapping-form-builder/js/components/FormBuilder/withResizeableColumns.es';
import LayoutProvider from 'dynamic-data-mapping-form-builder/js/components/LayoutProvider/LayoutProvider.es';
import RuleBuilder from 'dynamic-data-mapping-form-builder/js/components/RuleBuilder/RuleBuilder.es';
import Sidebar from 'dynamic-data-mapping-form-builder/js/components/Sidebar/Sidebar.es';
import {pageStructure} from 'dynamic-data-mapping-form-builder/js/util/config.es';
import {
isKeyInSet,
isModifyingKey,
} from 'dynamic-data-mapping-form-builder/js/util/dom.es';
import {sub} from 'dynamic-data-mapping-form-builder/js/util/strings.es';
import {PagesVisitor, compose} from 'dynamic-data-mapping-form-renderer';
import core from 'metal';
import dom from 'metal-dom';
import {EventHandler} from 'metal-events';
import Component from 'metal-jsx';
import {Config} from 'metal-state';
import PreviewButton from './components/PreviewButton/PreviewButton.es';
import PublishButton from './components/PublishButton/PublishButton.es';
import ShareFormPopover from './components/ShareFormPopover/ShareFormPopover.es';
import AutoSave from './util/AutoSave.es';
import FormURL from './util/FormURL.es';
import Notifications from './util/Notifications.es';
import StateSyncronizer from './util/StateSyncronizer.es';
const NAV_ITEMS = {
FORM: 0,
REPORT: 2,
RULES: 1,
};
/**
* Form.
* @extends Component
*/
class Form extends Component {
attached() {
const {store} = this.refs;
const {
localizedDescription,
localizedName,
namespace,
published,
showPublishAlert,
} = this.props;
const {paginationMode} = this.state;
this._eventHandler = new EventHandler();
const dependencies = [
this._createEditor('nameEditor').then((editor) => {
this._eventHandler.add(
dom.on(
editor.element.$,
'keydown',
this._handleNameEditorKeydown
),
dom.on(
editor.element.$,
'keyup',
this._handleNameEditorCopyAndPaste
),
dom.on(
editor.element.$,
'keypress',
this._handleNameEditorCopyAndPaste
)
);
return editor;
}),
this._createEditor('descriptionEditor'),
Liferay.componentReady('translationManager'),
];
if (this.isFormBuilderView()) {
dependencies.push(this._getSettingsDDMForm());
}
Promise.all(dependencies).then(
([
nameEditor,
descriptionEditor,
translationManager,
settingsDDMForm,
]) => {
if (translationManager) {
this.props.defaultLanguageId = translationManager.get(
'defaultLocale'
);
this.props.editingLanguageId = translationManager.get(
'editingLocale'
);
this._translationManagerHandles = [
translationManager.on('editingLocale', ({newValue}) => {
this.props.editingLanguageId = newValue;
if (
translationManager.get('defaultLocale') ===
newValue
) {
this.showAddButton();
}
else {
this.hideAddButton();
}
}),
translationManager.on(
'availableLocales',
this.onAvailableLocalesRemoved.bind(this)
),
];
}
this._stateSyncronizer = new StateSyncronizer(
{
descriptionEditor,
localizedDescription,
localizedName,
nameEditor,
namespace,
paginationMode,
published,
settingsDDMForm,
store,
translationManager,
},
this.element
);
this._autoSave = new AutoSave(
{
form: document.querySelector(`#${namespace}editForm`),
interval: Liferay.DDM.FormSettings.autosaveInterval,
namespace,
stateSyncronizer: this._stateSyncronizer,
url: Liferay.DDM.FormSettings.autosaveURL,
},
this.element
);
this._eventHandler.add(
this._autoSave.on('autosaved', this._updateAutoSaveMessage)
);
}
);
this._eventHandler.add(
dom.on(
`#addFieldButton`,
'click',
this._handleAddFieldButtonClicked.bind(this)
),
dom.on(
`#${namespace}controlMenu .sites-control-group span.lfr-portal-tooltip`,
'click',
this._handleBackButtonClicked
),
dom.on(
'.forms-management-bar li',
'click',
this._handleFormNavClicked
)
);
if (showPublishAlert) {
if (published) {
this._showPublishedAlert(this._createFormURL());
}
else {
this._showUnpublishedAlert();
}
}
if (!this._pageHasFields(store.getPages(), store.state.activePage)) {
this.openSidebar();
}
store.on('fieldDuplicated', () => this.openSidebar());
store.on('focusedFieldChanged', ({newVal}) => {
if (newVal && Object.keys(newVal).length > 0) {
this.openSidebar();
}
});
store.on('activePageChanged', () => {
const {activePage, pages} = store.state;
if (
activePage > -1 &&
pages[activePage] &&
!pages[activePage].successPageSettings
) {
this.enableAddButton();
if (!this._pageHasFields(pages, activePage)) {
this.openSidebar();
}
}
else {
this.disableAddButton();
}
});
store.on('pagesChanged', ({newVal, prevVal}) => {
if (
newVal &&
prevVal &&
newVal.length !== prevVal.length &&
!this._pageHasFields(newVal, store.state.activePage)
) {
this.openSidebar();
}
this.enableAddButton();
});
store.on(
'paginationModeChanged',
this._handlePaginationModeChanded.bind(this)
);
store.on('ruleCancelled', this.showAddButton.bind(this));
store.on('rulesModified', this._handleRulesModified.bind(this));
}
checkEditorLimit(event, limit) {
const charCode = event.which ? event.which : event.keyCode;
if (this.isForbiddenKey(event, limit) && charCode != 91) {
event.preventDefault();
}
}
created() {
this._createFormURL = this._createFormURL.bind(this);
this._handleBackButtonClicked = this._handleBackButtonClicked.bind(
this
);
this._handleFormNavClicked = this._handleFormNavClicked.bind(this);
this._handleNameEditorCopyAndPaste = this._handleNameEditorCopyAndPaste.bind(
this
);
this._handleNameEditorKeydown = this._handleNameEditorKeydown.bind(
this
);
this._handlePaginationModeChanded = this._handlePaginationModeChanded.bind(
this
);
this._resolvePreviewURL = this._resolvePreviewURL.bind(this);
this._updateAutoSaveMessage = this._updateAutoSaveMessage.bind(this);
this.ComposedFormBuilder = this._createFormBuilder();
this.submitForm = this.submitForm.bind(this);
}
disableAddButton() {
const addButton = document.querySelector('#addFieldButton');
addButton.setAttribute('disabled', true);
}
disposed() {
if (this._autoSave) {
this._autoSave.dispose();
}
if (this._stateSyncronizer) {
this._stateSyncronizer.dispose();
}
Notifications.closeAlert();
this._eventHandler.removeAllListeners();
if (this._translationManagerHandles) {
this._translationManagerHandles.forEach((handle) =>
handle.detach()
);
}
}
enableAddButton() {
const addButton = document.querySelector('#addFieldButton');
addButton.removeAttribute('disabled');
}
hideAddButton() {
const addButton = document.querySelector('#addFieldButton');
addButton.classList.add('hide');
}
isForbiddenKey(event, limit) {
const charCode = event.which ? event.which : event.keyCode;
let forbidden = false;
if (
event.target.innerText.length >= limit &&
isModifyingKey(charCode) &&
!isKeyInSet(charCode, ['BACKSPACE', 'DELETE', 'ESC', 'ENTER'])
) {
forbidden = true;
}
return forbidden;
}
isFormBuilderView() {
const {view} = this.props;
return view !== 'fieldSets';
}
isShowRuleBuilder() {
const {activeNavItem} = this.state;
return activeNavItem === NAV_ITEMS.RULES && this.isFormBuilderView();
}
isShowReport() {
const {activeNavItem} = this.state;
return activeNavItem === NAV_ITEMS.REPORT && this.isFormBuilderView();
}
onAvailableLocalesRemoved({newValue, previousValue}) {
const {store} = this.refs;
const removedItems = new Map();
previousValue.forEach((value, key) => {
if (!newValue.has(key)) {
removedItems.set(key, value);
}
});
if (removedItems.size > 0) {
store.emit('languageIdDeleted', {
locale: removedItems.keys().next().value,
});
}
}
openSidebar() {
this.refs.sidebar.open();
}
preventCopyAndPaste(event, limit) {
const {target} = event;
if (this.isForbiddenKey(event, limit)) {
target.innerText = target.innerText.substr(0, limit);
const range = document.createRange();
const sel = window.getSelection();
range.setStart(target.childNodes[0], target.textContent.length);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
render() {
const {ComposedFormBuilder} = this;
const {
context,
dataProviderInstanceParameterSettingsURL,
dataProviderInstancesURL,
defaultLanguageId,
editingLanguageId,
fieldSetDefinitionURL,
fieldSets,
fieldTypes,
functionsMetadata,
functionsURL,
groupId,
namespace,
published,
redirectURL,
rolesURL,
rules,
spritemap,
view,
} = this.props;
const {saveButtonLabel} = this.state;
const storeProps = {
...this.props,
defaultLanguageId,
editingLanguageId,
initialPages: context.pages,
initialPaginationMode: context.paginationMode,
initialSuccessPageSettings: context.successPageSettings,
ref: 'store',
};
const LayoutProviderTag = LayoutProvider;
return (
<div class={'ddm-form-builder'}>
<LayoutProviderTag {...storeProps}>
{this.isFormBuilderView() && (
<RuleBuilder
dataProviderInstanceParameterSettingsURL={
dataProviderInstanceParameterSettingsURL
}
dataProviderInstancesURL={dataProviderInstancesURL}
fieldTypes={fieldTypes}
functionsMetadata={functionsMetadata}
functionsURL={functionsURL}
groupId={groupId}
portletNamespace={namespace}
ref="ruleBuilder"
rolesURL={rolesURL}
rules={rules}
spritemap={spritemap}
visible={this.isShowRuleBuilder()}
/>
)}
<ComposedFormBuilder
fieldSets={fieldSets}
fieldTypes={fieldTypes}
groupId={groupId}
portletNamespace={namespace}
ref="formBuilder"
rules={rules}
spritemap={spritemap}
view={view}
visible={
!this.isShowRuleBuilder() && !this.isShowReport()
}
/>
<Sidebar
defaultLanguageId={defaultLanguageId}
editingLanguageId={editingLanguageId}
fieldSetDefinitionURL={fieldSetDefinitionURL}
fieldSets={fieldSets}
fieldTypes={fieldTypes}
portletNamespace={namespace}
ref="sidebar"
spritemap={spritemap}
visible={
!this.isShowRuleBuilder() && !this.isShowReport()
}
/>
</LayoutProviderTag>
<div class="container-fluid-1280">
{this.isFormBuilderView() && (
<div class="button-holder ddm-form-builder-buttons">
<PublishButton
namespace={namespace}
published={published}
spritemap={spritemap}
submitForm={this.submitForm}
url={
Liferay.DDM.FormSettings
.publishFormInstanceURL
}
/>
<button
class="btn btn-secondary ddm-button"
data-onclick="_handleSaveButtonClicked"
ref="saveButton"
>
{saveButtonLabel}
</button>
<PreviewButton
namespace={namespace}
resolvePreviewURL={this._resolvePreviewURL}
spritemap={spritemap}
/>
</div>
)}
{!this.isFormBuilderView() && (
<div class="button-holder ddm-form-builder-buttons">
<button
class="btn btn-primary ddm-button"
data-onclick="_handleSaveButtonClicked"
ref="saveFieldSetButton"
>
{saveButtonLabel}
</button>
<a
class="btn btn-cancel btn-link"
data-onclick="_handleCancelButtonClicked"
href={redirectURL}
ref="cancelFieldSetButton"
>
{Liferay.Language.get('cancel')}
</a>
</div>
)}
<ClayModal
body={Liferay.Language.get(
'any-unsaved-changes-will-be-lost-are-you-sure-you-want-to-leave'
)}
footerButtons={[
{
alignment: 'right',
label: Liferay.Language.get('leave'),
style: 'secondary',
type: 'close',
},
{
alignment: 'right',
label: Liferay.Language.get('stay'),
style: 'primary',
type: 'button',
},
]}
ref={'discardChangesModal'}
size={'sm'}
spritemap={spritemap}
title={Liferay.Language.get('leave-form')}
/>
</div>
{published && (
<ShareFormPopover
alignElement={document.querySelector(
'.share-form-icon'
)}
spritemap={spritemap}
url={this._createFormURL()}
visible={false}
/>
)}
</div>
);
}
showAddButton() {
const addButton = document.querySelector('#addFieldButton');
addButton.classList.remove('hide');
}
submitForm() {
const {namespace} = this.props;
this._stateSyncronizer.syncInputs();
submitForm(document.querySelector(`#${namespace}editForm`));
}
syncActiveNavItem(activeNavItem) {
switch (activeNavItem) {
case NAV_ITEMS.FORM:
this._toggleRulesBuilder(false);
this._toggleReport(false);
this._toggleFormBuilder(true);
break;
case NAV_ITEMS.RULES:
this._toggleFormBuilder(false);
this._toggleReport(false);
this._toggleRulesBuilder(true);
break;
case NAV_ITEMS.REPORT:
this._toggleFormBuilder(false);
this._toggleRulesBuilder(false);
this._toggleReport(true);
break;
default:
break;
}
}
willReceiveProps({published = {}}) {
if (published.newVal != null) {
this._updateShareFormIcon(published.newVal);
}
}
_handleAddFieldButtonClicked() {
if (this.isShowRuleBuilder()) {
this.refs.ruleBuilder.showRuleCreation();
this.hideAddButton();
}
else {
this.openSidebar();
}
}
_createEditor(name) {
const {namespace} = this.props;
const editorName = `${namespace}${name}`;
const editor = window[editorName];
let promise;
if (editor) {
editor.create();
promise = Promise.resolve(CKEDITOR.instances[editorName]);
}
else {
promise = new Promise((resolve) => {
Liferay.on('editorAPIReady', (event) => {
if (event.editorName === editorName) {
event.editor.create();
resolve(CKEDITOR.instances[editorName]);
}
});
});
}
return promise;
}
_createFormBuilder() {
const composeList = [
withActionableFields,
withClickableFields,
withMoveableFields,
withMultiplePages,
withResizeableColumns,
];
if (this.isFormBuilderView()) {
composeList.push(withEditablePageHeader);
}
return compose(...composeList)(FormBuilderBase);
}
_createFormURL() {
const settingsDDMForm = Liferay.component('settingsDDMForm');
let requireAuthentication = false;
if (settingsDDMForm) {
const settingsPageVisitor = new PagesVisitor(settingsDDMForm.pages);
settingsPageVisitor.mapFields((field) => {
if (field.fieldName === 'requireAuthentication') {
requireAuthentication = field.value;
}
});
}
const formURL = new FormURL(
this._getFormInstanceId(),
this.props.published,
requireAuthentication
);
return formURL.create();
}
_getFormInstanceId() {
const {namespace} = this.props;
return document.querySelector(`#${namespace}formInstanceId`).value;
}
_getSettingsDDMForm() {
let promise;
const settingsDDMForm = Liferay.component('settingsDDMForm');
if (settingsDDMForm) {
promise = Promise.resolve(settingsDDMForm);
}
else {
promise = Liferay.componentReady('settingsDDMForm');
}
return promise;
}
_handleBackButtonClicked(event) {
if (this._autoSave.hasUnsavedChanges()) {
event.preventDefault();
event.stopPropagation();
const href = event.delegateTarget.firstElementChild.href;
this.refs.discardChangesModal.visible = true;
const listener = this.refs.discardChangesModal.addListener(
'clickButton',
({target}) => {
if (target.classList.contains('close-modal')) {
window.location.href = href;
}
listener.dispose();
this.refs.discardChangesModal.emit('hide');
}
);
}
}
_handleCancelButtonClicked(event) {
const href = event.delegateTarget.href;
event.preventDefault();
event.stopPropagation();
window.location.href = href;
}
_handleFormNavClicked(event) {
const {delegateTarget} = event;
const navItem = dom.closest(delegateTarget, '.nav-item');
const navItemIndex = Number(navItem.dataset.navItemIndex);
const navLink = navItem.querySelector('.nav-link');
document
.querySelector('.forms-management-bar li > a.active')
.classList.remove('active');
navLink.classList.add('active');
this.setState({
activeNavItem: navItemIndex,
});
this.syncActiveNavItem(this.state.activeNavItem);
}
_handleNameEditorCopyAndPaste(event) {
return this.preventCopyAndPaste(event, 120);
}
_handleNameEditorKeydown(event) {
return this.checkEditorLimit(event, 120);
}
_handlePaginationModeChanded({newVal}) {
this.setState({
paginationMode: newVal,
});
}
_handleRulesModified() {
this._autoSave.save(true);
this.showAddButton();
}
_handleSaveButtonClicked(event) {
event.preventDefault();
this.setState({
saveButtonLabel: Liferay.Language.get('saving'),
});
this.submitForm();
}
_pageHasFields(pages, pageIndex) {
const visitor = new PagesVisitor([pages[pageIndex]]);
let hasFields = false;
visitor.mapFields(() => {
hasFields = true;
});
return hasFields;
}
_pagesValueFn() {
const {context} = this.props;
return context.pages;
}
_paginationModeValueFn() {
const {context} = this.props;
return context.paginationMode;
}
_resolvePreviewURL() {
return this._autoSave.save(true).then(() => {
return `${this._createFormURL()}/preview`;
});
}
_saveButtonLabelValueFn() {
let label = Liferay.Language.get('save');
if (this.isFormBuilderView()) {
label = Liferay.Language.get('save-form');
}
return label;
}
_setContext(context) {
let {successPageSettings} = context;
const {successPage} = context;
if (!successPageSettings) {
successPageSettings = successPage;
}
if (core.isString(successPageSettings.title)) {
successPageSettings.title = {};
successPageSettings.title[themeDisplay.getLanguageId()] = '';
}
if (core.isString(successPageSettings.body)) {
successPageSettings.body = {};
successPageSettings.body[themeDisplay.getLanguageId()] = '';
}
successPageSettings.enabled = true;
const emptyLocalizableValue = {
[themeDisplay.getLanguageId()]: '',
};
if (!context.pages.length) {
context = {
...context,
pages: [
{
description: '',
localizedDescription: emptyLocalizableValue,
localizedTitle: emptyLocalizableValue,
rows: [
{
columns: [
{
fields: [],
size: 12,
},
],
},
],
title: '',
},
],
paginationMode: 'wizard',
successPageSettings,
};
}
return {
...context,
pages: context.pages.map((page) => {
let {
description,
localizedDescription,
localizedTitle,
title,
} = page;
if (!core.isString(description)) {
description = description[themeDisplay.getLanguageId()];
localizedDescription = {
[themeDisplay.getLanguageId()]: description,
};
}
if (!core.isString(title)) {
title = title[themeDisplay.getLanguageId()];
localizedTitle = {
[themeDisplay.getLanguageId()]: title,
};
}
return {
...page,
description,
localizedDescription,
localizedTitle,
title,
};
}),
};
}
_showPublishedAlert(publishURL) {
const message = Liferay.Language.get(
'the-form-was-published-successfully-access-it-with-this-url-x'
);
Notifications.showAlert(
message.replace(
/\{0\}/gim,
`<span style="font-weight: 500"><a href=${publishURL} target="_blank">${publishURL}</a></span>`
)
);
}
_showUnpublishedAlert() {
Notifications.showAlert(
Liferay.Language.get('the-form-was-unpublished-successfully')
);
}
_toggleFormBuilder(show) {
const {
defaultLanguageId,
editingLanguageId,
namespace,
published,
saved,
} = this.props;
const managementToolbar = document.querySelector(
`#${namespace}managementToolbar`
);
const formBasicInfo = document.querySelector('.ddm-form-basic-info');
const formBuilderButtons = document.querySelector(
'.ddm-form-builder-buttons'
);
const publishIcon = document.querySelector('.publish-icon');
const shareURLButton = document.querySelector(
'.lfr-ddm-share-url-button'
);
const translationManager = document.querySelector(
'.ddm-translation-manager'
);
if (show) {
managementToolbar.classList.remove('hide');
formBasicInfo.classList.remove('hide');
formBuilderButtons.classList.remove('hide');
if (publishIcon) {
publishIcon.classList.remove('hide');
}
if (translationManager) {
translationManager.classList.remove('hide');
}
if (saved || published) {
shareURLButton.classList.remove('hide');
}
if (defaultLanguageId === editingLanguageId) {
this.showAddButton();
}
else {
this.hideAddButton();
}
}
else {
managementToolbar.classList.add('hide');
formBasicInfo.classList.add('hide');
formBuilderButtons.classList.add('hide');
if (publishIcon) {
publishIcon.classList.add('hide');
}
if (translationManager) {
translationManager.classList.add('hide');
}
shareURLButton.classList.add('hide');
this.hideAddButton();
}
}
_toggleReport(show) {
const formReport = document.querySelector('.ddm-form-report');
if (!formReport) {
return;
}
if (show) {
formReport.classList.remove('hide');
}
else {
formReport.classList.add('hide');
}
}
_toggleRulesBuilder(show) {
const {namespace} = this.props;
const managementToolbar = document.querySelector(
`#${namespace}managementToolbar`
);
if (show) {
managementToolbar.classList.remove('hide');
}
else {
managementToolbar.classList.add('hide');
}
if (this.refs.ruleBuilder.isViewMode()) {
this.showAddButton();
}
else {
this.hideAddButton();
}
}
_updateAutoSaveMessage({modifiedDate, savedAsDraft}) {
const {namespace} = this.props;
let message = '';
if (savedAsDraft) {
message = Liferay.Language.get('draft-x');
}
else {
message = Liferay.Language.get('saved-x');
}
const autoSaveMessageNode = document.querySelector(
`#${namespace}autosaveMessage`
);
autoSaveMessageNode.innerHTML = sub(message, [modifiedDate]);
}
_updateShareFormIcon(published) {
const {saved} = this.props;
const shareFormIcon = document.querySelector('.share-form-icon');
if (saved && published) {
shareFormIcon.classList.remove('ddm-btn-disabled');
shareFormIcon.setAttribute(
'title',
Liferay.Language.get('copy-url')
);
}
else {
shareFormIcon.classList.add('ddm-btn-disabled');
shareFormIcon.setAttribute(
'title',
Liferay.Language.get(
'publish-the-form-to-get-its-shareable-link'
)
);
}
}
}
Form.PROPS = {
/**
* The context for rendering a layout that represents a form.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
context: Config.shapeOf({
pages: Config.arrayOf(Config.object()),
paginationMode: Config.string(),
rules: Config.array(),
successPageSettings: Config.object(),
})
.required()
.setter('_setContext'),
/**
* The rules of a form.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
dataProviderInstanceParameterSettingsURL: Config.string().required(),
/**
* The rules of a form.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
dataProviderInstancesURL: Config.string().required(),
/**
* The default language id of the form.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
defaultLanguageId: Config.string().value(
themeDisplay.getDefaultLanguageId()
),
/**
* The default language id of the form.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
editingLanguageId: Config.string().value(
themeDisplay.getDefaultLanguageId()
),
/**
* @default undefined
* @instance
* @memberof Form
* @type {?string}
*/
fieldSetDefinitionURL: Config.string(),
/**
* @default []
* @instance
* @memberof Form
* @type {?(array|undefined)}
*/
fieldSets: Config.array().value([]),
/**
* @default []
* @instance
* @memberof Form
* @type {?(array|undefined)}
*/
fieldTypes: Config.array().value([]),
/**
* A map with all translated values available as the form description.
* @default 0
* @instance
* @memberof Form
* @type {!array}
*/
formInstanceId: Config.number().value(0),
/**
* A map with all translated values available as the form name.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
functionsMetadata: Config.object().value({}),
/**
* A map with all translated values available as the form name.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
functionsURL: Config.string(),
/**
* A map with all translated values available as the form description.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
localizedDescription: Config.object().value({}),
/**
* The context for rendering a layout that represents a form.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
localizedName: Config.object().value({}),
/**
* The namespace of the portlet.
* @default undefined
* @instance
* @memberof Form
* @type {!string}
*/
namespace: Config.string().required(),
/**
* Whether the form is published or not
* @default false
* @instance
* @memberof Form
* @type {!boolean}
*/
published: Config.bool().value(false),
/**
* The url to be redirected when canceling the Element Set edition.
* @default undefined
* @instance
* @memberof Form
* @type {!string}
*/
redirectURL: Config.string(),
/**
* The rules of a form.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
rolesURL: Config.string(),
/**
* The rules of a form.
* @default undefined
* @instance
* @memberof Form
* @type {!array}
*/
rules: Config.array().value([]),
/**
* The path to the SVG spritemap file containing the icons.
* @default undefined
* @instance
* @memberof Form
* @type {!boolean}
*/
saved: Config.bool(),
/**
* Whether to show an alert telling the user about the result of the
* "Publish" operation.
* @default false
* @instance
* @memberof Form
* @type {!boolean}
*/
showPublishAlert: Config.bool().value(false),
/**
* The path to the SVG spritemap file containing the icons.
* @default undefined
* @instance
* @memberof Form
* @type {!string}
*/
spritemap: Config.string().required(),
view: Config.string(),
};
Form.STATE = {
/**
* Current active tab index.
* @default
* @instance
* @memberof Form
* @type {!number}
*/
activeNavItem: Config.number().value(NAV_ITEMS.FORM),
/**
* Internal mirror of the pages state
* @default _pagesValueFn
* @instance
* @memberof Form
* @type {!array}
*/
pages: Config.arrayOf(pageStructure).valueFn('_pagesValueFn'),
/**
* @default _paginationModeValueFn
* @instance
* @memberof Form
* @type {!array}
*/
paginationMode: Config.string().valueFn('_paginationModeValueFn'),
/**
* The label of the save button
* @default 'save-form'
* @instance
* @memberof Form
* @type {!string}
*/
saveButtonLabel: Config.string().valueFn('_saveButtonLabelValueFn'),
};
export default Form;
export {Form};