From 9a0a51d57f7da2d99b4f2a2986762b97670f1f33 Mon Sep 17 00:00:00 2001 From: rfgvieira Date: Fri, 28 Jun 2024 11:53:51 -0300 Subject: [PATCH] feat: add intl to project Closes #17 --- dashboard/package.json | 6 +- dashboard/pnpm-lock.yaml | 133 ++++++++++++++++++ .../src/components/SideMenu/SideMenu.tsx | 22 +-- dashboard/src/locales/constants.ts | 4 + dashboard/src/locales/messages/index.ts | 12 ++ dashboard/src/main.tsx | 13 +- 6 files changed, 177 insertions(+), 13 deletions(-) create mode 100644 dashboard/src/locales/constants.ts create mode 100644 dashboard/src/locales/messages/index.ts diff --git a/dashboard/package.json b/dashboard/package.json index 1d9bdf7..9ee8a92 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -24,16 +24,18 @@ "@radix-ui/react-navigation-menu": "^1.2.0", "@radix-ui/react-separator": "^1.1.0", "@tanstack/react-query": "^5.45.1", + "@vitejs/plugin-react": "^4.3.1", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "flat": "^6.0.1", "lucide-react": "^0.396.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-icons": "^5.2.1", + "react-intl": "^6.6.8", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", - "vite": "^5.3.1", - "@vitejs/plugin-react": "^4.3.1" + "vite": "^5.3.1" }, "devDependencies": { "@chromatic-com/storybook": "^1.5.0", diff --git a/dashboard/pnpm-lock.yaml b/dashboard/pnpm-lock.yaml index 4a46dcd..3f15099 100644 --- a/dashboard/pnpm-lock.yaml +++ b/dashboard/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: clsx: specifier: ^2.1.1 version: 2.1.1 + flat: + specifier: ^6.0.1 + version: 6.0.1 lucide-react: specifier: ^0.396.0 version: 0.396.0(react@18.3.1) @@ -56,6 +59,9 @@ importers: react-icons: specifier: ^5.2.1 version: 5.2.1(react@18.3.1) + react-intl: + specifier: ^6.6.8 + version: 6.6.8(react@18.3.1)(typescript@5.2.2) tailwind-merge: specifier: ^2.3.0 version: 2.3.0 @@ -1179,6 +1185,35 @@ packages: '@floating-ui/utils@0.2.2': resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==} + '@formatjs/ecma402-abstract@2.0.0': + resolution: {integrity: sha512-rRqXOqdFmk7RYvj4khklyqzcfQl9vEL/usogncBHRZfZBDOwMGuSRNFl02fu5KGHXdbinju+YXyuR+Nk8xlr/g==} + + '@formatjs/fast-memoize@2.2.0': + resolution: {integrity: sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==} + + '@formatjs/icu-messageformat-parser@2.7.8': + resolution: {integrity: sha512-nBZJYmhpcSX0WeJ5SDYUkZ42AgR3xiyhNCsQweFx3cz/ULJjym8bHAzWKvG5e2+1XO98dBYC0fWeeAECAVSwLA==} + + '@formatjs/icu-skeleton-parser@1.8.2': + resolution: {integrity: sha512-k4ERKgw7aKGWJZgTarIcNEmvyTVD9FYh0mTrrBMHZ1b8hUu6iOJ4SzsZlo3UNAvHYa+PnvntIwRPt1/vy4nA9Q==} + + '@formatjs/intl-displaynames@6.6.8': + resolution: {integrity: sha512-Lgx6n5KxN16B3Pb05z3NLEBQkGoXnGjkTBNCZI+Cn17YjHJ3fhCeEJJUqRlIZmJdmaXQhjcQVDp6WIiNeRYT5g==} + + '@formatjs/intl-listformat@7.5.7': + resolution: {integrity: sha512-MG2TSChQJQT9f7Rlv+eXwUFiG24mKSzmF144PLb8m8OixyXqn4+YWU+5wZracZGCgVTVmx8viCf7IH3QXoiB2g==} + + '@formatjs/intl-localematcher@0.5.4': + resolution: {integrity: sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==} + + '@formatjs/intl@2.10.4': + resolution: {integrity: sha512-56483O+HVcL0c7VucAS2tyH020mt9XTozZO67cwtGg0a7KWDukS/FzW3OnvaHmTHDuYsoPIzO+ZHVfU6fT/bJw==} + peerDependencies: + typescript: ^4.7 || 5 + peerDependenciesMeta: + typescript: + optional: true + '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -2119,6 +2154,9 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/hoist-non-react-statics@3.3.5': + resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} + '@types/http-errors@2.0.4': resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} @@ -3245,6 +3283,11 @@ packages: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} + flat@6.0.1: + resolution: {integrity: sha512-/3FfIa8mbrg3xE7+wAhWeV+bd7L2Mof+xtZb5dRDKZ+wDvYJK4WDYeIOuOhre5Yv5aQObZrlbRmk3RTSiuQBtw==} + engines: {node: '>=18'} + hasBin: true + flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} @@ -3509,6 +3552,9 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} + intl-messageformat@10.5.14: + resolution: {integrity: sha512-IjC6sI0X7YRjjyVH9aUgdftcmZK7WXdHeil4KwbjDnRWjnVitKpAx3rr6t6di1joFp5188VqKcobOPA6mCLG/w==} + invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} @@ -4384,6 +4430,15 @@ packages: peerDependencies: react: '*' + react-intl@6.6.8: + resolution: {integrity: sha512-M0pkhzcgV31h++2901BiRXWl69hp2zPyLxRrSwRjd1ErXbNoubz/f4M6DrRTd4OiSUrT4ajRQzrmtS5plG4FtA==} + peerDependencies: + react: ^16.6.0 || 17 || 18 + typescript: ^4.7 || 5 + peerDependenciesMeta: + typescript: + optional: true + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -6304,6 +6359,54 @@ snapshots: '@floating-ui/utils@0.2.2': {} + '@formatjs/ecma402-abstract@2.0.0': + dependencies: + '@formatjs/intl-localematcher': 0.5.4 + tslib: 2.6.3 + + '@formatjs/fast-memoize@2.2.0': + dependencies: + tslib: 2.6.3 + + '@formatjs/icu-messageformat-parser@2.7.8': + dependencies: + '@formatjs/ecma402-abstract': 2.0.0 + '@formatjs/icu-skeleton-parser': 1.8.2 + tslib: 2.6.3 + + '@formatjs/icu-skeleton-parser@1.8.2': + dependencies: + '@formatjs/ecma402-abstract': 2.0.0 + tslib: 2.6.3 + + '@formatjs/intl-displaynames@6.6.8': + dependencies: + '@formatjs/ecma402-abstract': 2.0.0 + '@formatjs/intl-localematcher': 0.5.4 + tslib: 2.6.3 + + '@formatjs/intl-listformat@7.5.7': + dependencies: + '@formatjs/ecma402-abstract': 2.0.0 + '@formatjs/intl-localematcher': 0.5.4 + tslib: 2.6.3 + + '@formatjs/intl-localematcher@0.5.4': + dependencies: + tslib: 2.6.3 + + '@formatjs/intl@2.10.4(typescript@5.2.2)': + dependencies: + '@formatjs/ecma402-abstract': 2.0.0 + '@formatjs/fast-memoize': 2.2.0 + '@formatjs/icu-messageformat-parser': 2.7.8 + '@formatjs/intl-displaynames': 6.6.8 + '@formatjs/intl-listformat': 7.5.7 + intl-messageformat: 10.5.14 + tslib: 2.6.3 + optionalDependencies: + typescript: 5.2.2 + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -7646,6 +7749,11 @@ snapshots: dependencies: '@types/unist': 3.0.2 + '@types/hoist-non-react-statics@3.3.5': + dependencies: + '@types/react': 18.3.3 + hoist-non-react-statics: 3.3.2 + '@types/http-errors@2.0.4': {} '@types/json-schema@7.0.15': {} @@ -9099,6 +9207,8 @@ snapshots: keyv: 4.5.4 rimraf: 3.0.2 + flat@6.0.1: {} + flatted@3.3.1: {} flow-parser@0.238.0: {} @@ -9367,6 +9477,13 @@ snapshots: internmap@2.0.3: {} + intl-messageformat@10.5.14: + dependencies: + '@formatjs/ecma402-abstract': 2.0.0 + '@formatjs/fast-memoize': 2.2.0 + '@formatjs/icu-messageformat-parser': 2.7.8 + tslib: 2.6.3 + invariant@2.2.4: dependencies: loose-envify: 1.4.0 @@ -10180,6 +10297,22 @@ snapshots: dependencies: react: 18.3.1 + react-intl@6.6.8(react@18.3.1)(typescript@5.2.2): + dependencies: + '@formatjs/ecma402-abstract': 2.0.0 + '@formatjs/icu-messageformat-parser': 2.7.8 + '@formatjs/intl': 2.10.4(typescript@5.2.2) + '@formatjs/intl-displaynames': 6.6.8 + '@formatjs/intl-listformat': 7.5.7 + '@types/hoist-non-react-statics': 3.3.5 + '@types/react': 18.3.3 + hoist-non-react-statics: 3.3.2 + intl-messageformat: 10.5.14 + react: 18.3.1 + tslib: 2.6.3 + optionalDependencies: + typescript: 5.2.2 + react-is@16.13.1: {} react-is@17.0.2: {} diff --git a/dashboard/src/components/SideMenu/SideMenu.tsx b/dashboard/src/components/SideMenu/SideMenu.tsx index afdd1b8..7769167 100644 --- a/dashboard/src/components/SideMenu/SideMenu.tsx +++ b/dashboard/src/components/SideMenu/SideMenu.tsx @@ -2,6 +2,8 @@ import { MdOutlineMonitorHeart, MdOutlineDashboard } from "react-icons/md"; import { ImTree, ImImages } from "react-icons/im"; +import { FormattedMessage } from "react-intl"; + import { NavigationMenu, NavigationMenuItem, @@ -13,7 +15,7 @@ import { Separator } from "../ui/separator"; type MenuItems = { onClick: () => void; - text: string; + idIntl: string; icon: JSX.Element; selected: boolean; }; @@ -23,25 +25,25 @@ const emptyFunc = () : void => {} const items: MenuItems[] = [ { onClick: emptyFunc, - text: "Dashboard", + idIntl: "lateralMenu.dashboard", icon: , selected: false, }, { onClick: emptyFunc, - text: "Tree Monitor", + idIntl: "lateralMenu.treeMonitor", icon: , selected: true, }, { onClick: emptyFunc, - text: "Device Monitor", + idIntl: "lateralMenu.deviceMonitor", icon: , selected: false, }, { onClick: emptyFunc, - text: "Labs Monitor", + idIntl: "lateralMenu.labsMonitor", icon: , selected: false, }, @@ -49,12 +51,12 @@ const items: MenuItems[] = [ const NavLink = ({ icon, - text, -}: Pick): JSX.Element => ( + idIntl, +}: Pick): JSX.Element => ( {icon} - {text} + ); @@ -79,9 +81,9 @@ const SideMenu = (): JSX.Element => { - + )} diff --git a/dashboard/src/locales/constants.ts b/dashboard/src/locales/constants.ts new file mode 100644 index 0000000..37633c6 --- /dev/null +++ b/dashboard/src/locales/constants.ts @@ -0,0 +1,4 @@ +export const LOCALES = { + EN_US: 'en-us', + }; + \ No newline at end of file diff --git a/dashboard/src/locales/messages/index.ts b/dashboard/src/locales/messages/index.ts new file mode 100644 index 0000000..7846d13 --- /dev/null +++ b/dashboard/src/locales/messages/index.ts @@ -0,0 +1,12 @@ +import {LOCALES} from '../constants' + +export const messages = { + [LOCALES.EN_US]: { + lateralMenu: { + dashboard: "Dashboard", + treeMonitor: "Tree Monitor", + deviceMonitor: "Device Monitor", + labsMonitor: "Labs Monitor", + }, + }, +}; diff --git a/dashboard/src/main.tsx b/dashboard/src/main.tsx index 8fc9e8d..1756a3e 100644 --- a/dashboard/src/main.tsx +++ b/dashboard/src/main.tsx @@ -1,12 +1,23 @@ import React from 'react' import ReactDOM from 'react-dom/client' +import {IntlProvider} from "react-intl"; + +import {flatten} from 'flat'; + +import {messages} from './locales/messages/index' +import {LOCALES} from './locales/constants' + + import './index.css' import App from './App' ReactDOM.createRoot(document.getElementById('root')!).render( - + + + + , )