/*
* Copyright 2015 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Helper for creating or editing a link
*/
Ext.define('Ametys.plugins.linkdirectory.link.EditLinkDialog', {
singleton: true,
/**
* @private
* @property {Ext.form.Panel} _formPanel The form panel.
*/
/**
* @private
* @property {Boolean} _allowInternalURL Are internal URL allowed?
*/
/**
* @private
* @property {Object} _dynamicInformationProviders The list of dynamic information providers returned by the server. Can be null on error.
*/
/**
* Open the dialog to create or edit a link
* @param {Object} config The configuration object
* @param {String} config.lang lang The language for link
* @param {String} [config.id] id The id of link to edit. Can not null in edition mode.
* @param {String} [config.mode=new] The mode: 'new' for creation or 'edit' for edition
* @param {String} [config.linkType=URL] The type of link
* @param {Function} [config.callback] The callback function
*/
open: function (config)
{
this._mode = config.mode || 'new';
this._linkType = config.linkType || 'URL';
this._cbFn = config.callback;
this._allowInternalURL = false;
this._dynamicInformationProviders = null;
this._config = config;
Ametys.plugins.linkdirectory.link.LinkDAO.getDynamicInformationProviders([], Ext.bind(this._getDynamicInfoProvidersCb, this, [config], 1), {scope: this});
},
/**
* @private
* Callback function invoked after retrieviing the list of providers
* @param {Object[]} dynamicInformationProviders The providers
* @param {Object} config The #open config object
*/
_getDynamicInfoProvidersCb: function(dynamicInformationProviders, config)
{
this._dynamicInformationProviders = dynamicInformationProviders;
Ametys.plugins.linkdirectory.link.LinkDAO.isInternalURLAllowed([Ametys.getAppParameter('siteName')], Ext.bind(this._loadColor, this, [config], 1), {scope: this});
},
/**
* @private
* Get the colors
* @param {Boolean} allowInternalURL true if there are a restriction IP parameter
* @param {Object} config The #open config object
*/
_loadColor: function (allowInternalURL, config)
{
Ametys.data.ServerComm.callMethod({
role: "org.ametys.plugins.linkdirectory.LinkDirectoryColorsComponent",
methodName: "getColors",
parameters: [Ametys.getAppParameter('siteName')],
callback: {
scope: this,
handler: Ext.bind(this._loadColorCb, this, [allowInternalURL, config], 1)
},
errorMessage: true
});
},
/**
* @private
* Load the colors types data into the store
* @param {Object[]} colors The list of color object
* @param {Boolean} allowInternalURL true if there are a restriction IP parameter
* @param {Object} config The #open config object
*/
_loadColorCb: function (colors, allowInternalURL, config)
{
var data = [];
var colorList = [];
for (var i in colors)
{
var color = colors[i];
var colorObj = [];
colorObj.push(i);
colorObj.push(color.main);
colorList.push(colorObj);
}
var colorField = Ext.create("Ametys.form.widget.ColorPicker", {
name: 'color',
fieldLabel: '{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_COLOR_LABEL}}',
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_COLOR_DESC}}",
enumeration: colorList
})
this._openDialogBox(allowInternalURL, config, colorField);
},
/**
* @private
* Open the dialog box
* @param {Boolean} allowInternalURL true if there are a restriction IP parameter
* @param {Object} config The #open config object
* @param {Ametys.form.widget.ColorPicker} colorField The color field
*/
_openDialogBox: function (allowInternalURL, config, colorField)
{
this._allowInternalURL = allowInternalURL;
this._delayedInitialize(config.lang, colorField);
this._initForm (config);
this._box.show();
},
/**
* @private
* Creates the dialog box
* @param {String} lang The lang
* @param {Ametys.form.widget.ColorPicker} colorField The color field
*/
_delayedInitialize: function (lang, colorField)
{
if (!this._initialized)
{
this._formPanel = this._createFormPanel(lang, colorField);
this._box = Ext.create('Ametys.window.DialogBox', {
title: "{{i18n PLUGINS_LINKDIRECTORY_LINK_ADD_TITLE}}",
iconCls: 'ametysicon-link23 decorator-ametysicon-add64',
width: 620,
maxHeight: 600,
scrollable: false,
layout: 'fit',
items: [this._formPanel],
defaultFocus: 'url_target',
closeAction: 'destroy', // FIXME destroy instead of hide because of illustration widget
referenceHolder: true,
defaultButton: 'validate',
buttons: [{
reference: 'validate',
text: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_OK}}",
handler: Ext.bind(this._validate, this)
}, {
text: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_CANCEL}}",
handler: Ext.bind(this._cancel, this)
}]
});
// FIXME this._initialized = true; the dialog is destroyed on close
}
if (this._mode == 'new')
{
this._box.setTitle("{{i18n PLUGINS_LINKDIRECTORY_LINK_ADD_TITLE}}");
this._box.setIconCls("ametysicon-link23 decorator-ametysicon-add64");
}
else
{
this._box.setTitle("{{i18n PLUGINS_LINKDIRECTORY_LINK_EDIT_TITLE}}");
this._box.setIconCls("ametysicon-link23 decorator-ametysicon-edit45");
}
},
/**
* @private
* Handler for the 'ok' button of the dialog box
*/
_validate: function ()
{
var form = this._formPanel.getForm();
if (!form.isValid())
{
return;
}
var values = form.getValues();
if (values['url-type'] == 'URL')
{
if (this._allowInternalURL)
{
var externalUrlField = form.findField('url_target');
var internalUrlField = form.findField('internal-url');
if (!externalUrlField.getValue() && !internalUrlField.getValue())
{
internalUrlField.markInvalid("{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_ERROR}}");
externalUrlField.markInvalid("{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_ERROR}}");
return;
}
}
else if (!form.findField('url_target').getValue())
{
form.findField('url_target').markInvalid("{{i18n plugin.core-ui:PLUGINS_CORE_UI_DEFAULT_VALIDATOR_MANDATORY}}");
return;
}
}
values.siteName = Ametys.getAppParameter('siteName');
values.url = values['url-type'] == 'PAGE' ? values['page_target'] : values['url_target'];
if (this._mode == 'new')
{
Ametys.plugins.linkdirectory.link.LinkDAO.createLink([values], this._validateCb, {scope: this, waitMessage: { target: this._box }});
}
else
{
Ametys.plugins.linkdirectory.link.LinkDAO.updateLink([values], this._validateCb, {scope: this, waitMessage: { target: this._box }});
}
},
/**
* @private
* Callback function called after creation or edition process
*/
_validateCb: function (response, args)
{
if (response.id)
{
this._box.close();
if (Ext.isFunction (this._cbFn))
{
this._cbFn (response.id);
}
}
},
/**
* @private
* Callback for the "cancel" button of the dialog. Close the dialog.
*/
_cancel: function ()
{
this._box.close();
},
/**
* @private
* Initializes the form with some optional values.
* @param {Object} config the configuration of the edit link dialog
*/
_initForm: function (config)
{
var form = this._formPanel.getForm();
// Reset form
form.reset();
var dynamicInformationProviderField = form.findField("dynamic-info-provider");
dynamicInformationProviderField.setVisible(this._dynamicInformationProviders.length > 0);
if (this._dynamicInformationProviders.length > 0)
{
var data = [];
data.push(["","{{i18n PLUGINS_LINKDIRECTORY_LINKCOMBOBOX_DYNAMIC_INFO_PROVIDER_NONE}}"]);
Ext.Array.each(this._dynamicInformationProviders, function(ws) {
data.push([ws.id, ws.label]);
});
dynamicInformationProviderField.getStore().loadData(data);
}
if (this._mode === "new")
{
form.findField('lang').setValue(config.lang);
form.findField('themes').setLanguage(config.lang);
form.findField('url-type').setValue(this._linkType);
form.findField('status').setValue("NORMAL");
form.findField('default-visibility').setValue("VISIBLE");
if (this._linkType == 'PAGE')
{
form.findField('url_target').setDisabled(true);
form.findField('url_target').setVisible(false);
form.findField('internal-url').setDisabled(true);
form.findField('internal-url').setVisible(false);
form.findField('page_target').setDisabled(false);
form.findField('page_target').setVisible(true);
form.findField('page_target').focus(false, 100);
}
else
{
form.findField('internal-url').setDisabled(!this._allowInternalURL);
form.findField('internal-url').setVisible(this._allowInternalURL);
if (this._allowInternalURL)
{
form.findField('url_target').setFieldLabel("{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_EXTERNAL_LABEL}} *");
}
else
{
form.findField('url_target').setFieldLabel("{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_LABEL}} *");
}
form.findField('url_target').setDisabled(false);
form.findField('url_target').setVisible(true);
form.findField('page_target').setDisabled(true);
form.findField('page_target').setVisible(false);
form.findField('url_target').focus(false, 100);
}
}
else
{
form.findField('id').setValue(config.id);
form.findField('lang').setValue(config.lang);
form.findField('themes').setLanguage(config.lang);
Ametys.plugins.linkdirectory.link.LinkDAO.getLink([config.id], this._setValues, {scope: this});
}
},
/**
* Fill the form with link's data
* @param {Ametys.plugins.linkdirectory.link.Link} link The link.
* @private
*/
_setValues: function(link)
{
var form = this._formPanel.getForm();
var urlType = link.getUrlType();
form.findField('url-type').setValue(urlType);
if (urlType == 'PAGE')
{
form.findField('url_target').setDisabled(true);
form.findField('url_target').setVisible(false);
form.findField('internal-url').setDisabled(true);
form.findField('internal-url').setVisible(false);
form.findField('page_target').setDisabled(false);
form.findField('page_target').setVisible(true);
form.findField('page_target').setValue(link.getUrl());
form.findField('url_target').setValue();
form.findField('page_target').focus(false, 100);
}
else
{
form.findField('url_target').setDisabled(false);
form.findField('url_target').setVisible(true);
form.findField('page_target').setDisabled(true);
form.findField('page_target').setVisible(false);
form.findField('url_target').setValue(link.getUrl());
if (this._allowInternalURL)
{
form.findField('url_target').setFieldLabel("{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_EXTERNAL_LABEL}} *");
}
else
{
form.findField('url_target').setFieldLabel("{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_LABEL}} *");
}
form.findField('internal-url').setDisabled(!this._allowInternalURL);
form.findField('internal-url').setVisible(this._allowInternalURL);
form.findField('internal-url').setValue(link.getInternalUrl());
form.findField('page_target').setValue();
form.findField('url_target').focus(false, 100);
}
form.findField('url-alternative').setValue(link.getAlternative());
form.findField('title').setValue(link.getTitle());
form.findField('content').setValue(link.getContent());
form.findField('picture-alternative').setValue(link.getPictureAlternative());
form.findField('dynamic-info-provider').setValue(link.getDynamicInfoProvider());
form.findField('color').setValue(link.getColor());
form.findField('page').setValue(link.getPage());
form.findField('status').setValue(link.getStatus());
form.findField('default-visibility').setValue(link.getDefaultVisibility());
var picture = link.getPicture();
if (!Ext.Object.isEmpty(picture))
{
picture.id = picture.type != 'glyph' ? 'untouched' : picture.id;
form.findField('picture').setValue(picture);
}
else
{
form.findField('picture').setValue();
}
var themes = link.getThemes();
var themeIds = [];
for (var i = 0; i < themes.length; i++)
{
themeIds.push(themes[i].id);
}
form.findField('themes').setValue(themeIds);
},
/**
* Creates the form panel of this dialog box.
* @param {String} lang The lang
* @param {Ametys.form.widget.ColorPicker} colorField The color field
* @return {Ext.form.Panel} The form panel
* @private
*/
_createFormPanel: function(lang, colorField)
{
var formPanel = Ext.create('Ext.form.Panel', {
defaultType: 'textfield',
defaults: {
cls: 'ametys',
labelSeparator: '',
labelAlign: 'right',
labelWidth: 180,
anchor: '90%',
msgTarget: 'side'
},
border: false,
scrollable: true,
items: [
{
xtype: 'hidden',
name: 'id'
},
{
xtype: 'hidden',
name: 'lang'
},
{
xtype: 'hidden',
name: 'url-type'
},
{
xtype: 'hidden',
name: 'url'
},
{
xtype: 'textfield',
name: 'url_target',
itemId: 'url_target',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_LABEL}} *",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_DESC}}",
warnRegex: new RegExp ('^https?://.*$'),
warnRegexText: "{{i18n plugin.core:PLUGINS_CORE_REGEXP_INVALID_HTTP_URL_START}}"
},
{
xtype: 'textfield',
name: 'internal-url',
itemId: 'internal-url',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_INTERNAL_LABEL}} *",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_INTERNAL_DESC}}",
warnRegex: new RegExp ('^https?://.*$'),
warnRegexText: "{{i18n plugin.core:PLUGINS_CORE_REGEXP_INVALID_HTTP_URL_START}}"
},
{
xtype: 'edition.select-page',
name: 'page_target',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_PAGE_LABEL}} *",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_PAGE_DESC}}",
allowBlank: false,
multiple: false,
siteContext: Ametys.web.form.widget.SelectPage.SITE_CONTEXT_ALL,
sitemapContext: lang
},
{
xtype: 'textfield',
name: 'title',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_TITLE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_TITLE_DESC}}"
},
{
xtype: 'textfield',
name: 'url-alternative',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_ALT_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_URL_ALT_DESC}}"
},
{
xtype: 'textarea',
name: 'content',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_CONTENT_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_CONTENT_DESC}}",
height: 90
},
{
xtype: 'edition.select-page',
siteContext: Ametys.web.form.widget.SelectPage.SITE_CONTEXT_ALL,
sitemapContext: Ametys.web.form.widget.SelectPage.SITEMAP_CONTEXT_ALL,
name: 'page',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_ADDITIONAL_PAGE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_ADDITIONAL_PAGE_DESC}}"
},
{
xtype: 'edition.illustration',
name: 'picture',
allowSources: [Ametys.form.widget.File.External.SOURCE, Ametys.cms.widget.File.Resource.SOURCE],
glyphSources: [Ametys.web.form.widget.Illustration.SkinGlyph.SOURCE],
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_PICTURE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_PICTURE_DESC}}"
},
{
xtype: 'textfield',
name: 'picture-alternative',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_PICTURE_ALT_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_PICTURE_ALT_DESC}}"
},
colorField,
{
xtype: 'edition.select-link-theme',
name: 'themes',
multiple: true,
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_THEMES_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_THEMES_DESC}}"
},
{
xtype: 'combobox',
name: 'dynamic-info-provider',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_DYNAMIC_INFO_PROVIDER_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_DYNAMIC_INFO_PROVIDER_DESC}}",
editable: false,
forceSelection: true,
queryMode: 'local',
typeAhead: false,
valueField: 'id',
displayField: 'label',
allowBlank: true,
emptyText: "{{i18n PLUGINS_LINKDIRECTORY_LINKCOMBOBOX_DYNAMIC_INFO_PROVIDER_NONE}}",
store: Ext.create('Ext.data.Store', {
fields: ['id', 'label']
})
},
{
xtype: 'combobox',
name: 'status',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_DESC}}",
queryMode: 'local',
displayField: 'label',
valueField: 'value',
editable: false,
store: Ext.create('Ext.data.Store', {
fields: ['value', 'label'],
data : [
{"value":"NORMAL", "label":"{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_NORMAL_LABEL}}"},
{"value":"NEW", "label":"{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_NEW_LABEL}}"},
{"value":"BROKEN", "label":"{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_STATUS_BROKEN_LABEL}}"}
]
})
},
{
xtype: 'combobox',
name: 'default-visibility',
fieldLabel: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_VISIBILITY_STATUS_LABEL}}",
ametysDescription: "{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_VISIBILITY_STATUS_DESC}}",
queryMode: 'local',
displayField: 'label',
valueField: 'value',
defaultValue: 'VISIBLE',
editable: false,
store: Ext.create('Ext.data.Store', {
fields: ['value', 'label'],
data : [
{"value":"VISIBLE", "label":"{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_VISIBILITY_STATUS_DEFAULT_VISIBLE}}"},
{"value":"HIDDEN", "label":"{{i18n PLUGINS_LINKDIRECTORY_LINK_DIALOG_VISIBILITY_STATUS_DEFAULT_HIDDEN}}"}
]
})
}
]
});
return formPanel;
}
});