/*
* Copyright 2013 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.
*/
/**
* This helper provides a dialog box to edit the dublin core metadata of a resource.
* See #open method.
*/
Ext.define('Ametys.explorer.resources.helper.DublinCore', {
singleton: true,
/**
* @property {Boolean} _initialized True if the dialog box has been initialized.
* @private
*/
/**
* @property {Ext.form.Basic} _form The inner basic form.
* @private
*/
/**
* @property {Ametys.window.DialogBox} _box The dialog box
* @private
*/
/**
* Opens dialog box to edit the Dublin Core metadata of a resource.
* @param {String} id The id of the resource to edit.
* @param {Function} callback The callback function called when the resource was uploaded. Has the following parameters
* @param {String} callback.id The id of updated resource
* @param {Object} scope the callback scope
*/
open: function (id, callback, scope)
{
this._formReady = false;
this._dirty = false;
this._cbFn = callback || Ext.emptyFn
this._cbScope = scope;
this._delayedInitialize ();
this._box.show();
this._initForm (id);
},
/**
* @private
* Initialize the dialog box
* @return {Boolean} true if the box has been initialized (or if it was already initialized).
*/
_delayedInitialize: function()
{
if (this._initialized)
{
return true;
}
this._box = Ext.create('Ametys.window.DialogBox', {
title :"{{i18n PLUGINS_EXPLORER_DC_DIALOG_TITLE}}",
icon : Ametys.getPluginResourcesPrefix('explorer') + "/img/resources/dublincore_16.png",
layout: 'fit',
width: 530,
maxHeight: 540,
items: this._createFormPanel(),
defaultFocus: 'dc_title',
closeAction: 'hide',
referenceHolder: true,
defaultButton: 'validate',
buttons: [{
reference: 'validate',
text: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_BUTTON_OK}}",
handler: this._ok,
scope: this
}, {
text: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_BUTTON_CANCEL}}",
handler: this._cancel,
scope: this
}]
});
this._initialized = true;
return true;
},
/**
* Get the data store for DCMI types
* @private
*/
_getDCMITypeStore: function ()
{
return Ext.create('Ext.data.Store', {
model: 'Ametys.explorer.resources.helper.DublinCore.DCMITypeEntry',
proxy: {
type: 'ametys',
plugin: 'explorer',
url: 'dublincore/dcmitypes.xml',
reader: {
type: 'xml',
record: 'type',
rootProperty: 'types'
}
},
sortOnLoad: true,
sorters: [{property: 'label', direction:'ASC'}]
});
},
/**
* Get the store for given metadata
* @param {String} metadataName The DC metadata name
* @private
*/
_getMetadataStore: function (metadataName)
{
return Ext.create('Ext.data.Store', {
model: 'Ametys.explorer.resources.helper.DublinCore.MetadataEntry',
proxy: {
type: 'ametys',
plugin: 'explorer',
url: 'dublincore/enumeration',
reader: {
type: 'xml',
record: 'entry',
rootProperty: 'enumeration'
}
},
sortOnLoad: true,
sorters: [{property: 'label', direction:'ASC'}],
listeners: {
beforeload: function (store, operation) {
operation.setParams(Ext.apply(operation.getParams() || {}, {
metadataName: metadataName
}));
}
}
});
},
/**
* Creates and return the form panel
* @return {Ext.form.Panel} The form panel
* @private
*/
_createFormPanel: function ()
{
this._enumeratedMetadataNames = this._getEnumeratedMetadataNames();
return Ext.create('Ext.form.Panel', {
border: false,
scrollable: true,
defaults: {
cls: 'ametys',
anchor: '95%',
xtype: 'textfield',
listeners: {
'change': {fn: this._onFieldChange, scope: this}
}
},
fieldDefaults : {
labelAlign: 'right',
labelSeparator: '',
labelWidth: 100
},
items: [{
// id
xtype: 'hiddenfield',
name: 'id'
}, {
// title
xtype: 'textfield',
name: 'dc_title',
itemId: 'dc_title',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_TITLE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_TITLE_DESC}}"
}, {
// creator
xtype: 'textfield',
name: 'dc_creator',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_CREATOR_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_CREATOR_DESC}}"
}, {
// subject
name: 'dc_subject',
xtype: 'edition.textfield',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_SUBJECT_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_SUBJECT_DESC}}",
multiple: true
}, {
// description
name: 'dc_description',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_DESCRIPTION_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_DESCRIPTION_DESC}}"
},
// Publisher
this._getItem ('dc_publisher', "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_PUBLISHER_LABEL}}", "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_PUBLISHER_DESC}}"),
{
// Contributor
name: 'dc_contributor',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_CONTRIBUTOR_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_CONTRIBUTOR_DESC}}"
}, {
// Date
xtype: 'edition.date',
name: 'dc_date',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_DATE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_DATE_DESC}}"
}, {
// DCMI types
xtype: 'combobox',
name: 'dc_type',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_TYPE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_TYPE_DESC}}",
store: this._getDCMITypeStore(),
valueField: 'value',
displayField: 'label',
editable: false,
forceSelection: true
}, {
// Format
xtype: 'textfield',
name: 'dc_format',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_FORMAT_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_FORMAT_DESC}}",
disabled: true
}, {
// Identifier
xtype: 'textfield',
name: 'dc_identifier',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_IDENTIFIER_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_IDENTIFIER_DESC}}",
disabled: true
},
// Source
this._getItem ('dc_source', "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_SOURCE_LABEL}}", "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_SOURCE_DESC}}"),
// Language
this._getItem ('dc_language', "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_LANGUAGE_LABEL}}", "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_LANGUAGE_DESC}}"),
{
// Relation
name: 'dc_relation',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_RELATION_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_RELATION_DESC}}"
}, {
// Coverage
name: 'dc_coverage',
fieldLabel: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_COVERAGE_LABEL}}",
ametysDescription: "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_COVERAGE_DESC}}"
},
// Rights
this._getItem ('dc_rights', "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_RIGHTS_LABEL}}", "{{i18n PLUGINS_EXPLORER_DC_DIALOG_META_RIGHTS_DESC}}")
]
});
},
/**
* Callback when any field from the form has changed
* @param {Ext.form.Field} field The field that has changed
* @param {Object} newValue The value new field
*/
_onFieldChange: function(field, newValue)
{
if (this._formReady)
{
this._dirty = true;
}
},
/**
* Get the list of enumerated DublinCore metadata
* @return {String[]} A array of metadata names
* @private
*/
_getEnumeratedMetadataNames: function ()
{
var metadataNames = [];
var response = Ametys.data.ServerComm.send({
plugin: 'explorer',
url: 'dublincore/enumerated-metadata',
priority: Ametys.data.ServerComm.PRIORITY_SYNCHRONOUS
});
// TODO Handler error
var nodes = Ext.dom.Query.select('enumerations/metadata', response);
for (var i=0; i < nodes.length; i++)
{
metadataNames.push(Ext.dom.Query.selectValue('', nodes[i]));
}
return metadataNames;
},
/**
* Get the item configuration
* @param {String} name The field name
* @param {String} label The field label
* @param {String} description The field description
* @private
*/
_getItem: function (name, label, description)
{
if (Ext.Array.contains(this._enumeratedMetadataNames, name))
{
return {
xtype: 'combobox',
name: name,
fieldLabel: label,
ametysDescription: description,
store: this._getMetadataStore(name),
valueField: 'value',
displayField: 'label',
editable: false,
forceSelection: true
};
}
else
{
return {
xtype: 'textfield',
name: name,
fieldLabel: label,
ametysDescription: description
};
}
},
/**
* @private
* Load the stores and initialize the form with the appropriate values.
* @param {String} id The id of resource.
*/
_initForm: function(id)
{
var form = this._box.down('form').getForm();
form.reset();
form.findField('id').setValue(id);
// Load stores
this._loadStores (id);
},
/**
* @private
* Load the stores before initializing the form with the appropriate values.
* @param {String} id The id of resource.
*/
_loadStores: function (id)
{
this._storecount = this._enumeratedMetadataNames.length + 1; // +1 form dc_type
var form = this._box.down('form').getForm();
form.findField('dc_type').getStore().load({callback: Ext.bind(this._loadCb, this, [id], false)});
if (Ext.Array.contains(this._enumeratedMetadataNames, 'dc_publisher'))
{
form.findField('dc_publisher').getStore().load({callback: Ext.bind(this._loadCb, this, [id], false)});
}
if (Ext.Array.contains(this._enumeratedMetadataNames, 'dc_source'))
{
form.findField('dc_source').getStore().load({callback: Ext.bind(this._loadCb, this, [id], false)});
}
if (Ext.Array.contains(this._enumeratedMetadataNames, 'dc_language'))
{
form.findField('dc_language').getStore().load({callback: Ext.bind(this._loadCb, this, [id], false)});
}
if (Ext.Array.contains(this._enumeratedMetadataNames, 'dc_rights'))
{
form.findField('dc_rights').getStore().load({callback: Ext.bind(this._loadCb, this, [id], false)});
}
},
/**
* Function called after a store was loaded.<br>
* Initialize the form when all stores were loaded.
* @param {String} id The id of resource.
*/
_loadCb: function (id)
{
// Wait for loading
if (--this._storecount == 0)
{
Ametys.data.ServerComm.callMethod({
role: 'org.ametys.plugins.explorer.resources.actions.ExplorerResourcesDAO',
methodName: 'getDCMetadata',
parameters: [id],
callback: {
handler: this._fillForm,
scope: this
},
errorMessage: "{{i18n PLUGINS_EXPLORER_DC_RESOURCE_META_ERROR}}",
waitMessage: {
target: this._box
}
});
}
},
/**
* Callback function invoked after retrieving DC metadata values
* @param {Object} response the server response
* @param {String} response.id The id of DC object
* @param {Object} response.values The DC values
* @private
*/
_fillForm: function (response)
{
var form = this._box.down('form').getForm();
form.findField('id').setValue(response.id);
var values = response.values;
Ext.Object.each(values, function(name, value) {
field = form.findField(name);
if (field != null)
{
field.setValue(value);
}
});
this._formReady = true;
},
/**
* Function invoked when validating the dialog box
* @private
*/
_ok: function()
{
if (!this._dirty)
{
// no changes
this._box.hide();
return;
}
var form = this._box.down('form').getForm();
if (!form.isValid())
{
return;
}
Ametys.data.ServerComm.callMethod({
role: 'org.ametys.plugins.explorer.resources.actions.ExplorerResourcesDAO',
methodName: 'setDCMetadata',
parameters: [form.findField('id').getValue(), form.getFieldValues()],
callback: {
handler: this._saveCb,
scope: this,
arguments: {
id: form.findField('id').getValue()
}
},
waitMessage: {
target: this._box
},
errorMessage: "{{i18n PLUGINS_EXPLORER_DC_RESOURCE_SAVE_META_ERROR}}"
});
},
/**
* Callback function called when the DC metadata was edited
* @param {Object} response The server response
* @param {Object} args The callback arguments
* @private
*/
_saveCb: function (response, args)
{
if (this._cbFn)
{
Ext.Function.defer (this._cbFn, 0, this._cbScope, [args.id]);
}
this._box.hide();
},
/**
* Function invoked when cancelling the dialog box
* @private
*/
_cancel: function()
{
this._box.hide();
}
});