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; }