From 97b6cc0be907b207c8af9da16878032696564b4d Mon Sep 17 00:00:00 2001 From: Can Bulut Bayburt Date: Tue, 28 May 2024 21:06:29 +0200 Subject: [PATCH 1/4] Fix displayed time in datetime pickers that use server's timezone (bsc#1225196) --- web/html/src/components/datetime/DateTimePicker.tsx | 4 ++-- web/spacewalk-web.changes.cbbayburt.bsc1225196 | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 web/spacewalk-web.changes.cbbayburt.bsc1225196 diff --git a/web/html/src/components/datetime/DateTimePicker.tsx b/web/html/src/components/datetime/DateTimePicker.tsx index 4e3d945e697a..174415b5fa91 100644 --- a/web/html/src/components/datetime/DateTimePicker.tsx +++ b/web/html/src/components/datetime/DateTimePicker.tsx @@ -89,8 +89,8 @@ export const DateTimePicker = (props: Props) => { // We use localizedMoment to clone the date so we don't modify the original const browserTimezoneValue = localizedMoment(props.value) - // We convert the date to the users configured timezone because this is what we want to show the user - .tz(localizedMoment.userTimeZone) + // We convert the date to the user's or server's configured timezone because this is what we want to show the user + .tz(timeZone) // The react-datepicker component only shows the browsers local timezone and will convert any date to that // before showing so since we already got the date with the right values we now pretend the date we have is in // the browsers local timezone but without changing its values. This will prevent the react component from diff --git a/web/spacewalk-web.changes.cbbayburt.bsc1225196 b/web/spacewalk-web.changes.cbbayburt.bsc1225196 new file mode 100644 index 000000000000..3dadb99112c9 --- /dev/null +++ b/web/spacewalk-web.changes.cbbayburt.bsc1225196 @@ -0,0 +1,2 @@ +- Fix displayed time in datetime pickers that use server's + timezone (bsc#1225196) From 52374be25aaff8c3c862ea344497fc33ebc5a32b Mon Sep 17 00:00:00 2001 From: Can Bulut Bayburt Date: Tue, 28 May 2024 21:08:12 +0200 Subject: [PATCH 2/4] Show server's timezone with the execution time in recurring action details --- .../src/manager/recurring/recurring-actions-details.tsx | 7 +++++-- web/spacewalk-web.changes.cbbayburt.bsc1225196 | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/web/html/src/manager/recurring/recurring-actions-details.tsx b/web/html/src/manager/recurring/recurring-actions-details.tsx index 0f7124685a3d..49cd6b66dbf1 100644 --- a/web/html/src/manager/recurring/recurring-actions-details.tsx +++ b/web/html/src/manager/recurring/recurring-actions-details.tsx @@ -11,6 +11,7 @@ import { TopPanel } from "components/panels/TopPanel"; import { Column } from "components/table/Column"; import { Table } from "components/table/Table"; +import { localizedMoment } from "utils"; import Network from "utils/network"; import { DisplayHighstate } from "../state/display-highstate"; @@ -94,14 +95,16 @@ class RecurringActionsDetails extends React.Component {"Every day at "} - {details.cronTimes.hour + ":" + details.cronTimes.minute} + {`${details.cronTimes.hour}:${details.cronTimes.minute} `} + {localizedMoment.serverTimeZoneAbbr} ) : details.type === "weekly" ? ( {"Every "} {this.weekDays[details.cronTimes.dayOfWeek - 1]} {" at "} - {details.cronTimes.hour + ":" + details.cronTimes.minute} + {`${details.cronTimes.hour}:${details.cronTimes.minute} `} + {localizedMoment.serverTimeZoneAbbr} ) : ( diff --git a/web/spacewalk-web.changes.cbbayburt.bsc1225196 b/web/spacewalk-web.changes.cbbayburt.bsc1225196 index 3dadb99112c9..b5b17e6ed774 100644 --- a/web/spacewalk-web.changes.cbbayburt.bsc1225196 +++ b/web/spacewalk-web.changes.cbbayburt.bsc1225196 @@ -1,2 +1,3 @@ +- Show proper timezones in recurring action details - Fix displayed time in datetime pickers that use server's timezone (bsc#1225196) From 749af3710238d1d9ac6e234fd78e107afda3966d Mon Sep 17 00:00:00 2001 From: Can Bulut Bayburt Date: Tue, 28 May 2024 21:09:00 +0200 Subject: [PATCH 3/4] Fix creation time display in recurring action details --- .../src/manager/recurring/recurring-actions-details.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/html/src/manager/recurring/recurring-actions-details.tsx b/web/html/src/manager/recurring/recurring-actions-details.tsx index 49cd6b66dbf1..8c0fbde11427 100644 --- a/web/html/src/manager/recurring/recurring-actions-details.tsx +++ b/web/html/src/manager/recurring/recurring-actions-details.tsx @@ -146,6 +146,12 @@ class RecurringActionsDetails extends React.Component
@@ -180,7 +186,7 @@ class RecurringActionsDetails extends React.Component {t("Created at")}: - {details.createdAt + " " + window.timezone} + {createdAt + " " + localizedMoment.userTimeZoneAbbr} } {this.getExecutionText(details)} From fba322b5481efcf41ea01e1a07b97459fac0ab71 Mon Sep 17 00:00:00 2001 From: Etheryte Date: Wed, 29 May 2024 20:16:29 +0300 Subject: [PATCH 4/4] Test internalized server date time parsing --- .../recurring/recurring-actions-details.tsx | 4 +--- .../src/utils/datetime/localizedMoment.ts | 23 +++++++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/web/html/src/manager/recurring/recurring-actions-details.tsx b/web/html/src/manager/recurring/recurring-actions-details.tsx index 8c0fbde11427..7f767f7ff5e6 100644 --- a/web/html/src/manager/recurring/recurring-actions-details.tsx +++ b/web/html/src/manager/recurring/recurring-actions-details.tsx @@ -148,9 +148,7 @@ class RecurringActionsDetails extends React.Component diff --git a/web/html/src/utils/datetime/localizedMoment.ts b/web/html/src/utils/datetime/localizedMoment.ts index f341ab0aaa3a..4f32ffd2749f 100644 --- a/web/html/src/utils/datetime/localizedMoment.ts +++ b/web/html/src/utils/datetime/localizedMoment.ts @@ -44,9 +44,8 @@ declare global { } } -if (process.env.NODE_ENV !== "production") { - (window as any).localizedMoment = localizedMomentConstructor; -} +// This is for debugging purposes only, if you need to use this module, import it properly +(window as any).localizedMoment = localizedMomentConstructor; function validateOrGuessTimeZone(input: string | undefined, errorLabel: "Server" | "User") { try { @@ -139,6 +138,13 @@ declare module "moment" { const userTimeZone: string; /** Abbreviated user time zone string, e.g. `"JST"` */ const userTimeZoneAbbr: string; + + /** + * Parse a date time string provided in the server time zone, e.g. `localizedMoment.fromServerString("May 29, 2024, 11:26:06 AM")`. + * + * @deprecated This function exists for backwards compatibility, for new backend code use ISO 8601 and call `localizedMoment(input)` directly. + */ + const fromServerDateTimeString: (input: string) => moment.Moment; } moment.fn.toServerString = function (this: moment.Moment): string { @@ -197,6 +203,13 @@ Object.defineProperties(moment, { return (userTimeZoneAbbr ??= moment().tz(config.userTimeZone).format("z")); }, }, + fromServerDateTimeString: { + get() { + // TODO: Is this format string correct? Maybe there's a library constant we can use here? + return (input: string): moment.Moment => + moment.tz(input, "MMM DD, YYYY, HH:mm:ss A", true, config.serverTimeZone); + }, + }, }); const parseTimeString = function (input: string): { hours: number; minutes: number } | null { @@ -218,7 +231,9 @@ function localizedMomentConstructor(input?: moment.MomentInput) { : moment(input, true).utc().tz("UTC"); if (!utcMoment.isValid()) { - throw new RangeError("Invalid localized moment on input " + JSON.stringify(input)); + throw new RangeError( + `Invalid input for localized moment, got input with type "${typeof input}" and value ${input}` + ); } return utcMoment;