This commit is contained in:
yuri
2016-01-11 16:02:03 +02:00
parent f6f58c679d
commit e7afe68868
46 changed files with 538 additions and 121 deletions
+1 -4
View File
@@ -29,10 +29,7 @@
require_once('../../../bootstrap.php');
//print_r($_SERVER);
//die;
$portalId = '567d4a0503c88c061';
$portalId = explode('/', $_SERVER['REQUEST_URI'])[count(explode('/', $_SERVER['SCRIPT_NAME'])) - 1];
$app = new \Espo\Core\ApplicationPortal($portalId);
$app->run();
+5 -2
View File
@@ -35,9 +35,12 @@ use \Espo\Core\Exceptions\Error;
class Email extends \Espo\Core\Controllers\Record
{
public function actionGetCopiedAttachments($params, $data, $request)
public function postActionGetCopiedAttachments($params, $data, $request)
{
$id = $request->get('id');
if (empty($data['id'])) {
throw new BadRequest();
}
$id = $data['id'];
return $this->getRecordService()->getCopiedAttachments($id);
}
@@ -37,6 +37,13 @@ class ExternalAccount extends \Espo\Core\Controllers\Record
{
public static $defaultAction = 'list';
protected function checkControllerAccess()
{
if (!$this->getAcl()->checkScope('ExternalAccount')) {
throw new Forbidden();
}
}
public function actionList($params, $data, $request)
{
$integrations = $this->getEntityManager()->getRepository('Integration')->find();
+2 -1
View File
@@ -215,7 +215,8 @@ class Container
{
return new \Espo\Core\Utils\Layout(
$this->get('fileManager'),
$this->get('metadata')
$this->get('metadata'),
$this->get('user')
);
}
+10
View File
@@ -63,6 +63,16 @@ class ContainerPortal extends Container
$this->get('portal')
);
}
protected function loadLayout()
{
return new \Espo\Core\Utils\LayoutPortal(
$this->get('fileManager'),
$this->get('metadata'),
$this->get('user')
);
}
public function setPortal(\Espo\Entities\Portal $portal)
{
$this->set('portal', $portal);
@@ -47,6 +47,11 @@ class RDB extends \Espo\ORM\Repositories\RDB implements Injectable
private $restoreData = null;
protected function addDependency($name)
{
$this->dependencies[] = $name;
}
public function inject($name, $object)
{
$this->injections[$name] = $object;
+18 -18
View File
@@ -28,18 +28,16 @@
************************************************************************/
namespace Espo\Core\Utils;
class Layout
{
private $fileManager;
private $metadata;
private $changedData = array();
private $user;
/**
* @var string - uses for loading default values
*/
private $name = 'layout';
protected $changedData = array();
protected $params = array(
'defaultsPath' => 'application/Espo/Core/defaults',
@@ -49,17 +47,18 @@ class Layout
/**
* @var array - path to layout files
*/
private $paths = array(
protected $paths = array(
'corePath' => 'application/Espo/Resources/layouts',
'modulePath' => 'application/Espo/Modules/{*}/Resources/layouts',
'customPath' => 'custom/Espo/Custom/Resources/layouts',
);
public function __construct(\Espo\Core\Utils\File\Manager $fileManager, \Espo\Core\Utils\Metadata $metadata)
public function __construct(\Espo\Core\Utils\File\Manager $fileManager, \Espo\Core\Utils\Metadata $metadata, \Espo\Entities\User $user)
{
$this->fileManager = $fileManager;
$this->metadata = $metadata;
$this->user = $user;
}
protected function getFileManager()
@@ -72,6 +71,11 @@ class Layout
return $this->metadata;
}
protected function getUser()
{
return $this->user;
}
protected function sanitizeInput($name)
{
return preg_replace("([\.]{2,})", '', $name);
@@ -94,16 +98,14 @@ class Layout
return Json::encode($this->changedData[$scope][$name]);
}
$fileFullPath = Util::concatPath($this->getLayoutPath($scope, true), $name.'.json');
$fileFullPath = Util::concatPath($this->getLayoutPath($scope, true), $name . '.json');
if (!file_exists($fileFullPath)) {
$fileFullPath = Util::concatPath($this->getLayoutPath($scope), $name.'.json');
$fileFullPath = Util::concatPath($this->getLayoutPath($scope), $name . '.json');
}
if (!file_exists($fileFullPath)) {
//load defaults
$defaultPath = $this->params['defaultsPath'];
$fileFullPath = Util::concatPath( Util::concatPath($defaultPath, $this->name), $name.'.json' );
//END: load defaults
$fileFullPath = Util::concatPath(Util::concatPath($defaultPath, 'layouts'), $name . '.json' );
if (!file_exists($fileFullPath)) {
return false;
@@ -162,11 +164,9 @@ class Layout
if (!empty($this->changedData)) {
foreach ($this->changedData as $scope => $rowData) {
foreach ($rowData as $layoutName => $layoutData) {
if (empty($scope) || empty($layoutName)) {
continue;
}
$layoutPath = $this->getLayoutPath($scope, true);
$data = Json::encode($layoutData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
@@ -221,17 +221,17 @@ class Layout
/**
* Get Layout path, ex. application/Modules/Crm/Layouts/Account
*
* @param string $entityName
* @param string $entityType
* @param bool $isCustom - if need to check custom folder
*
* @return string
*/
protected function getLayoutPath($entityName, $isCustom = false)
protected function getLayoutPath($entityType, $isCustom = false)
{
$path = $this->paths['customPath'];
if (!$isCustom) {
$moduleName = $this->getMetadata()->getScopeModuleName($entityName);
$moduleName = $this->getMetadata()->getScopeModuleName($entityType);
$path = $this->paths['corePath'];
if ($moduleName !== false) {
@@ -239,7 +239,7 @@ class Layout
}
}
$path = Util::concatPath($path, $entityName);
$path = Util::concatPath($path, $entityType);
return $path;
}
@@ -0,0 +1,127 @@
<?php
/************************************************************************
* 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/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Core\Utils;
class LayoutPortal extends Layout
{
public function get($scope, $name)
{
$scope = $this->sanitizeInput($scope);
$name = $this->sanitizeInput($name);
if (isset($this->changedData[$scope][$name])) {
return Json::encode($this->changedData[$scope][$name]);
}
$fileFullPath = Util::concatPath($this->getLayoutPath($scope, true), 'portal/' . $name . '.json');
if (!file_exists($fileFullPath)) {
$fileFullPath = Util::concatPath($this->getLayoutPath($scope), 'portal/' . $name . '.json');
}
if (!file_exists($fileFullPath)) {
$fileFullPath = Util::concatPath($this->getLayoutPath($scope, true), $name . '.json');
}
if (!file_exists($fileFullPath)) {
$fileFullPath = Util::concatPath($this->getLayoutPath($scope), $name . '.json');
}
if (!file_exists($fileFullPath)) {
$defaultPath = $this->params['defaultsPath'];
$fileFullPath = Util::concatPath(Util::concatPath($defaultPath, 'layouts'), $name . '.json' );
if (!file_exists($fileFullPath)) {
return false;
}
}
return $this->getFileManager()->getContents($fileFullPath);
}
public function set($data, $scope, $name)
{
$scope = $this->sanitizeInput($scope);
$name = $this->sanitizeInput($name);
if (empty($scope) || empty($name)) {
return false;
}
$this->changedData[$scope][$name] = $data;
}
public function resetToDefault($scope, $name)
{
$scope = $this->sanitizeInput($scope);
$name = $this->sanitizeInput($name);
$filePath = 'custom/Espo/Custom/Resources/layouts/' . $scope . '/' . $name . '.json';
if ($this->getFileManager()->isFile($filePath)) {
$this->getFileManager()->removeFile($filePath);
}
if (!empty($this->changedData[$scope]) && !empty($this->changedData[$scope][$name])) {
unset($this->changedData[$scope][$name]);
}
return $this->get($scope, $name);
}
/**
* Save changes
*
* @return bool
*/
public function save()
{
$result = true;
if (!empty($this->changedData)) {
foreach ($this->changedData as $scope => $rowData) {
foreach ($rowData as $layoutName => $layoutData) {
if (empty($scope) || empty($layoutName)) {
continue;
}
$layoutPath = $this->getLayoutPath($scope, true);
$data = Json::encode($layoutData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$result &= $this->getFileManager()->putContents(array($layoutPath, $layoutName.'.json'), $data);
}
}
}
if ($result == true) {
$this->clearChanges();
}
return (bool) $result;
}
}
+7 -4
View File
@@ -39,13 +39,16 @@ class Portal extends \Espo\Core\EntryPoints\Base
public function run()
{
if (empty($_GET['id'])) {
throw new BadRequest();
if (!empty($_GET['id'])) {
$id = $_GET['id'];
} else {
$id = $this->getConfig()->get('defaultPortalId');
if (!$id) {
throw new NotFound();
}
}
$id = $_GET['id'];
$application = new \Espo\Core\ApplicationPortal($id);
$application->runClient();
}
}
+1 -1
View File
@@ -25,7 +25,7 @@
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
************************************************************************/
namespace Espo\Repositories;
+62
View File
@@ -0,0 +1,62 @@
<?php
/************************************************************************
* 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/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Repositories;
use Espo\ORM\Entity;
use \Espo\Core\Exceptions\Error;
class Portal extends \Espo\Core\ORM\Repositories\RDB
{
protected function init()
{
$this->addDependency('config');
}
protected function getConfig()
{
return $this->getInjection('config');
}
protected function afterSave(Entity $entity, array $options)
{
parent::afterSave($entity, $options);
if ($entity->has('isDefault')) {
if ($entity->get('isDefault')) {
$this->getConfig()->set('defaultPortalId', $entity->id);
} else {
$this->getConfig()->set('defaultPortalId', null);
}
$this->getConfig()->save();
}
}
}
@@ -74,6 +74,7 @@
"onlyMyTeam": "Only My Team"
},
"presetFilters": {
"active": "Active"
"active": "Active",
"activePortal": "Portal"
}
}
@@ -3,7 +3,8 @@
"label": "General",
"rows": [
[{"name": "name"}, {"name": "isActive"}],
[{"name": "url"}, {"name": "isDefault"}]
[{"name": "url"}, {"name": "isDefault"}],
[{"name": "portalRoles"}, false]
]
},
{
@@ -0,0 +1,31 @@
[
{
"label": "Locale",
"rows": [
[{"name": "dateFormat"}, {"name": "timeFormat"}],
[{"name": "timeZone"}, {"name": "weekStart"}],
[{"name": "defaultCurrency"}, false],
[{"name": "thousandSeparator"}, {"name": "decimalMark"}],
[{"name": "language"}, false]
]
},
{
"label": "Misc",
"rows": [
[{"name": "exportDelimiter"}, {"name":"autoFollowEntityTypeList"}]
]
},
{
"label": "User Interface",
"rows": [
[
{"name":"theme"},
false
],
[
{"name":"useCustomTabList"},
{"name":"tabList"}
]
]
}
]
@@ -20,6 +20,7 @@
"delete": "own"
},
"EmailAccount": false,
"ExternalAccount": false,
"Role": false,
"PortalRole": false,
"EmailFilter": false,
@@ -2,9 +2,10 @@
"controller": "controllers/record",
"relationshipPanels": {
"users": {
"create": true,
"create": false,
"rowActionsView": "views/record/row-actions/relationship-unlink-only",
"layout": "listForTeam"
"layout": "listSmall",
"selectPrimaryFilterName": "activePortal"
}
},
"recordViews": {
@@ -1,15 +1,16 @@
{
"relationshipPanels":{
"relationshipPanels": {
"users":{
"create":false,
"rowActionsView": "Record.RowActions.RelationshipUnlinkOnly",
"layout":"listForTeam"
"create": false,
"rowActionsView": "views/record/row-actions/relationship-unlink-only",
"layout": "listForTeam",
"selectPrimaryFilterName": "active"
}
},
"recordViews":{
"detail":"Team.Record.Detail",
"edit":"Team.Record.Edit",
"list":"Team.Record.List"
"recordViews": {
"detail": "views/team/record/detail",
"edit": "views/team/record/edit",
"list": "views/team/record/list"
},
"boolFilterList": ["onlyMy"]
}
@@ -9,6 +9,6 @@
"editQuick":"User.Record.Edit",
"list":"User.Record.List"
},
"filterList": ["active"],
"filterList": ["active","activePortal"],
"boolFilterList": ["onlyMyTeam"]
}
@@ -28,12 +28,12 @@
"tabList": {
"type": "array",
"translation": "Global.scopeNamesPlural",
"view": "views/settings/fields/tab-list"
"view": "views/portal/fields/tab-list"
},
"quickCreateList": {
"type": "array",
"translation": "Global.scopeNames",
"view": "views/settings/fields/quick-create-list"
"view": "views/portal/fields/quick-create-list"
},
"companyLogo": {
"type": "image"
@@ -2,6 +2,7 @@
"entity":true,
"layouts":false,
"tab":false,
"acl":false,
"acl": "boolean",
"aclPortal": false,
"customizable":false
}
+1 -1
View File
@@ -53,7 +53,7 @@ class User extends \Espo\Core\SelectManagers\Base
);
}
protected function filterActivePortalUsers(&$result)
protected function filterActivePortal(&$result)
{
$result['whereClause'][] = array(
'isActive' => true,
+34 -26
View File
@@ -34,6 +34,9 @@ use \Espo\Entities;
use \Espo\Core\Exceptions\Error;
use \Espo\Core\Exceptions\Forbidden;
use \Espo\Core\Exceptions\NotFound;
use \Espo\Core\Exceptions\BadRequest;
class Email extends Record
{
@@ -548,36 +551,41 @@ class Email extends Record
$ids = array();
$names = new \stdClass();
if (!empty($id)) {
$email = $this->getEntityManager()->getEntity('Email', $id);
if ($email && $this->getAcl()->check($email, 'read')) {
$email->loadLinkMultipleField('attachments');
$attachmentsIds = $email->get('attachmentsIds');
if (empty($id)) {
throw new BadRequest();
}
$email = $this->getEntityManager()->getEntity('Email', $id);
if (!$email) {
throw new NotFound();
}
if (!$this->getAcl()->checkEntity($email, 'read')) {
throw new Forbidden();
}
$email->loadLinkMultipleField('attachments');
$attachmentsIds = $email->get('attachmentsIds');
foreach ($attachmentsIds as $attachmentId) {
$source = $this->getEntityManager()->getEntity('Attachment', $attachmentId);
if ($source) {
$attachment = $this->getEntityManager()->getEntity('Attachment');
$attachment->set('role', 'Attachment');
$attachment->set('type', $source->get('type'));
$attachment->set('size', $source->get('size'));
$attachment->set('global', $source->get('global'));
$attachment->set('name', $source->get('name'));
foreach ($attachmentsIds as $attachmentId) {
$source = $this->getEntityManager()->getEntity('Attachment', $attachmentId);
if ($source) {
$attachment = $this->getEntityManager()->getEntity('Attachment');
$attachment->set('role', 'Attachment');
$attachment->set('type', $source->get('type'));
$attachment->set('size', $source->get('size'));
$attachment->set('global', $source->get('global'));
$attachment->set('name', $source->get('name'));
if (!empty($parentType) && !empty($parentId)) {
$attachment->set('parentType', $parentType);
$attachment->set('parentId', $parentId);
}
if (!empty($parentType) && !empty($parentId)) {
$attachment->set('parentType', $parentType);
$attachment->set('parentId', $parentId);
}
$this->getEntityManager()->saveEntity($attachment);
$this->getEntityManager()->saveEntity($attachment);
$contents = $this->getFileManager()->getContents('data/upload/' . $source->id);
if (!empty($contents)) {
$this->getFileManager()->putContents('data/upload/' . $attachment->id, $contents);
$ids[] = $attachment->id;
$names->{$attachment->id} = $attachment->get('name');
}
}
$contents = $this->getFileManager()->getContents('data/upload/' . $source->id);
if (!empty($contents)) {
$this->getFileManager()->putContents('data/upload/' . $attachment->id, $contents);
$ids[] = $attachment->id;
$names->{$attachment->id} = $attachment->get('name');
}
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
/************************************************************************
* 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/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Services;
use \Espo\ORM\Entity;
class Portal extends Record
{
public function loadAdditionalFields(Entity $entity)
{
parent::loadAdditionalFields($entity);
$siteUrl = $this->getConfig()->get('siteUrl');
$url = $siteUrl . '?entryPoint=portal';
if ($entity->id === $this->getConfig()->get('defaultPortalId')) {
$entity->set('isDefault', true);
} else {
$url .= '&id=' . $entity->id;
}
$entity->set('url', $url);
}
}
@@ -4,7 +4,7 @@
<div class="pull-right btn-group">
{{#if buttonList}}
{{#each buttonList}}
<button type="button" class="btn btn-default btn-sm action{{#if hidden}} hidden{{/if}}" data-action="{{action}}" data-panel="{{../../name}}" {{#each data}} data-{{@key}}="{{./this}}"{{/each}} title="{{translate title scope=../../scope}}">{{#if html}}{{{html}}}{{else}}{{translate label scope=../scope}}{{/if}}</button>
<button type="button" class="btn btn-default btn-sm action{{#if hidden}} hidden{{/if}}" data-action="{{action}}" data-panel="{{../../name}}" {{#each data}} data-{{hyphen @key}}="{{./this}}"{{/each}} title="{{translate title scope=../../scope}}">{{#if html}}{{{html}}}{{else}}{{translate label scope=../scope}}{{/if}}</button>
{{/each}}
{{/if}}
{{#if actionList}}
@@ -13,7 +13,7 @@
</button>
<ul class="dropdown-menu">
{{#each actionList}}
<li><a {{#if link}}href="{{link}}"{{else}}href="javascript:"{{/if}} class="action{{#if hidden}} hidden{{/if}}" data-panel="{{../../name}}" {{#if action}} data-action={{action}}{{/if}}{{#each data}} data-{{@key}}="{{./this}}"{{/each}}>{{#if html}}{{{html}}}{{else}}{{translate label scope=../scope}}{{/if}}</a></li>
<li><a {{#if link}}href="{{link}}"{{else}}href="javascript:"{{/if}} class="action{{#if hidden}} hidden{{/if}}" data-panel="{{../../name}}" {{#if action}} data-action={{action}}{{/if}}{{#each data}} data-{{hyphen @key}}="{{./this}}"{{/each}}>{{#if html}}{{{html}}}{{else}}{{translate label scope=../scope}}{{/if}}</a></li>
{{/each}}
</ul>
{{/if}}
@@ -5,7 +5,7 @@
<div class="pull-right btn-group">
{{#if buttonList}}
{{#each buttonList}}
<button type="button" class="btn btn-default btn-sm action{{#if hidden}} hidden{{/if}}" data-action="{{action}}" data-panel="{{../../name}}" {{#each data}} data-{{@key}}="{{./this}}"{{/each}} title="{{translate title scope=../scope}}">{{#if html}}{{{html}}}{{else}}{{translate label scope=../scope}}{{/if}}</button>
<button type="button" class="btn btn-default btn-sm action{{#if hidden}} hidden{{/if}}" data-action="{{action}}" data-panel="{{../../name}}" {{#each data}} data-{{hyphen @key}}="{{./this}}"{{/each}} title="{{translate title scope=../scope}}">{{#if html}}{{{html}}}{{else}}{{translate label scope=../scope}}{{/if}}</button>
{{/each}}
{{/if}}
{{#if actionList}}
@@ -14,7 +14,7 @@
</button>
<ul class="dropdown-menu">
{{#each actionList}}
<li><a {{#if link}}href="{{link}}"{{else}}href="javascript:"{{/if}} class="action{{#if hidden}} hidden{{/if}}" {{#if action}} data-panel="{{../../name}}" data-action="{{action}}"{{/if}}{{#each data}} data-{{@key}}="{{./this}}"{{/each}}>{{#if html}}{{{html}}}{{else}}{{translate label scope=../scope}}{{/if}}</a></li>
<li><a {{#if link}}href="{{link}}"{{else}}href="javascript:"{{/if}} class="action{{#if hidden}} hidden{{/if}}" {{#if action}} data-panel="{{../../name}}" data-action="{{action}}"{{/if}}{{#each data}} data-{{hyphen @key}}="{{./this}}"{{/each}}>{{#if html}}{{{html}}}{{else}}{{translate label scope=../scope}}{{/if}}</a></li>
{{/each}}
</ul>
{{/if}}
+4 -1
View File
@@ -35,6 +35,8 @@ Espo.define(
var App = function (options, callback) {
var options = options || {};
this.id = options.id || 'espocrm-application-id';
this.useCache = options.useCache || this.useCache;
this.url = options.url || this.url;
@@ -159,6 +161,7 @@ Espo.define(
this.settings.defs = this.metadata.get('entityDefs.Settings');
this.user.defs = this.metadata.get('entityDefs.User');
this.preferences.defs = this.metadata.get('entityDefs.Preferences');
this.viewHelper.layoutManager.userId = this.user.id;
if (this.themeManager.isUserTheme()) {
$('#main-stylesheet').attr('href', this.themeManager.getStylesheet());
@@ -295,7 +298,7 @@ Espo.define(
initView: function () {
var helper = this.viewHelper = new ViewHelper();
helper.layoutManager = new LayoutManager({cache: this.cache});
helper.layoutManager = new LayoutManager({cache: this.cache, applicationId: this.id});
helper.settings = this.settings;
helper.user = this.user;
helper.preferences = this.preferences;
+18 -13
View File
@@ -28,11 +28,13 @@
Espo.define('layout-manager', [], function () {
var LayoutManager = function (options) {
var LayoutManager = function (options, userId) {
var options = options || {};
this.cache = options.cache || null;
this.applicationId = options.applicationId || 'default-id';
this.data = {};
this.ajax = $.ajax;
this.userId = userId;
}
_.extend(LayoutManager.prototype, {
@@ -41,11 +43,14 @@ Espo.define('layout-manager', [], function () {
data: null,
_getKey: function (scope, type) {
return scope + '-' + type;
getKey: function (scope, type) {
if (this.userId) {
return this.applicationId + '-' + this.userId + '-' + scope + '-' + type;
}
return this.applicationId + '-' + scope + '-' + type;
},
_getUrl: function (scope, type) {
getUrl: function (scope, type) {
return scope + '/layout/' + type;
},
@@ -54,7 +59,7 @@ Espo.define('layout-manager', [], function () {
cache = true;
}
var key = this._getKey(scope, type);
var key = this.getKey(scope, type);
if (cache) {
if (key in this.data) {
@@ -65,7 +70,7 @@ Espo.define('layout-manager', [], function () {
}
}
if (this.cache !== null && cache) {
if (this.cache && cache) {
var cached = this.cache.get('app-layout', key);
if (cached) {
if (typeof callback === 'function') {
@@ -77,7 +82,7 @@ Espo.define('layout-manager', [], function () {
}
this.ajax({
url: this._getUrl(scope, type),
url: this.getUrl(scope, type),
type: 'GET',
dataType: 'json',
success: function (layout) {
@@ -85,7 +90,7 @@ Espo.define('layout-manager', [], function () {
callback(layout);
}
this.data[key] = layout;
if (this.cache !== null) {
if (this.cache) {
this.cache.set('app-layout', key, layout);
}
}.bind(this)
@@ -93,14 +98,14 @@ Espo.define('layout-manager', [], function () {
},
set: function (scope, type, layout, callback) {
var key = this._getKey(scope, type);
var key = this.getKey(scope, type);
this.ajax({
url: this._getUrl(scope, type),
url: this.getUrl(scope, type),
type: 'PUT',
data: JSON.stringify(layout),
success: function () {
if (this.cache !== null) {
if (this.cache && key) {
this.cache.set('app-layout', key, layout);
}
this.data[key] = layout;
@@ -113,7 +118,7 @@ Espo.define('layout-manager', [], function () {
},
resetToDefault: function (scope, type, callback) {
var key = this._getKey(scope, type);
var key = this.getKey(scope, type);
this.ajax({
url: 'Layout/action/resetToDefault',
@@ -123,7 +128,7 @@ Espo.define('layout-manager', [], function () {
name: type
}),
success: function (layout) {
if (this.cache !== null) {
if (this.cache) {
this.cache.clear('app-layout', key);
}
this.data[key] = layout;
+4 -2
View File
@@ -187,6 +187,8 @@ Espo.define('views/detail', 'views/main', function (Dep) {
selectBoolFilterLists: [],
actionCreateRelated: function (data) {
data = data || {};
var link = data.link;
var scope = this.model.defs['links'][link].entity;
var foreignLink = this.model.defs['links'][link].foreign;
@@ -252,12 +254,12 @@ Espo.define('views/detail', 'views/main', function (Dep) {
}
}
var primaryFilterName = this.selectPrimaryFilterNames[link] || null;
var primaryFilterName = data.primaryFilterName || this.selectPrimaryFilterNames[link] || null;
if (typeof primaryFilterName == 'function') {
primaryFilterName = primaryFilterName.call(this);
}
var boolFilterList = Espo.Utils.cloneDeep(this.selectBoolFilterLists[link] || []);
var boolFilterList = data.boolFilterList || Espo.Utils.cloneDeep(this.selectBoolFilterLists[link] || []);
if (typeof boolFilterList == 'function') {
boolFilterList = boolFilterList.call(this);
}
+4 -4
View File
@@ -351,16 +351,16 @@ Espo.define('views/email/detail', ['views/detail', 'email-helper'], function (De
$.ajax({
url: 'Email/action/getCopiedAttachments',
type: 'GET',
data: {
type: 'POST',
data: JSON.stringify({
id: this.model.id
}
})
}).done(function (data) {
attributes['attachmentsIds'] = data.ids;
attributes['attachmentsNames'] = data.names;
this.notify('Loading...');
this.createView('quickCreate', 'Modals.ComposeEmail', {
this.createView('quickCreate', 'views/modals/compose-email', {
attributes: attributes,
}, function (view) {
view.render(function () {
@@ -172,7 +172,7 @@ Espo.define('views/fields/attachment-multiple', 'views/fields/base', function (D
getImageUrl: function (id, size) {
var url = '?entryPoint=image&id=' + id;
if (size) {
size += '&size=' + size;
url += '&size=' + size;
}
if (this.getUser().get('portalId')) {
url += '&portalId=' + this.getUser().get('portalId');
+1 -1
View File
@@ -189,7 +189,7 @@ Espo.define('views/fields/file', 'views/fields/link', function (Dep) {
getImageUrl: function (id, size) {
var url = '?entryPoint=image&id=' + id;
if (size) {
size += '&size=' + size;
url += '&size=' + size;
}
if (this.getUser().get('portalId')) {
url += '&portalId=' + this.getUser().get('portalId');
+1 -1
View File
@@ -46,7 +46,7 @@ Espo.define('views/fields/image', 'views/fields/file', function (Dep) {
if ('previewSize' in this.params && this.params.previewSize) {
this.previewSize = this.params.previewSize;
}
},
}
});
});
@@ -0,0 +1,45 @@
/************************************************************************
* 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/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('views/portal/fields/quick-create-list', 'views/settings/fields/quick-create-list', function (Dep) {
return Dep.extend({
setup: function () {
Dep.prototype.setup.call(this);
this.params.options = this.params.options.filter(function (tab) {
if (!!this.getMetadata().get('scopes.' + tab + '.aclPortal')) {
return true;
}
}, this);
},
});
});
@@ -0,0 +1,45 @@
/************************************************************************
* 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/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('views/portal/fields/tab-list', 'views/settings/fields/tab-list', function (Dep) {
return Dep.extend({
setup: function () {
Dep.prototype.setup.call(this);
this.params.options = this.params.options.filter(function (tab) {
if (!!this.getMetadata().get('scopes.' + tab + '.aclPortal')) {
return true;
}
}, this);
},
});
});
@@ -89,12 +89,17 @@ Espo.define('views/record/panels/relationship', ['views/record/panels/bottom', '
}
if (this.defs.select) {
var data = {link: this.link};
if (this.defs.selectPrimaryFilterName) {
data.primaryFilterName = this.defs.selectPrimaryFilterName;
}
if (this.defs.selectBoolFilterList) {
data.boolFilterList = this.defs.selectBoolFilterList;
}
this.actionList.unshift({
label: 'Select',
action: this.defs.selectAction || 'selectRelated',
data: {
link: this.link,
}
data: data
});
}
+19 -18
View File
@@ -50,7 +50,7 @@ Espo.define('views/user/detail', 'views/detail', function (Dep) {
});
}
if (this.model.id == this.getUser().id) {
if (this.model.id == this.getUser().id && this.getAcl().checkScope('ExternalAccount')) {
this.menu.buttons.push({
name: 'externalAccounts',
label: 'External Accounts',
@@ -60,26 +60,27 @@ Espo.define('views/user/detail', 'views/detail', function (Dep) {
}
}
var showActivities = this.getAcl().checkUserPermission(this.model);
if (!showActivities) {
if (this.getAcl().get('userPermission') === 'team') {
if (!this.model.has('teamsIds')) {
this.listenToOnce(this.model, 'sync', function () {
if (this.getAcl().checkUserPermission(this.model)) {
this.showHeaderActionItem('calendar');
}
}, this);
if (this.getAcl().checkScope('Calendar')) {
var showActivities = this.getAcl().checkUserPermission(this.model);
if (!showActivities) {
if (this.getAcl().get('userPermission') === 'team') {
if (!this.model.has('teamsIds')) {
this.listenToOnce(this.model, 'sync', function () {
if (this.getAcl().checkUserPermission(this.model)) {
this.showHeaderActionItem('calendar');
}
}, this);
}
}
}
this.menu.buttons.push({
name: 'calendar',
html: this.translate('Calendar', 'scopeNames'),
style: 'default',
link: '#Calendar/show/userId=' + this.model.id + '&userName=' + this.model.get('name'),
hidden: !showActivities
});
}
this.menu.buttons.push({
name: 'calendar',
html: this.translate('Calendar', 'scopeNames'),
style: 'default',
link: '#Calendar/show/userId=' + this.model.id + '&userName=' + this.model.get('name'),
hidden: !showActivities
});
},
actionPreferences: function () {
+1
View File
@@ -36,6 +36,7 @@
$(function () {
Espo.require('app-portal', function (App) {
var app = new App({
id: '{{portalId}}',
useCache: false,
url: '../api/v1/portal/{{portalId}}',
}, function (app) {
+1
View File
@@ -15,6 +15,7 @@
$(function () {
Espo.require('app-portal', function (App) {
var app = new App({
id: '{{portalId}}',
useCache: {{useCache}},
cacheTimestamp: {{cacheTimestamp}},
url: '../api/v1/portal/{{portalId}}',