diff --git a/application/Espo/Core/Repositories/Event.php b/application/Espo/Core/Repositories/Event.php
index 0546a03d9e..5d4b60401a 100644
--- a/application/Espo/Core/Repositories/Event.php
+++ b/application/Espo/Core/Repositories/Event.php
@@ -251,15 +251,17 @@ class Event extends \Espo\Core\ORM\Repositories\RDB
protected function convertDateTimeToDefaultTimezone($string)
{
- $dateTime = \DateTime::createFromFormat($this->getDateTime()->getInternalDateTimeFormat(), $string);
- $timeZone = $this->getConfig()->get('timeZone');
- if (empty($timeZone)) {
- $timeZone = 'UTC';
- }
- $tz = $timezone = new \DateTimeZone($timeZone);
+ $timeZone = $this->getConfig()->get('timeZone') ?? 'UTC';
- if ($dateTime) {
- return $dateTime->setTimezone($tz)->format($this->getDateTime()->getInternalDateTimeFormat());
+ $tz = new \DateTimeZone($timeZone);
+
+ try {
+ $dt = \DateTime::createFromFormat($this->getDateTime()->getInternalDateTimeFormat(), $string, $tz);
+ } catch (\Exception $e) {}
+
+ if ($dt) {
+ $utcTz = new \DateTimeZone('UTC');
+ return $dt->setTimezone($utcTz)->format($this->getDateTime()->getInternalDateTimeFormat());
}
return null;
}
diff --git a/application/Espo/Core/defaults/config.php b/application/Espo/Core/defaults/config.php
index 15f213297f..cc4824d510 100644
--- a/application/Espo/Core/defaults/config.php
+++ b/application/Espo/Core/defaults/config.php
@@ -43,8 +43,8 @@ return [
'applicationName' => 'EspoCRM',
'version' => '@@version',
'timeZone' => 'UTC',
- 'dateFormat' => 'MM/DD/YYYY',
- 'timeFormat' => 'hh:mm a',
+ 'dateFormat' => 'DD.MM.YYYY',
+ 'timeFormat' => 'hh:mm',
'weekStart' => 0,
'thousandSeparator' => ',',
'decimalMark' => '.',
diff --git a/application/Espo/Modules/Crm/Repositories/Task.php b/application/Espo/Modules/Crm/Repositories/Task.php
index f75aa1e551..8f21dac91b 100644
--- a/application/Espo/Modules/Crm/Repositories/Task.php
+++ b/application/Espo/Modules/Crm/Repositories/Task.php
@@ -56,15 +56,17 @@ class Task extends \Espo\Core\Repositories\Event
protected function convertDateTimeToDefaultTimezone($string)
{
- $dateTime = \DateTime::createFromFormat($this->getDateTime()->getInternalDateTimeFormat(), $string);
- $timeZone = $this->getConfig()->get('timeZone');
- if (empty($timeZone)) {
- $timeZone = 'UTC';
- }
- $tz = $timezone = new \DateTimeZone($timeZone);
+ $timeZone = $this->getConfig()->get('timeZone') ?? 'UTC';
- if ($dateTime) {
- return $dateTime->setTimezone($tz)->format($this->getDateTime()->getInternalDateTimeFormat());
+ $tz = new \DateTimeZone($timeZone);
+
+ try {
+ $dt = \DateTime::createFromFormat($this->getDateTime()->getInternalDateTimeFormat(), $string, $tz);
+ } catch (\Exception $e) {}
+
+ if ($dt) {
+ $utcTz = new \DateTimeZone('UTC');
+ return $dt->setTimezone($utcTz)->format($this->getDateTime()->getInternalDateTimeFormat());
}
return null;
}
diff --git a/application/Espo/Resources/metadata/entityDefs/Settings.json b/application/Espo/Resources/metadata/entityDefs/Settings.json
index 8d5dea78e8..d74f46a8be 100644
--- a/application/Espo/Resources/metadata/entityDefs/Settings.json
+++ b/application/Espo/Resources/metadata/entityDefs/Settings.json
@@ -27,8 +27,8 @@
},
"dateFormat": {
"type": "enum",
- "options": ["MM/DD/YYYY", "YYYY-MM-DD", "DD.MM.YYYY", "DD/MM/YYYY"],
- "default": "MM/DD/YYYY"
+ "options": ["DD.MM.YYYY", "MM/DD/YYYY", "DD/MM/YYYY", "YYYY-MM-DD"],
+ "default": "DD.MM.YYYY"
},
"timeFormat": {
"type": "enum",
diff --git a/client/modules/crm/src/views/meeting/fields/date-end.js b/client/modules/crm/src/views/meeting/fields/date-end.js
index 48d009aa72..f5c892cf65 100644
--- a/client/modules/crm/src/views/meeting/fields/date-end.js
+++ b/client/modules/crm/src/views/meeting/fields/date-end.js
@@ -26,7 +26,7 @@
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
-Espo.define('crm:views/meeting/fields/date-end', 'views/fields/datetime-optional', function (Dep) {
+define('crm:views/meeting/fields/date-end', 'views/fields/datetime-optional', function (Dep) {
return Dep.extend({
@@ -39,10 +39,19 @@ Espo.define('crm:views/meeting/fields/date-end', 'views/fields/datetime-optional
setup: function () {
Dep.prototype.setup.call(this);
+ this.isAllDayValue = this.model.get('isAllDay');
+
this.listenTo(this.model, 'change:isAllDay', function (model, value, o) {
if (!o.ui) return;
if (!this.isEditMode()) return;
+ if (this.isAllDayValue === undefined && !value) {
+ this.isAllDayValue = value;
+ return;
+ }
+
+ this.isAllDayValue = value;
+
if (value) {
this.$time.val(this.noneOption);
} else {
@@ -51,11 +60,13 @@ Espo.define('crm:views/meeting/fields/date-end', 'views/fields/datetime-optional
dateTime = this.getDateTime().getNow(5);
}
var m = this.getDateTime().toMoment(dateTime);
- dateTime = m.format(this.getDateTime().internalDateTimeFormat);
+ dateTime = m.format(this.getDateTime().getDateTimeFormat());
var index = dateTime.indexOf(' ');
var time = dateTime.substr(index + 1);
- this.$time.val(time);
+ if (this.model.get('dateEnd')) {
+ this.$time.val(time);
+ }
}
this.trigger('change');
this.controlTimePartVisibility();
@@ -80,7 +91,7 @@ Espo.define('crm:views/meeting/fields/date-end', 'views/fields/datetime-optional
this.$time.removeClass('hidden');
this.$el.find('.time-picker-btn').removeClass('hidden');
}
- }
+ },
});
});
diff --git a/client/res/templates/fields/datetime/edit.tpl b/client/res/templates/fields/datetime/edit.tpl
index eb6ee735c1..3cfa4ca695 100644
--- a/client/res/templates/fields/datetime/edit.tpl
+++ b/client/res/templates/fields/datetime/edit.tpl
@@ -1,11 +1,15 @@
-
+
diff --git a/client/src/views/record/detail-middle.js b/client/src/views/record/detail-middle.js
index 8ebacd04dc..5d6eb8607f 100644
--- a/client/src/views/record/detail-middle.js
+++ b/client/src/views/record/detail-middle.js
@@ -43,6 +43,8 @@ define('views/record/detail-middle', 'view', function (Dep) {
},
showPanel: function (name) {
+ if (this.recordHelper.getPanelStateParam(name, 'hiddenLocked')) return;
+
if (this.isRendered()) {
this.$el.find('.panel[data-name="'+name+'"]').removeClass('hidden');
}
diff --git a/client/src/views/record/detail.js b/client/src/views/record/detail.js
index 9407357b4c..05bcd4c7ca 100644
--- a/client/src/views/record/detail.js
+++ b/client/src/views/record/detail.js
@@ -426,6 +426,8 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct
},
showPanel: function (name) {
+ if (this.recordHelper.getPanelStateParam(name, 'hiddenLocked')) return;
+
this.recordHelper.setPanelStateParam(name, 'hidden', false);
var middleView = this.getView('middle');
@@ -462,9 +464,13 @@ define('views/record/detail', ['views/record/base', 'view-record-helper'], funct
}
},
- hidePanel: function (name) {
+ hidePanel: function (name, locked) {
this.recordHelper.setPanelStateParam(name, 'hidden', true);
+ if (locked) {
+ this.recordHelper.setPanelStateParam(name, 'hiddenLocked', true);
+ }
+
var middleView = this.getView('middle');
if (middleView) {
middleView.hidePanel(name);
diff --git a/client/src/views/record/panels-container.js b/client/src/views/record/panels-container.js
index 9a97b6390b..3463d77884 100644
--- a/client/src/views/record/panels-container.js
+++ b/client/src/views/record/panels-container.js
@@ -179,6 +179,8 @@ define('views/record/panels-container', 'view', function (Dep) {
},
showPanel: function (name, callback) {
+ if (this.recordHelper.getPanelStateParam(name, 'hiddenLocked')) return;
+
this.recordHelper.setPanelStateParam(name, 'hidden', false);
var isFound = false;
diff --git a/frontend/less/espo-rtl/main.less b/frontend/less/espo-rtl/main.less
index 2717e5b636..1a749daf42 100644
--- a/frontend/less/espo-rtl/main.less
+++ b/frontend/less/espo-rtl/main.less
@@ -15,8 +15,6 @@
@import "custom.less";
-@import "../espo/mixins/side-modal.less";
-
@import "bootstrap-rtl/utilities-rtl.less";
body {
diff --git a/frontend/less/espo-vertical/main.less b/frontend/less/espo-vertical/main.less
index 4ce6373463..4feeb2af0b 100644
--- a/frontend/less/espo-vertical/main.less
+++ b/frontend/less/espo-vertical/main.less
@@ -10,8 +10,6 @@
@import "../espo/custom.less";
@import "custom.less";
-@import "../espo/mixins/side-modal.less";
-
@import "../espo/bootstrap/utilities.less";
body {
diff --git a/frontend/less/espo/custom.less b/frontend/less/espo/custom.less
index ad31271635..018ceda4c7 100644
--- a/frontend/less/espo/custom.less
+++ b/frontend/less/espo/custom.less
@@ -187,10 +187,6 @@ b, strong {
font-size: @font-size-smaller;
}
-.btn {
- border-radius: @button-radius;
-}
-
.panel-body {
padding: @panel-padding;
.clearfix();
@@ -1300,26 +1296,19 @@ optgroup {
z-index: 3;
}
-.input-group {
- .input-group-btn > {
- .btn {
- height: 33px;
- }
+.input-group-container-2 {
+ width: ~"calc(100% + 1px)";
+ > div {
+ width: 50%;
+ float: left;
}
-
- &.input-group-sm {
- .input-group-btn > {
- .btn {
- height: 30px;
- }
- }
+ > div:last-child {
+ margin-left: -1px;
}
- &.input-group-lg {
- .input-group-btn > {
- .btn {
- height: 46px;
- }
- }
+ &:after {
+ clear: both;
+ content: " ";
+ display: block;
}
}
@@ -1337,6 +1326,12 @@ optgroup {
width: 36px;
float: left;
}
+
+ &:after {
+ clear: both;
+ content: " ";
+ display: block;
+ }
}
h3 {
@@ -1821,6 +1816,7 @@ table.no-margin {
.list .checkbox-dropdown > a {
padding: 0;
line-height: 1;
+ height: 14px;
}
.list .record-checkbox-container {
@@ -2484,8 +2480,16 @@ h4.panel-title span.fas.color-icon {
img.avatar.avatar-link {
display: inline-block;
- margin-top: -2px;
+ margin-top: 0;
margin-right: 3px;
+ position: relative;
+ vertical-align: top;
+ top: 2px;
+
+ &[width="14"] {
+ top: 2px;
+ vertical-align: baseline;
+ }
}
stream-head-text-container .span {
@@ -3413,85 +3417,15 @@ a.field-info > span.fa-info-circle {
}
}
-.btn-icon {
- width: 36px;
- padding-left: 0;
- padding-right: 0;
-
- .fa, .fas {
- position: relative;
- width: 16px;
- text-align: center;
- }
- .fa-sm {
- top: -1px;
- }
-}
-
-
-.btn-icon.btn-sm {
- .fa-sm {
- top: 0;
- }
-}
-
-.btn-icon.btn-sm {
- width: 34px;
-
- .fa, .fas {
- font-size: 12px;
- width: 12px;
- }
-}
-
.btn > .fa-ellipsis-v {
position: relative;
top: 1px;
}
-.btn.btn-icon-wide {
- width: 54px;
-}
-
-.btn.btn-icon-x-wide {
- width: 76px;
-}
-
-.btn.btn-icon-xx-wide {
- width: 100px;
-}
-
.btn-icon > .fa-chevron-left {
left: -1px;
}
-.btn.btn-wide {
- min-width: 100px;
-}
-
-.btn.btn-x-wide {
- min-width: 150px;
-}
-
-.btn.btn-xx-wide {
- min-width: 200px;
-}
-
-.btn-default > .fa,
-.btn-default > .fas {
- color: @gray-soft;
-}
-
-.btn-default > .fa.text-muted,
-.btn-default > .fas.text-muted {
- color: @gray-light;
-}
-
-.btn-default.disabled > .fa,
-.btn-default.disabled > .fas {
- color: @gray-light;
-}
-
.btn-default > .fa-sm.fa-rss {
position: relative;
top: -1px;
@@ -3751,4 +3685,7 @@ a.link-gray {
.selectize-control.as-list .item {
display: block;
-}
\ No newline at end of file
+}
+
+@import "elements/side-modal.less";
+@import "elements/buttons.less";
diff --git a/frontend/less/espo/elements/buttons.less b/frontend/less/espo/elements/buttons.less
new file mode 100644
index 0000000000..525bdb7467
--- /dev/null
+++ b/frontend/less/espo/elements/buttons.less
@@ -0,0 +1,110 @@
+.btn {
+ border-radius: @button-radius;
+}
+
+.btn {
+ height: @input-height-base;
+}
+.btn-lg {
+ height: @input-height-large;
+}
+.btn-sm {
+ height: @input-height-small;
+}
+
+.btn.btn-link {
+ height: auto;
+}
+
+.input-group {
+ .input-group-btn > {
+ .btn {
+ height: @input-height-base;
+ }
+ }
+
+ &.input-group-sm {
+ .input-group-btn > {
+ .btn {
+ height: @input-height-small;
+ }
+ }
+ }
+ &.input-group-lg {
+ .input-group-btn > {
+ .btn {
+ height: @input-height-large;
+ }
+ }
+ }
+}
+
+.btn-icon {
+ width: 36px;
+ padding-left: 0;
+ padding-right: 0;
+
+ .fa, .fas {
+ position: relative;
+ width: 16px;
+ text-align: center;
+ }
+ .fa-sm {
+ top: -1px;
+ }
+}
+
+.btn-icon.btn-sm {
+ .fa-sm {
+ top: 0;
+ }
+}
+
+.btn-icon.btn-sm {
+ width: 34px;
+
+ .fa, .fas {
+ font-size: 12px;
+ width: 12px;
+ }
+}
+
+.btn.btn-wide {
+ min-width: 100px;
+}
+
+.btn.btn-x-wide {
+ min-width: 150px;
+}
+
+.btn.btn-xx-wide {
+ min-width: 200px;
+}
+
+.btn.btn-icon-wide {
+ width: 54px;
+}
+
+.btn.btn-icon-x-wide {
+ width: 76px;
+}
+
+.btn.btn-icon-xx-wide {
+ width: 100px;
+}
+
+.btn-default > .fa,
+.btn-default > .fas {
+ color: @gray-soft;
+}
+
+.btn-default > .fa.text-muted,
+.btn-default > .fas.text-muted {
+ color: @gray-light;
+}
+
+.btn-default.disabled > .fa,
+.btn-default.disabled > .fas {
+ color: @gray-light;
+}
+
diff --git a/frontend/less/espo/mixins/side-modal.less b/frontend/less/espo/elements/side-modal.less
similarity index 100%
rename from frontend/less/espo/mixins/side-modal.less
rename to frontend/less/espo/elements/side-modal.less
diff --git a/frontend/less/espo/main.less b/frontend/less/espo/main.less
index 4e22a3b323..dadf5ba432 100644
--- a/frontend/less/espo/main.less
+++ b/frontend/less/espo/main.less
@@ -6,8 +6,6 @@
@import "layout.less";
@import "custom.less";
-@import "../espo/mixins/side-modal.less";
-
@import "bootstrap/utilities.less";
body {
diff --git a/frontend/less/hazyblue-vertical/main.less b/frontend/less/hazyblue-vertical/main.less
index 2df901f38a..14af213e41 100644
--- a/frontend/less/hazyblue-vertical/main.less
+++ b/frontend/less/hazyblue-vertical/main.less
@@ -14,8 +14,6 @@
@import "custom.less";
-@import "../espo/mixins/side-modal.less";
-
@import "../espo/bootstrap/utilities.less";
body {
diff --git a/frontend/less/hazyblue/main.less b/frontend/less/hazyblue/main.less
index 14acabef36..5014ead9e1 100644
--- a/frontend/less/hazyblue/main.less
+++ b/frontend/less/hazyblue/main.less
@@ -12,8 +12,6 @@
@import "custom.less";
-@import "../espo/mixins/side-modal.less";
-
@import "../espo/bootstrap/utilities.less";
body {
diff --git a/frontend/less/sakura-vertical/main.less b/frontend/less/sakura-vertical/main.less
index 4a909463fe..8bc7905783 100644
--- a/frontend/less/sakura-vertical/main.less
+++ b/frontend/less/sakura-vertical/main.less
@@ -11,8 +11,6 @@
@import "../espo/custom.less";
@import "../espo-vertical/custom.less";
-@import "../espo/mixins/side-modal.less";
-
@import "../espo/bootstrap/utilities.less";
body {
diff --git a/frontend/less/sakura/main.less b/frontend/less/sakura/main.less
index 2dd9ac5151..76219626c0 100644
--- a/frontend/less/sakura/main.less
+++ b/frontend/less/sakura/main.less
@@ -7,8 +7,6 @@
@import "../espo/layout.less";
@import "../espo/custom.less";
-@import "../espo/mixins/side-modal.less";
-
@import "../espo/bootstrap/utilities.less";
body {
diff --git a/frontend/less/violet-vertical/main.less b/frontend/less/violet-vertical/main.less
index 222def9db0..05d8488873 100644
--- a/frontend/less/violet-vertical/main.less
+++ b/frontend/less/violet-vertical/main.less
@@ -11,8 +11,6 @@
@import "../espo/custom.less";
@import "../espo-vertical/custom.less";
-@import "../espo/mixins/side-modal.less";
-
@import "../espo/bootstrap/utilities.less";
body {
diff --git a/frontend/less/violet/main.less b/frontend/less/violet/main.less
index eb0195725e..5fbcc6887a 100644
--- a/frontend/less/violet/main.less
+++ b/frontend/less/violet/main.less
@@ -7,8 +7,6 @@
@import "../espo/layout.less";
@import "../espo/custom.less";
-@import "../espo/mixins/side-modal.less";
-
@import "../espo/bootstrap/utilities.less";
body {
diff --git a/install/core/Installer.php b/install/core/Installer.php
index e7c4a64279..022e8ece53 100644
--- a/install/core/Installer.php
+++ b/install/core/Installer.php
@@ -328,8 +328,7 @@ class Installer
$res = $this->saveConfig($preferences);
- /*save these settings for admin*/
- $this->setAdminPreferences($preferences);
+ $this->saveAdminPreferences($preferences);
return $res;
}
@@ -408,20 +407,19 @@ class Installer
return $result;
}
- protected function setAdminPreferences($preferences)
+ protected function saveAdminPreferences($preferences)
{
- $allowedPreferences = array(
- 'dateFormat',
- 'timeFormat',
- 'timeZone',
- 'weekStart',
- 'defaultCurrency',
- 'thousandSeparator',
- 'decimalMark',
- 'language',
- );
+ $data = [
+ 'dateFormat' => '',
+ 'timeFormat' => '',
+ 'timeZone' => '',
+ 'weekStart' => -1,
+ 'defaultCurrency' => '',
+ 'language' => '',
+ 'thousandSeparator' => $preferences['thousandSeparator'] ?? ',',
+ 'decimalMark' => $preferences['decimalMark'] ?? '.',
+ ];
- $data = array_intersect_key($preferences, array_flip($allowedPreferences));
if (empty($data)) {
return true;
}