diff --git a/backend/i18n/frontend_en.json b/backend/i18n/frontend_en.json
index 114c164bc..bbaab29ad 100644
--- a/backend/i18n/frontend_en.json
+++ b/backend/i18n/frontend_en.json
@@ -210,7 +210,7 @@
"common.created": "Created",
"common.date": "Date",
"common.dateTimeEditor.now": "Now",
- "common.dateTimeEditor.nowTooltip": "Use Now (UTC)",
+ "common.dateTimeEditor.nowTooltip": "Use Now",
"common.dateTimeEditor.today": "Today",
"common.dateTimeEditor.todayTooltip": "Use Today (UTC)",
"common.delete": "Delete",
diff --git a/backend/i18n/frontend_nl.json b/backend/i18n/frontend_nl.json
index f492bb661..7911670f6 100644
--- a/backend/i18n/frontend_nl.json
+++ b/backend/i18n/frontend_nl.json
@@ -210,7 +210,7 @@
"common.created": "Gemaakt",
"common.date": "Datum",
"common.dateTimeEditor.now": "Nu",
- "common.dateTimeEditor.nowTooltip": "Nu gebruiken (UTC)",
+ "common.dateTimeEditor.nowTooltip": "Nu gebruiken",
"common.dateTimeEditor.today": "Vandaag",
"common.dateTimeEditor.todayTooltip": "Gebruik vandaag (UTC)",
"common.delete": "Verwijderen",
diff --git a/backend/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs b/backend/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs
index 13eca6150..937e3151e 100644
--- a/backend/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs
+++ b/backend/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs
@@ -29,6 +29,8 @@ namespace Squidex.Areas.Api.Controllers.UI
public bool HideDateButtons { get; set; }
+ public bool HideDateTimeModeButton { get; set; }
+
public bool DisableScheduledChanges { get; set; }
public bool RedirectToLogin { get; set; }
diff --git a/backend/src/Squidex/appsettings.json b/backend/src/Squidex/appsettings.json
index d9d802ee7..e7e7d5f6d 100644
--- a/backend/src/Squidex/appsettings.json
+++ b/backend/src/Squidex/appsettings.json
@@ -118,6 +118,10 @@
*/
"hideDateButtons": false,
+ /*
+ * Hide the Local/UTC button
+ */
+ "hideDateTimeModeButton": false,
/*
* True to disable scheduled content status changed, for example when you have your own scheduling system.
*/
diff --git a/frontend/app/features/content/shared/content-status.component.ts b/frontend/app/features/content/shared/content-status.component.ts
index 3e0b50d71..9bdb4dd53 100644
--- a/frontend/app/features/content/shared/content-status.component.ts
+++ b/frontend/app/features/content/shared/content-status.component.ts
@@ -43,7 +43,7 @@ export class ContentStatusComponent {
public get tooltipText() {
if (this.scheduled) {
- return `Will be set to '${this.scheduled.status}' at ${this.scheduled.dueTime.toStringFormatUTC('PPpp')}`;
+ return `Will be set to '${this.scheduled.status}' at ${this.scheduled.dueTime.toStringFormat('PPpp')}`;
} else {
return this.status;
}
diff --git a/frontend/app/framework/angular/forms/editors/date-time-editor.component.html b/frontend/app/framework/angular/forms/editors/date-time-editor.component.html
index 63c510fe6..f83ce504f 100644
--- a/frontend/app/framework/angular/forms/editors/date-time-editor.component.html
+++ b/frontend/app/framework/angular/forms/editors/date-time-editor.component.html
@@ -1,25 +1,37 @@
-
+
\ No newline at end of file
diff --git a/frontend/app/framework/angular/forms/editors/date-time-editor.component.scss b/frontend/app/framework/angular/forms/editors/date-time-editor.component.scss
index 8c5a4912a..74673c3c0 100644
--- a/frontend/app/framework/angular/forms/editors/date-time-editor.component.scss
+++ b/frontend/app/framework/angular/forms/editors/date-time-editor.component.scss
@@ -33,16 +33,27 @@
width: 8.5rem;
}
+ .form-date-time-only {
+ padding-left: 3.3rem;
+ width: 11rem;
+ }
+
+
.form-time {
width: 7rem;
}
}
-.btn-clear {
- & {
+.btn {
+ &-clear {
@include absolute(auto, 4px, 3px, auto);
}
+ &-time-mode {
+ @include absolute(1px, auto, -1px, auto);
+ z-index: 1000;
+ }
+
&:focus {
box-shadow: none;
}
diff --git a/frontend/app/framework/angular/forms/editors/date-time-editor.component.ts b/frontend/app/framework/angular/forms/editors/date-time-editor.component.ts
index 61e51ea9a..f673d1074 100644
--- a/frontend/app/framework/angular/forms/editors/date-time-editor.component.ts
+++ b/frontend/app/framework/angular/forms/editors/date-time-editor.component.ts
@@ -32,6 +32,7 @@ export class DateTimeEditorComponent extends StatefulControlComponent<{}, string
private picker: any;
private dateTime: DateTime | null;
private hideDateButtonsSettings: boolean;
+ private hideDateTimeModeButtonSetting: boolean;
private suppressEvents = false;
@Input()
@@ -46,17 +47,29 @@ export class DateTimeEditorComponent extends StatefulControlComponent<{}, string
@Input()
public hideDateButtons: boolean;
+ @Input()
+ public hideDateTimeModeButton: boolean;
+
+ @Input()
+ public isCompact: boolean;
+
@ViewChild('dateInput', { static: false })
public dateInput: ElementRef
;
public timeControl = new FormControl();
public dateControl = new FormControl();
+ public isLocalMode = true;
+
public get shouldShowDateButtons() {
return !this.hideDateButtonsSettings && !this.hideDateButtons;
}
- public get showTime() {
+ public get shouldShowDateTimeModeButton() {
+ return !this.hideDateTimeModeButtonSetting && !this.hideDateTimeModeButton;
+ }
+
+ public get isDateTimeMode() {
return this.mode === 'DateTime';
}
@@ -68,23 +81,28 @@ export class DateTimeEditorComponent extends StatefulControlComponent<{}, string
super(changeDetector, {});
this.hideDateButtonsSettings = !!uiOptions.get('hideDateButtons');
+ this.hideDateTimeModeButtonSetting = !!uiOptions.get('hideDateTimeModeButton');
}
public ngOnInit() {
this.own(
this.timeControl.valueChanges.subscribe(() => {
+ this.dateTime = this.getValue();
+
this.callChangeFormatted();
}));
this.own(
this.dateControl.valueChanges.subscribe(() => {
+ this.dateTime = this.getValue();
+
this.callChangeFormatted();
}));
}
public writeValue(obj: any) {
try {
- this.dateTime = DateTime.parseISO(obj);
+ this.dateTime = DateTime.parseISO(obj, false);
} catch (ex) {
this.dateTime = null;
}
@@ -109,7 +127,7 @@ export class DateTimeEditorComponent extends StatefulControlComponent<{}, string
}
public ngAfterViewInit() {
- this.picker = new Pikaday({ field: this.dateInput.nativeElement, format: 'YYYY-MM-DD',
+ this.picker = new Pikaday({field: this.dateInput.nativeElement, format: 'YYYY-MM-DD',
onSelect: () => {
if (this.suppressEvents) {
return;
@@ -125,7 +143,7 @@ export class DateTimeEditorComponent extends StatefulControlComponent<{}, string
}
public writeNow() {
- this.writeValue(DateTime.now().toISOString());
+ this.dateTime = DateTime.now();
this.updateControls();
this.callChangeFormatted();
@@ -138,58 +156,55 @@ export class DateTimeEditorComponent extends StatefulControlComponent<{}, string
this.dateTime = null;
this.updateControls();
-
- this.callChange(null);
+ this.callChangeFormatted();
this.callTouched();
return false;
}
private callChangeFormatted() {
- this.callChange(this.getValue());
+ this.callChange(this.dateTime?.toISOString());
}
- private getValue(): string | null {
+ private getValue(): DateTime | null {
if (!this.dateControl.value) {
return null;
}
- let result: string | null = null;
-
- if (this.showTime && this.timeControl.value) {
+ if (this.isDateTimeMode && this.timeControl.value) {
const combined = `${this.dateControl.value}T${this.timeControl.value}`;
- const parsed = DateTime.tryParseISO(combined, true);
-
- if (parsed) {
- result = parsed.toISOString();
- }
- }
-
- if (!result) {
- const parsed = DateTime.tryParseISO(this.dateControl.value, true);
-
- if (parsed) {
- result = parsed.toISOString();
- }
+ return DateTime.tryParseISO(combined, !this.isLocalMode);
}
- return result;
+ return DateTime.tryParseISO(this.dateControl.value);
}
private updateControls() {
this.suppressEvents = true;
- if (this.dateTime && this.mode === 'DateTime') {
- this.timeControl.setValue(this.dateTime.toStringFormatUTC('HH:mm:ss'), NO_EMIT);
+ if (this.dateTime && this.isDateTimeMode) {
+ if (this.isLocalMode) {
+ this.timeControl.setValue(this.dateTime.toStringFormat('HH:mm:ss'), NO_EMIT);
+ } else {
+ this.timeControl.setValue(this.dateTime.toStringFormatUTC('HH:mm:ss'), NO_EMIT);
+ }
} else {
this.timeControl.setValue(null, NO_EMIT);
}
if (this.dateTime && this.picker) {
- const dateString = this.dateTime.toStringFormatUTC('yyyy-MM-dd');
+ let dateString: string;
+
+ if (this.isDateTimeMode && this.isLocalMode) {
+ dateString = this.dateTime.toStringFormat('yyyy-MM-dd');
+
+ this.picker.setDate(DateHelper.getLocalDate(this.dateTime.raw), true);
+ } else {
+ dateString = this.dateTime.toStringFormatUTC('yyyy-MM-dd');
- this.picker.setDate(DateHelper.getUTCDate(this.dateTime.raw), true);
+ this.picker.setDate(DateHelper.getUTCDate(this.dateTime.raw), true);
+ }
this.dateControl.setValue(dateString, NO_EMIT);
} else {
@@ -198,4 +213,14 @@ export class DateTimeEditorComponent extends StatefulControlComponent<{}, string
this.suppressEvents = false;
}
+
+ public setLocalMode(isLocalMode: boolean) {
+ this.isLocalMode = isLocalMode;
+
+ this.updateControls();
+ }
+
+ public setCompact(isCompact: boolean) {
+ this.next(s => ({ ...s, isCompact }));
+ }
}
\ No newline at end of file
diff --git a/frontend/app/framework/utils/date-time.ts b/frontend/app/framework/utils/date-time.ts
index 4f8234a9f..f237c0687 100644
--- a/frontend/app/framework/utils/date-time.ts
+++ b/frontend/app/framework/utils/date-time.ts
@@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
-import { addDays, addHours, addMilliseconds, addMinutes, addMonths, addSeconds, addYears, format, formatDistanceToNow, parse, parseISO, startOfDay, startOfMonth, startOfTomorrow, startOfWeek, startOfYesterday } from 'date-fns';
+import { addDays, addHours, addMilliseconds, addMinutes, addMonths, addSeconds, addYears, format, formatDistanceToNow, formatISO, parse, parseISO, startOfDay, startOfMonth, startOfTomorrow, startOfWeek, startOfYesterday } from 'date-fns';
import { DateHelper } from './date-helper';
const DATE_FORMAT = 'yyyy-MM-dd';
@@ -177,6 +177,10 @@ export class DateTime {
return format(this.value, DATE_FORMAT);
}
+ public toISODateTime(): string {
+ return formatISO(this.value);
+ }
+
public toStringFormat(pattern: string): string {
return format(this.value, pattern);
}
diff --git a/frontend/app/shared/state/contents.forms.spec.ts b/frontend/app/shared/state/contents.forms.spec.ts
index 882d4e7e6..efc2df609 100644
--- a/frontend/app/shared/state/contents.forms.spec.ts
+++ b/frontend/app/shared/state/contents.forms.spec.ts
@@ -250,19 +250,19 @@ describe('DateTimeField', () => {
it('should format old format to date', () => {
const dateField = createField({ properties: createProperties('DateTime', { editor: 'Date' }) });
- expect(FieldFormatter.format(dateField, '2017-12-12')).toBe('2017-12-12');
+ expect(FieldFormatter.format(dateField, '2017-12-12')).toBe('12/12/2017');
});
it('should format to date', () => {
const dateField = createField({ properties: createProperties('DateTime', { editor: 'Date' }) });
- expect(FieldFormatter.format(dateField, '2017-12-12T16:00:00Z')).toBe('2017-12-12');
+ expect(FieldFormatter.format(dateField, '2017-12-12T16:00:00Z')).toBe('12/12/2017');
});
it('should format to date time', () => {
const field2 = createField({ properties: createProperties('DateTime', { editor: 'DateTime' }) });
- expect(FieldFormatter.format(field2, '2017-12-12T16:00:00Z')).toBe('2017-12-12 16:00:00');
+ expect(FieldFormatter.format(field2, '2017-12-12T16:00:00Z')).toBe('12/12/2017, 4:00:00 PM');
});
it('should return default for DateFieldProperties', () => {
diff --git a/frontend/app/shared/state/contents.forms.visitors.ts b/frontend/app/shared/state/contents.forms.visitors.ts
index 9b75ee2ea..2b426a72d 100644
--- a/frontend/app/shared/state/contents.forms.visitors.ts
+++ b/frontend/app/shared/state/contents.forms.visitors.ts
@@ -130,9 +130,9 @@ export class FieldFormatter implements FieldPropertiesVisitor {
const parsed = DateTime.parseISO(this.value);
if (properties.editor === 'Date') {
- return parsed.toStringFormatUTC('yyyy-MM-dd');
+ return parsed.toStringFormat('P');
} else {
- return parsed.toStringFormatUTC('yyyy-MM-dd HH:mm:ss');
+ return parsed.toStringFormat('Ppp');
}
} catch (ex) {
return this.value;