Merge branch 'hotfix/5.5.2'

This commit is contained in:
yuri
2018-12-21 14:35:50 +02:00
20 changed files with 402 additions and 174 deletions
@@ -42,11 +42,13 @@ class EmailAddress extends \Espo\Core\Controllers\Record
throw new Forbidden();
}
$q = $request->get('q');
$limit = intval($request->get('limit'));
if (empty($limit) || $limit > 30) {
$limit = 5;
$maxSize = intval($request->get('maxSize'));
if (empty($maxSize) || $maxSize > 50) {
$maxSize = $this->getConfig()->get('recordsPerPage', 20);
}
return $this->getRecordService()->searchInAddressBook($q, $limit);
$onlyActual = $request->get('onlyActual') === 'true';
return $this->getRecordService()->searchInAddressBook($q, $maxSize, $onlyActual);
}
}
@@ -962,6 +962,7 @@ class Base
case 'after':
$where['type'] = 'after';
$dt = new \DateTime($value, new \DateTimeZone($timeZone));
$dt->modify('+1 day -1 second');
$dt->setTimezone(new \DateTimeZone('UTC'));
$where['value'] = $dt->format($format);
break;
@@ -28,12 +28,11 @@
************************************************************************/
namespace Espo\Core\Utils\Database\DBAL\Schema;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Column;
class Comparator extends \Doctrine\DBAL\Schema\Comparator
{
public function diffColumn(Column $column1, Column $column2)
{
$changedProperties = array();
@@ -80,6 +79,15 @@ class Comparator extends \Doctrine\DBAL\Schema\Comparator
}
}
if ($column1->getType() instanceof \Doctrine\DBAL\Types\TextType) {
$length1 = $column1->getLength() ?: 16777215/* mediumtext length*/;
$length2 = $column2->getLength() ?: 16777215;
if ($length2 > $length1) {
$changedProperties[] = 'length';
}
}
if ($column1->getType() instanceof \Doctrine\DBAL\Types\DecimalType) {
if (($column1->getPrecision()?:10) != ($column2->getPrecision()?:10)) {
$changedProperties[] = 'precision';
@@ -27,29 +27,28 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
return array(
return [
'unset' => array(
'unset' => [
'__APPEND__',
'Preferences'
),
'Preferences',
],
'unsetIgnore' => [
'__APPEND__',
['Preferences', 'fields', 'id'],
['Preferences', 'fields', 'data']
['Preferences', 'fields', 'data'],
],
'Preferences' => array(
'fields' => array(
'id' => array(
'Preferences' => [
'fields' => [
'id' => [
'dbType' => 'varchar',
'len' => 24,
'type' => 'id'
),
'data' => array(
'type' => 'text'
)
)
)
);
'type' => 'id',
],
'data' => [
'type' => 'text',
'len' => 16777216,
]
]
],
];
@@ -61,6 +61,10 @@
"type": "enum",
"notStorable": true,
"options": ["None", "Accepted", "Tentative", "Declined"],
"style": {
"Accepted": "success",
"Declined": "danger"
},
"layoutDetailDisabled": true,
"layoutMassUpdateDisabled": true,
"where": {
@@ -65,6 +65,10 @@
"type": "enum",
"notStorable": true,
"options": ["None", "Accepted", "Tentative", "Declined"],
"style": {
"Accepted": "success",
"Declined": "danger"
},
"layoutDetailDisabled": true,
"layoutMassUpdateDisabled": true,
"where": {
@@ -265,6 +265,7 @@
"fieldShouldBeGreater": "{field} shouldn't be less then {value}",
"fieldBadPasswordConfirm": "{field} not confirmed properly",
"fieldMaxFileSizeError": "File should not exceed {max} Mb",
"fieldValueDuplicate": "Duplicate value",
"fieldIsUploading": "Uploading in progress",
"resetPreferencesDone": "Preferences has been reset to defaults",
"confirmation": "Are you sure?",
+86 -109
View File
@@ -37,130 +37,96 @@ class EmailAddress extends Record
{
const ERASED_PREFIX = 'ERASED:';
protected function findInAddressBookByEntityType($query, $limit, $entityType, &$result)
protected function findInAddressBookByEntityType($query, $limit, $entityType, &$result, $onlyActual = false)
{
$whereClause = array(
'OR' => array(
array(
$whereClause = [
'OR' => [
[
'name*' => $query . '%'
),
array(
],
[
'emailAddress*' => $query . '%'
)
),
array(
]
],
[
'emailAddress!=' => null
)
);
]
];
$searchParams = array(
$selectParams = [
'whereClause' => $whereClause,
'orderBy' => 'name',
'limit' => $limit
);
];
$handleSelectParamsMethodName = 'handleSelectParams' . $entityType;
if (method_exists($this, $handleSelectParamsMethodName)) {
$this->$handleSelectParamsMethodName($query, $selectParams);
}
$selectManager = $this->getSelectManagerFactory()->create($entityType);
$selectManager->applyAccess($selectParams);
$selectManager->applyAccess($searchParams);
$collection = $this->getEntityManager()->getRepository($entityType)->find($searchParams);
$collection = $this->getEntityManager()->getRepository($entityType)->find($selectParams);
foreach ($collection as $entity) {
$emailAddress = $entity->get('emailAddress');
$emailAddressData = $this->getEntityManager()->getRepository('EmailAddress')->getEmailAddressData($entity);
$skipPrimaryEmailAddress = false;
if ($emailAddress) {
if (strpos($emailAddress, self::ERASED_PREFIX) === 0) {
continue;
if (strpos($emailAddress, self::ERASED_PREFIX) === 0) $skipPrimaryEmailAddress = true;
if ($onlyActual) {
if ($entity->get('emailAddressIsOptedOut')) $skipPrimaryEmailAddress = true;
foreach ($emailAddressData as $item) {
if ($emailAddress !== $item->emailAddress) continue;
if (!empty($item->invalid)) $skipPrimaryEmailAddress = true;
}
}
}
$result[] = [
'emailAddress' => $emailAddress,
'entityName' => $entity->get('name'),
'entityType' => $entityType,
'entityId' => $entity->id
];
if (!$skipPrimaryEmailAddress) {
$result[] = [
'emailAddress' => $emailAddress,
'entityName' => $entity->get('name'),
'entityType' => $entityType,
'entityId' => $entity->id
];
}
$emailAddressData = $this->getEntityManager()->getRepository('EmailAddress')->getEmailAddressData($entity);
foreach ($emailAddressData as $d) {
if ($emailAddress != $d->emailAddress) {
$emailAddress = $d->emailAddress;
if (strpos($emailAddress, $query) === 0 && strpos($emailAddress, self::ERASED_PREFIX) !== 0) {
$result[] = [
'emailAddress' => $emailAddress,
'entityName' => $entity->get('name'),
'entityType' => $entityType,
'entityId' => $entity->id
];
}
foreach ($emailAddressData as $item) {
if ($emailAddress === $item->emailAddress) continue;
if (strpos($item->emailAddress, self::ERASED_PREFIX) === 0) continue;
if ($onlyActual) {
if (!empty($item->invalid)) continue;
if (!empty($item->optOut)) continue;
}
$result[] = [
'emailAddress' => $item->emailAddress,
'entityName' => $entity->get('name'),
'entityType' => $entityType,
'entityId' => $entity->id
];
}
}
}
protected function findInAddressBookUsers($query, $limit, &$result)
protected function handleSelectParamsUser($query, &$selectParams)
{
$whereClause = array(
'OR' => array(
array(
'name*' => $query . '%'
),
array(
'emailAddress*' => $query . '%'
)
),
array(
'emailAddress!=' => null
)
);
if ($this->getAcl()->get('portalPermission') === 'no') {
$whereClause['type!='] = 'portal';
}
$searchParams = array(
'whereClause' => $whereClause,
'orderBy' => 'name',
'limit' => $limit
);
$selectManager = $this->getSelectManagerFactory()->create('User');
$selectManager->applyAccess($searchParams);
$collection = $this->getEntityManager()->getRepository('User')->find($searchParams);
foreach ($collection as $entity) {
$emailAddress = $entity->get('emailAddress');
if ($emailAddress) {
if (strpos($emailAddress, self::ERASED_PREFIX) === 0) {
continue;
}
}
$result[] = [
'emailAddress' => $emailAddress,
'entityName' => $entity->get('name'),
'entityType' => 'User',
'entityId' => $entity->id
$selectParams['whereClause'][] = [
'type!=' => 'portal'
];
$emailAddressData = $this->getEntityManager()->getRepository('EmailAddress')->getEmailAddressData($entity);
foreach ($emailAddressData as $d) {
if ($emailAddress != $d->emailAddress) {
$emailAddress = $d->emailAddress;
if (strpos($emailAddress, $query) === 0 && strpos($emailAddress, self::ERASED_PREFIX) !== 0) {
$result[] = [
'emailAddress' => $emailAddress,
'entityName' => $entity->get('name'),
'entityType' => 'User',
'entityId' => $entity->id
];
}
}
}
}
$selectParams['whereClause'][] = [
'type!=' => ['api', 'system', 'super-admin']
];
}
protected function findInInboundEmail($query, $limit, &$result)
@@ -188,39 +154,52 @@ class EmailAddress extends Record
}
}
public function searchInAddressBook($query, $limit)
public function searchInAddressBook($query, $limit, $onlyActual = false)
{
$result = [];
$this->findInAddressBookUsers($query, $limit, $result);
$this->findInAddressBookByEntityType($query, $limit, 'User', $result, $onlyActual);
if ($this->getAcl()->checkScope('Contact')) {
$this->findInAddressBookByEntityType($query, $limit, 'Contact', $result);
$this->findInAddressBookByEntityType($query, $limit, 'Contact', $result, $onlyActual);
}
if ($this->getAcl()->checkScope('Lead')) {
$this->findInAddressBookByEntityType($query, $limit, 'Lead', $result);
$this->findInAddressBookByEntityType($query, $limit, 'Lead', $result, $onlyActual);
}
if ($this->getAcl()->checkScope('Account')) {
$this->findInAddressBookByEntityType($query, $limit, 'Account', $result);
$this->findInAddressBookByEntityType($query, $limit, 'Account', $result, $onlyActual);
}
$this->findInInboundEmail($query, $limit, $result);
foreach ($this->getHavingEmailAddressEntityTypeList() as $entityType) {
if ($this->getAcl()->checkScope($entityType)) {
$this->findInAddressBookByEntityType($query, $limit, $entityType, $result);
$this->findInAddressBookByEntityType($query, $limit, $entityType, $result, $onlyActual);
}
}
$final = array();
$finalResult = [];
foreach ($result as $r) {
foreach ($final as $f) {
if ($f['emailAddress'] == $r['emailAddress']) {
foreach ($result as $item) {
foreach ($finalResult as $item1) {
if ($item['emailAddress'] == $item1['emailAddress']) {
continue 2;
}
}
$final[] = $r;
$finalResult[] = $item;
}
return $final;
usort($finalResult, function ($item1, $item2) use ($query) {
if (strpos($query, '@') === false) return 0;
$p1 = strpos($item1['emailAddress'], $query);
$p2 = strpos($item2['emailAddress'], $query);
if ($p1 === 0 && $p2 !== 0) return -1;
if ($p1 !== 0 && $p2 !== 0) return 0;
if ($p1 !== 0 && $p2 === 0) return 1;
return 0;
});
return $finalResult;
}
protected function getHavingEmailAddressEntityTypeList()
@@ -234,6 +213,4 @@ class EmailAddress extends Record
}
return $list;
}
}
+1 -1
View File
@@ -13,7 +13,6 @@
{{#unless isInMore}}
<li data-name="{{name}}" class="not-in-more tab">
<a href="{{link}}" class="nav-link"{{#if color}} style="border-color: {{color}}"{{/if}}>
<span class="full-label">{{label}}</span>
<span class="short-label" title="{{label}}"{{#if color}} style="color: {{color}}"{{/if}}>
{{#if iconClass}}
<span class="{{iconClass}}"></span>
@@ -24,6 +23,7 @@
<span class="short-label-text">{{shortLabel}}</span>
{{/if}}
</span>
<span class="full-label">{{label}}</span>
</a>
</li>
{{/unless}}
@@ -87,6 +87,13 @@ Espo.define('views/email/fields/email-address-varchar', ['views/fields/varchar',
}
},
getAutocompleteMaxCount: function () {
if (this.autocompleteMaxCount) {
return this.autocompleteMaxCount;
}
return this.getConfig().get('recordsPerPage');
},
parseNameFromStringAddress: function (s) {
return From.prototype.parseNameFromStringAddress.call(this, s);
},
@@ -143,11 +150,12 @@ Espo.define('views/email/fields/email-address-varchar', ['views/fields/varchar',
this.$input.autocomplete({
serviceUrl: function (q) {
return 'EmailAddress/action/searchInAddressBook?limit=5';
return 'EmailAddress/action/searchInAddressBook?onlyActual=true&maxSize=' + this.getAutocompleteMaxCount();
}.bind(this),
paramName: 'q',
minChars: 1,
autoSelectFirst: true,
triggerSelectOnValidInput: false,
formatResult: function (suggestion) {
return suggestion.name + ' &#60;' + suggestion.id + '&#62;';
},
@@ -29,6 +29,13 @@ Espo.define('views/email/fields/email-address', ['views/fields/base'], function
return Dep.extend({
getAutocompleteMaxCount: function () {
if (this.autocompleteMaxCount) {
return this.autocompleteMaxCount;
}
return this.getConfig().get('recordsPerPage');
},
afterRender: function () {
Dep.prototype.afterRender.call(this);
@@ -37,11 +44,12 @@ Espo.define('views/email/fields/email-address', ['views/fields/base'], function
if (this.mode == 'search') {
this.$input.autocomplete({
serviceUrl: function (q) {
return 'EmailAddress/action/searchInAddressBook?limit=5';
return 'EmailAddress/action/searchInAddressBook?maxSize=' + this.getAutocompleteMaxCount();
}.bind(this),
paramName: 'q',
minChars: 1,
autoSelectFirst: true,
triggerSelectOnValidInput: false,
formatResult: function (suggestion) {
return suggestion.name + ' &#60;' + suggestion.id + '&#62;';
},
+35 -14
View File
@@ -42,20 +42,33 @@ Espo.define('views/fields/email', 'views/fields/varchar', function (Dep) {
validateEmailData: function () {
var data = this.model.get(this.dataFieldName);
if (data && data.length) {
var re = /\S+@+\S+/;
var notValid = false;
data.forEach(function (row, i) {
var emailAddress = row.emailAddress;
if (!re.test(emailAddress) && emailAddress.indexOf(this.erasedPlaceholder) !== 0) {
var msg = this.translate('fieldShouldBeEmail', 'messages').replace('{field}', this.getLabelText());
this.showValidationMessage(msg, 'div.email-address-block:nth-child(' + (i + 1).toString() + ') input');
notValid = true;
}
}, this);
if (notValid) {
return true;
if (!data || !data.length) return;
var addressList = [];
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
var notValid = false;
data.forEach(function (row, i) {
var address = row.emailAddress;
var addressLowerCase = String(address).toLowerCase();
if (!re.test(addressLowerCase) && address.indexOf(this.erasedPlaceholder) !== 0) {
var msg = this.translate('fieldShouldBeEmail', 'messages').replace('{field}', this.getLabelText());
this.showValidationMessage(msg, 'div.email-address-block:nth-child(' + (i + 1).toString() + ') input');
notValid = true;
return;
}
if (~addressList.indexOf(addressLowerCase)) {
var msg = this.translate('fieldValueDuplicate', 'messages').replace('{field}', this.getLabelText());
this.showValidationMessage(msg, 'div.email-address-block:nth-child(' + (i + 1).toString() + ') input');
notValid = true;
return;
}
addressList.push(addressLowerCase);
}, this);
if (notValid) {
return true;
}
},
@@ -126,6 +139,13 @@ Espo.define('views/fields/email', 'views/fields/varchar', function (Dep) {
return data;
},
getAutocompleteMaxCount: function () {
if (this.autocompleteMaxCount) {
return this.autocompleteMaxCount;
}
return this.getConfig().get('recordsPerPage');
},
events: {
'click [data-action="mailTo"]': function (e) {
this.mailTo($(e.currentTarget).data('email-address'));
@@ -230,11 +250,12 @@ Espo.define('views/fields/email', 'views/fields/varchar', function (Dep) {
if (this.mode == 'search') {
this.$element.autocomplete({
serviceUrl: function (q) {
return 'EmailAddress/action/searchInAddressBook?limit=5';
return 'EmailAddress/action/searchInAddressBook?maxSize=' + this.getAutocompleteMaxCount();
}.bind(this),
paramName: 'q',
minChars: 1,
autoSelectFirst: true,
triggerSelectOnValidInput: false,
formatResult: function (suggestion) {
return suggestion.name + ' &#60;' + suggestion.id + '&#62;';
},
@@ -80,7 +80,9 @@ Espo.define('views/fields/link-multiple-with-role', 'views/fields/link-multiple'
role = '';
}
if (role != '') {
roleHtml = '<span class="text-muted small"> &#187; ' +
var style = this.getMetadata().get(['entityDefs', this.model.entityType, 'fields', this.roleField, 'style', role]) || 'muted';
roleHtml = '<span class="text-muted small"> &#187; </span>' +
'<span class="text-'+style+' small">' +
this.getHelper().stripTags(this.getLanguage().translateOption(role, this.roleField, this.roleFieldScope)) +
'</span>';
}
+25 -1
View File
@@ -38,7 +38,7 @@ Espo.define('views/fields/phone', 'views/fields/varchar', function (Dep) {
listTemplate: 'fields/phone/list',
validations: ['required'],
validations: ['required', 'phoneData'],
validateRequired: function () {
if (this.isRequired()) {
@@ -50,6 +50,30 @@ Espo.define('views/fields/phone', 'views/fields/varchar', function (Dep) {
}
},
validatePhoneData: function () {
var data = this.model.get(this.dataFieldName);
if (!data || !data.length) return;
var numberList = [];
var notValid = false;
data.forEach(function (row, i) {
var number = row.phoneNumber;
var numberClean = String(number).replace(/[\s\+]/g, '');
if (~numberList.indexOf(numberClean)) {
var msg = this.translate('fieldValueDuplicate', 'messages').replace('{field}', this.getLabelText());
this.showValidationMessage(msg, 'div.phone-number-block:nth-child(' + (i + 1).toString() + ') input');
notValid = true;
return;
}
numberList.push(numberClean);
}, this);
if (notValid) {
return true;
}
},
data: function () {
var phoneNumberData;
if (this.mode == 'edit') {
+22 -5
View File
@@ -251,17 +251,27 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
}
};
var tabCount = this.tabList.length;
var $navbar = $('#navbar .navbar');
var navbarNeededHeight = (this.getThemeManager().getParam('navbarHeight') || 43) + 1;
if (window.innerWidth >= smallScreenWidth) {
$tabs.children('li').each(function (i, li) {
hideOneTab();
});
$navbar.css('max-height', 'unset');
$navbar.css('overflow', 'visible');
}
var navbarHeight = this.getThemeManager().getParam('navbarHeight') || 43;
var navbarBaseWidth = this.getThemeManager().getParam('navbarBaseWidth') || 556;
var tabCount = this.tabList.length;
var navbarNeededHeight = navbarHeight + 1;
$moreDd = $('#nav-more-tabs-dropdown');
$moreLi = $moreDd.closest('li');
var navbarBaseWidth = this.getThemeManager().getParam('navbarBaseWidth') || 556;
var updateWidth = function () {
var windowWidth = $(window.document).width();
var windowWidth = window.innerWidth;
var moreWidth = $moreLi.width();
@@ -273,6 +283,9 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
return;
}
$navbar.css('max-height', navbarHeight + 'px');
$navbar.css('overflow', 'hidden');
$more.parent().addClass('hidden');
var headerWidth = this.$el.width();
@@ -293,6 +306,9 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
}
}
$navbar.css('max-height', 'unset');
$navbar.css('overflow', 'visible');
if ($more.children().length > 0) {
$moreDropdown.removeClass('hidden');
}
@@ -306,6 +322,7 @@ Espo.define('views/site/navbar', 'view', function (Dep) {
}, 200);
} else {
if (!isRecursive) {
updateWidth();
setTimeout(function () {
processUpdateWidth(true);
}, 10);
+75
View File
@@ -0,0 +1,75 @@
#navbar .navbar {
ul.tabs {
> li.more {
> ul > li > a {
> span.full-label {
padding-left: 30px;
padding-right: 30px;
position: static;
}
}
}
}
}
@media screen and (min-width: @screen-sm-min) {
#navbar .navbar {
ul.tabs {
> li > a > span.short-label {
float: right;
right: -4px;
left: 0;
margin-left: 4px;
margin-right: 0;
}
li.more > li > a {
padding-right: 10px;
padding-left: 0;
}
}
}
.search-container .view-mode-switcher-buttons-group {
float: left !important;
}
}
@media screen and (max-width: (@screen-sm-min - 1px)) {
#navbar .navbar {
ul.tabs {
> li a > span.full-label {
padding-right: 30px;
padding-left: 0;
}
}
}
}
div.list-kanban > div > table {
th.group-header {
> div {
padding-left: 0;
padding-right: @table-cell-padding;
}
> div:before,
> div:after {
content: none;
}
}
}
.kanban-row {
.item-menu-container.pull-right {
float: left !important;
left: -9px;
margin-left: -10px;
margin-right: 0;
}
}
+3
View File
@@ -10,6 +10,9 @@
@import "../espo/layout.less";
@import "../espo/custom.less";
@import "layout.less";
@import "custom.less";
@import "../espo/mixins/side-modal.less";
+15 -6
View File
@@ -277,9 +277,8 @@
body {
#navbar {
ul.tabs {
> li > a > span.full-label {
position: absolute;
margin-left: 30px;
> li > a {
height: 37px
}
> li.more > ul > li > a > span.full-label {
@@ -287,7 +286,17 @@ body {
position: static;
}
> li.more > ul > li > a > span.short-label, {
> li a > span.full-label {
position: static;
padding-left: 30px;
position: static;
}
> li a > span.short-label {
position: absolute;
}
> li.more > ul > li > a > span.short-label {
position: absolute;
}
@@ -303,9 +312,9 @@ body {
}
> li > a > span.full-label {
display: inline;
display: inline-block;
text-overflow: ellipsis;
max-width: ~"calc(100% - 50px)";
max-width: ~"calc(100%)";
overflow: hidden;
white-space: nowrap;
}
+74 -9
View File
@@ -18,6 +18,10 @@
padding: 0;
width: @logo-width;
height: @logo-height;
img.logo {
max-width: @logo-width;
}
}
.side-menu-button {
@@ -35,15 +39,45 @@
display: none;
}
.more-icon {
display: inline;
}
ul.tabs span.short-label {
display: none;
}
ul.tabs span.full-label {
display: inline;
ul.tabs {
span.full-label {
display: inline;
}
span.short-label > span {
display: inline-block;
width: 16px;
text-align: center;
}
.more-icon {
display: inline;
}
> li.more {
> ul > li > a {
padding-top: 9px;
padding-bottom: 9px;
height: 37px;
> span.full-label {
padding-left: 30px;
position: static;
}
> span.short-label {
position: absolute;
}
}
}
> li span.short-label {
> span.short-label-text {
display: none;
}
}
}
.navbar-right {
@@ -76,6 +110,18 @@
border-color: transparent;
}
ul.tabs {
> li a > span.full-label {
position: static;
padding-left: 30px;
position: static;
}
> li a > span.short-label {
position: absolute;
}
}
input.global-search-input {
width: 100%;
}
@@ -87,7 +133,26 @@
}
@media screen and (min-width: @screen-sm-min) {
#navbar .navbar {
max-height: @navbar-height;
overflow: hidden;
ul.tabs {
> li > a > span.short-label {
display: block;
float: left;
position: relative;
left: -4px;
margin-right: 4px;
}
li.more > li > a {
padding-left: 10px;
}
}
.more-icon {
top: 1px;
position: relative;
@@ -108,7 +173,7 @@
border-left-width: @navbar-color-border-width;
border-left-style: solid;
border-color: transparent;
padding-left: 20px - @navbar-color-border-width;
padding-left: 15px - @navbar-color-border-width;
}
}
}
+1 -1
View File
@@ -168,7 +168,7 @@
@modal-title-line-height: floor(@font-size-h4 * @line-height-base);
@navbar-color-border-width: 4px;
@navbar-color-border-width: 0;
@container-max-width: 1800px;