Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: Remove Moment.js dependency and replace with Intl.DateTime #885

Merged
merged 3 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"keycloakify": "^11.3.29",
"memoizee": "^0.4.17",
"minimal-polyfills": "^2.2.3",
"moment": "^2.30.1",
"mui-icons-material-lazy": "^1.0.3",
"oidc-spa": "^5.6.1",
"onyxia-ui": "^6.2.1",
"pathe": "^1.1.2",
Expand All @@ -78,8 +78,7 @@
"xterm-addon-web-links": "^0.9.0",
"xterm-addon-webgl": "^0.16.0",
"yaml": "^2.6.0",
"zod": "^3.23.8",
"mui-icons-material-lazy": "^1.0.3"
"zod": "^3.23.8"
},
"resolutions": {
"@codemirror/view": "6.34.1"
Expand Down
4 changes: 1 addition & 3 deletions web/src/ui/i18n/resources/de.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -943,9 +943,7 @@ Fühlen Sie sich frei, Ihre Kubernetes-Bereitstellungen zu erkunden und die Kont
CommandBar: {
ok: "Ok"
},
moment: {
"date format": ({ isSameYear }) =>
`dddd, Do MMMM${isSameYear ? "" : " YYYY"}, HH:mm`,
formattedDate: {
past1: ({ divisorKey }) => {
switch (divisorKey) {
case "now":
Expand Down
4 changes: 1 addition & 3 deletions web/src/ui/i18n/resources/en.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -923,9 +923,7 @@ Feel free to explore and take charge of your Kubernetes deployments!
CommandBar: {
ok: "Ok"
},
moment: {
"date format": ({ isSameYear }) =>
`dddd, MMMM Do${isSameYear ? "" : " YYYY"}, h:mm a`,
formattedDate: {
past1: ({ divisorKey }) => {
switch (divisorKey) {
case "now":
Expand Down
4 changes: 1 addition & 3 deletions web/src/ui/i18n/resources/es.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -937,9 +937,7 @@ export const translations: Translations<"en"> = {
CommandBar: {
ok: "Aceptar"
},
moment: {
"date format": ({ isSameYear }) =>
`dddd, MMMM Do${isSameYear ? "" : " YYYY"}, h:mm a`,
formattedDate: {
past1: ({ divisorKey }) => {
switch (divisorKey) {
case "now":
Expand Down
4 changes: 1 addition & 3 deletions web/src/ui/i18n/resources/fi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -929,9 +929,7 @@ Tutustu vapaasti ja ota hallintaan Kubernetes-julkaisusi!
CommandBar: {
ok: "ok"
},
moment: {
"date format": ({ isSameYear }) =>
`dddd, Do MMMM${isSameYear ? "" : " YYYY"}, HH:mm`,
formattedDate: {
past1: ({ divisorKey }) => {
switch (divisorKey) {
case "now":
Expand Down
4 changes: 1 addition & 3 deletions web/src/ui/i18n/resources/fr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -947,9 +947,7 @@ N'hésitez pas à explorer et à prendre en main vos déploiements Kubernetes !
CommandBar: {
ok: "ok"
},
moment: {
"date format": ({ isSameYear }) =>
`dddd Do MMMM${isSameYear ? "" : " YYYY"} à H[h]mm`,
formattedDate: {
past1: ({ divisorKey }) => {
switch (divisorKey) {
case "now":
Expand Down
4 changes: 1 addition & 3 deletions web/src/ui/i18n/resources/it.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -938,9 +938,7 @@ Sentiti libero di esplorare e prendere il controllo dei tuoi deployment Kubernet
CommandBar: {
ok: "ok"
},
moment: {
"date format": ({ isSameYear }) =>
`dddd, Do MMMM${isSameYear ? "" : " YYYY"}, HH:mm`,
formattedDate: {
past1: ({ divisorKey }) => {
switch (divisorKey) {
case "now":
Expand Down
4 changes: 1 addition & 3 deletions web/src/ui/i18n/resources/nl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -940,9 +940,7 @@ Voel je vrij om te verkennen en de controle over je Kubernetes-implementaties te
CommandBar: {
ok: "ok"
},
moment: {
"date format": ({ isSameYear }) =>
`dddd, Do MMMM${isSameYear ? "" : " YYYY"}, HH:mm`,
formattedDate: {
past1: ({ divisorKey }) => {
switch (divisorKey) {
case "now":
Expand Down
4 changes: 1 addition & 3 deletions web/src/ui/i18n/resources/no.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -934,9 +934,7 @@ Utforsk gjerne og ta kontroll over tjenestene du kjører på Kubernetes!
CommandBar: {
ok: "ok"
},
moment: {
"date format": ({ isSameYear }) =>
`dddd, Do MMMM${isSameYear ? "" : " YYYY"}, HH:mm`,
formattedDate: {
past1: ({ divisorKey }) => {
switch (divisorKey) {
case "now":
Expand Down
4 changes: 1 addition & 3 deletions web/src/ui/i18n/resources/zh-CN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -876,9 +876,7 @@ ${
CommandBar: {
ok: "是"
},
moment: {
"date format": ({ isSameYear }) =>
`dddd, MMMM Do${isSameYear ? "" : " YYYY"}, h:mm a`,
formattedDate: {
past1: ({ divisorKey }) => {
switch (divisorKey) {
case "now":
Expand Down
2 changes: 1 addition & 1 deletion web/src/ui/i18n/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export type ComponentKey =
| import("ui/pages/dataExplorer/DataExplorer").I18n
| import("ui/pages/dataExplorer/UrlInput").I18n
| import("ui/shared/CommandBar").I18n
| import("ui/shared/useMoment").I18n
| import("ui/shared/formattedDate/useFormattedDate").I18n
| import("ui/shared/CopyToClipboardIconButton").I18n
| import("ui/shared/Datagrid/CustomDataGrid").I18n
| import("ui/shared/Datagrid/CustomDataGridToolbarDensitySelector").I18n
Expand Down
2 changes: 1 addition & 1 deletion web/src/ui/pages/account/AccountKubernetesTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useConstCallback } from "powerhooks/useConstCallback";
import { IconButton } from "onyxia-ui/IconButton";
import { CircularProgress } from "onyxia-ui/CircularProgress";
import { useCoreState, useCore } from "core";
import { useFromNow } from "ui/shared/useMoment";
import { useFromNow } from "ui/shared/formattedDate";
import { getIconUrlByName } from "lazy-icons";

const CodeBlock = lazy(() => import("ui/shared/CodeBlock"));
Expand Down
2 changes: 1 addition & 1 deletion web/src/ui/pages/account/AccountStorageTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { tss } from "tss";
import { assert } from "tsafe/assert";
import { saveAs } from "file-saver";
import { smartTrim } from "ui/tools/smartTrim";
import { useFromNow } from "ui/shared/useMoment";
import { useFromNow } from "ui/shared/formattedDate";
import { useCoreState, useCore } from "core";
import { declareComponentKeys } from "i18nifty";
import { useConstCallback } from "powerhooks/useConstCallback";
Expand Down
2 changes: 1 addition & 1 deletion web/src/ui/pages/account/AccountVaultTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { useConstCallback } from "powerhooks/useConstCallback";
import { IconButton } from "onyxia-ui/IconButton";
import { CircularProgress } from "onyxia-ui/CircularProgress";
import { useCoreState, useCore } from "core";
import { useFromNow } from "ui/shared/useMoment";
import { useFromNow } from "ui/shared/formattedDate";
import type { Link } from "type-route";
import { routes } from "ui/routes";
import { capitalize } from "tsafe/capitalize";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { SecretsExplorerButtonBar } from "./SecretsExplorerButtonBar";
import { DirectoryHeader } from "onyxia-ui/DirectoryHeader";
import { useDomRect } from "powerhooks/useDomRect";
import { ExplorerIcon } from "./ExplorerIcon";
import { getFormattedDate } from "ui/shared/useMoment";
import { getFormattedDate } from "ui/shared/formattedDate";
import { Dialog } from "onyxia-ui/Dialog";
import { useCallbackFactory } from "powerhooks/useCallbackFactory";
import { Deferred } from "evt/tools/Deferred";
Expand Down Expand Up @@ -297,14 +297,13 @@ export const SecretsExplorer = memo((props: ExplorerProps) => {
});

const { formattedDate } = (function useClosure() {
// NOTE: For enforcing refresh if lang is changed
useLang();
const { lang } = useLang();

const formattedDate = !props.isFileOpen ? undefined : props.openFileTime ===
undefined ? (
<>&nbsp;</>
) : (
getFormattedDate({ time: props.openFileTime })
getFormattedDate({ time: props.openFileTime, lang })
);

return { formattedDate };
Expand Down
2 changes: 1 addition & 1 deletion web/src/ui/pages/myServices/ClusterEventsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useEvt } from "evt/hooks";
import { Dialog } from "onyxia-ui/Dialog";
import { Button } from "onyxia-ui/Button";
import { useCoreState, useCore } from "core";
import { fromNow } from "ui/shared/useMoment";
import { fromNow } from "ui/shared/formattedDate";
import { tss } from "tss";
import { useWindowInnerSize } from "powerhooks/useWindowInnerSize";
import { assert } from "tsafe/assert";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { memo } from "react";
import { tss } from "tss";
import { Icon } from "onyxia-ui/Icon";
import { Text } from "onyxia-ui/Text";
import { useFromNow } from "ui/shared/useMoment";
import { useFromNow } from "ui/shared/formattedDate";
import { getIconUrlByName } from "lazy-icons";

export type Props = {
Expand Down
27 changes: 27 additions & 0 deletions web/src/ui/shared/formattedDate/getFormattedDate.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { describe, it, expect } from "vitest";
import { getFormattedDate } from "./getFormattedDate";

describe("getFormattedDate", () => {
it("formats date within the same year", () => {
const time = new Date(1732544444722).setMonth(5, 15);
const formattedDate = getFormattedDate({ time, lang: "en" });

expect(formattedDate).toBe("Saturday, June 15 at 3:20 PM");
});

it("formats date in a different year", () => {
const time = new Date(1732544444722).setFullYear(2023);
const formattedDate = getFormattedDate({ time, lang: "en" });

expect(formattedDate).toBe("Saturday, November 25, 2023 at 3:20 PM");
});

it("respects localization (fr)", () => {
const time = 1732544444722;

const formattedDate = getFormattedDate({ time, lang: "fr" });

// cspell: disable-next-line
expect(formattedDate).toBe("lundi 25 novembre à 15:20");
});
});
18 changes: 18 additions & 0 deletions web/src/ui/shared/formattedDate/getFormattedDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export function getFormattedDate(params: { time: number; lang: string }): string {
const { time, lang } = params;

const date = new Date(time);

const isSameYear = date.getFullYear() === new Date().getFullYear();

const formattedDate = new Intl.DateTimeFormat(lang, {
weekday: "long",
day: "numeric",
month: "long",
year: isSameYear ? undefined : "numeric",
hour: "numeric",
minute: "numeric"
}).format(date);

return formattedDate;
}
2 changes: 2 additions & 0 deletions web/src/ui/shared/formattedDate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { fromNow, useFormattedDate, useFromNow } from "./useFormattedDate";
export { getFormattedDate } from "./getFormattedDate";
Original file line number Diff line number Diff line change
@@ -1,47 +1,16 @@
import { useMemo, useEffect, useReducer } from "react";
import moment from "moment";
import { useLang, getTranslation, evtLang } from "ui/i18n";
import { useLang, getTranslation } from "ui/i18n";
import { assert } from "tsafe/assert";
import { declareComponentKeys } from "i18nifty";

export function getFormattedDate(params: { time: number }): string {
const { time } = params;

const date = new Date(time);

const isSameYear = date.getFullYear() === new Date().getFullYear();

const lang = evtLang.state;
const { t } = getTranslation("moment");

return moment(date).locale(lang).format(t("date format", { isSameYear }));
}
import { getFormattedDate } from "./getFormattedDate";

export function useFormattedDate(params: { time: number }): string {
const { time } = params;

// NOTE: So that we get a refresh when the lang is changed.
const { lang } = useLang();

return useMemo(() => getFormattedDate({ time }), [time, lang]);
}

export function useValidUntil(params: { millisecondsLeft: number }): string {
const { millisecondsLeft } = params;

const { lang } = useLang();

const validUntil = useMemo(
() =>
moment()
.locale(lang)
.add(millisecondsLeft, "milliseconds")
.calendar()
.toLowerCase(),
[lang, millisecondsLeft]
);

return validUntil;
return useMemo(() => getFormattedDate({ time, lang }), [time, lang]);
}

export const { fromNow } = (() => {
Expand All @@ -64,7 +33,7 @@ export const { fromNow } = (() => {
const YEAR = 365 * DAY;

function getUnits(): Unit[] {
const { t } = getTranslation("moment");
const { t } = getTranslation("formattedDate");

return divisorKeys.map(divisorKey => ({
divisor: (() => {
Expand Down Expand Up @@ -173,10 +142,6 @@ const divisorKeys = [
type DivisorKey = (typeof divisorKeys)[number];

const { i18n } = declareComponentKeys<
| {
K: "date format";
P: { isSameYear: boolean };
}
| {
K: "past1";
P: { divisorKey: DivisorKey };
Expand All @@ -193,5 +158,5 @@ const { i18n } = declareComponentKeys<
K: "futureN";
P: { divisorKey: DivisorKey };
}
>()("moment");
>()("formattedDate");
export type I18n = typeof i18n;
5 changes: 0 additions & 5 deletions web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5371,11 +5371,6 @@ minimist@^1.2.6:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==

moment@^2.30.1:
version "2.30.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==

ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
Expand Down
Loading