diff --git a/application/Espo/Controllers/EntityManager.php b/application/Espo/Controllers/EntityManager.php
index 532a62816e..76d46d2747 100644
--- a/application/Espo/Controllers/EntityManager.php
+++ b/application/Espo/Controllers/EntityManager.php
@@ -83,6 +83,9 @@ class EntityManager extends \Espo\Core\Controllers\Base
if (isset($data['textFilterFields']) && is_array($data['textFilterFields'])) {
$params['textFilterFields'] = $data['textFilterFields'];
}
+ if (!empty($data['color'])) {
+ $params['color'] = $data['color'];
+ }
$result = $this->getContainer()->get('entityManagerUtil')->create($name, $type, $params);
diff --git a/application/Espo/Core/Utils/EntityManager.php b/application/Espo/Core/Utils/EntityManager.php
index e555fd6685..e4d2a940e7 100644
--- a/application/Espo/Core/Utils/EntityManager.php
+++ b/application/Espo/Core/Utils/EntityManager.php
@@ -302,6 +302,10 @@ class EntityManager
$clientDefsContents = str_replace('{'.$key.'}', $value, $clientDefsContents);
}
$clientDefsData = Json::decode($clientDefsContents, true);
+
+ if (array_key_exists('color', $params)) {
+ $clientDefsData['color'] = $params['color'];
+ };
$this->getMetadata()->set('clientDefs', $name, $clientDefsData);
$this->getBaseLanguage()->set('Global', 'scopeNames', $name, $labelSingular);
@@ -387,6 +391,13 @@ class EntityManager
$this->getMetadata()->set('entityDefs', $name, $entityDefsData);
}
+ if (array_key_exists('color', $data)) {
+ $clientDefsData = [
+ 'color' => $data['color']
+ ];
+ $this->getMetadata()->set('clientDefs', $name, $clientDefsData);
+ }
+
$this->getMetadata()->save();
$this->getLanguage()->save();
if ($isCustom) {
diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Account.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Account.json
index 07a60d624d..27e6e00cb7 100644
--- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Account.json
+++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Account.json
@@ -74,5 +74,6 @@
"detailConvert": {
"type": "detail"
}
- }
+ },
+ "color": "#edc755"
}
diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Calendar.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Calendar.json
index 39f6691efc..ea497047a7 100644
--- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Calendar.json
+++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Calendar.json
@@ -9,5 +9,6 @@
"modeList": ["month", "agendaWeek", "agendaDay", "timeline"],
"canceledStatusList": ["Not Held", "Canceled"],
"completedStatusList": ["Held", "Completed"],
- "additionalColorList": ["#AB78AD", "#CC9B45"]
+ "additionalColorList": ["#AB78AD", "#CC9B45"],
+ "iconClass": "glyphicon glyphicon-calendar"
}
\ No newline at end of file
diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Contact.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Contact.json
index 8d6a44d4ea..216fb4dc63 100644
--- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Contact.json
+++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Contact.json
@@ -116,5 +116,6 @@
}
}
}
- }
+ },
+ "color": "#70a9d7"
}
\ No newline at end of file
diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Document.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Document.json
index 927c0c0546..c2c1422874 100644
--- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Document.json
+++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Document.json
@@ -25,5 +25,6 @@
}
]
}
- }
+ },
+ "iconClass": "glyphicon glyphicon-file"
}
diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json
index 6326b5fcef..cd733c24b1 100644
--- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json
+++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Lead.json
@@ -155,5 +155,6 @@
}
}
}
- }
+ },
+ "color": "#d69cc7"
}
\ No newline at end of file
diff --git a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Opportunity.json b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Opportunity.json
index 15bfb9c689..b4cf16a582 100644
--- a/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Opportunity.json
+++ b/application/Espo/Modules/Crm/Resources/metadata/clientDefs/Opportunity.json
@@ -70,5 +70,6 @@
"listForContact": {
"type": "listSmall"
}
- }
+ },
+ "color": "#91c36a"
}
diff --git a/application/Espo/Resources/i18n/en_US/EntityManager.json b/application/Espo/Resources/i18n/en_US/EntityManager.json
index cc6dfee8fb..99aea3ed5f 100644
--- a/application/Espo/Resources/i18n/en_US/EntityManager.json
+++ b/application/Espo/Resources/i18n/en_US/EntityManager.json
@@ -28,7 +28,8 @@
"audited": "Audited",
"auditedForeign": "Foreign Audited",
"statusField": "Status Field",
- "beforeSaveCustomScript": "Before Save Custom Script"
+ "beforeSaveCustomScript": "Before Save Custom Script",
+ "color": "Color"
},
"options": {
"type": {
diff --git a/application/Espo/Resources/i18n/en_US/Settings.json b/application/Espo/Resources/i18n/en_US/Settings.json
index b598a66063..d737e18dda 100644
--- a/application/Espo/Resources/i18n/en_US/Settings.json
+++ b/application/Espo/Resources/i18n/en_US/Settings.json
@@ -94,7 +94,10 @@
"adminNotifications": "System notifications in administration panel",
"adminNotificationsNewVersion": "Show notification when new EspoCRM version is available",
"textFilterUseContainsForVarchar": "Use 'contains' opertor when filtering varchar fields",
- "authTokenPreventConcurrent": "Only one auth token per user"
+ "authTokenPreventConcurrent": "Only one auth token per user",
+ "scopeColorsDisabled": "Disable scope colors",
+ "tabColorsDisabled": "Disable tab colors",
+ "tabIconsDisabled": "Disable tab icons"
},
"options": {
"weekStart": {
diff --git a/application/Espo/Resources/layouts/Settings/userInterface.json b/application/Espo/Resources/layouts/Settings/userInterface.json
index f84704f4fb..6da9dbb400 100644
--- a/application/Espo/Resources/layouts/Settings/userInterface.json
+++ b/application/Espo/Resources/layouts/Settings/userInterface.json
@@ -7,6 +7,8 @@
[{"name": "recordsPerPage"},{"name": "displayListViewRecordCount"}],
[{"name": "recordsPerPageSmall"}, {"name": "avatarsDisabled"}],
[{"name": "tabList"},{"name": "quickCreateList"}],
+ [{"name": "scopeColorsDisabled"}, {"name": "tabIconsDisabled"}],
+ [{"name": "tabColorsDisabled"}, false],
[{"name": "dashboardLayout", "fullWidth": true}]
]
}
diff --git a/application/Espo/Resources/metadata/entityDefs/Settings.json b/application/Espo/Resources/metadata/entityDefs/Settings.json
index d45e968502..84cc882585 100644
--- a/application/Espo/Resources/metadata/entityDefs/Settings.json
+++ b/application/Espo/Resources/metadata/entityDefs/Settings.json
@@ -456,6 +456,15 @@
"textFilterUseContainsForVarchar": {
"type": "bool",
"tooltip": true
+ },
+ "scopeColorsDisabled": {
+ "type": "bool"
+ },
+ "tabColorsDisabled": {
+ "type": "bool"
+ },
+ "tabIconsDisabled": {
+ "type": "bool"
}
}
}
diff --git a/client/res/templates/admin/entity-manager/modals/edit-entity.tpl b/client/res/templates/admin/entity-manager/modals/edit-entity.tpl
index bda115bb36..415ebe4b6d 100644
--- a/client/res/templates/admin/entity-manager/modals/edit-entity.tpl
+++ b/client/res/templates/admin/entity-manager/modals/edit-entity.tpl
@@ -79,3 +79,12 @@
{{/if}}
{{/unless}}
+
+
diff --git a/client/res/templates/fields/link-parent/detail.tpl b/client/res/templates/fields/link-parent/detail.tpl
index f47efd68b8..4068fbdbd2 100644
--- a/client/res/templates/fields/link-parent/detail.tpl
+++ b/client/res/templates/fields/link-parent/detail.tpl
@@ -1,5 +1,3 @@
-{{#if idValue}}
-{{nameValue}}
-{{else}}
+{{#if idValue}}{{#if iconHtml}}{{{iconHtml}}}{{/if}}{{nameValue}}{{else}}
{{#if valueIsSet}}{{translate 'None'}}{{else}}...{{/if}}
{{/if}}
diff --git a/client/res/templates/fields/link/detail.tpl b/client/res/templates/fields/link/detail.tpl
index 0fba42c538..df4b6f5f9b 100644
--- a/client/res/templates/fields/link/detail.tpl
+++ b/client/res/templates/fields/link/detail.tpl
@@ -1,5 +1,3 @@
-{{#if idValue}}
-{{nameValue}}
-{{else}}
+{{#if idValue}}{{#if iconHtml}}{{{iconHtml}}}{{/if}}{{nameValue}}{{else}}
{{#if valueIsSet}}{{translate 'None'}}{{else}}...{{/if}}
{{/if}}
diff --git a/client/res/templates/global-search/name-field.tpl b/client/res/templates/global-search/name-field.tpl
index 4b740fb940..d745507ab9 100644
--- a/client/res/templates/global-search/name-field.tpl
+++ b/client/res/templates/global-search/name-field.tpl
@@ -1 +1 @@
-{{{name}}}
+{{{iconHtml}}}{{{name}}}
diff --git a/client/res/templates/record/bottom.tpl b/client/res/templates/record/bottom.tpl
index 9c79ef2823..05cea492c5 100644
--- a/client/res/templates/record/bottom.tpl
+++ b/client/res/templates/record/bottom.tpl
@@ -26,7 +26,11 @@
{{#unless notRefreshable}}
{{/unless}}
- {{title}}
+ {{#if titleHtml}}
+ {{{titleHtml}}}
+ {{else}}
+ {{title}}
+ {{/if}}
{{#unless notRefreshable}}
{{/unless}}
diff --git a/client/res/templates/record/side.tpl b/client/res/templates/record/side.tpl
index 8124213456..4337294d7a 100644
--- a/client/res/templates/record/side.tpl
+++ b/client/res/templates/record/side.tpl
@@ -27,7 +27,11 @@
{{#unless notRefreshable}}
{{/unless}}
- {{title}}
+ {{#if titleHtml}}
+ {{{titleHtml}}}
+ {{else}}
+ {{title}}
+ {{/if}}
{{#unless notRefreshable}}
{{/unless}}
diff --git a/client/res/templates/site/navbar.tpl b/client/res/templates/site/navbar.tpl
index 2505ec4519..34787d0c43 100644
--- a/client/res/templates/site/navbar.tpl
+++ b/client/res/templates/site/navbar.tpl
@@ -12,7 +12,7 @@
{{#each tabDefsList}}
{{#unless isInMore}}
- - {{label}}{{shortLabel}}
+ - {{label}}{{#if iconClass}}{{else}}{{shortLabel}}{{/if}}
{{/unless}}
{{/each}}
-
@@ -20,7 +20,7 @@
diff --git a/client/src/view-helper.js b/client/src/view-helper.js
index da1f568eee..abe17859d4 100644
--- a/client/src/view-helper.js
+++ b/client/src/view-helper.js
@@ -289,6 +289,30 @@ Espo.define('view-helper', [], function () {
Handlebars.registerHelper('basePath', function () {
return self.basePath || '';
});
+ },
+
+ getScopeColorIconHtml: function (scope, noWhiteSpace, additionalClassName) {
+ if (this.settings.get('scopeColorsDisabled')) {
+ return '';
+ }
+
+ var color = this.metadata.get(['clientDefs', scope, 'color']);
+ var html = '';
+
+ if (color) {
+ var $span = $('');
+ $span.css('color', color);
+ if (additionalClassName) {
+ $span.addClass(additionalClassName);
+ }
+ html = $span.get(0).outerHTML;
+ }
+
+ if (!noWhiteSpace) {
+ if (html) html += ' ';
+ }
+
+ return html;
}
});
diff --git a/client/src/views/admin/entity-manager/modals/edit-entity.js b/client/src/views/admin/entity-manager/modals/edit-entity.js
index d6f03b0458..b5ae02034b 100644
--- a/client/src/views/admin/entity-manager/modals/edit-entity.js
+++ b/client/src/views/admin/entity-manager/modals/edit-entity.js
@@ -89,6 +89,8 @@ Espo.define('views/admin/entity-manager/modals/edit-entity', ['views/modal', 'mo
this.model.set('textFilterFields', this.getMetadata().get('entityDefs.' + scope + '.collection.textFilterFields') || ['name']);
this.model.set('statusField', this.getMetadata().get('scopes.' + scope + '.statusField') || null);
+
+ this.model.set('color', this.getMetadata().get(['clientDefs', scope, 'color']) || null);
}
this.createView('type', 'views/fields/enum', {
@@ -169,6 +171,15 @@ Espo.define('views/admin/entity-manager/modals/edit-entity', ['views/modal', 'mo
}
});
+ this.createView('color', 'views/fields/colorpicker', {
+ model: model,
+ mode: 'edit',
+ el: this.options.el + ' .field[data-name="color"]',
+ defs: {
+ name: 'color'
+ }
+ });
+
if (scope) {
var fieldDefs = this.getMetadata().get('entityDefs.' + scope + '.fields') || {};
@@ -383,7 +394,8 @@ Espo.define('views/admin/entity-manager/modals/edit-entity', ['views/modal', 'mo
stream: this.model.get('stream'),
disabled: this.model.get('disabled'),
textFilterFields: this.model.get('textFilterFields'),
- statusField: this.model.get('statusField')
+ statusField: this.model.get('statusField'),
+ color: this.model.get('color') || null
};
if (data.statusField === '') {
diff --git a/client/src/views/detail.js b/client/src/views/detail.js
index 12e6664eaf..041b202882 100644
--- a/client/src/views/detail.js
+++ b/client/src/views/detail.js
@@ -165,8 +165,10 @@ Espo.define('views/detail', 'views/main', function (Dep) {
var rootUrl = this.options.rootUrl || this.options.params.rootUrl || '#' + this.scope;
+ var headerIconHtml = this.getHeaderIconHtml();
+
return this.buildHeaderHtml([
- '' + this.getLanguage().translate(this.scope, 'scopeNamesPlural') + '',
+ headerIconHtml + '' + this.getLanguage().translate(this.scope, 'scopeNamesPlural') + '',
name
]);
},
diff --git a/client/src/views/edit.js b/client/src/views/edit.js
index 12fdc5d750..714bf7b96f 100644
--- a/client/src/views/edit.js
+++ b/client/src/views/edit.js
@@ -82,13 +82,15 @@ Espo.define('views/edit', 'views/main', function (Dep) {
getHeader: function () {
var html = '';
+ var headerIconHtml = this.getHeaderIconHtml();
+
var arr = [];
if (this.options.noHeaderLinks) {
arr.push(this.getLanguage().translate(this.scope, 'scopeNamesPlural'));
} else {
var rootUrl = this.options.rootUrl || this.options.params.rootUrl || '#' + this.scope;
- arr.push('' + this.getLanguage().translate(this.scope, 'scopeNamesPlural') + '');
+ arr.push(headerIconHtml + '' + this.getLanguage().translate(this.scope, 'scopeNamesPlural') + '');
}
if (this.model.isNew()) {
diff --git a/client/src/views/email/detail.js b/client/src/views/email/detail.js
index 7224ff3801..be13bed7d5 100644
--- a/client/src/views/email/detail.js
+++ b/client/src/views/email/detail.js
@@ -356,8 +356,10 @@ Espo.define('views/email/detail', ['views/detail', 'email-helper'], function (De
var rootUrl = this.options.rootUrl || this.options.params.rootUrl || '#' + this.scope;
+ var headerIconHtml = this.getHeaderIconHtml();
+
return this.buildHeaderHtml([
- '' + this.getLanguage().translate(this.model.name, 'scopeNamesPlural') + '',
+ headerIconHtml+ '' + this.getLanguage().translate(this.model.name, 'scopeNamesPlural') + '',
nameHtml
]);
},
diff --git a/client/src/views/fields/link-multiple-with-columns.js b/client/src/views/fields/link-multiple-with-columns.js
index 903bcef84a..2ecbc41d5b 100644
--- a/client/src/views/fields/link-multiple-with-columns.js
+++ b/client/src/views/fields/link-multiple-with-columns.js
@@ -128,8 +128,12 @@ Espo.define('views/fields/link-multiple-with-columns', 'views/fields/link-multip
}
}, this);
+ var iconHtml = '';
+ if (this.mode == 'detail') {
+ iconHtml = this.iconHtml;
+ }
- var lineHtml = '';
+ var lineHtml = '';
return lineHtml;
},
diff --git a/client/src/views/fields/link-multiple-with-role.js b/client/src/views/fields/link-multiple-with-role.js
index 294b5359cc..3df6faa8e3 100644
--- a/client/src/views/fields/link-multiple-with-role.js
+++ b/client/src/views/fields/link-multiple-with-role.js
@@ -84,7 +84,11 @@ Espo.define('views/fields/link-multiple-with-role', 'views/fields/link-multiple'
this.getHelper().stripTags(this.getLanguage().translateOption(role, this.roleField, this.roleFieldScope)) +
'';
}
- var lineHtml = '';
+ var iconHtml = '';
+ if (this.mode == 'detail') {
+ iconHtml = this.iconHtml;
+ }
+ var lineHtml = '';
return lineHtml;
},
diff --git a/client/src/views/fields/link-multiple.js b/client/src/views/fields/link-multiple.js
index 470e7e5b06..0abc9b7d2a 100644
--- a/client/src/views/fields/link-multiple.js
+++ b/client/src/views/fields/link-multiple.js
@@ -111,6 +111,8 @@ Espo.define('views/fields/link-multiple', 'views/fields/base', function (Dep) {
this.sortable = this.sortable || this.params.sortable;
+ this.iconHtml = this.getHelper().getScopeColorIconHtml(this.foreignScope);
+
if (this.mode != 'list') {
this.addActionHandler('selectLink', function () {
self.notify('Loading...');
@@ -301,7 +303,11 @@ Espo.define('views/fields/link-multiple', 'views/fields/base', function (Dep) {
if (!name && id) {
name = this.translate(this.foreignScope, 'scopeNames');
}
- return '' + this.getHelper().stripTags(name) + '';
+ var iconHtml = '';
+ if (this.mode == 'detail') {
+ iconHtml = this.iconHtml;
+ }
+ return '' + iconHtml + this.getHelper().stripTags(name) + '';
},
getValueForDisplay: function () {
diff --git a/client/src/views/fields/link-parent.js b/client/src/views/fields/link-parent.js
index 9617f779c1..3df6b8c545 100644
--- a/client/src/views/fields/link-parent.js
+++ b/client/src/views/fields/link-parent.js
@@ -63,6 +63,10 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) {
if (!nameValue && this.model.get(this.idName) && this.model.get(this.typeName)) {
nameValue = this.translate(this.model.get(this.typeName), 'scopeNames');
}
+ var iconHtml = null;
+ if (this.mode === 'detail' && this.foreignScope) {
+ iconHtml = this.getHelper().getScopeColorIconHtml(this.foreignScope);
+ }
return _.extend({
idName: this.idName,
nameName: this.nameName,
@@ -72,7 +76,8 @@ Espo.define('views/fields/link-parent', 'views/fields/base', function (Dep) {
typeValue: this.model.get(this.typeName),
foreignScope: this.foreignScope,
foreignScopeList: this.foreignScopeList,
- valueIsSet: this.model.has(this.idName) || this.model.has(this.typeName)
+ valueIsSet: this.model.has(this.idName) || this.model.has(this.typeName),
+ iconHtml: iconHtml
}, Dep.prototype.data.call(this));
},
diff --git a/client/src/views/fields/link.js b/client/src/views/fields/link.js
index 580652a4a4..bd63946ebe 100644
--- a/client/src/views/fields/link.js
+++ b/client/src/views/fields/link.js
@@ -64,13 +64,19 @@ Espo.define('views/fields/link', 'views/fields/base', function (Dep) {
if (this.mode === 'detail' && !nameValue && this.model.get(this.idName)) {
nameValue = this.translate(this.foreignScope, 'scopeNames');
}
+
+ var iconHtml = null;
+ if (this.mode === 'detail') {
+ iconHtml = this.getHelper().getScopeColorIconHtml(this.foreignScope);
+ }
return _.extend({
idName: this.idName,
nameName: this.nameName,
idValue: this.model.get(this.idName),
nameValue: nameValue,
foreignScope: this.foreignScope,
- valueIsSet: this.model.has(this.idName)
+ valueIsSet: this.model.has(this.idName),
+ iconHtml: iconHtml
}, Dep.prototype.data.call(this));
},
diff --git a/client/src/views/global-search/name-field.js b/client/src/views/global-search/name-field.js
index cbe575450f..ed9e1bf5e2 100644
--- a/client/src/views/global-search/name-field.js
+++ b/client/src/views/global-search/name-field.js
@@ -37,10 +37,28 @@ Espo.define('views/global-search/name-field', 'views/fields/base', function (Dep
scope: this.model.get('_scope'),
name: this.model.get('name'),
id: this.model.id,
+ iconHtml: this.getHelper().getScopeColorIconHtml(this.model.get('_scope'))
};
},
+ getIconHtml: function () {
+ if (this.getConfig().get('scopeColorsDisabled')) {
+ return '';
+ }
+ var scope = this.model.get('_scope');
+ var color = this.getMetadata().get(['clientDefs', scope, 'color']);
+ var html = '';
+
+ if (color) {
+ var $span = $('');
+ $span.css('color', color);
+ html = $span.get(0).outerHTML;
+ }
+
+ if (html) html += ' ';
+
+ return html;
+ }
+
});
-
});
-
diff --git a/client/src/views/list.js b/client/src/views/list.js
index e58d6d56d5..4a1e245985 100644
--- a/client/src/views/list.js
+++ b/client/src/views/list.js
@@ -238,8 +238,10 @@ Espo.define('views/list', ['views/main', 'search-manager'], function (Dep, Searc
},
getHeader: function () {
+ var headerIconHtml = this.getHeaderIconHtml();
+
return this.buildHeaderHtml([
- this.getLanguage().translate(this.scope, 'scopeNamesPlural')
+ headerIconHtml + this.getLanguage().translate(this.scope, 'scopeNamesPlural')
]);
},
diff --git a/client/src/views/main.js b/client/src/views/main.js
index 6dc674eec2..5b9d567c97 100644
--- a/client/src/views/main.js
+++ b/client/src/views/main.js
@@ -104,6 +104,10 @@ Espo.define('views/main', 'view', function (Dep) {
return '';
},
+ getHeaderIconHtml: function () {
+ return this.getHelper().getScopeColorIconHtml(this.scope);
+ },
+
actionShowModal: function (data) {
var view = data.view;
if (!view) {
diff --git a/client/src/views/record/detail-bottom.js b/client/src/views/record/detail-bottom.js
index 70a712e981..66448ac1ed 100644
--- a/client/src/views/record/detail-bottom.js
+++ b/client/src/views/record/detail-bottom.js
@@ -189,6 +189,9 @@ Espo.define('views/record/detail-bottom', ['view'], function (Dep) {
} else {
p.title = view.title;
}
+ if (view.titleHtml) {
+ p.titleHtml = view.titleHtml;
+ }
}, this);
}, this);
},
diff --git a/client/src/views/record/detail-side.js b/client/src/views/record/detail-side.js
index 02b87c1183..c7f4123e7a 100644
--- a/client/src/views/record/detail-side.js
+++ b/client/src/views/record/detail-side.js
@@ -239,6 +239,9 @@ Espo.define('views/record/detail-side', ['view'], function (Dep) {
} else {
p.title = view.title;
}
+ if (view.titleHtml) {
+ p.titleHtml = view.titleHtml;
+ }
}, this);
}, this);
},
diff --git a/client/src/views/record/panels/relationship.js b/client/src/views/record/panels/relationship.js
index 390e963c03..1f5b866abb 100644
--- a/client/src/views/record/panels/relationship.js
+++ b/client/src/views/record/panels/relationship.js
@@ -57,6 +57,13 @@ Espo.define('views/record/panels/relationship', ['views/record/panels/bottom', '
this.title = this.translate(this.link, 'links', this.model.name);
this.scope = this.scope || this.model.defs.links[this.link].entity;
+ if (!this.getConfig().get('scopeColorsDisabled')) {
+ var iconHtml = this.getHelper().getScopeColorIconHtml(this.scope);
+ if (iconHtml) {
+ this.titleHtml = iconHtml + this.title;
+ }
+ }
+
var url = this.url || this.model.name + '/' + this.model.id + '/' + this.link;
if (!this.readOlny && !this.defs.readOnly) {
diff --git a/client/src/views/site/navbar.js b/client/src/views/site/navbar.js
index 63a2b2b74e..3736fb6b8e 100644
--- a/client/src/views/site/navbar.js
+++ b/client/src/views/site/navbar.js
@@ -80,10 +80,10 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
var $body = $('body');
if ($body.hasClass('minimized')) {
$body.removeClass('minimized');
- this.getStorage().clear('state', 'layoutMinimized');
+ this.getStorage().set('state', 'siteLayoutState', 'expanded');
} else {
$body.addClass('minimized');
- this.getStorage().set('state', 'layoutMinimized', true);
+ this.getStorage().set('state', 'siteLayoutState', 'collapsed');
}
if (window.Event) {
try {
@@ -313,7 +313,13 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
afterRender: function () {
this.selectTab(this.getRouter().getLast().controller);
- if (this.getStorage().get('state', 'layoutMinimized')) {
+ var layoutState = this.getStorage().get('state', 'siteLayoutState');
+ var layoutMinimized = false;
+ if (layoutState === 'collapsed' || !layoutState) {
+ layoutMinimized = true;
+ }
+
+ if (layoutMinimized) {
var $body = $('body');
$body.addClass('minimized');
}
@@ -368,19 +374,36 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
setupTabDefsList: function () {
var tabDefsList = [];
- var moreIsMet = false;;
+ var moreIsMet = false;
+ var colorsDisabled = this.getConfig().get('scopeColorsDisabled') || this.getConfig().get('tabColorsDisabled');
+ var tabIconsDisabled = this.getConfig().get('tabIconsDisabled');
+
this.tabList.forEach(function (tab, i) {
if (tab === '_delimiter_') {
moreIsMet = true;
return;
}
var label = this.getLanguage().translate(tab, 'scopeNamesPlural');
+ var color = null;
+ if (!colorsDisabled) {
+ var color = this.getMetadata().get(['clientDefs', tab, 'color']);
+ }
+
+ var shortLabel = label.substr(0, 2);
+
+ var iconClass = null;
+ if (!tabIconsDisabled) {
+ iconClass = this.getMetadata().get(['clientDefs', tab, 'iconClass'])
+ }
+
var o = {
link: '#' + tab,
label: label,
- shortLabel: label.substr(0, 2),
+ shortLabel: shortLabel,
name: tab,
- isInMore: moreIsMet
+ isInMore: moreIsMet,
+ color: color,
+ iconClass: iconClass
};
tabDefsList.push(o);
}, this);
diff --git a/client/src/views/stream/message.js b/client/src/views/stream/message.js
index 7154852fbf..4cd12efa77 100644
--- a/client/src/views/stream/message.js
+++ b/client/src/views/stream/message.js
@@ -58,7 +58,8 @@ Espo.define('views/stream/message', 'view', function (Dep) {
name: name,
params: params || {}
},
- mode: 'list'
+ mode: 'detail',
+ readOnly: true
});
}
diff --git a/frontend/less/espo-vertical/layout.less b/frontend/less/espo-vertical/layout.less
index 9e1cc032fb..6e412e834e 100644
--- a/frontend/less/espo-vertical/layout.less
+++ b/frontend/less/espo-vertical/layout.less
@@ -48,6 +48,12 @@ body > #header .navbar-brand span.home-icon {
}
}
+#header .navbar li.tab > a {
+ border-left-width: @navbar-color-border-width;
+ border-left-style: solid;
+ border-color: transparent;
+}
+
@media screen and (min-width: @screen-sm-min) {
#header .nav > li.more > .dropdown-menu {
@@ -101,7 +107,6 @@ body > #header .navbar-brand span.home-icon {
height: 35px;
width: @navbar-minimized-width;
padding-top: 8px;
- paddin-left: 12px;
}
#header a.navbar-brand span.home-icon {
@@ -149,7 +154,11 @@ body > #header .navbar-brand span.home-icon {
}
#header ul.tabs > li > a {
- padding-left: 10px;
+ padding-left: 11px;
+ }
+
+ #header ul.tabs > li.tab > a {
+ padding-left: 11px - @navbar-color-border-width;
}
#header ul.tabs > li > a > span.short-label {
@@ -160,6 +169,11 @@ body > #header .navbar-brand span.home-icon {
display: none;
}
+ span.short-label > .short-label-text {
+ position: relative;
+ left: -1px;
+ }
+
}
#header .navbar {
@@ -286,11 +300,15 @@ body > #header .navbar-brand span.home-icon {
width: 35px;
}
- #header ul.tabs li > a {
- padding-top: 8px;
- padding-bottom: 8px;
- padding-left: 12px;
- }
+ #header ul.tabs li > a {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ padding-left: 12px;
+ }
+
+ #header ul.tabs li.tab > a {
+ padding-left: 12px - @navbar-color-border-width;
+ }
#header .navbar-form {
margin-top: 0px;
@@ -321,5 +339,3 @@ body .stick-sub.button-container {
body.minimized .stick-sub.button-container {
width: calc(~"100% - "@navbar-minimized-width);
}
-
-
diff --git a/frontend/less/espo-vertical/variables.less b/frontend/less/espo-vertical/variables.less
index 4aace55c32..a7d939d63c 100644
--- a/frontend/less/espo-vertical/variables.less
+++ b/frontend/less/espo-vertical/variables.less
@@ -1,4 +1,4 @@
@navbar-width: 153px;
-@navbar-minimized-width: 40px;
+@navbar-minimized-width: 39px;
@tob-bar-height: 30px;
@top-navbar-bg-color: @main-gray;
\ No newline at end of file
diff --git a/frontend/less/espo/custom.less b/frontend/less/espo/custom.less
index 01dadc766f..0c9b337f56 100644
--- a/frontend/less/espo/custom.less
+++ b/frontend/less/espo/custom.less
@@ -1183,6 +1183,26 @@ body > footer > p a:visited {
overflow-x: hidden;
}
+.header-breadcrumbs .color-icon {
+ line-height: 0.8;
+ font-size: 90%;
+ top: 1px;
+}
+
+span.color-icon {
+ font-size: 85%;
+ top: 0;
+}
+
+.message > span.color-icon,
+.field span.color-icon {
+ width: 11px;
+}
+
+h4.panel-title span.color-icon {
+ font-size: 80%;
+}
+
@media screen and (max-width: @screen-sm-min) {
.list {
width: auto;
@@ -1647,7 +1667,7 @@ table.table td.cell .complex-text {
#global-search-panel {
position: absolute;
- width: 500px;
+ width: 540px;
z-index: 1001;
right: 0;
left: auto;
diff --git a/frontend/less/espo/variables.less b/frontend/less/espo/variables.less
index 2c82e2efac..15af5cf618 100644
--- a/frontend/less/espo/variables.less
+++ b/frontend/less/espo/variables.less
@@ -138,3 +138,5 @@
@form-group-margin-bottom: 12px;
@modal-title-line-height: floor(@font-size-h4 * @line-height-base);
+
+@navbar-color-border-width: 2px;