/*
* Copyright 2010 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.
*/
/**
* Model for repository node as a search result.
* @private
*/
Ext.define('Ametys.repository.data.RepositorySearchNode', {
extend: 'Ext.data.TreeModel',
fields: [
{name: 'text', mapping: '@path', persist: false},
{name: 'path', mapping: '@path'},
{name: 'pathWithGroups', mapping: '@pathWithGroups'},
{name: 'name', mapping: '@name'},
{name: 'iconCls', defaultValue: 'a-tree-glyph ametysicon-document112'},
{name: 'leaf', defaultValue: true}
]
});
/**
* Tree panel used to display search results.
* @private
*/
Ext.define('Ametys.repository.tree.SearchTreePanel',
{
extend: 'Ext.tree.Panel',
config: {
/**
* @cfg {String} [defaultWorkspaceName='default'] The default workspace. Defaults to 'default'
*/
defaultWorkspaceName : 'default',
/**
* @cfg {String} searchUrl The search URL.
*/
searchUrl: Ametys.getPluginDirectPrefix('repositoryapp') + '/repository/query',
/**
* @cfg {String} modelName The model name.
*/
modelName: 'Ametys.repository.data.RepositorySearchNode'
},
statics: {
/**
* @property {String} JCR_ICON_SEARCH
* The icon used for the search root.
*/
JCR_ICON_SEARCH: Ametys.getPluginResourcesPrefix('repositoryapp') + '/img/jcr/search_16.png'
},
/**
* @property {String} _workspaceName The workspace name.
* @private
*/
_workspaceName: null,
// Tree properties.
scrollable: true,
animate: true,
hidden: true,
initComponent: function() {
var store = Ext.create('Ext.data.TreeStore', {
model: this.modelName,
proxy: {
type: 'ajax',
url: this.searchUrl,
reader: {
type: 'xml',
rootProperty: 'resultList',
record: 'result',
successProperty: function(data) {
return data.firstChild == null || data.firstChild.tagName != 'error';
}
}
},
root: {
text: "{{i18n PLUGINS_REPOSITORYAPP_SEARCH_ROOT_NODE_LABEL}}",
iconCls: 'a-tree-glyph ametysicon-magnifier12',
path: '',
expanded: true,
'config-doNotEscapeHtml': true,
leaf: false
},
folderSort: true,
sorters: [{
property: 'text',
direction: 'ASC'
}],
listeners: {
beforeload: {fn: this.onBeforeLoad, scope: this},
load: {fn: this.onLoad, scope: this}
}
});
Ext.apply(this, {
store: store,
viewConfig: {
toggleOnDblClick: false
}
});
this.callParent(arguments);
this.getSelectionModel().on('beforeselect', this.beforeSelectNode, this);
this.getRootNode().on('expand', this.onExpandRoot, this);
this.getRootNode().on('collapse', this.onCollapseRoot, this);
},
/**
* Adds additional parameters to the Operation before loading the store.
* @param {Ext.data.TreeStore} store The tree store.
* @param {Ext.data.Operation} operation The operation object that will be passed to the Proxy to load the Store.
* @param {Object} eOpts Options added to the addListener
* @private
*/
onBeforeLoad: function(store, operation, eOpts)
{
if (this._waitMsg != null)
{
this._waitMsg.hide();
}
// Do not load the store if there is no query.
if (this._query == null || this._query == '')
{
return false;
}
Ext.getBody().mask("{{i18n PLUGINS_REPOSITORYAPP_QUERY_EXECUTE_WAITING_MSG}}", "ametys-mask-unloading");
// Set the current workspace name
operation.setParams({
workspaceName: this._workspaceName || this.defaultWorkspaceName,
query: this._query,
language: this._language
});
},
/**
* Fired when the store is loaded.
* @param {Ext.data.TreeStore} store The tree store.
* @param {Ext.data.TreeModel[]} records The loaded records.
* @param {Boolean} successful true if the operation was successful, false otherwise.
* @param {Ext.data.Operation} operation The operation that triggered this load.
* @param {Ext.data.NodeInterface} node The loaded node.
* @private
*/
onLoad: function(store, records, successful, operation, node)
{
Ext.getBody().unmask();
var root = store.getRoot();
if (!successful)
{
Ametys.Msg.show({
title: "{{i18n PLUGINS_REPOSITORYAPP_QUERY_PROMPT_TITLE}}",
msg: "{{i18n PLUGINS_REPOSITORYAPP_QUERY_EXECUTE_UNEXPECTED_ERROR_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
root.set('text', "<b>{{i18n PLUGINS_REPOSITORYAPP_SEARCH_ROOT_NODE_LABEL}} : 0 {{i18n PLUGINS_REPOSITORYAPP_SEARCH_NB_RESULTS}} - <span style='color:red'>{{i18n PLUGINS_REPOSITORYAPP_QUERY_EXECUTE_ERROR_NODE}}</span></b>");
root.commit();
root.removeAll();
this.setHeight(20);
this.setVisible(true);
return;
}
var nbResults = root.childNodes.length;
if (nbResults == 1 && root.childNodes[0].get('type') == 'error')
{
Ametys.Msg.show({
title: "{{i18n PLUGINS_REPOSITORYAPP_QUERY_PROMPT_TITLE}}",
msg: "{{i18n PLUGINS_REPOSITORYAPP_QUERY_EXECUTE_ERROR_MSG}}",
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
root.set('text', "<b>{{i18n PLUGINS_REPOSITORYAPP_SEARCH_ROOT_NODE_LABEL}} : 0 {{i18n PLUGINS_REPOSITORYAPP_SEARCH_NB_RESULTS}} - <span style='color:red'>{{i18n PLUGINS_REPOSITORYAPP_QUERY_EXECUTE_ERROR_NODE}}</span></b>");
root.commit();
root.removeAll();
this.setHeight(20);
}
else
{
root.set('text', "<b>{{i18n PLUGINS_REPOSITORYAPP_SEARCH_ROOT_NODE_LABEL}} : " + nbResults + " {{i18n PLUGINS_REPOSITORYAPP_SEARCH_NB_RESULTS}}</b>");
root.commit();
this.setHeight(nbResults > 0 ? 200 : 20);
}
this.setVisible(true);
this.expand();
},
/**
* Set the query to execute.
* @param {String} query The query to execute.
* @param {String} language The query language.
* @param {String} workspaceName The workspace to execute the query in.
*/
setQuery: function(query, language, workspaceName)
{
this._query = query;
this._workspaceName = workspaceName || this.defaultWorkspaceName;
this._language = language != null ? language : 'xpath';
},
/**
* Tracks root expansion to expand/collapse the panel.
* @param {Ext.data.TreeModel} node The expanded node.
* @param {Object} eOpts Options added to the addListener
* @private
*/
onExpandRoot: function(node, eOpts)
{
this.setHeight(200);
},
/**
* Tracks root collapse to expand/collapse the panel.
* @param {Ext.data.TreeModel} node The collapsed node.
* @param {Object} eOpts Options added to the addListener
* @private
*/
onCollapseRoot: function(node, eOpts)
{
this.setHeight(20);
},
/**
* Listens before a node selection to prevent selecting the root node.
* @param {Ext.selection.TreeModel} sm The tree selection model.
* @param {Ext.data.NodeInterface} record The selected node.
* @param {Number} index The row index of the record
* @param {Object} eOpts Options added to the addListener
* @private
*/
beforeSelectNode: function(sm, record, index, eOpts)
{
// Prevent selecting the root node.
if (record == null || record.isRoot())
{
return false;
}
}
});