/*
* Copyright 2016 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.
*/
/**
* @private
* This tool displays a sql table
* Must be parametrized with 'id', an id of a datasource ; and 'table' the sql table name
*/
Ext.define('Ametys.plugins.datasourcesexplorer.tool.DatasourcesExplorerSQLTableViewTool', {
extend: 'Ametys.tool.Tool',
/**
* @private
* @property {String} _datasourceId The displayed datasource id
*/
/**
* @private
* @property {String} _sqlTableName The displayed table name
*/
/**
* @private
* @property {String} _modelName The name of the store model to use
*/
/**
* @private
* @property {Ext.grid.Panel} _grid The main grid panel
*/
/**
* @private
* @property {Number} _columnsHashCode Th server columns hashcode of the last reconfiguration
*/
statics: {
/**
* @readonly
* @private
* @property {Number} __PAGE_SIZE the default value for pagination size
*/
__PAGE_SIZE: 10
},
constructor: function(config)
{
this.callParent(arguments);
// Bus messages listeners
Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onModified, this);
Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onDeleted, this);
},
createPanel: function()
{
var store = this.createStore();
this._grid = Ext.create('Ext.grid.Panel', {
store: store,
columns: [],
dockedItems: [{
xtype: 'pagingtoolbar',
store: store,
dock: 'bottom',
itemId: 'paging',
items: [
{
xtype: 'component',
flex: 1
},
{
xtype: 'textfield',
fieldLabel: 'WHERE',
labelSeparator: '',
labelWidth: 50,
flex: 20,
itemId: 'where',
listeners: {
'blur': function() {
this._grid.getStore().load();
},
'specialkey': function(field, e) {
if (e.getKey() == e.ENTER) {
this._grid.getStore().load();
}
},
scope: this
}
},
{
xtype: 'textfield',
fieldLabel: 'BY',
labelSeparator: '',
labelWidth: 20,
width: 60,
itemId: 'by',
value: Ametys.plugins.datasourcesexplorer.tool.DatasourcesExplorerSQLTableViewTool.__PAGE_SIZE,
listeners: {
'blur': function() {
this._grid.getStore().load();
},
'specialkey': function(field, e) {
if (e.getKey() == e.ENTER) {
this._grid.getStore().load();
}
},
scope: this
}
}
],
displayInfo: true
}]
});
return this._grid;
},
/**
* @protected
* Get the store the grid should use as its data source.
* @return {Ext.data.Store} The store
*/
createStore: function()
{
this._createModel();
return Ext.create('Ext.data.Store', {
model: this._modelName,
autoDestroy: true,
remoteSort: true,
proxy: {
type: 'ametys',
plugin: 'datasources-explorer',
url: 'sql-data.json',
reader: {
type: 'json',
rootProperty: 'data',
metaProperty: 'meta'
}
},
pageSize: Ametys.plugins.datasourcesexplorer.tool.DatasourcesExplorerSQLTableViewTool.__PAGE_SIZE,
sortOnLoad: true,
listeners: {
'beforeload': {fn: this._onBeforeLoad, scope: this},
'metachange': {fn: this._onMetaChange, scope: this}
}
});
},
/**
* Function called before loading the store
* @param {Ext.data.Store} store The store
* @param {Ext.data.operation.Operation} operation The object that will be passed to the Proxy to load the store
* @private
*/
_onBeforeLoad: function(store, operation)
{
if (this._sqlTableName)
{
this._grid.getView().unmask();
var pageSize = this._grid.getDockedComponent('paging').getComponent('by').getValue();
operation.setParams( Ext.apply(operation.getParams() || {}, {
datasourceId: this._datasourceId,
sqlTableName: this._sqlTableName,
where: this._grid.getDockedComponent('paging').getComponent('where').getValue(),
limit: pageSize
}));
this._grid.getStore().setPageSize(pageSize);
}
else
{
// not parametrized yet
return false;
}
},
/**
* @private
* Fired when the strucure is send
* @param {Ext.data.Store} store The data store
* @param {Object} response The server side response for the metadata part
*/
_onMetaChange: function(store, response)
{
if (response.columnsHashcode != this._columnsHashCode)
{
response.columnsHashcode = this._columnsHashCode;
this.setTitle(this._sqlTableName + " (" + response.datasource + ")");
// Update model and columns
var fields = [{name: '_internal_id'}];
var columns = [];
for (var i = 0; i < response.columns.length; i++)
{
fields.push({ name: response.columns[i].name });
columns.push({ dataIndex: response.columns[i].name, text: response.columns[i].label, width: Math.max(100, Math.min(250, response.columns[i].displaySize*3)), renderer: Ext.bind(this._renderColumn, this) });
}
this._createModel(fields);
this._grid.reconfigure (this._grid.getStore(), columns);
}
},
/**
* @private
* Render the column to escape special characters
* @param {String} value The value
*/
_renderColumn: function(value)
{
return value ? value.replace(/</g, '<') : "<em><null></em>";
},
/**
* Creates the model for the store
* @param {Object[]} [fields] The fields for this model
* @private
*/
_createModel: function (fields)
{
fields = fields || [{name: '_internal_id'}];
this._modelName = this.getId() + "-Entry";
if (Ext.data.schema.Schema.get('default').hasEntity(this._modelName))
{
Ext.data.schema.Schema.get('default').getEntity(this._modelName).replaceFields(fields, true);
}
else
{
Ext.define(this._modelName, {
extend: 'Ext.data.Model',
schema: 'default',
idProperty: '_internal_id',
fields: fields
});
}
},
setParams: function(params)
{
this.callParent(arguments);
this._datasourceId = params['datasource-id'];
this._sqlTableName = params['table'];
this._columnsHashCode = 0;
this.setTitle("...");
this.refresh();
},
getMBSelectionInteraction: function()
{
return Ametys.tool.Tool.MB_TYPE_ACTIVE;
},
sendCurrentSelection : function()
{
var targets = [];
targets.push({
id: Ametys.message.MessageTarget.DATASOURCE_SQLTABLE,
parameters: {
id: this._datasourceId,
name: this._sqlTableName
}
});
Ext.create("Ametys.message.Message", {
type: Ametys.message.Message.SELECTION_CHANGED,
targets: targets
});
},
refresh: function ()
{
this.showRefreshing();
this._grid.getStore().load({callback: this.showRefreshed, scope: this});
},
/**
* @private
* Handler function invoked whenever a {@link Ametys.message.Message#MODIFIED} message is sent out on the
* message bus. Update the corresponding record of the grid panel's store.
* @param {Ametys.message.Message} message the message
*/
_onModified: function (message)
{
var targets = message.getTargets(Ametys.message.MessageTarget.DATASOURCE);
for (var i=0; i < targets.length; i++)
{
if (target.getParameters().id == this._datasourceId)
{
this.showOutOfDate();
break;
}
}
},
/**
* @private
* Handler function invoked whenever a {@link Ametys.message.Message#DELETED} message
* is sent out on the message bus. Delete the corresponding record from the grid panel's store.
* @param {Ametys.message.Message} message the message
*/
_onDeleted: function (message)
{
var targets = message.getTargets(Ametys.message.MessageTarget.DATASOURCE);
for (var i=0; i < targets.length; i++)
{
if (target.getParameters().id == this._datasourceId)
{
this.close();
break;
}
}
}
});