Merge branch 'master' of ssh://172.20.0.1/var/git/espo/backend

This commit is contained in:
Taras Machyshyn
2015-05-12 12:16:54 +03:00
14 changed files with 177 additions and 27 deletions
+7
View File
@@ -6,6 +6,13 @@ It's a web application with a frontend designed as a single page application bas
Download the latest release from our [website](http://www.espocrm.com).
### Requirements
* PHP 5.4 or above (with pdo, json, gd, mcrypt extensions);
* MySQL 5.1 or above.
For more information about server configuration see [this article](http://blog.espocrm.com/administration/server-configuration-for-espocrm/).
### How to report bug
Create an issue [here](https://github.com/espocrm/espocrm/issues) or post on our [forum](http://forum.espocrm.com/bug-reports?routestring=forum/bug-reports).
@@ -62,6 +62,12 @@ class EntityManager extends \Espo\Core\Controllers\Base
if (!empty($data['stream'])) {
$params['stream'] = $data['stream'];
}
if (!empty($data['sortBy'])) {
$params['sortBy'] = $data['sortBy'];
}
if (!empty($data['sortDirection'])) {
$params['asc'] = $data['sortDirection'] === 'asc';
}
$result = $this->getContainer()->get('entityManagerUtil')->create($name, $type, $params);
@@ -90,6 +96,10 @@ class EntityManager extends \Espo\Core\Controllers\Base
$name = $data['name'];
$name = filter_var($name, \FILTER_SANITIZE_STRING);
if (!empty($data['sortDirection'])) {
$data['asc'] = $data['sortDirection'] === 'asc';
}
$result = $this->getContainer()->get('entityManagerUtil')->update($name, $data);
if ($result) {
@@ -193,6 +193,16 @@ class EntityManager
$this->getLanguage()->set('Global', 'scopeNamesPlural', $name, $labelPlural);
}
if (isset($data['sortBy'])) {
$entityDefsData = array(
'collection' => array(
'sortBy' => $data['sortBy'],
'asc' => !empty($data['asc'])
)
);
$this->getMetadata()->set('entityDefs', $name, $entityDefsData);
}
$this->getMetadata()->save();
$this->getLanguage()->save();
+8
View File
@@ -184,6 +184,10 @@ class Stream extends \Espo\Core\Hooks\Base
$this->getStreamService()->noteCreate($entity);
}
if (in_array($this->getUser()->id, $userIdList)) {
$entity->set('isFollowed', true);
}
$autofollowUserIdList = $this->getAutofollowUserIdList($entity, $userIdList);
foreach ($autofollowUserIdList as $i => $userId) {
if (in_array($userId, $userIdList)) {
@@ -213,6 +217,10 @@ class Stream extends \Espo\Core\Hooks\Base
if (!empty($assignedUserId)) {
$this->getStreamService()->followEntity($entity, $assignedUserId);
$this->getStreamService()->noteAssign($entity);
if ($this->getUser()->id === $assignedUserId) {
$entity->set('isFollowed', true);
}
}
}
$this->getStreamService()->handleAudited($entity);
@@ -33,7 +33,7 @@ class Campaign extends \Espo\Services\Record
$sentCount = $this->getEntityManager()->getRepository('CampaignLogRecord')->where(array(
'campaignId' => $entity->id,
'action' => 'Clicked'
'action' => 'Sent'
))->count();
$entity->set('sentCount', $sentCount);
@@ -8,7 +8,8 @@
"port": "Port",
"monitoredFolders": "Monitored Folders",
"ssl": "SSL",
"fetchSince": "Fetch Since"
"fetchSince": "Fetch Since",
"emailAddress": "Email Address"
},
"links": {
},
@@ -14,7 +14,9 @@
"entityForeign": "Foreign Entity",
"linkForeign": "Foreign Link",
"link": "Link",
"labelForeign": "Foreign Label"
"labelForeign": "Foreign Label",
"sortBy": "Default Order (field)",
"sortDirection": "Default Order (direction)"
},
"options": {
"type": {
@@ -29,6 +31,10 @@
"manyToOne": "Many-to-One",
"parentToChildren": "Parent-to-Children",
"childrenToParent": "Children-to-Parent"
},
"sortDirection": {
"asc": "Ascending",
"desc": "Descending"
}
},
"messages": {
@@ -3,10 +3,11 @@
"label":"Main",
"rows":[
[
{"name":"name"},
{"name":"emailAddress"},
{"name":"status"}
],
[
{"name":"name"},
{"name":"fetchSince"}
]
]
@@ -4,6 +4,12 @@
"type": "varchar",
"required": true
},
"emailAddress": {
"type": "varchar",
"required": true,
"maxLength": 100,
"view": "EmailAccount.Fields.EmailAddress"
},
"status": {
"type": "enum",
"options": ["Active", "Inactive"]
@@ -26,13 +26,29 @@
</div>
</div>
</div>
{{#if stream}}
<div class="row">
{{#if stream}}
<div class="cell cell-stream form-group col-md-6">
<label class="field-label-stream control-label">{{translate 'stream' category='fields' scope='EntityManager'}}</label>
<div class="field field-stream">
{{{stream}}}
</div>
</div>
{{/if}}
</div>
{{/if}}
{{#if sortBy}}
<div class="row">
<div class="cell cell-sortBy form-group col-md-6">
<label class="field-label-sortBy control-label">{{translate 'sortBy' category='fields' scope='EntityManager'}}</label>
<div class="field field-sortBy">
{{{sortBy}}}
</div>
</div>
<div class="cell cell-sortDirection form-group col-md-6">
<label class="field-label-sortDirection control-label">{{translate 'sortDirection' category='fields' scope='EntityManager'}}</label>
<div class="field field-sortDirection">
{{{sortDirection}}}
</div>
</div>
</div>
{{/if}}
@@ -70,6 +70,9 @@ Espo.define('Views.Admin.EntityManager.Modals.EditEntity', 'Views.Modal', functi
this.model.set('labelPlural', this.translate(scope, 'scopeNamesPlural'));
this.model.set('type', this.getMetadata().get('scopes.' + scope + '.type') || '');
this.model.set('stream', this.getMetadata().get('scopes.' + scope + '.stream') || false);
this.model.set('sortBy', this.getMetadata().get('entityDefs.' + scope + '.collection.sortBy'));
this.model.set('sortDirection', this.getMetadata().get('entityDefs.' + scope + '.collection.asc') ? 'asc' : 'desc');
}
this.createView('type', 'Fields.Enum', {
@@ -131,6 +134,46 @@ Espo.define('Views.Admin.EntityManager.Modals.EditEntity', 'Views.Modal', functi
}
}
});
if (scope) {
var fieldDefs = this.getMetadata().get('entityDefs.' + scope + '.fields') || {}
var orderableFieldList = Object.keys(fieldDefs).filter(function (item) {
if (fieldDefs[item].notStorable) {
return false;
}
return true;
}, this);
var translatedOptions = {};
orderableFieldList.forEach(function (item) {
translatedOptions[item] = this.translate(item, 'fields', scope);
}, this);
this.createView('sortBy', 'Fields.Enum', {
model: model,
mode: 'edit',
el: this.options.el + ' .field-sortBy',
defs: {
name: 'sortBy',
params: {
options: orderableFieldList,
translatedOptions: translatedOptions
}
}
});
this.createView('sortDirection', 'Fields.Enum', {
model: model,
mode: 'edit',
el: this.options.el + ' .field-sortDirection',
defs: {
name: 'sortDirection',
params: {
options: ['asc', 'desc']
}
}
});
}
},
afterRender: function () {
@@ -162,6 +205,11 @@ Espo.define('Views.Admin.EntityManager.Modals.EditEntity', 'Views.Modal', functi
'stream'
];
if (this.scope) {
arr.push('sortBy');
arr.push('sortDirection');
}
var notValid = false;
arr.forEach(function (item) {
@@ -189,16 +237,23 @@ Espo.define('Views.Admin.EntityManager.Modals.EditEntity', 'Views.Modal', functi
var name = this.model.get('name');
var data = {
name: name,
labelSingular: this.model.get('labelSingular'),
labelPlural: this.model.get('labelPlural'),
type: this.model.get('type'),
stream: this.model.get('stream')
};
if (this.scope) {
data.sortBy = this.model.get('sortBy');
data.sortDirection = this.model.get('sortDirection');
}
$.ajax({
url: url,
type: 'POST',
data: JSON.stringify({
name: name,
labelSingular: this.model.get('labelSingular'),
labelPlural: this.model.get('labelPlural'),
type: this.model.get('type'),
stream: this.model.get('stream')
}),
data: JSON.stringify(data),
error: function () {
this.$el.find('button[data-name="save"]').removeClass('disabled');
}.bind(this)
+4 -14
View File
@@ -91,19 +91,11 @@ Espo.define('Views.Detail', 'Views.Main', function (Dep) {
if (this.getMetadata().get('scopes.' + this.scope + '.stream')) {
if (this.model.has('isFollowed')) {
this.handleFollowButton();
} else {
this.once('after:render', function () {
if (this.model.has('isFollowed')) {
this.handleFollowButton();
} else {
this.listenToOnce(this.model, 'sync', function () {
if (this.model.has('isFollowed')) {
this.handleFollowButton();
}
}, this);
}
}, this);
}
this.listenTo(this.model, 'change:isFollowed', function () {
this.handleFollowButton();
}, this);
}
},
@@ -144,7 +136,6 @@ Espo.define('Views.Detail', 'Views.Main', function (Dep) {
success: function () {
$el.remove();
this.model.set('isFollowed', true);
this.handleFollowButton();
}.bind(this),
error: function () {
$el.removeClass('disabled');
@@ -161,7 +152,6 @@ Espo.define('Views.Detail', 'Views.Main', function (Dep) {
success: function () {
$el.remove();
this.model.set('isFollowed', false);
this.handleFollowButton();
}.bind(this),
error: function () {
$el.removeClass('disabled');
@@ -0,0 +1,36 @@
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2015 Yuri Kuznetsov, Taras Machyshyn, Oleksiy Avramenko
* Website: http://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
Espo.define('Views.EmailAccount.Fields.EmailAddress', 'Views.Fields.Varchar', function (Dep) {
return Dep.extend({
setup: function () {
Dep.prototype.setup.call(this);
this.on('change', function () {
var emailAddress = this.model.get('emailAddress');
this.model.set('name', emailAddress);
}, this);
},
});
});
+4
View File
@@ -49,6 +49,10 @@ Espo.define('Views.Fields.Enum', ['Views.Fields.Base'], function (Dep) {
}
}
if ('translatedOptions' in this.params) {
this.translatedOptions = this.params.translatedOptions;
}
if (this.params.translation) {
var data = this.getLanguage().data;
var arr = this.params.translation.split('.');