From 2cae0301ef5e2cdcf68646e12d97e35a9c196125 Mon Sep 17 00:00:00 2001 From: Michal Gasiorek Date: Tue, 20 Aug 2024 13:53:11 +0200 Subject: [PATCH 1/6] fix: lint warnings and errors --- src/components/Tooltip/Tooltip.tsx | 2 +- .../CalendarProvider/CalendarProvider.tsx | 4 +- src/context/LocaleProvider/LocaleProvider.tsx | 53 +++++++++++++------ 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index f7a7b32c..af9089f6 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -51,7 +51,7 @@ const Tooltip: FC = ({ tooltipData, zoom }) => { tooltipRef.current.style.top = `${coords.y + 8}px`; // disposition.overtime affects tooltip's width, thus it's needed to recalculate it's coords whenever overtime changes - }, [coords.x, width, disposition.overtime, coords.y]); + }, [coords.x, width, disposition.overtime, coords.y, zoom]); return ( diff --git a/src/context/CalendarProvider/CalendarProvider.tsx b/src/context/CalendarProvider/CalendarProvider.tsx index fc79cf68..7953af0b 100644 --- a/src/context/CalendarProvider/CalendarProvider.tsx +++ b/src/context/CalendarProvider/CalendarProvider.tsx @@ -122,13 +122,13 @@ const CalendarProvider = ({ }, 300); load(); }, - [onRangeChange, range] + [onRangeChange, range, zoom] ); useEffect(() => { outsideWrapper.current = document.getElementById(outsideWrapperId); setCols(getCols(zoom)); - }, []); + }, [zoom]); useEffect(() => { const handleResize = () => setCols(getCols(zoom)); diff --git a/src/context/LocaleProvider/LocaleProvider.tsx b/src/context/LocaleProvider/LocaleProvider.tsx index 0075b1dd..04cb9270 100644 --- a/src/context/LocaleProvider/LocaleProvider.tsx +++ b/src/context/LocaleProvider/LocaleProvider.tsx @@ -5,27 +5,46 @@ import { locales } from "./locales"; import { LocaleProviderProps } from "./types"; const LocaleProvider = ({ children, lang, translations }: LocaleProviderProps) => { - const [currentLocale, setCurrentLocale] = useState( - locales.getLocales().filter((locale) => locale.id === "en")[0] - ); + const [localLang, setLocalLang] = useState("en"); + const localesData = locales.getLocales(); - useEffect(() => { - const overwrittenLocalesData = locales.locales.map((locale) => { - let localeTemp = locale; - translations?.forEach((translation) => { - if (locale.id === translation.id) { - localeTemp = translation; - } - }); - return localeTemp; + const findLocale = useCallback(() => { + const locale = localesData.find((l) => { + return l.id === localLang; }); - const location = overwrittenLocalesData?.find((locale) => locale.id === lang); - if (location) { - setCurrentLocale(location); - dayjs.locale(location.dayjsTranslations); + if (typeof locale?.dayjsTranslations === "object") { + dayjs.locale(locale.dayjsTranslations); } - }, [translations, lang]); + + return locale || localesData[0]; + }, [localLang, localesData]); + + const [currentLocale, setCurrentLocale] = useState(findLocale()); + + const saveCurrentLocale = (locale: LocaleType) => { + localStorage.setItem("locale", locale.translateCode); + setCurrentLocale(locale); + }; + + useEffect(() => { + translations?.forEach((translation) => { + const localeData = localesData.find((el) => el.id === translation.id); + if (!localeData) { + locales.addLocales(translation); + } + }); + }, [localesData, translations]); + + useEffect(() => { + const localeId = localStorage.getItem("locale"); + const language = lang ?? localeId ?? "en"; + localStorage.setItem("locale", language); + setLocalLang(language); + setCurrentLocale(findLocale()); + }, [findLocale, lang]); + + const { Provider } = localeContext; return ( Date: Tue, 20 Aug 2024 13:58:21 +0200 Subject: [PATCH 2/6] docs: add hour view config to readme --- readme.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/readme.md b/readme.md index 68c49327..7686bc89 100644 --- a/readme.md +++ b/readme.md @@ -186,17 +186,19 @@ const mockedSchedulerData: SchedulerData = [ ##### Scheduler Config Object -| Property Name | Type | Default | Description | -| ------------------------------------ | --------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| zoom | `0` or `1` | 0 | `0` - display grid divided into weeks `1` - display grid divided into days | -| filterButtonState | `number` | 0 | `< 0` - hides filter button, `0` - state for when filters were not set, `> 0` - state for when some filters were set (allows to also handle `onClearFilterData` event) | -| maxRecordsPerPage | `number` | 50 | number of items from `SchedulerData` visible per page | -| lang | `en`, `lt`, `de`, `fr`, `it`, `pt-BR` or `pl` | en | scheduler's language | -| includeTakenHoursOnWeekendsInDayView | `boolean` | `false` | show weekends as taken when given resource is longer than a week | -| showTooltip | `boolean` | `true` | show tooltip when hovering over tiles | -| translations | `LocaleType[]` | `undefined` | option to add specific langs translations | -| showTooltip | `boolean` | `true` | show tooltip when hovering over tiles | -| translations | `LocaleType[]` | `undefined` | option to add specific langs translations | +--- + +| Property Name | Type | Default | Description | +| ------------------------------------ | ------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| zoom | `0` or `1` or `2` | 0 | `0` - display grid divided into weeks `1` - display grid divided into days `2` - display grid divided into hours | +| filterButtonState | `number` | 0 | `< 0` - hides filter button, `0` - state for when filters were not set, `> 0` - state for when some filters were set (allows to also handle `onClearFilterData` event) | +| maxRecordsPerPage | `number` | 50 | number of items from `SchedulerData` visible per page | +| lang | `en`, `lt` or `pl` | en | scheduler's language | +| includeTakenHoursOnWeekendsInDayView | `boolean` | `false` | show weekends as taken when given resource is longer than a week | +| showTooltip | `boolean` | `true` | show tooltip when hovering over tiles | +| translations | `LocaleType[]` | `undefined` | option to add specific langs translations | +| showThemeToggle | `boolean` | `false` | show toggle button to switch between light/dark mode | +| defaultTheme | `light` or `dark` | `light` | scheduler's default theme | #### Translation object example From 2f1cb1208a83d96da3db055f3cf680043e85c4d7 Mon Sep 17 00:00:00 2001 From: Piotr Baranek Date: Fri, 23 Aug 2024 11:48:15 +0200 Subject: [PATCH 3/6] 0.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 72b22c78..abf1ade0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bitnoi.se/react-scheduler", - "version": "0.2.1", + "version": "0.3.0", "type": "module", "license": "MIT", "repository": { From c9752c49461e7faecf8a5c00a24fa4748427a210 Mon Sep 17 00:00:00 2001 From: Mark Grinberg Date: Sat, 24 Aug 2024 04:41:50 -0400 Subject: [PATCH 4/6] feat: i18n - hebrew, romanian, spanish --- src/context/LocaleProvider/locales.ts | 29 ++++++++++++++++++++++++++- src/locales/es.ts | 17 ++++++++++++++++ src/locales/he.ts | 17 ++++++++++++++++ src/locales/index.ts | 3 +++ src/locales/ro.ts | 17 ++++++++++++++++ src/types/global.ts | 4 ++-- 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 src/locales/es.ts create mode 100644 src/locales/he.ts create mode 100644 src/locales/ro.ts diff --git a/src/context/LocaleProvider/locales.ts b/src/context/LocaleProvider/locales.ts index d9331792..fb2ddd3d 100644 --- a/src/context/LocaleProvider/locales.ts +++ b/src/context/LocaleProvider/locales.ts @@ -5,7 +5,10 @@ import ltDayjsTranslations from "dayjs/locale/lt"; import frDayjsTranslations from "dayjs/locale/fr"; import itDayjsTranslations from "dayjs/locale/it"; import ptBRDayjsTranslations from "dayjs/locale/pt-br"; -import { en, pl, de, lt, fr, it, ptBR } from "@/locales"; +import { roDayjsTranslations } from "dayjs/locale/ro"; +import { heDayjsTranslations } from "dayjs/locale/he"; +import { esDayjsTranslations } from "dayjs/locale/es"; +import { en, pl, de, lt, fr, it, ptBR, es, he, ro } from "@/locales"; import { LocaleType } from "./types"; export const localesData: LocaleType[] = [ @@ -39,6 +42,30 @@ export const localesData: LocaleType[] = [ translateCode: "lt-LT", dayjsTranslations: ltDayjsTranslations }, + { + id: "de", + lang: de, + translateCode: "de-DE", + dayjsTranslations: deDayjsTranslations + }, + { + id: "es", + lang: es, + translateCode: "es-ES", + dayjsTranslations: esDayjsTranslations + }, + { + id: "he", + lang: he, + translateCode: "he_IL", + dayjsTranslations: heDayjsTranslations + }, + { + id: "ro", + lang: ro, + translateCode: "ro_RO", + dayjsTranslations: roDayjsTranslations + }, { id: "pl", lang: pl, diff --git a/src/locales/es.ts b/src/locales/es.ts new file mode 100644 index 00000000..b947f350 --- /dev/null +++ b/src/locales/es.ts @@ -0,0 +1,17 @@ +export const es = { + feelingEmpty: "Me siento vacío...", + free: "Libre", + loadNext: "Siguiente", + loadPrevious: "Anterior", + over: "Finalizado", + taken: "Reservado", + topbar: { + filters: "Filtros", + next: "Siguiente", + prev: "Anterior", + today: "Hoy", + view: "Vista" + }, + search: "Buscar", + week: "Semana" +}; diff --git a/src/locales/he.ts b/src/locales/he.ts new file mode 100644 index 00000000..d2f7f6a7 --- /dev/null +++ b/src/locales/he.ts @@ -0,0 +1,17 @@ +export const he = { + feelingEmpty: "אני מרגיש ריק...", + free: "חופשי", + loadNext: "הבא", + loadPrevious: "הקודם", + over: "מסתיים", + taken: "תפוס", + topbar: { + filters: "מסננים", + next: "הבא", + prev: "הקודם", + today: "היום", + view: "תצוגה" + }, + search: "חיפוש", + week: "שבוע" +}; diff --git a/src/locales/index.ts b/src/locales/index.ts index d1d62c23..af263b63 100644 --- a/src/locales/index.ts +++ b/src/locales/index.ts @@ -5,3 +5,6 @@ export { lt } from "./lt"; export { fr } from "./fr"; export { it } from "./it"; export { ptBR } from "./ptBR"; +export { he } from "./he"; +export { ro } from "./ro"; +export { es } from "./es"; diff --git a/src/locales/ro.ts b/src/locales/ro.ts new file mode 100644 index 00000000..a4c11044 --- /dev/null +++ b/src/locales/ro.ts @@ -0,0 +1,17 @@ +export const ro = { + feelingEmpty: "Mă simt gol...", + free: "Liber", + loadNext: "Următorul", + loadPrevious: "Anterior", + over: "Finalizat", + taken: "Ocupat", + topbar: { + filters: "Filtre", + next: "Următorul", + prev: "Anterior", + today: "Astăzi", + view: "Vizualizare" + }, + search: "Căutare", + week: "Săptămână" +}; diff --git a/src/types/global.ts b/src/types/global.ts index 634f2ae7..e5cf8ebf 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -9,7 +9,7 @@ type ZoomLevelTuple = typeof allZoomLevel; export type ZoomLevel = ZoomLevelTuple[number]; -export type LangCodes = "en" | "pl" | "de" | "lt" | "fr" | "it" | "pt-BR"; +export type LangCodes = "en" | "pl" | "de" | "lt" | "fr" | "it" | "pt-BR" | "he" | "es" | "ro"; export type Config = { zoom: ZoomLevel; @@ -21,7 +21,7 @@ export type Config = { */ filterButtonState?: number; /** - * Language code: "en" | "pl" | "de" | "lt" | "fr" | "it" | "pt-BR" + * Language code: "en" | "pl" | "de" | "lt" | "fr" | "it" | "pt-BR" | "he" | "es" | "ro" */ lang?: LangCodes | string; isFiltersButtonVisible?: boolean; From 4029981841bc589bb2e8484ba6aa4422231c9572 Mon Sep 17 00:00:00 2001 From: Mark Grinberg Date: Sat, 24 Aug 2024 05:07:33 -0400 Subject: [PATCH 5/6] Bugfixes --- src/context/LocaleProvider/LocaleProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/context/LocaleProvider/LocaleProvider.tsx b/src/context/LocaleProvider/LocaleProvider.tsx index 04cb9270..c9a71e49 100644 --- a/src/context/LocaleProvider/LocaleProvider.tsx +++ b/src/context/LocaleProvider/LocaleProvider.tsx @@ -1,4 +1,4 @@ -import { useContext, useEffect, useState } from "react"; +import { useCallback, useContext, useEffect, useState } from "react"; import dayjs from "dayjs"; import { localeContext } from "./localeContext"; import { locales } from "./locales"; From beefbf13935ebd1193a0a685fd28998e23ff9a90 Mon Sep 17 00:00:00 2001 From: Mark Grinberg Date: Sat, 24 Aug 2024 05:20:39 -0400 Subject: [PATCH 6/6] Linting and Bugfixes --- src/context/LocaleProvider/LocaleProvider.tsx | 55 ++++++------------- src/context/LocaleProvider/locales.ts | 6 +- 2 files changed, 21 insertions(+), 40 deletions(-) diff --git a/src/context/LocaleProvider/LocaleProvider.tsx b/src/context/LocaleProvider/LocaleProvider.tsx index c9a71e49..0075b1dd 100644 --- a/src/context/LocaleProvider/LocaleProvider.tsx +++ b/src/context/LocaleProvider/LocaleProvider.tsx @@ -1,50 +1,31 @@ -import { useCallback, useContext, useEffect, useState } from "react"; +import { useContext, useEffect, useState } from "react"; import dayjs from "dayjs"; import { localeContext } from "./localeContext"; import { locales } from "./locales"; import { LocaleProviderProps } from "./types"; const LocaleProvider = ({ children, lang, translations }: LocaleProviderProps) => { - const [localLang, setLocalLang] = useState("en"); - const localesData = locales.getLocales(); - - const findLocale = useCallback(() => { - const locale = localesData.find((l) => { - return l.id === localLang; - }); - - if (typeof locale?.dayjsTranslations === "object") { - dayjs.locale(locale.dayjsTranslations); - } - - return locale || localesData[0]; - }, [localLang, localesData]); - - const [currentLocale, setCurrentLocale] = useState(findLocale()); - - const saveCurrentLocale = (locale: LocaleType) => { - localStorage.setItem("locale", locale.translateCode); - setCurrentLocale(locale); - }; + const [currentLocale, setCurrentLocale] = useState( + locales.getLocales().filter((locale) => locale.id === "en")[0] + ); useEffect(() => { - translations?.forEach((translation) => { - const localeData = localesData.find((el) => el.id === translation.id); - if (!localeData) { - locales.addLocales(translation); - } + const overwrittenLocalesData = locales.locales.map((locale) => { + let localeTemp = locale; + translations?.forEach((translation) => { + if (locale.id === translation.id) { + localeTemp = translation; + } + }); + return localeTemp; }); - }, [localesData, translations]); - useEffect(() => { - const localeId = localStorage.getItem("locale"); - const language = lang ?? localeId ?? "en"; - localStorage.setItem("locale", language); - setLocalLang(language); - setCurrentLocale(findLocale()); - }, [findLocale, lang]); - - const { Provider } = localeContext; + const location = overwrittenLocalesData?.find((locale) => locale.id === lang); + if (location) { + setCurrentLocale(location); + dayjs.locale(location.dayjsTranslations); + } + }, [translations, lang]); return (