Compare commits

...

53 Commits

Author SHA1 Message Date
yuri 1b7aa9e48c css fixes 2018-01-19 12:39:59 +02:00
yuri 51fd3e681c css fix 2018-01-18 16:38:17 +02:00
yuri 484510f763 css fix 2018-01-18 15:50:26 +02:00
yuri 7fde7327fe css fixes 2018-01-18 15:14:28 +02:00
tanyalei 256d30847e PDF: Images rendered not properly in footer FIX (#768) 2018-01-18 14:11:14 +02:00
yuri 0bbfee8716 timeline fixes 2018-01-18 11:53:23 +02:00
yuri 8d58e81d28 email account list fix 2018-01-18 11:41:22 +02:00
yuri 8fb80d12c9 portal hide custom tab list 2018-01-18 11:26:49 +02:00
yuri dccd5305e7 css fix 2018-01-17 17:04:29 +02:00
yuri bbb418d2af fix select record w/ categories 2018-01-17 15:27:45 +02:00
yuri a5bae56f8d cleanup 2018-01-17 14:56:28 +02:00
yuri e9750e145f kb: hide side for portal 2018-01-17 14:35:11 +02:00
yuri 451aa7f5da relatonshipsPortal layout 2018-01-17 13:34:25 +02:00
yuri 43ee6ef8f6 css fix 2018-01-17 13:28:38 +02:00
yuri c366e8decc search filters disabled for portal 2018-01-17 13:22:48 +02:00
yuri 8610c61c18 fix css 2018-01-17 13:12:07 +02:00
yuri bee3a3b012 update vis 2018-01-17 12:57:54 +02:00
yuri dc2d46ca21 noAppCache param for libs 2018-01-17 12:41:22 +02:00
yuri 8bc633aed9 fix preset filter for ie 2018-01-17 12:17:16 +02:00
yuri ee3dee0570 fixc wysiwyg for ie 2018-01-17 12:11:05 +02:00
yuri 69048d8f89 fix css 2018-01-17 12:04:19 +02:00
yuri 427025c2ed storage fixes 2018-01-17 11:36:33 +02:00
yuri a8be115d4b fix service populateDefaults 2018-01-16 17:12:32 +02:00
yuri e4b357e8d3 loading and caching impovements 2018-01-16 15:23:51 +02:00
yuri 560a7b2465 markdown disable tables 2018-01-16 12:56:59 +02:00
yuri acfe05297b cache set try catch 2018-01-16 11:48:55 +02:00
yuri 2dcf81a516 css fix 2018-01-16 11:12:39 +02:00
yuri 44f379e3d2 fix wysiwyg 2018-01-16 10:49:11 +02:00
yuri 9be406c0a2 fix categories 2018-01-15 16:31:37 +02:00
yuri c9ca3a497f wysywyg resize fix 2018-01-15 16:14:21 +02:00
yuri 71886cd91c role action title 2018-01-15 14:50:00 +02:00
yuri 9829ca8d28 ff textarea fix 2018-01-15 14:44:22 +02:00
yuri 14de81520b job: fix failed attempts 2018-01-15 14:23:05 +02:00
yuri 3a11d335a2 fix css 2018-01-15 12:51:03 +02:00
yuri 0d3554cc49 file upload ready validation 2018-01-15 12:50:48 +02:00
yuri 8c5a455f08 fix assigned permission issues 2018-01-15 11:55:21 +02:00
yuri 42581469da list in panel margin bottom fix 2 2018-01-12 16:45:06 +02:00
yuri 562fa03c6c list in panel margin bottom fix 2018-01-12 16:42:45 +02:00
yuri 8feca2783f fix navbar 2018-01-12 15:45:05 +02:00
yuri eb11f9f757 label manager: filter options 2018-01-12 15:08:17 +02:00
yuri 2ace19face horizontal navbar fix 2 2018-01-12 13:43:15 +02:00
yuri 25b6a94fd6 horizontal navbar fix 2018-01-12 13:25:07 +02:00
yuri d0768b3dce email plain fix 2018-01-11 17:18:09 +02:00
yuri b4c27f50ea diff change 2018-01-11 17:01:45 +02:00
yuri 669cb10f10 fix email side panel 2018-01-11 16:52:24 +02:00
yuri 06708a8b7e version 2018-01-11 16:44:45 +02:00
yuri fba8ca7817 css form panel bottom margin fix 2018-01-11 16:31:25 +02:00
yuri 37cae817a7 fix file uploading validate message 2018-01-11 14:26:58 +02:00
yuri a32c560f60 hide merge action if no remove access 2018-01-11 12:29:34 +02:00
yuri a4d4e640a2 merge improvements 2018-01-11 12:24:12 +02:00
yuri 76f17e3f95 Merge branch 'hotfix/5.0.3' of ssh://172.20.0.1/var/git/espo/backend into hotfix/5.0.3 2018-01-10 14:46:42 +02:00
Taras Machyshyn ab4ce21927 Integration test fixes 2018-01-10 14:46:09 +02:00
yuri eb14dedb63 update tests for phpunit 6 2018-01-10 12:54:44 +02:00
108 changed files with 811 additions and 316 deletions
+32 -1
View File
@@ -35,10 +35,41 @@ module.exports = function (grunt) {
'client/lib/bootstrap.min.js',
'client/lib/bootstrap-datepicker.js',
'client/lib/bull.js',
'client/lib/marked.min.js',
'client/src/namespace.js',
'client/src/exceptions.js',
'client/src/loader.js',
'client/src/utils.js'
'client/src/utils.js',
'client/src/acl.js',
'client/src/model.js',
'client/src/model-offline.js',
'client/src/ajax.js',
'client/src/controller.js',
'client/src/ui.js',
'client/src/acl-manager.js',
'client/src/cache.js',
'client/src/storage.js',
'client/src/models/settings.js',
'client/src/language.js',
'client/src/metadata.js',
'client/src/field-manager.js',
'client/src/models/user.js',
'client/src/models/preferences.js',
'client/src/model-factory.js',
'client/src/collection-factory.js',
'client/src/pre-loader.js',
'client/src/controllers/base.js',
'client/src/router.js',
'client/src/date-time.js',
'client/src/layout-manager.js',
'client/src/theme-manager.js',
'client/src/session-storage.js',
'client/src/view-helper.js',
'client/src/app.js'
];
function camelCaseToHyphen (string){
+8 -2
View File
@@ -171,6 +171,7 @@ class CronManager
$this->getEntityManager()->saveEntity($job);
$isSuccess = true;
$skipLog = false;
try {
if ($job->get('scheduledJobId')) {
@@ -180,7 +181,12 @@ class CronManager
}
} catch (\Exception $e) {
$isSuccess = false;
$GLOBALS['log']->error('CronManager: Failed job running, job ['.$job->id.']. Error Details: '.$e->getMessage());
if ($e->getCode() === -1) {
$job->set('attempts', 0);
$skipLog = true;
} else {
$GLOBALS['log']->error('CronManager: Failed job running, job ['.$job->id.']. Error Details: '.$e->getMessage());
}
}
$status = $isSuccess ? self::SUCCESS : self::FAILED;
@@ -188,7 +194,7 @@ class CronManager
$job->set('status', $status);
$this->getEntityManager()->saveEntity($job);
if ($job->get('scheduledJobId')) {
if ($job->get('scheduledJobId') && !$skipLog) {
$this->getCronScheduledJobUtil()->addLogRecord($job->get('scheduledJobId'), $status, null, $job->get('targetId'), $job->get('targetType'));
}
}
+7
View File
@@ -51,10 +51,17 @@ class Tcpdf extends \TCPDF
}
public function Footer() {
$breakMargin = $this->getBreakMargin();
$autoPageBreak = $this->AutoPageBreak;
$this->SetAutoPageBreak(false, 0);
$this->SetY((-1) * $this->footerPosition);
$html = str_replace('{pageNumber}', '{:pnp:}', $this->footerHtml);
$this->writeHTMLCell(0, 0, '', '', $html, 0, 1, 0, '', 0, false, 'T');
$this->SetAutoPageBreak($autoPageBreak, $breakMargin);
}
protected function _putpages() {
@@ -111,6 +111,28 @@ class LabelManager extends \Espo\Core\Injectable
}
}
foreach ($this->getMetadata()->get(['entityDefs', $scope, 'fields'], []) as $field => $item) {
if (!$this->getMetadata()->get(['entityDefs', $scope, 'fields', $field, 'options'])) continue;
$optionsData = array();
$optionList = $this->getMetadata()->get(['entityDefs', $scope, 'fields', $field, 'options'], []);
if (!array_key_exists('options', $data)) {
$data['options'] = array();
}
if (!array_key_exists($field, $data['options'])) {
$data['options'][$field] = array();
}
foreach ($optionList as $option) {
if (empty($option)) continue;
$optionsData[$option] = $option;
if (array_key_exists($option, $data['options'][$field])) {
if (!empty($data['options'][$field][$option])) {
$optionsData[$option] = $data['options'][$field][$option];
}
}
}
$data['options'][$field] = $optionsData;
}
if ($scope === 'Global') {
if (empty($data['scopeNames'])) {
$data['scopeNames'] = array();
@@ -43,11 +43,11 @@ class CheckEmailAccounts extends \Espo\Core\Jobs\Base
$entity = $this->getEntityManager()->getEntity('EmailAccount', $targetId);
if (!$entity) {
throw new Error("Job CheckEmailAccounts '".$targetId."': EmailAccount does not exist.");
throw new Error("Job CheckEmailAccounts '".$targetId."': EmailAccount does not exist.", -1);
};
if ($entity->get('status') !== 'Active') {
throw new Error("Job CheckEmailAccounts '".$targetId."': EmailAccount is not active.");
throw new Error("Job CheckEmailAccounts '".$targetId."': EmailAccount is not active.", -1);
}
try {
@@ -6,6 +6,7 @@
},
"vis": {
"path": "client/modules/crm/lib/vis.min.js",
"exportsAs": "vis"
"exportsAs": "vis",
"noAppCache": true
}
}
@@ -14,7 +14,8 @@
"name":"attendees",
"label":"Attendees",
"view":"crm:views/meeting/record/panels/attendees",
"sticked": true
"sticked": true,
"isForm": true
}
],
"detailSmall":[
@@ -22,7 +23,8 @@
"name":"attendees",
"label":"Attendees",
"view":"crm:views/meeting/record/panels/attendees",
"sticked": true
"sticked": true,
"isForm": true
}
],
"edit":[
@@ -30,7 +32,8 @@
"name":"attendees",
"label":"Attendees",
"view":"crm:views/meeting/record/panels/attendees",
"sticked": true
"sticked": true,
"isForm": true
}
],
"editSmall":[
@@ -38,7 +41,8 @@
"name":"attendees",
"label":"Attendees",
"view":"crm:views/meeting/record/panels/attendees",
"sticked": true
"sticked": true,
"isForm": true
}
]
},
@@ -39,7 +39,8 @@
"name":"statistics",
"label":"Statistics",
"view":"crm:views/campaign/record/panels/campaign-stats",
"hidden": false
"hidden": false,
"isForm": true
}
]
},
@@ -13,9 +13,17 @@
"select": "crm:views/knowledge-base-article/modals/select-records"
},
"filterList": [
"published"
{
"name": "published",
"inPortalDisabled": true
}
],
"boolFilterList": [
{
"name": "onlyMy",
"inPortalDisabled": true
}
],
"boolFilterList": ["onlyMy"],
"relationshipPanels": {
"cases": {
"create": false,
@@ -43,6 +51,9 @@
},
"listPortal": {
"type": "list"
},
"relationshipsPortal": {
"type": "relationships"
}
}
}
@@ -36,7 +36,8 @@
"view":"crm:views/lead/record/panels/converted-to",
"notRefreshable":true,
"hidden":true,
"style":"success"
"style":"success",
"isForm": true
},
{
"name":"activities",
@@ -64,7 +65,8 @@
"view":"crm:views/lead/record/panels/converted-to",
"notRefreshable":true,
"hidden":true,
"style":"success"
"style":"success",
"isForm": true
}
],
"detailSmall":[
@@ -74,7 +76,8 @@
"view":"crm:views/lead/record/panels/converted-to",
"notRefreshable":true,
"hidden":true,
"style":"success"
"style":"success",
"isForm": true
},
{
"name":"activities",
@@ -102,7 +105,8 @@
"view":"crm:views/lead/record/panels/converted-to",
"notRefreshable":true,
"hidden":true,
"style":"success"
"style":"success",
"isForm": true
}
]
},
@@ -21,7 +21,8 @@
"leads"
]
},
"sticked": true
"sticked": true,
"isForm": true
}
],
"detailSmall":[
@@ -29,7 +30,8 @@
"name":"attendees",
"label":"Attendees",
"view":"crm:views/meeting/record/panels/attendees",
"sticked": true
"sticked": true,
"isForm": true
}
],
"edit":[
@@ -37,7 +39,8 @@
"name":"attendees",
"label":"Attendees",
"view":"crm:views/meeting/record/panels/attendees",
"sticked": true
"sticked": true,
"isForm": true
}
],
"editSmall":[
@@ -45,7 +48,8 @@
"name":"attendees",
"label":"Attendees",
"view":"crm:views/meeting/record/panels/attendees",
"sticked": true
"sticked": true,
"isForm": true
}
]
},
+1 -1
View File
@@ -50,7 +50,7 @@ class Job extends \Espo\Core\ORM\Repositories\RDB
$entity->set('executeTime', date('Y-m-d H:i:s'));
}
if (!$entity->has('attempts')) {
if (!$entity->has('attempts') && $entity->isNew()) {
$attempts = $this->getConfig()->get('cron.attempts', 0);
$entity->set('attempts', $attempts);
}
@@ -67,6 +67,7 @@
"detailSmallPortal": "Detail (Small, Portal)",
"listSmallPortal": "List (Small, Portal)",
"listPortal": "List (Portal)",
"relationshipsPortal": "Relationship Panels (Portal)",
"filters": "Search Filters",
"massUpdate": "Mass Update",
"relationships": "Relationship Panels",
@@ -246,6 +246,7 @@
"fieldShouldBeGreater": "{field} shouldn't be less then {value}",
"fieldBadPasswordConfirm": "{field} not confirmed properly",
"fieldMaxFileSizeError": "File should not exceed {max} Mb",
"fieldIsUploading": "Uploading in progress",
"resetPreferencesDone": "Preferences has been reset to defaults",
"confirmation": "Are you sure?",
"unlinkAllConfirmation": "Are you sure you want to unlink all related records?",
@@ -21,10 +21,6 @@
[
{"name":"theme"},
false
],
[
{"name":"useCustomTabList"},
{"name":"tabList"}
]
]
},
@@ -63,7 +63,9 @@
"signature": false,
"followCreatedEntities": false,
"followEntityOnStreamPost": false,
"doNotFillAssignedUserIfNotRequired": false
"doNotFillAssignedUserIfNotRequired": false,
"useCustomTabList": false,
"tabList": false
},
"Call": {
"reminders": false
@@ -18,22 +18,26 @@
"detail": {
"name": "default",
"label": false,
"view": "views/user/record/panels/default-side"
"view": "views/user/record/panels/default-side",
"isForm": true
},
"detailSmall": {
"name": "default",
"label": false,
"view": "views/user/record/panels/default-side"
"view": "views/user/record/panels/default-side",
"isForm": true
},
"edit": {
"name": "default",
"label": false,
"view": "views/user/record/panels/default-side"
"view": "views/user/record/panels/default-side",
"isForm": true
},
"editSmall": {
"name": "default",
"label": false,
"view": "views/user/record/panels/default-side"
"view": "views/user/record/panels/default-side",
"isForm": true
}
},
"defaultSidePanelFieldLists": {
+42 -3
View File
@@ -407,7 +407,7 @@ class Record extends \Espo\Core\Services\Base
return true;
}
if ($assignmentPermission === true || !in_array($assignmentPermission, ['team', 'no'])) {
if ($assignmentPermission === true || $assignmentPermission === 'yes' || !in_array($assignmentPermission, ['team', 'no'])) {
return true;
}
@@ -445,11 +445,16 @@ class Record extends \Espo\Core\Services\Base
return true;
}
if (!$entity->hasAttribute('teamsIds')) {
if (!$entity->hasLinkMultipleField('teams')) {
return true;
}
$teamIdList = $entity->get('teamsIds');
$teamIdList = $entity->getLinkMultipleIdList('teams');
if (empty($teamIdList)) {
if ($assignmentPermission === 'team') {
if (!$entity->get('assignedUserId')) {
return false;
}
}
return true;
}
@@ -535,6 +540,38 @@ class Record extends \Espo\Core\Services\Base
}
}
public function populateDefaults(Entity $entity, $data)
{
if (!$this->getUser()->isPortal()) {
$forbiddenFieldList = null;
if ($entity->hasAttribute('assignedUserId')) {
$forbiddenFieldList = $this->getAcl()->getScopeForbiddenFieldList($this->entityType, 'edit');
if (in_array('assignedUser', $forbiddenFieldList)) {
$entity->set('assignedUserId', $this->getUser()->id);
$entity->set('assignedUserName', $this->getUser()->get('name'));
}
}
if ($entity->hasLinkMultipleField('teams')) {
if (is_null($forbiddenFieldList)) {
$forbiddenFieldList = $this->getAcl()->getScopeForbiddenFieldList($this->entityType, 'edit');
}
if (in_array('teams', $forbiddenFieldList)) {
if ($this->getUser()->get('defaultTeamId')) {
$defaultTeamId = $this->getUser()->get('defaultTeamId');
$entity->addLinkMultipleId('teams', $defaultTeamId);
$teamsNames = $entity->get('teamsNames');
if (!$teamsNames || !is_object($teamsNames)) {
$teamsNames = (object) [];
}
$teamsNames->$defaultTeamId = $this->getUser()->get('defaultTeamName');
$entity->set('teamsNames', $teamsNames);
}
}
}
}
}
public function createEntity($data)
{
if (!$this->getAcl()->check($this->getEntityType(), 'create')) {
@@ -559,6 +596,8 @@ class Record extends \Espo\Core\Services\Base
throw new Forbidden();
}
$this->populateDefaults($entity, $data);
$this->beforeCreateEntity($entity, $data);
if (!$this->isValid($entity)) {
+4 -4
View File
@@ -6,10 +6,10 @@
"header",
"list",
"login",
"modals.edit",
"modals.select-records",
"site.header",
"site.navbar"
"modals/edit",
"modals/select-records",
"site/header",
"site/navbar"
],
"layoutTypes": [
"columns-2",
+25 -18
View File
File diff suppressed because one or more lines are too long
@@ -424,8 +424,8 @@ Espo.define('crm:views/calendar/timeline', ['view', 'lib!vis'], function (Dep, V
var itemsDataSet = new Vis.DataSet(eventList);
var timeline = this.timeline = new Vis.Timeline($timeline.get(0), itemsDataSet, this.groupsDataSet, {
dataAttributes: 'all',
start: this.start.format(this.getDateTime().internalDateTimeFormat),
end: this.end.format(this.getDateTime().internalDateTimeFormat),
start: this.start.toDate(),
end: this.end.toDate(),
moment: function (date) {
var m = moment(date);
if (date && date.noTimeZone) {
@@ -454,6 +454,7 @@ Espo.define('crm:views/calendar/timeline', ['view', 'lib!vis'], function (Dep, V
});
timeline.on('click', function (e) {
if (this.blockClick) return;
if (e.item) {
var $item = this.$el.find('.timeline .vis-item[data-id="'+e.item+'"]');
var id = $item.attr('data-record-id');
@@ -468,6 +469,11 @@ Espo.define('crm:views/calendar/timeline', ['view', 'lib!vis'], function (Dep, V
}.bind(this));
timeline.on('rangechanged', function (e) {
e.skipClick = true;
this.blockClick = true;
setTimeout(function () {this.blockClick = false}.bind(this), 100);
this.start = moment(e.start);
this.end = moment(e.end);
@@ -33,6 +33,10 @@ Espo.define('crm:views/knowledge-base-article/record/detail', 'views/record/deta
setup: function () {
Dep.prototype.setup.call(this);
if (this.getUser().isPortal()) {
this.sideDisabled = true;
}
if (this.getAcl().checkScope('Email', 'create')) {
this.dropdownItemList.push({
'label': 'Send in Email',
@@ -42,7 +46,6 @@ Espo.define('crm:views/knowledge-base-article/record/detail', 'views/record/deta
if (this.getUser().isPortal()) {
if (!this.getAcl().checkScope(this.scope, 'edit')) {
var at
if (!this.model.getLinkMultipleIdList('attachments').length) {
this.hideField('attachments');
this.listenToOnce(this.model, 'sync', function () {
+1 -1
View File
@@ -15,7 +15,7 @@
<% if (panelLabelString) { %>
<div class="panel-heading"><h4 class="panel-title"><%= panelLabelString %></h4></div>
<% } %>
<div class="panel-body">
<div class="panel-body panel-body-form">
<% _.each(panel.rows, function (row, rowNumber) { %>
<div class="row">
<% _.each(row, function (cell, cellNumber) { %>
@@ -1,4 +1,4 @@
<textarea class="form-control" name="{{name}}Street" rows="1" placeholder="{{translate 'Street'}}">{{streetValue}}</textarea>
<textarea class="form-control auto-height" name="{{name}}Street" rows="1" placeholder="{{translate 'Street'}}">{{streetValue}}</textarea>
<div class="row">
<div class="col-sm-4 col-xs-4">
<input type="text" class="form-control" name="{{name}}City" value="{{cityValue}}" placeholder="{{translate 'City'}}">
@@ -1,4 +1,4 @@
<textarea class="form-control" name="{{name}}Street" rows="1" placeholder="{{translate 'Street'}}">{{streetValue}}</textarea>
<textarea class="form-control auto-height" name="{{name}}Street" rows="1" placeholder="{{translate 'Street'}}">{{streetValue}}</textarea>
<div class="row">
<div class="col-sm-6 col-xs-6">
<input type="text" class="form-control" name="{{name}}PostalCode" value="{{postalCodeValue}}" placeholder="{{translate 'PostalCode'}}">
@@ -1,5 +1,5 @@
<input type="text" class="form-control" name="{{name}}Country" value="{{countryValue}}" placeholder="{{translate 'Country'}}">
<input type="text" class="form-control auto-height" name="{{name}}Country" value="{{countryValue}}" placeholder="{{translate 'Country'}}">
<div class="row">
<div class="col-sm-4 col-xs-4">
<input type="text" class="form-control" name="{{name}}PostalCode" value="{{postalCodeValue}}" placeholder="{{translate 'PostalCode'}}">
@@ -1,5 +1,5 @@
<textarea class="form-control" name="{{name}}Street" rows="1" placeholder="{{translate 'Street'}}">{{streetValue}}</textarea>
<textarea class="form-control auto-height" name="{{name}}Street" rows="1" placeholder="{{translate 'Street'}}">{{streetValue}}</textarea>
<input type="text" class="form-control" name="{{name}}City" value="{{cityValue}}" placeholder="{{translate 'City'}}">
<div class="row">
<div class="col-sm-5 col-xs-5">
+1 -1
View File
@@ -1,4 +1,4 @@
<textarea class="form-control" name="{{name}}Street" rows="1" placeholder="{{translate 'Street'}}">{{streetValue}}</textarea>
<textarea class="form-control auto-height" name="{{name}}Street" rows="1" placeholder="{{translate 'Street'}}">{{streetValue}}</textarea>
<div class="row">
<div class="col-sm-4 col-xs-4">
<input type="text" class="form-control" name="{{name}}City" value="{{cityValue}}" placeholder="{{translate 'City'}}">
@@ -1,10 +1,10 @@
<div>
<div class="clearfix">
<div class="attachment-upload">
<div class="clearfix attachment-control">
{{#unless uploadFromFileSystemDisabled}}
<div class="pull-left">
<label style="overflow: hidden; width: 50px; cursor: pointer;" title="{{translate 'Attach File'}}">
<span class="btn btn-default" style="cursor: pointer;"><span class="glyphicon glyphicon-paperclip"></span></span>
<input type="file" class="file pull-right" multiple style="opacity: 0; width: 1px;">
<label class="attach-file-label" title="{{translate 'Attach File'}}">
<span class="btn btn-default"><span class="glyphicon glyphicon-paperclip"></span></span>
<input type="file" class="file pull-right" multiple>
</label>
</div>
{{/unless}}
+4 -4
View File
@@ -1,9 +1,9 @@
<div>
<div class="attachment-upload">
<div class="attachment-button{{#if id}} hidden{{/if}}">
<div class="pull-left">
<label style="overflow: hidden; width: 50px; cursor: pointer;">
<span class="btn btn-default" style="cursor: pointer;"><span class="glyphicon glyphicon-paperclip"></span></span>
<input type="file" class="file pull-right" style="opacity: 0; width: 1px;" {{#if acceptAttribue}}accept="{{acceptAttribue}}"{{/if}}>
<label class="attach-file-label" title="{{translate 'Attach File'}}">
<span class="btn btn-default"><span class="glyphicon glyphicon-paperclip"></span></span>
<input type="file" class="file pull-right" {{#if acceptAttribue}}accept="{{acceptAttribue}}"{{/if}}>
</label>
</div>
{{#unless id}}
+1 -1
View File
@@ -1,2 +1,2 @@
<textarea class="main-element form-control" name="{{name}}" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} rows="{{rows}}">{{value}}</textarea>
<textarea class="main-element form-control auto-height" name="{{name}}" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} rows="{{rows}}">{{value}}</textarea>
@@ -5,5 +5,5 @@
<div class="html-container">{{{value}}}</div>
{{/if}}
{{else}}
<div class="plain hidden">{{complexText value}}</div>
<div class="plain complex-text hidden">{{complexText value}}</div>
{{/unless}}
+1 -1
View File
@@ -1,5 +1,5 @@
<link href="{{basePath}}client/css/summernote-icons.css" rel="stylesheet">
<textarea class="main-element form-control hidden" name="{{name}}" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} rows="{{rows}}"></textarea>
<textarea class="main-element form-control hidden auto-height" name="{{name}}" {{#if params.maxLength}} maxlength="{{params.maxLength}}"{{/if}} rows="{{rows}}"></textarea>
<div class="summernote hidden"></div>
+2 -2
View File
@@ -2,7 +2,7 @@
<div class="panel panel-default">
<div class="panel-heading"><h4 class="panel-title">{{translate 'What to Import?' scope='Import'}}</h4></div>
<div class="panel-body">
<div class="panel-body panel-body-form">
<div class="row">
<div class="col-sm-4 form-group cell">
<label class="control-label">{{translate 'Entity Type' scope='Import'}}</label>
@@ -35,7 +35,7 @@
<div class="panel panel-default">
<div class="panel-heading"><h4 class="panel-title">{{translate 'Properties' scope='Import'}}</h4></div>
<div class="panel-body">
<div class="panel-body panel-body-form">
<div id="import-properties">
<div class="row">
<div class="col-sm-4 form-group cell">
+1 -2
View File
@@ -32,9 +32,8 @@
{{/unless}}
</h4>
</div>
<div class="panel-body" data-name="{{name}}">
<div class="panel-body{{#if isForm}} panel-body-form{{/if}}" data-name="{{name}}">
{{{var name ../this}}}
</div>
</div>
{{/each}}
+20 -5
View File
@@ -4,17 +4,32 @@
<thead>
<tr>
<th width="20%"></th>
{{#each models}}
{{#each dataList}}
<th width="5%">
<input type="radio" name="check-all" value="{{prop this 'id'}}" data-id="{{id}}" class="pull-right">
<input type="radio" name="check-all" value="{{id}}" data-id="{{id}}" class="pull-right">
</th>
<th width="{{../width}}%">
<a href="#{{../scope}}/view/{{prop this 'id'}}">{{get this 'name'}}</a>
<a href="#{{../scope}}/view/{{id}}" target="_BLANK">{{name}}</a>
</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#if hasCreatedAt}}
<tr>
<td align="right">
{{translate 'createdAt' scope=../scope category='fields'}}
</td>
{{#each dataList}}
<td></td>
<td data-id="{{id}}">
<div class="field" data-name="createdAt">
{{{var createdAtViewName ../../this}}}
</div>
</td>
{{/each}}
</tr>
{{/if}}
{{#each rows}}
<tr>
<td align="right">
@@ -24,8 +39,8 @@
<td>
<input type="radio" name="{{../name}}" value="{{id}}" data-id="{{id}}" class="pull-right field-radio">
</td>
<td class="{{id}}">
<div class="field" data-name="{{name}}">
<td data-id="{{id}}">
<div class="field" data-name="{{../name}}">
{{{var fieldVariable ../../this}}}
</div>
</td>
+1 -1
View File
@@ -34,7 +34,7 @@
</h4>
</div>
{{/if}}
<div class="panel-body" data-name="{{name}}">
<div class="panel-body{{#if isForm}} panel-body-form{{/if}}" data-name="{{name}}">
{{{var name ../this}}}
</div>
</div>
+2 -2
View File
@@ -25,7 +25,7 @@
{{#each ../list}}
<td>
{{#if levelList}}
<select name="{{name}}" class="form-control{{#ifNotEqual ../../../access 'enabled'}} hidden{{/ifNotEqual}}" data-scope="{{../../name}}"{{#ifNotEqual ../../access 'enabled'}} disabled{{/ifNotEqual}}>
<select name="{{name}}" class="form-control{{#ifNotEqual ../../../access 'enabled'}} hidden{{/ifNotEqual}}" data-scope="{{../../name}}"{{#ifNotEqual ../../access 'enabled'}} disabled{{/ifNotEqual}} title="{{translate action scope='Role' category='actions'}}">
{{options levelList level field='levelList' scope='Role'}}
</select>
{{/if}}
@@ -67,7 +67,7 @@
<td><b>{{translate name category='fields' scope=../name}}</b></td>
{{#each list}}
<td>
<select name="field-{{../../name}}-{{../name}}" class="form-control" data-field="{{../name}}" data-scope="{{../../name}}" data-action="{{name}}">{{options ../../../fieldLevelList value scope='Role' field='accessList'}}</select>
<select name="field-{{../../name}}-{{../name}}" class="form-control" data-field="{{../name}}" data-scope="{{../../name}}" data-action="{{name}}" title="{{translate name scope='Role' category='actions'}}">{{options ../../../fieldLevelList value scope='Role' field='accessList'}}</select>
</td>
{{/each}}
<td colspan="2">
+30 -4
View File
@@ -44,15 +44,37 @@ Espo.define(
'model-factory',
'collection-factory',
'pre-loader',
'view-helper',
'controllers/base',
'router',
'date-time',
'layout-manager',
'theme-manager',
'session-storage'
'session-storage',
'view-helper'
],
function (Ui, Utils, AclManager, Cache, Storage, Settings, Language, Metadata, FieldManager, User, Preferences, ModelFactory, CollectionFactory, PreLoader, ViewHelper, BaseController, Router, DateTime, LayoutManager, ThemeManager, SessionStorage) {
function (
Ui,
Utils,
AclManager,
Cache,
Storage,
Settings,
Language,
Metadata,
FieldManager,
User,
Preferences,
ModelFactory,
CollectionFactory,
PreLoader,
BaseController,
Router,
DateTime,
LayoutManager,
ThemeManager,
SessionStorage,
ViewHelper
) {
var App = function (options, callback) {
var options = options || {};
@@ -71,7 +93,7 @@ Espo.define(
this.controllers = {};
if (this.useCache) {
this.cache = new Cache();
this.cache = new Cache(options.cacheTimestamp);
if (options.cacheTimestamp) {
this.cache.handleActuality(options.cacheTimestamp);
} else {
@@ -84,6 +106,10 @@ Espo.define(
this.loader.cache = this.cache;
if (this.useCache && !this.loader.cacheTimestamp && options.cacheTimestamp) {
this.loader.cacheTimestamp = options.cacheTimestamp;
}
this.setupAjax();
this.settings = new Settings(null);
+31 -20
View File
@@ -28,7 +28,11 @@
Espo.define('cache', [], function () {
var Cache = function () {
var Cache = function (cacheTimestamp) {
this.basePrefix = this.prefix;
if (cacheTimestamp) {
this.prefix = this.basePrefix + '-' + cacheTimestamp;
}
if (!this.get('app', 'timestamp')) {
this.storeTimestamp();
}
@@ -36,7 +40,7 @@ Espo.define('cache', [], function () {
_.extend(Cache.prototype, {
_prefix: 'cache',
prefix: 'cache',
handleActuality: function (cacheTimestamp) {
var stored = parseInt(this.get('app', 'cacheTimestamp'));
@@ -58,25 +62,32 @@ Espo.define('cache', [], function () {
this.set('app', 'timestamp', frontendCacheTimestamp);
},
_composeFullPrefix: function (type) {
return this._prefix + '-' + type;
composeFullPrefix: function (type) {
return this.prefix + '-' + type;
},
_composeKey: function (type, name) {
return this._composeFullPrefix(type) + '-' + name;
composeKey: function (type, name) {
return this.composeFullPrefix(type) + '-' + name;
},
_checkType: function (type) {
checkType: function (type) {
if (typeof type === 'undefined' && toString.call(type) != '[object String]') {
throw new TypeError("Bad type \"" + type + "\" passed to Cache().");
}
},
get: function (type, name) {
this._checkType(type);
this.checkType(type);
var key = this.composeKey(type, name);
try {
var stored = localStorage.getItem(key);
} catch (error) {
console.error(error);
return null;
}
var key = this._composeKey(type, name);
var stored = localStorage.getItem(key);
if (stored) {
var result = stored;
@@ -94,24 +105,28 @@ Espo.define('cache', [], function () {
},
set: function (type, name, value) {
this._checkType(type);
var key = this._composeKey(type, name);
this.checkType(type);
var key = this.composeKey(type, name);
if (value instanceof Object || Array.isArray(value)) {
value = '__JSON__:' + JSON.stringify(value);
}
localStorage.setItem(key, value);
try {
localStorage.setItem(key, value);
} catch (error) {
console.error(error);
}
},
clear: function (type, name) {
var reText;
if (typeof type !== 'undefined') {
if (typeof name === 'undefined') {
reText = '^' + this._composeFullPrefix(type);
reText = '^' + this.composeFullPrefix(type);
} else {
reText = '^' + this._composeKey(type, name);
reText = '^' + this.composeKey(type, name);
}
} else {
reText = '^' + this._prefix + '-';
reText = '^' + this.basePrefix + '-';
}
var re = new RegExp(reText);
for (var i in localStorage) {
@@ -126,7 +141,3 @@ Espo.define('cache', [], function () {
return Cache;
});
-22
View File
@@ -30,28 +30,6 @@ Espo.define('controllers/email-account', 'controllers/record', function (Dep) {
return Dep.extend({
list: function (options) {
var userId = (options || {}).userId;
if (!userId) {
Dep.prototype.list.call(this, options);
} else {
this.getCollection(function (collection) {
collection.where = [{
type: 'equals',
field: 'assignedUserId',
value: userId
}];
this.main(this.getViewName('list'), {
scope: this.name,
collection: collection,
userId: userId,
userName: (options || {}).userName
});
});
}
},
});
});
+12 -8
View File
@@ -118,7 +118,7 @@ var Espo = Espo || {classMap:{}};
if (!o) {
if (self.cache) {
self.cache.clear('script', subject);
self.cache.clear('a', subject);
}
throw new Error("Could not load '" + subject + "'");
}
@@ -212,6 +212,8 @@ var Espo = Espo || {classMap:{}};
var dataType, type, path, fetchObject;
var realName = name;
var noAppCache = false;
if (name.indexOf('lib!') === 0) {
dataType = 'script';
type = 'lib';
@@ -223,9 +225,11 @@ var Espo = Espo || {classMap:{}};
var exportsAs = realName;
if (realName in this.libsConfig) {
path = this.libsConfig[realName].path || path;
exportsTo = this.libsConfig[realName].exportsTo || exportsTo;
exportsAs = this.libsConfig[realName].exportsAs || exportsAs;
var libData = this.libsConfig[realName] || {};
path = libData.path || path;
exportsTo = libData.exportsTo || exportsTo;
exportsAs = libData.exportsAs || exportsAs;
noAppCache = libData.noAppCache || noAppCache;
}
fetchObject = function (name, d) {
@@ -271,7 +275,7 @@ var Espo = Espo || {classMap:{}};
}
if (this.cache) {
var cached = this.cache.get(type, name);
var cached = this.cache.get('a', name);
if (cached) {
if (type == 'class') {
this.loadingSubject = name;
@@ -320,8 +324,8 @@ var Espo = Espo || {classMap:{}};
local: true,
url: this.basePath + path,
success: function (response) {
if (this.cache) {
this.cache.set(type, name, response);
if (this.cache && !noAppCache) {
this.cache.set('a', name, response);
}
this._addLoadCallback(name, callback);
@@ -363,7 +367,7 @@ var Espo = Espo || {classMap:{}};
loadLib: function (url, callback) {
if (this.cache) {
var script = this.cache.get('script', url);
var script = this.cache.get('a', url);
if (script) {
this._execute(script);
if (typeof callback == 'function') {
+20 -10
View File
@@ -33,27 +33,37 @@ Espo.define('session-storage', 'storage', function (Dep) {
storageObject: sessionStorage,
get: function (name) {
var stored = this.storageObject.getItem(name);
try {
var stored = this.storageObject.getItem(name);
} catch (error) {
console.error(error);
return null;
}
if (stored) {
var str = stored;
if (stored[0] == "{" || stored[0] == "[") {
var result = stored;
if (stored.length > 9 && stored.substr(0, 9) === '__JSON__:') {
var jsonString = stored.substr(9);
try {
str = JSON.parse(stored);
result = JSON.parse(jsonString);
} catch (error) {
str = stored;
result = stored;
}
stored = str;
}
return stored;
return result;
}
return null;
},
set: function (name, value) {
if (value instanceof Object) {
value = JSON.stringify(value);
if (value instanceof Object || Array.isArray(value)) {
value = '__JSON__:' + JSON.stringify(value);
}
try {
this.storageObject.setItem(name, value);
} catch (error) {
console.error(error);
}
this.storageObject.setItem(name, value);
},
clear: function (name) {
+43 -25
View File
@@ -33,72 +33,90 @@ Espo.define('storage', [], function () {
_.extend(Storage.prototype, {
_prefix: 'espo',
prefix: 'espo',
storageObject: localStorage,
_composeFullPrefix: function (type) {
return this._prefix + '-' + type;
composeFullPrefix: function (type) {
return this.prefix + '-' + type;
},
_composeKey: function (type, name) {
return this._composeFullPrefix(type) + '-' + name;
composeKey: function (type, name) {
return this.composeFullPrefix(type) + '-' + name;
},
_checkType: function (type) {
checkType: function (type) {
if (typeof type === 'undefined' && toString.call(type) != '[object String]' || type == 'cache') {
throw new TypeError("Bad type \"" + type + "\" passed to Espo.Storage.");
}
},
has: function (type, name) {
this._checkType(type);
var key = this._composeKey(type, name);
this.checkType(type);
var key = this.composeKey(type, name);
return this.storageObject.getItem(key) !== null;
},
get: function (type, name) {
this._checkType(type);
this.checkType(type);
var key = this._composeKey(type, name);
var key = this.composeKey(type, name);
try {
var stored = this.storageObject.getItem(key);
} catch (error) {
console.error(error);
return null;
}
var stored = this.storageObject.getItem(key);
if (stored) {
var str = stored;
if (stored[0] == "{" || stored[0] == "[") {
var result = stored;
if (stored.length > 9 && stored.substr(0, 9) === '__JSON__:') {
var jsonString = stored.substr(9);
try {
str = JSON.parse(stored);
result = JSON.parse(jsonString);
} catch (error) {
str = stored;
result = stored;
}
} else if (stored[0] == "{" || stored[0] == "[") { // for backward compatibility
try {
result = JSON.parse(stored);
} catch (error) {
result = stored;
}
stored = str;
}
return stored;
return result;
}
return null;
},
set: function (type, name, value) {
this._checkType(type);
this.checkType(type);
var key = this._composeKey(type, name);
if (value instanceof Object) {
value = JSON.stringify(value);
var key = this.composeKey(type, name);
if (value instanceof Object || Array.isArray(value)) {
value = '__JSON__:' + JSON.stringify(value);
}
try {
this.storageObject.setItem(key, value);
} catch (error) {
console.error(error);
return null;
}
this.storageObject.setItem(key, value);
},
clear: function (type, name) {
var reText;
if (typeof type !== 'undefined') {
if (typeof name === 'undefined') {
reText = '^' + this._composeFullPrefix(type);
reText = '^' + this.composeFullPrefix(type);
} else {
reText = '^' + this._composeKey(type, name);
reText = '^' + this.composeKey(type, name);
}
} else {
reText = '^' + this._prefix + '-';
reText = '^' + this.prefix + '-';
}
var re = new RegExp(reText);
for (var i in this.storageObject) {
+3 -2
View File
@@ -26,7 +26,7 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
Espo.define('view-helper', ['lib!client/lib/marked.min.js'], function () {
Espo.define('view-helper', [], function () {
var ViewHelper = function (options) {
this.urlRegex = /(^|[^\(])(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
@@ -52,7 +52,8 @@ Espo.define('view-helper', ['lib!client/lib/marked.min.js'], function () {
];
marked.setOptions({
breaks: true
breaks: true,
tables: false
});
}
+14 -3
View File
@@ -43,13 +43,24 @@ Espo.define('views/email-account/list', 'views/list', function (Dep) {
style: 'primary',
acl: 'edit'
});
this.options.params = this.options.params || {};
var params = this.options.params || {};
if (params.userId) {
this.collection.where = [{
type: 'equals',
field: 'assignedUserId',
value: params.userId
}];
}
},
getCreateAttributes: function () {
var attributes = {};
if (this.options.userId) {
attributes.assignedUserId = this.options.userId;
attributes.assignedUserName = this.options.userName || this.options.userId;
if (this.options.params.userId) {
attributes.assignedUserId = this.options.params.userId;
attributes.assignedUserName = this.options.params.userName || this.options.params.userId;
}
return attributes;
}
+1 -1
View File
@@ -51,7 +51,7 @@ Espo.define('views/email/list', 'views/list', function (Dep) {
this.addMenuItem('dropdown', {
name: 'reply',
label: 'Email Accounts',
link: '#EmailAccount/list/userId=' + this.getUser().id + '&userName=' + this.getUser().get('name')
link: '#EmailAccount/list/userId=' + this.getUser().id + '&userName=' + encodeURIComponent(this.getUser().get('name'))
});
}
+2 -1
View File
@@ -43,7 +43,8 @@ Espo.define('views/email/record/detail-side', 'views/record/detail-side', functi
'replied',
'replies'
]
}
},
isForm: true
}
});
+25 -7
View File
@@ -54,6 +54,8 @@ Espo.define('views/fields/attachment-multiple', 'views/fields/base', function (D
'image/gif',
],
validations: ['ready', 'required'],
events: {
'click a.remove-attachment': function (e) {
var $div = $(e.currentTarget).parent();
@@ -281,10 +283,7 @@ Espo.define('views/fields/attachment-multiple', 'views/fields/base', function (D
preview = '<a href="'+this.getBasePath()+'?entryPoint=download&id='+id+'" target="_BLANK">' + preview + '</a>';
}
var $att = $('<div>').css('display', 'inline-block')
.css('width', '100%')
.css('max-width', '300px')
.addClass('gray-box')
var $att = $('<div>').addClass('gray-box')
.append(removeLink)
.append($('<span class="preview">' + preview + '</span>').css('width', 'cacl(100% - 30px)'));
@@ -341,6 +340,8 @@ Espo.define('views/fields/attachment-multiple', 'views/fields/base', function (D
return;
}
this.isUploading = true;
this.getModelFactory().create('Attachment', function (model) {
var canceledList = [];
@@ -356,7 +357,13 @@ Espo.define('views/fields/attachment-multiple', 'views/fields/base', function (D
$attachmentBox.find('.remove-attachment').on('click.uploading', function () {
canceledList.push(attachment.cid);
totalCount--;
});
if (uploadedCount == totalCount) {
this.isUploading = false;
if (totalCount) {
this.afterAttachmentsUploaded.call(this);
}
}
}.bind(this));
var attachment = model.clone();
@@ -376,7 +383,8 @@ Espo.define('views/fields/attachment-multiple', 'views/fields/base', function (D
this.pushAttachment(attachment);
$attachmentBox.attr('data-id', attachment.id);
uploadedCount++;
if (uploadedCount == totalCount) {
if (uploadedCount == totalCount && this.isUploading) {
this.isUploading = false;
this.afterAttachmentsUploaded.call(this);
}
}
@@ -384,9 +392,11 @@ Espo.define('views/fields/attachment-multiple', 'views/fields/base', function (D
$attachmentBox.remove();
totalCount--;
if (!totalCount) {
this.isUploading = false;
this.$el.find('.uploading-message').remove();
}
if (uploadedCount == totalCount) {
if (uploadedCount == totalCount && this.isUploading) {
this.isUploading = false;
this.afterAttachmentsUploaded.call(this);
}
}.bind(this));
@@ -563,6 +573,14 @@ Espo.define('views/fields/attachment-multiple', 'views/fields/base', function (D
}
},
validateReady: function () {
if (this.isUploading) {
var msg = this.translate('fieldIsUploading', 'messages').replace('{field}', this.translate(this.name, 'fields', this.model.name));
this.showValidationMessage(msg, 'label');
return true;
}
},
fetch: function () {
var data = {};
data[this.idsName] = this.model.get(this.idsName);
+10 -3
View File
@@ -526,10 +526,17 @@ Espo.define('views/fields/base', 'view', function (Dep) {
this.trigger('inline-edit-on');
},
showValidationMessage: function (message, selector) {
selector = selector || '.main-element';
showValidationMessage: function (message, target) {
var $el;
target = target || '.main-element';
if (typeof target === 'string' || target instanceof String) {
$el = this.$el.find(target);
} else {
$el = $(target);
}
var $el = this.$el.find(selector);
if (!$el.size() && this.$element) {
$el = this.$element;
}
+25 -5
View File
@@ -52,6 +52,8 @@ Espo.define('views/fields/file', 'views/fields/link', function (Dep) {
previewSize: 'small',
validations: ['ready', 'required'],
events: {
'click a.remove-attachment': function (e) {
var $div = $(e.currentTarget).parent();
@@ -119,12 +121,28 @@ Espo.define('views/fields/file', 'views/fields/link', function (Dep) {
if (this.isRequired()) {
if (this.model.get(this.idName) == null) {
var msg = this.translate('fieldIsRequired', 'messages').replace('{field}', this.translate(this.name, 'fields', this.model.name));
this.showValidationMessage(msg, '.attachment-button label');
var $target;
if (this.isUploading) {
$target = this.$el.find('.gray-box');
} else {
$target = this.$el.find('.attachment-button label');
}
this.showValidationMessage(msg, $target);
return true;
}
}
},
validateReady: function () {
if (this.isUploading) {
var $target = this.$el.find('.gray-box');
var msg = this.translate('fieldIsUploading', 'messages').replace('{field}', this.translate(this.name, 'fields', this.model.name));
this.showValidationMessage(msg, $target);
return true;
}
},
setup: function () {
this.nameName = this.name + 'Name';
this.idName = this.name + 'Id';
@@ -312,6 +330,8 @@ Espo.define('views/fields/file', 'views/fields/link', function (Dep) {
return;
}
this.isUploading = true;
this.getModelFactory().create('Attachment', function (attachment) {
var $attachmentBox = this.addAttachmentBox(file.name, file.type);
@@ -320,6 +340,7 @@ Espo.define('views/fields/file', 'views/fields/link', function (Dep) {
$attachmentBox.find('.remove-attachment').on('click.uploading', function () {
isCanceled = true;
this.$el.find('.attachment-button').removeClass('hidden');
this.isUploading = false;
}.bind(this));
var fileReader = new FileReader();
@@ -334,6 +355,7 @@ Espo.define('views/fields/file', 'views/fields/link', function (Dep) {
attachment.set('field', this.name);
attachment.save().then(function () {
this.isUploading = false;
if (!isCanceled) {
$attachmentBox.trigger('ready');
this.setAttachment(attachment);
@@ -342,6 +364,7 @@ Espo.define('views/fields/file', 'views/fields/link', function (Dep) {
$attachmentBox.remove();
this.$el.find('.uploading-message').remove();
this.$el.find('.attachment-button').removeClass('hidden');
this.isUploading = false;
}.bind(this));
}.bind(this));
}.bind(this);
@@ -372,10 +395,7 @@ Espo.define('views/fields/file', 'views/fields/link', function (Dep) {
preview = this.getEditPreview(name, type, id);
}
var $att = $('<div>').css('display', 'inline-block')
.css('width', '100%')
.css('max-width', '300px')
.append(removeLink)
var $att = $('<div>').append(removeLink)
.append($('<span class="preview">' + preview + '</span>').css('width', 'cacl(100% - 30px)'))
.addClass('gray-box');
+1 -1
View File
@@ -156,7 +156,7 @@ Espo.define('views/fields/text', 'views/fields/base', function (Dep) {
if (clientHeight === lastHeight) return;
if (scrollHeight > clientHeight) {
if (scrollHeight > clientHeight + 1) {
var rows = this.$element.prop('rows');
if (this.params.rows && rows >= this.params.rows) return;
+21 -6
View File
@@ -96,6 +96,10 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
this.$summernote.summernote('destroy');
}
});
this.once('remove', function () {
$(window).off('resize.' + this.cid);
}.bind(this));
},
data: function () {
@@ -164,23 +168,29 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
var documentElement = iframeElement.contentWindow.document;
var linkElement = documentElement.createElement('link');
linkElement.type = 'text/css';
linkElement.rel = 'stylesheet';
linkElement.href = this.getBasePath() + this.getThemeManager().getIframeStylesheet();
var body = this.sanitizeHtml(this.model.get(this.name) || '');
documentElement.write(body);
documentElement.close();
iframeElement.contentWindow.document.head.appendChild(linkElement);
var linkElement = iframeElement.contentWindow.document.createElement('link');
linkElement.type = 'text/css';
linkElement.rel = 'stylesheet';
linkElement.href = this.getBasePath() + this.getThemeManager().getIframeStylesheet();
try {
iframeElement.contentWindow.document.head.appendChild(linkElement);
} catch (error) {
console.error(error);
}
var processHeight = function () {
iframeElement.style.height = '0px';
var $body = $iframe.contents().find('html body');
var height = $body.height();
if (height === 0) {
height = $body.children(0).height() + 100;
}
height += 30;
iframeElement.style.height = height + 'px';
};
@@ -191,6 +201,11 @@ Espo.define('views/fields/wysiwyg', ['views/fields/text', 'lib!Summernote'], fun
processHeight();
});
}, 50);
$(window).off('resize.' + this.cid);
$(window).on('resize.' + this.cid, function() {
processHeight();
}.bind(this));
}
} else {
+1 -1
View File
@@ -258,7 +258,7 @@ Espo.define('views/list-with-categories', 'views/list', function (Dep) {
this.$listContainer.removeClass('hidden');
return;
}
if (!this.collection.models.length && this.nestedCategoriesCollection.models.length) {
if (!this.collection.models.length && this.nestedCategoriesCollection && this.nestedCategoriesCollection.models.length) {
this.$listContainer.addClass('hidden');
} else {
this.$listContainer.removeClass('hidden');
@@ -75,7 +75,13 @@ Espo.define('views/modals/select-records-with-categories', ['views/modals/select
buttonsDisabled: true,
checkboxes: false
}, function (view) {
view.render();
if (this.isRendered()) {
view.render();
} else {
this.listenToOnce(this, 'after:render', function () {
view.render();
}, this);
}
this.listenTo(view, 'select', function (model) {
this.currentCategoryId = null;
+6
View File
@@ -519,6 +519,12 @@ Espo.define('views/record/base', ['view', 'view-record-helper', 'dynamic-logic']
fillAssignedUser = false;
if (this.model.getFieldParam('assignedUser', 'required')) {
fillAssignedUser = true;
} else if (this.getAcl().get('assignmentPermission') === 'no') {
fillAssignedUser = true;
} else if (this.getAcl().get('assignmentPermission') === 'team' && !this.getUser().get('defaultTeamId')) {
fillAssignedUser = true;
} else if (~this.getAcl().getScopeForbiddenFieldList(this.model.name, 'edit').indexOf('assignedUser')) {
fillAssignedUser = true;
}
}
if (fillAssignedUser) {
+11 -1
View File
@@ -40,6 +40,8 @@ Espo.define('views/record/detail-bottom', 'view', function (Dep) {
readOnly: false,
portalLayoutDisabled: false,
data: function () {
return {
panelList: this.panelList,
@@ -198,6 +200,8 @@ Espo.define('views/record/detail-bottom', 'view', function (Dep) {
this.readOnly = this.options.readOnly || this.readOnly;
this.inlineEditDisabled = this.options.inlineEditDisabled || this.inlineEditDisabled;
this.portalLayoutDisabled = this.options.portalLayoutDisabled || this.portalLayoutDisabled;
this.recordViewObject = this.options.recordViewObject;
},
@@ -254,7 +258,13 @@ Espo.define('views/record/detail-bottom', 'view', function (Dep) {
},
loadRelationshipsLayout: function (callback) {
this._helper.layoutManager.get(this.model.name, 'relationships', function (layout) {
var layoutName = 'relationships';
if (this.getUser().isPortal() && !this.portalLayoutDisabled) {
if (this.getMetadata().get(['clientDefs', this.scope, 'additionalLayouts', layoutName + 'Portal'])) {
layoutName += 'Portal';
}
}
this._helper.layoutManager.get(this.model.name, layoutName, function (layout) {
this.relationshipsLayout = layout;
callback.call(this);
}.bind(this));
+1 -1
View File
@@ -46,6 +46,7 @@ Espo.define('views/record/detail-side', 'view', function (Dep) {
name: 'default',
label: false,
view: 'views/record/panels/default-side',
isForm: true,
options: {
fieldList: [
{
@@ -334,4 +335,3 @@ Espo.define('views/record/detail-side', 'view', function (Dep) {
});
});
+2 -1
View File
@@ -1185,7 +1185,8 @@ Espo.define('views/record/detail', ['views/record/base', 'view-record-helper'],
type: this.type,
inlineEditDisabled: this.inlineEditDisabled,
recordHelper: this.recordHelper,
recordViewObject: this
recordViewObject: this,
portalLayoutDisabled: this.portalLayoutDisabled
});
},
+1 -2
View File
@@ -36,6 +36,7 @@ Espo.define('views/record/edit-side', 'views/record/detail-side', function (Dep)
name: 'default',
label: false,
view: 'views/record/panels/side',
isForm: true,
options: {
fieldList: [
{
@@ -52,5 +53,3 @@ Espo.define('views/record/edit-side', 'views/record/detail-side', function (Dep)
});
});
+1
View File
@@ -672,6 +672,7 @@ Espo.define('views/record/list', 'view', function (Dep) {
if (!this.getAcl().checkScope(this.entityType, 'delete')) {
this.removeMassAction('remove');
this.removeMassAction('merge');
}
if (!this.getAcl().checkScope(this.entityType, 'edit')) {
+33 -5
View File
@@ -52,9 +52,11 @@ Espo.define('views/record/merge', 'view', function (Dep) {
}.bind(this));
return {
rows: rows,
models: this.models,
modelList: this.models,
scope: this.scope,
width: Math.round(((80 - this.models.length * 5) / this.models.length * 10)) / 10
hasCreatedAt: this.hasCreatedAt,
width: Math.round(((80 - this.models.length * 5) / this.models.length * 10)) / 10,
dataList: this.getDataList()
};
},
@@ -172,7 +174,7 @@ Espo.define('views/record/merge', 'view', function (Dep) {
this.createView(model.id + '-' + field, viewName, {
model: model,
el: '.merge .' + model.id + ' .field[data-name="' + field + '"]',
el: '.merge [data-id="'+model.id+'"] .field[data-name="' + field + '"]',
defs: {
name: field,
},
@@ -182,8 +184,34 @@ Espo.define('views/record/merge', 'view', function (Dep) {
}.bind(this));
}.bind(this));
this.hasCreatedAt = this.getMetadata().get(['entityDefs', this.scope, 'fields', 'createdAt']);
if (this.hasCreatedAt) {
this.models.forEach(function (model) {
this.createView(model.id + '-' + 'createdAt', 'views/fields/datetime', {
model: model,
el: '.merge [data-id="'+model.id+'"] .field[data-name="createdAt"]',
defs: {
name: 'createdAt',
},
mode: 'detail',
readOnly: true,
});
}, this);
}
},
getDataList: function () {
var dataList = [];
this.models.forEach(function (model, i) {
var o = {};
o.id = model.id;
o.name = Handlebars.Utils.escapeExpression(model.get('name'));
o.createdAtViewName = model.id + '-' + 'createdAt';
dataList.push(o);
}, this);
return dataList;
},
});
});
+24 -5
View File
@@ -84,7 +84,17 @@ Espo.define('views/record/search', 'view', function (Dep) {
return this.fieldList != null && this.moreFieldList != null;
}.bind(this));
this.boolFilterList = Espo.Utils.clone(this.getMetadata().get('clientDefs.' + this.scope + '.boolFilterList') || []);
this.boolFilterList = Espo.Utils.clone(this.getMetadata().get('clientDefs.' + this.scope + '.boolFilterList') || []).filter(function (item) {
if (typeof item === 'string') return true;
item = item || {};
if (item.inPortalDisabled && this.getUser().isPortal()) return false;
if (item.isPortalOnly && !this.getUser().isPortal()) return false;
return true;
}, this).map(function (item) {
if (typeof item === 'string') return item;
item = item || {};
return item.name;
}, this);
var forbiddenFieldList = this.getAcl().getScopeForbiddenFieldList(this.entityType) || [];
@@ -97,7 +107,13 @@ Espo.define('views/record/search', 'view', function (Dep) {
this.tryReady();
}.bind(this));
this.presetFilterList = Espo.Utils.clone(this.getMetadata().get('clientDefs.' + this.scope + '.filterList') || []);
this.presetFilterList = (Espo.Utils.clone(this.getMetadata().get('clientDefs.' + this.scope + '.filterList') || [])).filter(function (item) {
if (typeof item === 'string') return true;
item = item || {};
if (item.inPortalDisabled && this.getUser().isPortal()) return false;
if (item.isPortalOnly && !this.getUser().isPortal()) return false;
return true;
}, this);
((this.getPreferences().get('presetFilters') || {})[this.scope] || []).forEach(function (item) {
this.presetFilterList.push(item);
}, this);
@@ -109,12 +125,15 @@ Espo.define('views/record/search', 'view', function (Dep) {
this.loadSearchData();
if (this.presetName) {
var hasPresetListed = this.presetFilterList.find(function (item) {
var hasPresetListed = false;
for (var i in this.presetFilterList) {
var item = this.presetFilterList[i] || {};
var name = (typeof item === 'string') ? item : item.name;
if (name === this.presetName) {
return true;
hasPresetListed = true;
break;
}
}, this);
}
if (!hasPresetListed) {
this.presetFilterList.push(this.presetName);
}
+11 -5
View File
@@ -196,13 +196,14 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
var navbarNeededHeight = (this.getThemeManager().getParam('navbarHeight') || 44) + 1;
$moreDd = $('#nav-more-tabs-dropdown');
$moreLi = $moreDd.closest('li');
var navbarBaseWidth = this.getThemeManager().getParam('navbarBaseWidth') || 546;
var navbarBaseWidth = this.getThemeManager().getParam('navbarBaseWidth') || 512;
var updateWidth = function () {
var windowWidth = $(window.document).width();
var windowWidth = window.innerWidth;
var moreWidth = $moreDd.width();
var moreWidth = $moreLi.width();
$more.children('li.not-in-more').each(function (i, li) {
unhideOneTab();
@@ -237,15 +238,20 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
}
}.bind(this);
var processUpdateWidth = function () {
var processUpdateWidth = function (isRecursive) {
if ($navbar.height() > navbarNeededHeight) {
updateWidth();
setTimeout(function () {
processUpdateWidth();
processUpdateWidth(true);
}, 200);
} else {
if (!isRecursive) {
setTimeout(function () {
processUpdateWidth(true);
}, 10);
}
setTimeout(function () {
processUpdateWidth();
processUpdateWidth(true);
}, 1000);
}
};
+7 -3
View File
@@ -83,8 +83,7 @@ Espo.define('views/stream/panel', ['views/record/panels/relationship', 'lib!Text
var clientHeight = this.$textarea.prop('clientHeight');
if (clientHeight === lastHeight) return;
if (scrollHeight > clientHeight) {
if (scrollHeight > clientHeight + 1) {
this.$textarea.attr('rows', this.$textarea.prop('rows') + 1);
this.controlTextareaHeight(clientHeight);
}
@@ -107,7 +106,7 @@ Espo.define('views/stream/panel', ['views/record/panels/relationship', 'lib!Text
if (this.$textarea.val() !== '') return;
var attachmentsIds = this.seed.get('attachmentsIds');
if (!attachmentsIds.length) {
if (!attachmentsIds.length && !this.getView('attachments').isUploading) {
this.disablePostingMode();
}
}.bind(this));
@@ -359,6 +358,11 @@ Espo.define('views/stream/panel', ['views/record/panels/relationship', 'lib!Text
this.$textarea.prop('disabled', true);
this.getModelFactory().create('Note', function (model) {
if (this.getView('attachments').validateReady()) {
this.$textarea.prop('disabled', false)
return;
}
if (message == '' && this.seed.get('attachmentsIds').length == 0) {
this.notify('Post cannot be empty', 'error');
this.$textarea.prop('disabled', false);
+2 -2
View File
@@ -79,7 +79,7 @@ Espo.define('views/user/detail', 'views/detail', function (Dep) {
name: 'calendar',
html: this.translate('Calendar', 'scopeNames'),
style: 'default',
link: '#Calendar/show/userId=' + this.model.id + '&userName=' + this.model.get('name'),
link: '#Calendar/show/userId=' + this.model.id + '&userName=' + encodeURIComponent(this.model.get('name')),
hidden: !showActivities
});
}
@@ -90,7 +90,7 @@ Espo.define('views/user/detail', 'views/detail', function (Dep) {
},
actionEmailAccounts: function () {
this.getRouter().navigate('#EmailAccount/list/userId=' + this.model.id, {trigger: true});
this.getRouter().navigate('#EmailAccount/list/userId=' + this.model.id + '&userName=' + encodeURIComponent(this.model.get('name')), {trigger: true});
},
actionExternalAccounts: function () {
+18 -1
View File
@@ -31,7 +31,20 @@ if (process.argv.length < 3) {
throw new Error("No 'version from' passed");
}
var acceptedVersionName = process.argv[3] || versionFrom;
var acceptedVersionName = versionFrom;
var isDev = false;
if (process.argv.length > 2) {
for (var i in process.argv) {
if (process.argv[i] === '--dev') {
isDev = true;
}
if (~process.argv[i].indexOf('--acceptedVersion=')) {
acceptedVersionName = process.argv[i].substr(('--acceptedVersion=').length);
}
}
}
var path = require('path');
var fs = require('fs');
@@ -119,6 +132,10 @@ execute('git diff --name-only ' + versionFrom, function (stdout) {
}
});
if (isDev) {
versionList = [];
}
var manifest = {
"name": "EspoCRM Upgrade "+acceptedVersionName+" to "+version,
"type": "upgrade",
+1
View File
@@ -21,6 +21,7 @@
<script type="text/javascript" src="{{basePath}}client/lib/bootstrap.min.js"></script>
<script type="text/javascript" src="{{basePath}}client/lib/bootstrap-datepicker.js"></script>
<script type="text/javascript" src="{{basePath}}client/lib/bull.js"></script>
<script type="text/javascript" src="{{basePath}}client/lib/marked.min.js"></script>
<script type="text/javascript" src="{{basePath}}client/src/loader.js" data-base-path="{{basePath}}"></script>
<script type="text/javascript" src="{{basePath}}client/src/utils.js"></script>
+1
View File
@@ -21,6 +21,7 @@
<script type="text/javascript" src="{{basePath}}client/lib/bootstrap.min.js"></script>
<script type="text/javascript" src="{{basePath}}client/lib/bootstrap-datepicker.js"></script>
<script type="text/javascript" src="{{basePath}}client/lib/bull.js"></script>
<script type="text/javascript" src="{{basePath}}client/lib/marked.min.js"></script>
<script type="text/javascript" src="{{basePath}}client/src/loader.js" data-base-path="{{basePath}}"></script>
<script type="text/javascript" src="{{basePath}}client/src/utils.js"></script>
+100 -11
View File
@@ -2,10 +2,6 @@
border-radius: @button-radius;
}
.panel-heading {
padding: 6px 10px;
}
.panel-body {
padding: @panel-padding;
.clearfix();
@@ -72,10 +68,6 @@ blockquote {
font-weight: normal;
}
.form-group {
margin-bottom: 12px;
}
.form-group.hidden-cell {
margin-bottom: 0;
}
@@ -88,6 +80,10 @@ blockquote {
display: none !important;
}
.hidden-cell .inline-edit-link {
display: none !important;
}
.panel-group .panel + .panel {
margin-top: 4px;
}
@@ -326,6 +322,10 @@ ul.dropdown-menu > li.checkbox:last-child {
margin-bottom: -1px;
}
.panel > .panel-body.panel-body-form {
padding-bottom: @panel-padding - @form-group-margin-bottom;
}
.panel-body .field > .link-container > .list-group-item {
background-color: @panel-bg;
}
@@ -472,7 +472,7 @@ table.table > tbody td > .list-row-buttons button {
.list > table th input[type="checkbox"] {
margin: 0;
position: relative;
top: 3px !important;
top: 2px !important;
}
.list > table th span.caret {
@@ -514,6 +514,10 @@ select[multiple].input-sm {
z-index: 3;
}
.panel-body > p:last-child {
margin-bottom: 0;
}
.panel-body > div > .list-expanded {
margin-left: -@panel-padding;
margin-right: -@panel-padding;
@@ -673,6 +677,12 @@ table.no-margin {
border-color: #e0e0e0;
}
.panel-body > .list-container > .list > div.show-more,
.list.no-bottom-margin > div.show-more {
display: inline-block;
width: 100%;
}
.panel-body > div:first-child > .list-expanded:first-child {
margin-top: -@panel-padding;
}
@@ -745,10 +755,12 @@ table.list th {
.list .checkbox-dropdown {
margin-left: 3px;
top: -1px;
}
.list .checkbox-dropdown > a {
padding: 0;
line-height: 1;
}
.list > table td > div.field {
@@ -906,11 +918,39 @@ td.cell[data-name="buttons"] > .btn-group {
.autocomplete-selected { background: #F0F0F0; }
.autocomplete-suggestions strong { font-weight: normal; color: #3399FF; }
label.attach-file-label {
overflow: hidden;
width: 50px;
cursor: pointer;
margin-bottom: 0;
> span.btn {
cursor: pointer;
margin-bottom: 0;
}
> input.file {
opacity: 0;
width: 1px;
}
}
.attachment-upload > .attachment-control > .dropdown > .btn {
margin-bottom: 0;
}
.attachment-upload > .attachments > div:first-child {
margin-top: 2px;
}
.gray-box {
background-color: @gray-lighter;
margin: 0 5px 3px 0;
padding: 2px 3px 2px 5px;
overflow: hidden;
display: inline-block;
width: 100%;
max-width: 300px;
}
.gray-box .preview {
@@ -999,6 +1039,10 @@ td.cell[data-name="buttons"] > .btn-group {
color: @brand-warning;
}
.post-container > textarea.note,
textarea.auto-height {
overflow-x: hidden;
}
body > footer {
background-color: @gray-lighter;
@@ -1236,6 +1280,47 @@ table.table td.cell .complex-text {
}
}
.field > .html-container {
h1:first-child,
h2:first-child,
h3:first-child,
h4:first-child,
h5:first-child,
h6:first-child,
> p:first-child,
> ul:first-child,
> ol:first-child,
> pre:first-child,
> blockquote:first-child {
margin-top: 0;
}
> p:last-child,
> ul:last-child,
> ol:last-child,
> pre:last-child,
> blockquote:last-child,
> table:last-child {
margin-bottom: 0;
}
ul > li {
list-style-type: disc;
}
ul, ol {
padding-left: 30px;
}
p,
ul,
ol,
pre,
blockquote {
margin-top: @line-height-computed / 2;
}
}
#popup-notifications-container {
overflow-y: auto;
overflow-x: hidden;
@@ -1251,7 +1336,7 @@ table.table td.cell .complex-text {
.popup-notification {
width: 400px;
padding: 14px;
padding: @panel-padding;
background-color: @panel-bg;
border: 2px solid @main-gray;
margin-top: 10px;
@@ -1575,6 +1660,10 @@ pre > code {
.admin-content .admin-right-column {
padding-top: 28px;
}
.col-md-12.hidden-cell {
min-height: 0;
}
}
@media screen and (max-width: @screen-sm-min) {
+13 -2
View File
@@ -5,6 +5,16 @@ body, table {
color: @text-color;
}
body {
> p:last-child,
> ul:last-child,
> ol:last-child,
> pre:last-child,
> blockquote:last-child {
margin-bottom: 0;
}
}
body {
margin: 0;
}
@@ -32,6 +42,7 @@ table {
.table {
width: 100%;
border-collapse: collapse;
}
.table-bordered {
@@ -53,8 +64,8 @@ table {
.table>thead>tr>td,
.table>tbody>tr>td,
.table>tfoot>tr>td {
padding: 8px;
line-height: 1.36;
padding: @table-cell-padding;
line-height: @line-height-base;
vertical-align: top;
border-top: 1px solid @default-border-color;
}
@@ -57,4 +57,8 @@
.calendar-container .timeline .vis-item.vis-selected {
border-color: lighten(@brand-primary, 30%);
background-color: lighten(@brand-primary, 50%);
}
.calendar-container .timeline .vis-tooltip {
display: none;
}
+5
View File
@@ -19,6 +19,7 @@
@container-lg: @container-large-desktop;
@panel-padding: 14px;
@panel-heading-padding: 6px 10px;
@container-padding: 15px;
@@ -133,3 +134,7 @@
@panel-border-width: 2px;
@navbar-panel-body-max-height: 350px;
@form-group-margin-bottom: 12px;
@modal-title-line-height: floor(@font-size-h4 * @line-height-base);
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "espocrm",
"version": "5.0.2",
"version": "5.0.3",
"description": "",
"main": "index.php",
"repository": {
+1 -1
View File
@@ -29,7 +29,7 @@
namespace tests\integration\Core;
abstract class BaseTestCase extends \PHPUnit_Framework_TestCase
abstract class BaseTestCase extends \PHPUnit\Framework\TestCase
{
protected $espoTester;
+15 -6
View File
@@ -158,7 +158,6 @@ class Tester
{
$this->install();
$this->loadData();
$this->getApplication(true)->runRebuild();
}
public function terminate()
@@ -215,22 +214,32 @@ class Tester
protected function loadData()
{
if (!empty($this->params['dataFile'])) {
$this->getDataLoader()->loadData($this->params['dataFile']);
}
if (!empty($this->params['pathToFiles'])) {
$this->getDataLoader()->loadFiles($this->params['pathToFiles']);
$this->clearVars();
$this->getApplication()->runRebuild();
}
if (!empty($this->params['dataFile'])) {
$this->getDataLoader()->loadData($this->params['dataFile']);
}
}
public function clearCache()
{
$fileManager = new \Espo\Core\Utils\File\Manager();
$this->clearVars();
$fileManager = new \Espo\Core\Utils\File\Manager();
return $fileManager->removeInDir('data/cache');
}
protected function clearVars()
{
$this->dataLoader = null;
$this->application = null;
$this->apiClient = null;
}
public function sendRequest($method, $action, $data = null)
{
$apiClient = $this->getApiClient();
+1 -1
View File
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core;
use tests\unit\ReflectionHelper;
class CronManagerTest extends \PHPUnit_Framework_TestCase
class CronManagerTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -32,7 +32,7 @@ namespace tests\unit\Espo\Core;
use tests\unit\ReflectionHelper;
class EntryPointManagerTest extends \PHPUnit_Framework_TestCase
class EntryPointManagerTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Formula;
use \Espo\ORM\Entity;
class EvaluatorTest extends \PHPUnit_Framework_TestCase
class EvaluatorTest extends \PHPUnit\Framework\TestCase
{
protected function setUp()
{
+5 -1
View File
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Formula;
use \Espo\ORM\Entity;
class FormulaTest extends \PHPUnit_Framework_TestCase
class FormulaTest extends \PHPUnit\Framework\TestCase
{
protected function setUp()
@@ -307,6 +307,8 @@ class FormulaTest extends \PHPUnit_Framework_TestCase
->with('teams', '1');
$this->formula->process($item, $this->entity);
$this->assertTrue(true);
}
function testRemoveLinkMultipleId()
@@ -339,6 +341,8 @@ class FormulaTest extends \PHPUnit_Framework_TestCase
->with('teams', '1');
$this->formula->process($item, $this->entity);
$this->assertTrue(true);
}
function testAnd()
+1 -1
View File
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Formula;
use \Espo\ORM\Entity;
class ParserTest extends \PHPUnit_Framework_TestCase
class ParserTest extends \PHPUnit\Framework\TestCase
{
protected function setUp()
{
+2 -2
View File
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core;
use tests\unit\ReflectionHelper;
class HookManagerTest extends \PHPUnit_Framework_TestCase
class HookManagerTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -363,7 +363,7 @@ class HookManagerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($result, $this->reflection->getProperty('data'));
}
public function testGetHookList()
public function noTestGetHookList()
{
$this->reflection->setProperty('data', array (
'Common' =>
@@ -29,7 +29,7 @@
namespace tests\unit\Espo\Core\Htmlizer;
class HtmlizerTest extends \PHPUnit_Framework_TestCase
class HtmlizerTest extends \PHPUnit\Framework\TestCase
{
protected $htmlizer;
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Mail;
use tests\unit\ReflectionHelper;
class FiltersMatcherTest extends \PHPUnit_Framework_TestCase
class FiltersMatcherTest extends \PHPUnit\Framework\TestCase
{
protected $object;
+5 -2
View File
@@ -32,7 +32,7 @@ namespace tests\unit\Espo\Core\Mail;
use \Espo\Entities\Attachment;
use \Espo\Entities\Email;
class ImporterTest extends \PHPUnit_Framework_TestCase
class ImporterTest extends \PHPUnit\Framework\TestCase
{
function setUp()
{
@@ -125,7 +125,10 @@ class ImporterTest extends \PHPUnit_Framework_TestCase
function testImport2()
{
if (extension_loaded('mailparse')) return;
if (extension_loaded('mailparse')) {
$this->assertTrue(true);
return;
}
$entityManager = $this->entityManager;
$config = $this->config;
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\SelectManagers;
use \tests\unit\testData\Entities\Test2;
class BaseTest extends \PHPUnit_Framework_TestCase
class BaseTest extends \PHPUnit\Framework\TestCase
{
protected function setUp()
{
@@ -33,7 +33,7 @@ use tests\unit\ReflectionHelper,
Espo\Core\ExtensionManager,
Espo\Core\UpgradeManager;
class ActionManagerTest extends \PHPUnit_Framework_TestCase
class ActionManagerTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -102,7 +102,7 @@ class ActionManagerTest extends \PHPUnit_Framework_TestCase
public function testGetObjectExtensionNotExists()
{
$this->setExpectedException('\Espo\Core\Exceptions\Error');
$this->expectException('\Espo\Core\Exceptions\Error');
$this->object->setAction('CustomClass');
$class = $this->reflection->invokeMethod('getObject');
@@ -128,7 +128,7 @@ class ActionManagerTest extends \PHPUnit_Framework_TestCase
public function testGetObjectUpgradeUninstall()
{
$this->setExpectedException('\Espo\Core\Exceptions\Error');
$this->expectException('\Espo\Core\Exceptions\Error');
$this->reflection->setProperty('managerName', 'Upgrade');
$this->object->setAction(UpgradeManager::UNINSTALL);
@@ -141,7 +141,7 @@ class ActionManagerTest extends \PHPUnit_Framework_TestCase
public function testGetObjectUpgradeDelete()
{
$this->setExpectedException('\Espo\Core\Exceptions\Error');
$this->expectException('\Espo\Core\Exceptions\Error');
$this->reflection->setProperty('managerName', 'Upgrade');
$this->object->setAction(UpgradeManager::DELETE);
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Upgrades\Actions;
use tests\unit\ReflectionHelper;
use Espo\Core\Utils\Util;
class BaseTest extends \PHPUnit_Framework_TestCase
class BaseTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -111,7 +111,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
public function testCreateProcessIdWithExists()
{
$this->setExpectedException('\Espo\Core\Exceptions\Error');
$this->expectException('\Espo\Core\Exceptions\Error');
$processId = $this->reflection->invokeMethod('createProcessId', array());
}
@@ -126,7 +126,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
public function testGetProcessId()
{
$this->setExpectedException('\Espo\Core\Exceptions\Error');
$this->expectException('\Espo\Core\Exceptions\Error');
$this->reflection->setProperty('processId', null);
$this->reflection->invokeMethod('getProcessId');
@@ -134,7 +134,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
public function testGetManifestIncorrect()
{
$this->setExpectedException('\Espo\Core\Exceptions\Error');
$this->expectException('\Espo\Core\Exceptions\Error');
$manifest = '{
"name": "Upgrade 1.0-b3 to 1.0-b4"
@@ -220,7 +220,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
$currentVersion = $this->currentVersion;
}
$this->setExpectedException('\Espo\Core\Exceptions\Error');
$this->expectException('\Espo\Core\Exceptions\Error');
$this->reflection->invokeMethod('checkVersions', array($versions, $currentVersion, 'error'));
}
@@ -260,7 +260,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
public function testCheckPackageTypeUpgrade()
{
$this->setExpectedException('\Espo\Core\Exceptions\Error');
$this->expectException('\Espo\Core\Exceptions\Error');
$this->reflection->setProperty('data', array('manifest' => array('type' => 'upgrade')));
$this->assertTrue( $this->reflection->invokeMethod('checkPackageType') );
+1 -1
View File
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Utils;
use tests\unit\ReflectionHelper;
class ConfigTest extends \PHPUnit_Framework_TestCase
class ConfigTest extends \PHPUnit\Framework\TestCase
{
protected $object;
+1 -1
View File
@@ -31,7 +31,7 @@ namespace tests\Espo\Core\Utils;
use Espo\Core\Utils\DataUtil;
class DataUtilTest extends \PHPUnit_Framework_TestCase
class DataUtilTest extends \PHPUnit\Framework\TestCase
{
public function testUnsetByKey1()
{
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Utils;
use tests\unit\ReflectionHelper;
class FieldManagerTest extends \PHPUnit_Framework_TestCase
class FieldManagerTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -57,7 +57,7 @@ class FieldManagerTest extends \PHPUnit_Framework_TestCase
public function testCreateExistingField()
{
$this->setExpectedException('\Espo\Core\Exceptions\Conflict');
$this->expectException('\Espo\Core\Exceptions\Conflict');
$data = array(
"type" => "varchar",
@@ -257,12 +257,4 @@ class FieldManagerTest extends \PHPUnit_Framework_TestCase
);
$this->assertEquals($result, $this->reflection->invokeMethod('normalizeDefs', array('CustomEntity', $input1, $input2)));
}
public function testDeleteTestFile()
{
$file = 'custom/Espo/Custom/Resources/metadata/entityDefs/CustomEntity.json';
if (file_exists($file)) {
@unlink($file);
}
}
}
@@ -32,7 +32,7 @@ namespace tests\unit\Espo\Core\Utils\File;
use tests\unit\ReflectionHelper;
class ClassParserTest extends \PHPUnit_Framework_TestCase
class ClassParserTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Utils\File;
use tests\unit\ReflectionHelper;
use Espo\Core\Utils\Util;
class ManagerTest extends \PHPUnit_Framework_TestCase
class ManagerTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Utils\File;
use tests\unit\ReflectionHelper;
class PermissionTest extends \PHPUnit_Framework_TestCase
class PermissionTest extends \PHPUnit\Framework\TestCase
{
protected $object;
+1 -1
View File
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Utils;
use Espo\Core\Utils\Json;
class JsonTest extends \PHPUnit_Framework_TestCase
class JsonTest extends \PHPUnit\Framework\TestCase
{
protected function setUp()
{
+1 -1
View File
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Utils;
use tests\unit\ReflectionHelper;
class LanguageTest extends \PHPUnit_Framework_TestCase
class LanguageTest extends \PHPUnit\Framework\TestCase
{
protected $object;
+1 -1
View File
@@ -32,7 +32,7 @@ namespace tests\unit\Espo\Core\Utils;
use tests\unit\ReflectionHelper;
use Espo\Core\Utils\Util;
class LayoutTest extends \PHPUnit_Framework_TestCase
class LayoutTest extends \PHPUnit\Framework\TestCase
{
protected $object;
+1 -1
View File
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Utils;
use tests\unit\ReflectionHelper;
class MetadataTest extends \PHPUnit_Framework_TestCase
class MetadataTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -31,7 +31,7 @@ namespace tests\unit\Espo\Core\Utils;
use tests\unit\ReflectionHelper;
class PasswordHashTest extends \PHPUnit_Framework_TestCase
class PasswordHashTest extends \PHPUnit\Framework\TestCase
{
protected $object;
@@ -83,7 +83,7 @@ class PasswordHashTest extends \PHPUnit_Framework_TestCase
public function testGetSaltException()
{
$this->setExpectedException('\Espo\Core\Exceptions\Error');
$this->expectException('\Espo\Core\Exceptions\Error');
$this->reflection->invokeMethod('getSalt');
}

Some files were not shown because too many files have changed in this diff Show More