Skip to content

Commit c2cebf3

Browse files
committed
Split datetime option, cleanup datepicker control [#9152]
1 parent 5f6571e commit c2cebf3

4 files changed

Lines changed: 152 additions & 115 deletions

File tree

web-ui/src/main/resources/catalog/components/edit/datepicker/DatePickerDirective.js

Lines changed: 109 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
(function () {
2525
goog.provide("gn_date_picker_directive");
2626

27-
var module = angular.module("gn_date_picker_directive", []);
27+
const module = angular.module("gn_date_picker_directive", []);
2828

2929
/**
3030
* Create a widget to handle date composed of
@@ -73,23 +73,57 @@
7373
templateUrl:
7474
"../../catalog/components/edit/datepicker/partials/" + "datepicker.html",
7575
link: function (scope, element, attrs) {
76+
// Define DATE_MODE constant
77+
const DATE_MODE = {
78+
DATE: "date",
79+
DATETIME: "datetime",
80+
MONTH: "month",
81+
YEAR: "year"
82+
};
83+
// Expose DATE_MODE to scope
84+
scope.DATE_MODE = DATE_MODE;
85+
86+
const coerceBool = function(val) {
87+
return val !== 'false' && !!val;
88+
};
89+
7690
// Check if browser support date type or not to
7791
// HTML date and time input types.
7892
// If not datetimepicker.js is used (it will not
7993
// support year or month only mode in this case)
8094
scope.dateTypeSupported = Modernizr.inputtypes.date;
8195
scope.isValidDate = true;
82-
scope.hideTime = scope.hideTime == "true";
96+
scope.hideTime = coerceBool(scope.hideTime);
8397
// Hide the date mode picker: date / datetime / month-year / year
84-
scope.hideDateMode = scope.hideDateMode == "true";
98+
scope.hideDateMode = coerceBool(scope.hideDateMode);
8599

86-
var getTimeZoneOffset = function (timeZone) {
87-
var actualTz = timeZone;
88-
if (
89-
timeZone &&
90-
timeZone !== null &&
91-
timeZone.trim().toLowerCase() === "browser"
92-
) {
100+
// Watch for external changes and re-coerce
101+
scope.$watch('hideTime', function(newVal) {
102+
const coerced = coerceBool(newVal);
103+
if (newVal !== coerced) {
104+
scope.hideTime = coerced;
105+
}
106+
});
107+
scope.$watch('hideDateMode', function(newVal) {
108+
const coerced = coerceBool(newVal);
109+
if (newVal !== coerced) {
110+
scope.hideTime = coerced;
111+
}
112+
});
113+
114+
const userTimezone = moment.tz.guess();
115+
const uiTimezone = gnGlobalSettings.gnCfg.mods.global.timezone;
116+
const serverTimezone = gnConfig["system.server.timeZone"];
117+
const datePattern = new RegExp(
118+
"^\\d{4}$|" +
119+
"^\\d{4}-\\d{2}$|" +
120+
"^\\d{4}-\\d{2}-\\d{2}$|" +
121+
"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$"
122+
);
123+
124+
const getTimeZoneOffset = function (timeZone) {
125+
let actualTz = timeZone;
126+
if (timeZone && timeZone.trim().toLowerCase() === "browser") {
93127
actualTz = userTimezone;
94128
}
95129
return moment
@@ -98,67 +132,66 @@
98132
.replace(/([+-]?[0-9]{2})([0-9]{2})/, "$1:$2");
99133
};
100134

101-
scope.timezone =
102-
getTimeZoneOffset(gnGlobalSettings.gnCfg.mods.global.timezone) ||
103-
gnConfig["system.server.timeZone"] ||
104-
"";
105-
scope.uiTimeZoneEqualToServer =
106-
gnConfig["system.server.timeZone"] ===
107-
gnGlobalSettings.gnCfg.mods.global.timezone;
135+
scope.timezone = getTimeZoneOffset(uiTimezone) || serverTimezone || "";
136+
scope.uiTimeZoneEqualToServer = serverTimezone === uiTimezone;
108137
scope.hideTimezone = scope.uiTimeZoneEqualToServer;
109-
var datePattern = new RegExp(
110-
"^\\d{4}$|" +
111-
"^\\d{4}-\\d{2}$|" +
112-
"^\\d{4}-\\d{2}-\\d{2}$|" +
113-
"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$"
114-
);
138+
115139
// Format date when datetimepicker is used.
116140
scope.formatFromDatePicker = function (date) {
117-
var format = "YYYY-MM-DDTHH:mm:ss";
118-
var dateTime = moment(date);
141+
const format = "YYYY-MM-DDTHH:mm:ss";
142+
const dateTime = moment(date);
119143
scope.dateInput = dateTime.format(format);
120144
};
121145

122-
var userTimezone = moment.tz.guess();
123-
146+
// Define timezone options
124147
scope.timezoneNames = [
125-
{ name: $translate.instant("NoTimezone"), offset: "" },
126148
{
127-
name: $translate.instant("YourTimezone") + " " + userTimezone,
149+
// No timezone
150+
name: $translate.instant("NoTimezone"),
151+
offset: ""
152+
},
153+
{
154+
// User timezone
155+
name:
156+
$translate.instant("YourTimezone") +
157+
(userTimezone ? " " + userTimezone : ""),
128158
offset: getTimeZoneOffset(userTimezone)
159+
},
160+
{
161+
// Server timezone
162+
name:
163+
$translate.instant("CatalogTimezone") +
164+
(serverTimezone ? " " + serverTimezone : ""),
165+
offset: getTimeZoneOffset(serverTimezone)
166+
},
167+
{
168+
// Recommended timezone (browser timezone)
169+
name:
170+
$translate.instant("CatalogUiTimezone") +
171+
(uiTimezone ? " " + uiTimezone : ""),
172+
offset: getTimeZoneOffset(uiTimezone)
173+
},
174+
{
175+
// Add separator between predefined timezones and all others
176+
name: "----",
177+
offset: ""
129178
}
130179
];
131-
// Add server timezone
132-
scope.timezoneNames.push({
133-
name:
134-
$translate.instant("CatalogTimezone") +
135-
" " +
136-
gnConfig["system.server.timeZone"],
137-
offset: getTimeZoneOffset(gnConfig["system.server.timeZone"])
138-
});
139-
// UI preferred timezone
140-
scope.timezoneNames.push({
141-
name:
142-
$translate.instant("CatalogUiTimezone") +
143-
" " +
144-
gnGlobalSettings.gnCfg.mods.global.timezone,
145-
offset: getTimeZoneOffset(gnGlobalSettings.gnCfg.mods.global.timezone)
146-
});
147-
scope.timezoneNames.push({ name: "----", offset: "" });
148-
_.forEach(moment.tz.names(), function (tz, index, list) {
180+
// Add all available timezones
181+
_.forEach(moment.tz.names(), function (tz) {
149182
scope.timezoneNames.push({
150183
name: tz,
151184
offset: getTimeZoneOffset(tz)
152185
});
153186
});
154187

155-
scope.mode =
156-
scope.year =
188+
scope.year =
157189
scope.month =
158190
scope.time =
159191
scope.date =
160192
scope.dateDropDownInput =
161193
"";
194+
scope.mode = DATE_MODE.DATE; // Default mode is date only
162195
scope.withIndeterminatePosition = attrs.indeterminatePosition !== undefined;
163196

164197
// Default date is empty
@@ -168,15 +201,16 @@
168201
scope.value = "";
169202
} else if (scope.value.length === 4) {
170203
scope.year = parseInt(scope.value);
171-
scope.mode = "year";
204+
scope.mode = DATE_MODE.YEAR;
172205
scope.hideTimezone = true;
173206
} else if (scope.value.length === 7) {
174207
scope.month = moment(scope.value, "YYYY-MM").toDate();
175-
scope.mode = "month";
208+
scope.mode = DATE_MODE.MONTH;
176209
scope.hideTimezone = true;
177210
} else {
178-
var isDateTime = scope.value.indexOf("T") !== -1;
179-
var tokens = scope.value.split("T");
211+
// Value is a date or datetime
212+
const isDateTime = scope.value.indexOf("T") !== -1;
213+
const tokens = scope.value.split("T");
180214

181215
// Default to empty string and prevent 'Invalid Date' string to xmlSnippet
182216
scope.date = "";
@@ -188,35 +222,36 @@
188222
);
189223
}
190224

191-
var time = tokens[1];
192-
193-
if (time != undefined) {
225+
// Process time part (if defined)
226+
let time = tokens[1];
227+
if (time !== undefined) {
194228
scope.time = isDateTime ? moment(time, "HH:mm:ss").toDate() : undefined;
195-
196-
scope.timezone = time.substr(8);
229+
console.log("parsed time:", scope.time);
230+
scope.timezone = time.slice(8);
197231
scope.hideTimezone =
198232
scope.uiTimeZoneEqualToServer &&
199-
getTimeZoneOffset(gnGlobalSettings.gnCfg.mods.global.timezone) ===
233+
getTimeZoneOffset(uiTimezone) ===
200234
scope.timezone;
235+
scope.mode = DATE_MODE.DATETIME;
201236
} else {
202237
scope.time = "";
203238
scope.timezone = "";
204239
scope.hideTimezone = scope.uiTimeZoneEqualToServer;
205240
}
206241
}
207-
if (scope.dateTypeSupported !== true) {
242+
if (!scope.dateTypeSupported) {
208243
scope.dateInput = scope.value;
209244
scope.dateDropDownInput = scope.value;
210245
}
211246

212247
scope.setMode = function (mode) {
248+
// Called when user changes date mode
213249
scope.mode = mode;
214-
scope.hideTimezone = mode === "year" || mode === "month";
250+
scope.hideTimezone = mode === DATE_MODE.YEAR || mode === DATE_MODE.MONTH;
215251
};
216252

217-
var resetDateIfNeeded = function () {
218-
// Reset date if indeterminate position is now
219-
// or unknows.
253+
const resetDateIfNeeded = function () {
254+
// Reset date if indeterminate position is now or unknown
220255
if (
221256
scope.withIndeterminatePosition &&
222257
(scope.indeterminatePosition === "now" ||
@@ -232,11 +267,11 @@
232267
};
233268

234269
// Build xml snippet based on input date.
235-
var buildDate = function () {
236-
var tag = scope.tagName !== undefined ? scope.tagName : "gco:Date";
237-
var namespace = tag.split(":")[0];
270+
const buildDate = function () {
271+
let tag = scope.tagName !== undefined ? scope.tagName : "gco:Date";
272+
const namespace = tag.split(":")[0];
238273

239-
if (scope.dateTypeSupported !== true) {
274+
if (!scope.dateTypeSupported) {
240275
// Check date against simple date pattern
241276
// to add a css class to highlight error.
242277
// Input will be saved anyway.
@@ -253,13 +288,13 @@
253288
: "gco:DateTime";
254289
}
255290
scope.dateTime = scope.dateInput;
256-
} else if (scope.mode === "year") {
291+
} else if (scope.mode === DATE_MODE.YEAR) {
257292
scope.dateTime = scope.year;
258-
} else if (scope.mode === "month") {
293+
} else if (scope.mode === DATE_MODE.MONTH) {
259294
scope.dateTime = $filter("date")(scope.month, "yyyy-MM");
260-
} else if (scope.time) {
295+
} else if (scope.mode === DATE_MODE.DATETIME && scope.time) {
261296
tag = scope.tagName !== undefined ? scope.tagName : "gco:DateTime";
262-
var time = $filter("date")(scope.time, "HH:mm:ss");
297+
let time = $filter("date")(scope.time, "HH:mm:ss");
263298
// TODO: Set seconds, Timezone ?
264299
scope.dateTime = $filter("date")(scope.date, "yyyy-MM-dd");
265300
scope.dateTime += "T" + time + scope.timezone;
@@ -269,7 +304,7 @@
269304
if (tag === "") {
270305
scope.xmlSnippet = scope.dateTime;
271306
} else {
272-
var attribute = "";
307+
let attribute = "";
273308
if (scope.withIndeterminatePosition && scope.indeterminatePosition !== "") {
274309
attribute =
275310
' indeterminatePosition="' + scope.indeterminatePosition + '"';
@@ -306,7 +341,7 @@
306341
scope.$watch("indeterminatePosition", resetDateIfNeeded);
307342
scope.$watch("xmlSnippet", function () {
308343
if (scope.id) {
309-
// This is required on init to have the optionnaly
344+
// This is required on init to have the optionally
310345
// templateFieldDirective initialized first so
311346
// that the template is properly computed.
312347
$timeout(function () {

0 commit comments

Comments
 (0)