/*
* 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 class provides a widget to query and select one or more users.
*
* This widget is the default widget registered for fields of type Ametys.form.WidgetManager#TYPE_USER.<br>
*/
Ext.define('Ametys.form.widget.User', {
extend: 'Ametys.form.AbstractQueryableComboBox',
valueField: 'value',
displayField: 'displayName',
/**
* @private
* @property {String[]} _contexts The contexts for the populations where to retrieve users
*/
/**
* @cfg {String[]} [contexts] The contexts for the populations where to retrieve users. Default to the default ametys contexts
*/
constructor: function(config)
{
config = config || {};
this._contexts = config.contexts ? Ext.Array.from(config.contexts) : Ametys.getAppParameter('populationContexts');
this.callParent(arguments);
},
getStore: function()
{
if (!Ext.data.schema.Schema.get('default').hasEntity('Ametys.form.widget.User.Users')) {
Ext.define("Ametys.form.widget.User.Users", {
extend: 'Ext.data.Model',
idProperty: 'value',
fields: [
{name: 'firstname', type: 'string'},
{name: 'lastname', type: 'string'},
{name: 'login', type: 'string'},
{name: 'populationId', type: 'string'},
{name: 'populationLabel', type: 'string'},
{
name: 'value',
type: 'string',
calculate: function(data)
{
return data.login + '#' + data.populationId;
}
},
{name: 'fullname', type: 'string'},
{name: 'sortablename', type: 'string'},
{
name: 'displayName',
type: 'string',
calculate: function (data)
{
return Ametys.helper.Users.renderUser(data.login, data.populationLabel, data.sortablename);
}
}
]
});
}
return Ext.create('Ext.data.Store', {
model: 'Ametys.form.widget.User.Users',
proxy: {
type: 'ametys',
role: "org.ametys.plugins.core.user.UserDAO",
methodName: "searchUsersByContexts",
methodArguments: ['contexts', 'limit', 'offset', 'searchCriteria', 'limitedToStoredUserData'],
reader: {
type: 'json',
rootProperty: 'users'
}
},
pageSize: this.maxResult,
sortOnLoad: true,
sorters: [{property: 'displayName', direction:'ASC'}],
listeners: {
beforeload: {fn: this._onStoreBeforeLoad, scope: this}
}
});
},
_convertToComparableValue: function(item)
{
if (!item)
{
return "";
}
else if (Ext.isString(item))
{
if (!item.startsWith('{'))
{
return item;
}
item = JSON.parse(item)
}
return item.login + '#' + item.populationId;
},
getValue: function ()
{
var value = this.callParent(arguments),
convertedValues = [];
value = Ext.Array.from(value);
var store = this.combobox.valueStore;
Ext.Array.forEach (value, function (val) {
var index = store.find('value', val);
if (index != -1)
{
// When editing field from a grid and to render correctly the value, we need populationLabel, sortablename or fullname (see Ametys.helper.Users.renderUser)
var record = store.getAt(index);
convertedValues.push({
login: record.get('login'),
populationId: record.get('populationId'),
populationLabel: record.get('populationLabel') || undefined, // undefined for an non existing user, otherwise '' would be considered as a modification by a grid edition
sortablename: record.get('sortablename') || undefined,
fullname: record.get('fullname') || undefined,
});
}
else
{
if (Ext.isString(val))
{
var parts = val.split('#');
convertedValues.push({
login: parts[0],
populationId: parts[1]
});
}
else if (val.isModel)
{
convertedValues.push({
login: val.get('login'),
populationId: val.get('populationId'),
populationLabel: val.get('populationLabel') || undefined, // undefined for an non existing user, otherwise '' would be considered as a modification by a grid edition
sortablename: val.get('sortablename') || undefined,
fullname: val.get('fullname') || undefined
});
}
else
{
convertedValues.push(Ext.clone(val));
}
}
});
return this.multiple ? convertedValues : convertedValues[0];
},
setValue: function(value)
{
value = value ? Ext.Array.from(value) : [];
var convertedValues = [];
Ext.Array.forEach(value, function(item) {
if (Ext.isObject(item))
{
let i = Ext.clone(item);
i.value = i.login + "#" + i.populationId
convertedValues.push(i);
}
else if (item == "CURRENT")
{
var currentUser = Ametys.getAppParameter("user");
if (currentUser)
{
let i = Ext.clone(currentUser);
i.value = i.login + "#" + i.populationId
convertedValues.push(i);
}
}
else
{
var userJson = Ext.JSON.decode(item, true /*safe to return null if it fails*/);
if (userJson == null)
{
// was not a JSON but a raw value
convertedValues.push(item);
}
else
{
userJson.value = userJson.login + "#" + userJson.populationId
convertedValues.push(userJson);
}
}
});
this.callParent([convertedValues]);
},
isEqual: function(val1, val2)
{
if (val1 == null && val2 == null)
{
return true;
}
else if (val1 == null || val2 == null)
{
return false;
}
else
{
return val1.login == val2.login && val1.populationId == val2.populationId;
}
},
/**
* Set the request parameters before loading the store.
* @param {Ext.data.Store} store The store.
* @param {Ext.data.operation.Operation} operation The Ext.data.Operation object that will be passed to the Proxy to load the Store.
* @protected
*/
_onStoreBeforeLoad: function(store, operation)
{
var proxy = operation.getProxy();
proxy.setExtraParam('contexts', this._contexts);
proxy.setExtraParam('limit', this.maxResult);
proxy.setExtraParam('offset', 0);
proxy.setExtraParam('searchCriteria', operation.getParams().query);
},
getSubmitValue: function ()
{
var value = this.getValue();
return value != null ? Ext.encode(this.getValue()) : null;
},
getLabelTpl: function ()
{
return [
'<tpl if="!sortablename && !fullname"><span class="a-widget-user-unknown"></tpl>',
'<img src="{[Ametys.helper.Users.getUserImage(values.login, values.populationId, 16)]}" style="float: left; margin-right: 3px; width: 16px; height: 16px;"/>',
'{displayName}',
'<tpl if="!sortablename && !fullname"></span></tpl>'
];
}
});