From 551a60cfaacf106d302062af711568edb2a8d0ca Mon Sep 17 00:00:00 2001 From: Yoann Fievez Date: Mon, 18 Nov 2024 16:39:15 +0100 Subject: [PATCH] feat(pci-quota): initialize react app ref: DTCORE-2865 Signed-off-by: Yoann Fievez --- packages/manager/apps/pci-quota/README.md | 1 + packages/manager/apps/pci-quota/index.html | 12 +++ packages/manager/apps/pci-quota/package.json | 74 +++++++++++++++ .../manager/apps/pci-quota/postcss.config.cjs | 6 ++ .../translations/common/Messages_de_DE.json | 1 + .../translations/common/Messages_en_GB.json | 1 + .../translations/common/Messages_es_ES.json | 1 + .../translations/common/Messages_fr_CA.json | 1 + .../translations/common/Messages_fr_FR.json | 1 + .../translations/common/Messages_it_IT.json | 1 + .../translations/common/Messages_pl_PL.json | 1 + .../translations/common/Messages_pt_PT.json | 1 + packages/manager/apps/pci-quota/src/App.tsx | 23 +++++ .../src/components/common.module.css | 28 ++++++ .../manager/apps/pci-quota/src/constants.ts | 18 ++++ .../apps/pci-quota/src/core/HidePreloader.tsx | 12 +++ .../pci-quota/src/core/ShellRoutingSync.tsx | 16 ++++ .../pci-quota/src/hooks/usePageTracking.ts | 33 +++++++ packages/manager/apps/pci-quota/src/index.css | 3 + packages/manager/apps/pci-quota/src/layout.ts | 7 ++ packages/manager/apps/pci-quota/src/main.tsx | 43 +++++++++ .../apps/pci-quota/src/pages/Layout.tsx | 55 +++++++++++ .../manager/apps/pci-quota/src/queryClient.ts | 11 +++ .../manager/apps/pci-quota/src/routes.tsx | 18 ++++ .../apps/pci-quota/src/sampleTest.spec.ts | 5 + .../manager/apps/pci-quota/src/setupTests.tsx | 86 +++++++++++++++++ .../apps/pci-quota/src/tracking.constants.ts | 2 + .../manager/apps/pci-quota/src/vite-env.d.ts | 1 + .../manager/apps/pci-quota/src/vite-hmr.ts | 5 + .../manager/apps/pci-quota/tailwind.config.js | 13 +++ .../apps/pci-quota/tsconfig.build.json | 4 + packages/manager/apps/pci-quota/tsconfig.json | 27 ++++++ .../manager/apps/pci-quota/vite.config.ts | 18 ++++ .../manager/apps/pci-quota/vitest.config.js | 35 +++++++ yarn.lock | 94 +++++++++++++------ 35 files changed, 627 insertions(+), 31 deletions(-) create mode 100644 packages/manager/apps/pci-quota/README.md create mode 100644 packages/manager/apps/pci-quota/index.html create mode 100644 packages/manager/apps/pci-quota/package.json create mode 100644 packages/manager/apps/pci-quota/postcss.config.cjs create mode 100644 packages/manager/apps/pci-quota/public/translations/common/Messages_de_DE.json create mode 100644 packages/manager/apps/pci-quota/public/translations/common/Messages_en_GB.json create mode 100644 packages/manager/apps/pci-quota/public/translations/common/Messages_es_ES.json create mode 100644 packages/manager/apps/pci-quota/public/translations/common/Messages_fr_CA.json create mode 100644 packages/manager/apps/pci-quota/public/translations/common/Messages_fr_FR.json create mode 100644 packages/manager/apps/pci-quota/public/translations/common/Messages_it_IT.json create mode 100644 packages/manager/apps/pci-quota/public/translations/common/Messages_pl_PL.json create mode 100644 packages/manager/apps/pci-quota/public/translations/common/Messages_pt_PT.json create mode 100644 packages/manager/apps/pci-quota/src/App.tsx create mode 100644 packages/manager/apps/pci-quota/src/components/common.module.css create mode 100644 packages/manager/apps/pci-quota/src/constants.ts create mode 100644 packages/manager/apps/pci-quota/src/core/HidePreloader.tsx create mode 100644 packages/manager/apps/pci-quota/src/core/ShellRoutingSync.tsx create mode 100644 packages/manager/apps/pci-quota/src/hooks/usePageTracking.ts create mode 100644 packages/manager/apps/pci-quota/src/index.css create mode 100644 packages/manager/apps/pci-quota/src/layout.ts create mode 100644 packages/manager/apps/pci-quota/src/main.tsx create mode 100644 packages/manager/apps/pci-quota/src/pages/Layout.tsx create mode 100644 packages/manager/apps/pci-quota/src/queryClient.ts create mode 100644 packages/manager/apps/pci-quota/src/routes.tsx create mode 100644 packages/manager/apps/pci-quota/src/sampleTest.spec.ts create mode 100644 packages/manager/apps/pci-quota/src/setupTests.tsx create mode 100644 packages/manager/apps/pci-quota/src/tracking.constants.ts create mode 100644 packages/manager/apps/pci-quota/src/vite-env.d.ts create mode 100644 packages/manager/apps/pci-quota/src/vite-hmr.ts create mode 100644 packages/manager/apps/pci-quota/tailwind.config.js create mode 100644 packages/manager/apps/pci-quota/tsconfig.build.json create mode 100644 packages/manager/apps/pci-quota/tsconfig.json create mode 100644 packages/manager/apps/pci-quota/vite.config.ts create mode 100644 packages/manager/apps/pci-quota/vitest.config.js diff --git a/packages/manager/apps/pci-quota/README.md b/packages/manager/apps/pci-quota/README.md new file mode 100644 index 000000000000..e560e1bd6dd2 --- /dev/null +++ b/packages/manager/apps/pci-quota/README.md @@ -0,0 +1 @@ +# PCI Quota and Regions diff --git a/packages/manager/apps/pci-quota/index.html b/packages/manager/apps/pci-quota/index.html new file mode 100644 index 000000000000..fedc5e25f607 --- /dev/null +++ b/packages/manager/apps/pci-quota/index.html @@ -0,0 +1,12 @@ + + + + + + OVHcloud + + +
+ + + diff --git a/packages/manager/apps/pci-quota/package.json b/packages/manager/apps/pci-quota/package.json new file mode 100644 index 000000000000..7c17746eb6e0 --- /dev/null +++ b/packages/manager/apps/pci-quota/package.json @@ -0,0 +1,74 @@ +{ + "name": "@ovh-ux/manager-pci-quota-app", + "version": "0.0.0", + "private": true, + "description": "PCI Quota and Regions react app", + "type": "module", + "scripts": { + "build": "tsc --project tsconfig.build.json && vite build", + "coverage": "vitest run --coverage", + "dev": "vite", + "lint": "eslint ./src", + "start": "lerna exec --stream --scope='@ovh-ux/manager-pci-quota-app' --include-dependencies -- npm run build --if-present", + "start:dev": "lerna exec --stream --scope='@ovh-ux/manager-pci-quota-app' --include-dependencies -- npm run dev --if-present", + "start:watch": "lerna exec --stream --parallel --scope='@ovh-ux/manager-pci-quota-app' --include-dependencies -- npm run dev:watch --if-present", + "test": "vitest run" + }, + "dependencies": { + "@ovh-ux/manager-config": "^8.0.0", + "@ovh-ux/manager-core-api": "^0.9.0", + "@ovh-ux/manager-pci-common": "^0.8.1", + "@ovh-ux/manager-react-components": "^1.41.2", + "@ovh-ux/manager-react-core-application": "^0.11.1", + "@ovh-ux/manager-react-shell-client": "^0.8.1", + "@ovh-ux/manager-tailwind-config": "^0.2.0", + "@ovh-ux/shell": "^4.0.1", + "@ovhcloud/ods-common-core": "17.2.2", + "@ovhcloud/ods-common-stencil": "17.2.2", + "@ovhcloud/ods-common-theming": "17.2.2", + "@ovhcloud/ods-components": "17.2.2", + "@ovhcloud/ods-theme-blue-jeans": "17.2.2", + "@tanstack/react-query": "^5.51.21", + "@tanstack/react-table": "^8.20.1", + "element-internals-polyfill": "^1.3.12", + "i18next": "^23.8.2", + "i18next-http-backend": "^2.5.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-hook-form": "^7.52.1", + "react-i18next": "^14.0.5", + "react-router-dom": "^6.24.1", + "react-use": "^17.5.0", + "zustand": "^4.5.5" + }, + "devDependencies": { + "@jest/globals": "^29.7.0", + "@ovh-ux/manager-vite-config": "^0.8.2", + "@tanstack/react-query-devtools": "^5.50.1", + "@testing-library/dom": "^10.1.0", + "@testing-library/jest-dom": "^6.4.5", + "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.5.2", + "@types/jest": "^29.5.12", + "@types/react": "^18.2.79", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.0", + "@vitest/coverage-v8": "^1.6.0", + "autoprefixer": "^10.4.19", + "eslint": "^8.57.0", + "postcss": "^8.4.38", + "rollup": "^4.18.0", + "tailwindcss": "^3.4.4", + "typescript": "^5.4.5", + "vite": "^5.3.3", + "vitest": "^1.6.0" + }, + "regions": [ + "CA", + "EU", + "US" + ], + "universes": [ + "@ovh-ux/manager-public-cloud" + ] +} diff --git a/packages/manager/apps/pci-quota/postcss.config.cjs b/packages/manager/apps/pci-quota/postcss.config.cjs new file mode 100644 index 000000000000..12a703d900da --- /dev/null +++ b/packages/manager/apps/pci-quota/postcss.config.cjs @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/packages/manager/apps/pci-quota/public/translations/common/Messages_de_DE.json b/packages/manager/apps/pci-quota/public/translations/common/Messages_de_DE.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/packages/manager/apps/pci-quota/public/translations/common/Messages_de_DE.json @@ -0,0 +1 @@ +{} diff --git a/packages/manager/apps/pci-quota/public/translations/common/Messages_en_GB.json b/packages/manager/apps/pci-quota/public/translations/common/Messages_en_GB.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/packages/manager/apps/pci-quota/public/translations/common/Messages_en_GB.json @@ -0,0 +1 @@ +{} diff --git a/packages/manager/apps/pci-quota/public/translations/common/Messages_es_ES.json b/packages/manager/apps/pci-quota/public/translations/common/Messages_es_ES.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/packages/manager/apps/pci-quota/public/translations/common/Messages_es_ES.json @@ -0,0 +1 @@ +{} diff --git a/packages/manager/apps/pci-quota/public/translations/common/Messages_fr_CA.json b/packages/manager/apps/pci-quota/public/translations/common/Messages_fr_CA.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/packages/manager/apps/pci-quota/public/translations/common/Messages_fr_CA.json @@ -0,0 +1 @@ +{} diff --git a/packages/manager/apps/pci-quota/public/translations/common/Messages_fr_FR.json b/packages/manager/apps/pci-quota/public/translations/common/Messages_fr_FR.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/packages/manager/apps/pci-quota/public/translations/common/Messages_fr_FR.json @@ -0,0 +1 @@ +{} diff --git a/packages/manager/apps/pci-quota/public/translations/common/Messages_it_IT.json b/packages/manager/apps/pci-quota/public/translations/common/Messages_it_IT.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/packages/manager/apps/pci-quota/public/translations/common/Messages_it_IT.json @@ -0,0 +1 @@ +{} diff --git a/packages/manager/apps/pci-quota/public/translations/common/Messages_pl_PL.json b/packages/manager/apps/pci-quota/public/translations/common/Messages_pl_PL.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/packages/manager/apps/pci-quota/public/translations/common/Messages_pl_PL.json @@ -0,0 +1 @@ +{} diff --git a/packages/manager/apps/pci-quota/public/translations/common/Messages_pt_PT.json b/packages/manager/apps/pci-quota/public/translations/common/Messages_pt_PT.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/packages/manager/apps/pci-quota/public/translations/common/Messages_pt_PT.json @@ -0,0 +1 @@ +{} diff --git a/packages/manager/apps/pci-quota/src/App.tsx b/packages/manager/apps/pci-quota/src/App.tsx new file mode 100644 index 000000000000..8476dd670edb --- /dev/null +++ b/packages/manager/apps/pci-quota/src/App.tsx @@ -0,0 +1,23 @@ +import { odsSetup } from '@ovhcloud/ods-common-core'; +import { QueryClientProvider } from '@tanstack/react-query'; +import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; +import { HashRouter } from 'react-router-dom'; +import RoutesComponent from '@/routes'; +import queryClient from './queryClient'; + +import '@ovhcloud/ods-theme-blue-jeans'; + +odsSetup(); + +function App() { + return ( + + + + + + + ); +} + +export default App; diff --git a/packages/manager/apps/pci-quota/src/components/common.module.css b/packages/manager/apps/pci-quota/src/components/common.module.css new file mode 100644 index 000000000000..8c4aceade79c --- /dev/null +++ b/packages/manager/apps/pci-quota/src/components/common.module.css @@ -0,0 +1,28 @@ +.linkContainer a { + font-family: 'Source Sans Pro', sans-serif; + font-weight: 600; + color: rgb(0, 80, 215); + transition: background-size 0.2s ease-in 0s, color 0.1s ease-in-out 0s; + background-position: 0 100%; + background-repeat: no-repeat; + background-size: 0 2px; + background-image: linear-gradient(currentcolor, currentcolor); + outline: none; + cursor: pointer; + text-decoration: none; + user-select: auto; +} + +.linkContainer a:hover { + transition: background-size 0.2s ease-out 0s; + background-size: 100% 2px; +} + +.linkContainer a:focus { + transition: background-size 0.2s ease-out 0s; + background-size: 100% 2px; +} + +.linkContainer a:active { + transition: color ease-in-out 0s; +} diff --git a/packages/manager/apps/pci-quota/src/constants.ts b/packages/manager/apps/pci-quota/src/constants.ts new file mode 100644 index 000000000000..267de5f300d2 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/constants.ts @@ -0,0 +1,18 @@ +export const ACTIVE_STATUS = ['ok', 'READY']; +export const PENDING_STATUS = ['PENDING', 'CREATING', 'UPDATING', 'DELETING']; + +export const HORIZON_LINK = { + EU: 'https://horizon.cloud.ovh.net/auth/login?username={username}', + CA: 'https://horizon.cloud.ovh.net/auth/login?username={username}', + US: 'https://horizon.cloud.ovh.us/auth/login?username={username}', +}; + +export const HORIZON_LINK_TRUSTED = { + EU: + 'https://horizon.trustedzone.cloud.ovh.net/auth/login?username={username}', + CA: + 'https://horizon.trustedzone.cloud.ovh.net/auth/login?username={username}', + US: '', +}; + +export const ALPHA_CHARACTERS_REGEX = /^[a-zA-Z-]+$/; diff --git a/packages/manager/apps/pci-quota/src/core/HidePreloader.tsx b/packages/manager/apps/pci-quota/src/core/HidePreloader.tsx new file mode 100644 index 000000000000..47a95bc826fe --- /dev/null +++ b/packages/manager/apps/pci-quota/src/core/HidePreloader.tsx @@ -0,0 +1,12 @@ +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { useContext, useEffect } from 'react'; + +export default function HidePreloader() { + const { ux } = useContext(ShellContext).shell; + + useEffect(() => { + ux.hidePreloader(); + }, []); + + return null; +} diff --git a/packages/manager/apps/pci-quota/src/core/ShellRoutingSync.tsx b/packages/manager/apps/pci-quota/src/core/ShellRoutingSync.tsx new file mode 100644 index 000000000000..5bac7bf20178 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/core/ShellRoutingSync.tsx @@ -0,0 +1,16 @@ +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { useContext, useEffect } from 'react'; +import { useLocation } from 'react-router-dom'; + +export default function ShellRoutingSync() { + const location = useLocation(); + + const { routing } = useContext(ShellContext).shell; + useEffect(() => { + routing.stopListenForHashChange(); + }, []); + useEffect(() => { + routing.onHashChange(); + }, [location]); + return null; +} diff --git a/packages/manager/apps/pci-quota/src/hooks/usePageTracking.ts b/packages/manager/apps/pci-quota/src/hooks/usePageTracking.ts new file mode 100644 index 000000000000..bb52919ab12e --- /dev/null +++ b/packages/manager/apps/pci-quota/src/hooks/usePageTracking.ts @@ -0,0 +1,33 @@ +import { useContext, useEffect } from 'react'; +import { useLocation } from 'react-router-dom'; +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { useProject } from '@ovh-ux/manager-pci-common'; +import { PAGE_PREFIX, PCI_LEVEL2 } from '@/tracking.constants'; + +const DISCOVERY_PLANCODE = 'project.discovery'; + +export default function usePageTracking() { + const location = useLocation(); + const { data: project } = useProject(); + const { setPciProjectMode, trackPage } = useContext( + ShellContext, + ).shell.tracking; + + useEffect(() => { + if (project) { + setPciProjectMode({ + projectId: project.project_id, + isDiscoveryProject: project.planCode === DISCOVERY_PLANCODE, + }); + } + }, [project]); + + useEffect(() => { + const pageId = location.pathname.split('/').pop(); + const pageKey = pageId === 'quota' ? '' : `::${pageId}`; + trackPage({ + name: `${PAGE_PREFIX}::${pageKey}`, + level2: PCI_LEVEL2, + }); + }, [location]); +} diff --git a/packages/manager/apps/pci-quota/src/index.css b/packages/manager/apps/pci-quota/src/index.css new file mode 100644 index 000000000000..b5c61c956711 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/index.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/packages/manager/apps/pci-quota/src/layout.ts b/packages/manager/apps/pci-quota/src/layout.ts new file mode 100644 index 000000000000..6f81e3311b47 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/layout.ts @@ -0,0 +1,7 @@ +export enum BreakPoints { + XS = 0, + SM = 540, + MD = 720, + LG = 960, + XL = 1140, +} diff --git a/packages/manager/apps/pci-quota/src/main.tsx b/packages/manager/apps/pci-quota/src/main.tsx new file mode 100644 index 000000000000..bd1a726a31ab --- /dev/null +++ b/packages/manager/apps/pci-quota/src/main.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { + initI18n, + initShellContext, + ShellContext, +} from '@ovh-ux/manager-react-shell-client'; +import App from './App'; + +import './index.css'; + +import '@/vite-hmr.ts'; + +const init = async ( + appName: string, + { reloadOnLocaleChange } = { reloadOnLocaleChange: false }, +) => { + const context = await initShellContext(appName); + + const region = context.environment.getRegion(); + try { + await import(`./config-${region}.js`); + } catch (error) { + // nothing to do + } + + await initI18n({ + context, + reloadOnLocaleChange, + ns: ['common'], + defaultNS: 'common', + }); + + ReactDOM.createRoot(document.getElementById('root')).render( + + + + + , + ); +}; + +init('pci-quota'); diff --git a/packages/manager/apps/pci-quota/src/pages/Layout.tsx b/packages/manager/apps/pci-quota/src/pages/Layout.tsx new file mode 100644 index 000000000000..a6e13781f339 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/pages/Layout.tsx @@ -0,0 +1,55 @@ +import { Outlet, useRouteError } from 'react-router-dom'; + +import { ShellContext } from '@ovh-ux/manager-react-shell-client'; +import { Suspense, useContext } from 'react'; +import { ErrorBanner } from '@ovh-ux/manager-react-components'; +import { ApiError } from '@ovh-ux/manager-core-api'; +import { useProject } from '@ovh-ux/manager-pci-common'; +import ShellRoutingSync from '@/core/ShellRoutingSync'; +import HidePreloader from '@/core/HidePreloader'; + +import usePageTracking from '@/hooks/usePageTracking'; + +export default function Layout() { + const { isSuccess } = useProject(); + usePageTracking(); + return ( +
+ + + {isSuccess && ( + <> + + + + )} + +
+ ); +} + +export const ErrorBoundary = () => { + const error = useRouteError() as ApiError; + const nav = useContext(ShellContext).shell.navigation; + + const redirectionApplication = 'public-cloud'; + + const navigateToHomePage = () => { + nav.navigateTo(redirectionApplication, '', {}); + }; + + const reloadPage = () => { + nav.reload(); + }; + return ( + + + + + + ); +}; diff --git a/packages/manager/apps/pci-quota/src/queryClient.ts b/packages/manager/apps/pci-quota/src/queryClient.ts new file mode 100644 index 000000000000..e3a6fb388e53 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/queryClient.ts @@ -0,0 +1,11 @@ +import { QueryClient } from '@tanstack/react-query'; + +export const queryClient = new QueryClient({ + defaultOptions: { + queries: { + staleTime: 300_000, + }, + }, +}); + +export default queryClient; diff --git a/packages/manager/apps/pci-quota/src/routes.tsx b/packages/manager/apps/pci-quota/src/routes.tsx new file mode 100644 index 000000000000..bcf7142b54f5 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/routes.tsx @@ -0,0 +1,18 @@ +import { lazy } from 'react'; +import { Route, Routes } from 'react-router-dom'; + +const ROUTE_PATHS = { + ROOT: '/pci/projects/:projectId/quota', + LISTING: '', +}; + +const LayoutPage = lazy(() => import('@/pages/Layout')); + +const RoutesComponent = () => ( + + + Page not found}> + +); + +export default RoutesComponent; diff --git a/packages/manager/apps/pci-quota/src/sampleTest.spec.ts b/packages/manager/apps/pci-quota/src/sampleTest.spec.ts new file mode 100644 index 000000000000..6138448c9680 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/sampleTest.spec.ts @@ -0,0 +1,5 @@ +describe('Sample Test', () => { + it('should test that true === true', () => { + expect(true).toBe(true); + }); +}); diff --git a/packages/manager/apps/pci-quota/src/setupTests.tsx b/packages/manager/apps/pci-quota/src/setupTests.tsx new file mode 100644 index 000000000000..4c93c39e2632 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/setupTests.tsx @@ -0,0 +1,86 @@ +import '@testing-library/jest-dom'; +import 'element-internals-polyfill'; +import { vi } from 'vitest'; + +vi.mock('react-router-dom', async () => { + const mod = await vi.importActual('react-router-dom'); + return { + ...mod, + useSearchParams: () => [new URLSearchParams({})], + useParams: () => ({ projectId: 'project-id', kubeId: 'kube-id' }), + useHref: vi.fn(), + useLocation: vi.fn(), + useNavigate: vi.fn(), + Navigate: () => null, + Outlet: vi.fn(() => 'Outlet'), + }; +}); + +vi.mock('@ovh-ux/manager-pci-common', async () => { + const mod = await vi.importActual('@ovh-ux/manager-pci-common'); + return { + ...mod, + useProject: vi.fn().mockResolvedValue({ + projectName: 'project-name', + project_id: 'project-id', + }), + }; +}); + +vi.mock('@ovh-ux/manager-react-components', async () => { + const mod = await vi.importActual('@ovh-ux/manager-react-components'); + return { + ...mod, + useProjectUrl: vi.fn().mockReturnValue('mockProjectUrl'), + useDatagridSearchParams: () => ({ + pagination: vi.fn(), + setPagination: vi.fn(), + sorting: vi.fn(), + setSorting: vi.fn(), + }), + PciGuidesHeader: vi.fn().mockReturnValue(
), + Notifications: vi + .fn() + .mockReturnValue(
), + useNotifications: () => ({ + addError: vi.fn(), + addSuccess: vi.fn(), + }), + }; +}); + +vi.mock('react-i18next', () => ({ + useTranslation: () => ({ + t: (translationKey: string) => translationKey, + i18n: { + changeLanguage: () => new Promise(() => {}), + exists: () => true, + }, + }), + Trans: ({ children }: { children: string }) => children, +})); + +vi.mock('@ovh-ux/manager-react-shell-client', async () => { + const mod = await vi.importActual('@ovh-ux/manager-react-shell-client'); + return { + ...mod, + useTracking: vi.fn(() => ({ + trackPage: vi.fn(), + trackClick: vi.fn(), + })), + }; +}); + +vi.mock('@ovh-ux/manager-core-api', async () => { + const mod = await vi.importActual('@ovh-ux/manager-core-api'); + return { + ...mod, + fetchIcebergV6: vi.fn(), + v6: { + get: vi.fn(), + post: vi.fn(), + put: vi.fn(), + delete: vi.fn(), + }, + }; +}); diff --git a/packages/manager/apps/pci-quota/src/tracking.constants.ts b/packages/manager/apps/pci-quota/src/tracking.constants.ts new file mode 100644 index 000000000000..25f630c6eaf8 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/tracking.constants.ts @@ -0,0 +1,2 @@ +export const PCI_LEVEL2 = '86'; +export const PAGE_PREFIX = 'PublicCloud::pci::projects::project'; diff --git a/packages/manager/apps/pci-quota/src/vite-env.d.ts b/packages/manager/apps/pci-quota/src/vite-env.d.ts new file mode 100644 index 000000000000..11f02fe2a006 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/manager/apps/pci-quota/src/vite-hmr.ts b/packages/manager/apps/pci-quota/src/vite-hmr.ts new file mode 100644 index 000000000000..473d87630039 --- /dev/null +++ b/packages/manager/apps/pci-quota/src/vite-hmr.ts @@ -0,0 +1,5 @@ +if (import.meta.hot) { + import.meta.hot.on('iframe-reload', () => { + window.location.reload(); + }); +} diff --git a/packages/manager/apps/pci-quota/tailwind.config.js b/packages/manager/apps/pci-quota/tailwind.config.js new file mode 100644 index 000000000000..78ea84cdc68a --- /dev/null +++ b/packages/manager/apps/pci-quota/tailwind.config.js @@ -0,0 +1,13 @@ +import config from '@ovh-ux/manager-tailwind-config'; + +/** @type {import('tailwindcss').Config} */ +module.exports = { + ...config, + content: [ + './src/**/*.{js,jsx,ts,tsx}', + '../../modules/manager-pci-common/**/*.{js,jsx,ts,tsx}', + ], + corePlugins: { + preflight: false, + }, +}; diff --git a/packages/manager/apps/pci-quota/tsconfig.build.json b/packages/manager/apps/pci-quota/tsconfig.build.json new file mode 100644 index 000000000000..4dc23fb9c4c5 --- /dev/null +++ b/packages/manager/apps/pci-quota/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["src/__tests__"] +} diff --git a/packages/manager/apps/pci-quota/tsconfig.json b/packages/manager/apps/pci-quota/tsconfig.json new file mode 100644 index 000000000000..22b760c06550 --- /dev/null +++ b/packages/manager/apps/pci-quota/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + /* Bundler mode */ + "moduleResolution": "node", + "allowImportingTsExtensions": false, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + /* Linting */ + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "paths": { + "@/*": ["./src/*"], + "react": ["./node_modules/@types/react"] + }, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true + }, + "include": ["src"], + "exclude": ["node_modules", "dist", "types"] +} diff --git a/packages/manager/apps/pci-quota/vite.config.ts b/packages/manager/apps/pci-quota/vite.config.ts new file mode 100644 index 000000000000..e3ad2b027ea2 --- /dev/null +++ b/packages/manager/apps/pci-quota/vite.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vite'; +import { getBaseConfig } from '@ovh-ux/manager-vite-config'; +import tailwindcss from 'tailwindcss'; + +const baseConfig = getBaseConfig({}); + +export default defineConfig({ + ...baseConfig, + root: '', + css: { + postcss: { + plugins: [tailwindcss], + }, + }, + resolve: { + ...baseConfig.resolve, + }, +}); diff --git a/packages/manager/apps/pci-quota/vitest.config.js b/packages/manager/apps/pci-quota/vitest.config.js new file mode 100644 index 000000000000..036671d6ab8d --- /dev/null +++ b/packages/manager/apps/pci-quota/vitest.config.js @@ -0,0 +1,35 @@ +import path from 'path'; +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + test: { + globals: true, + environment: 'jsdom', + setupFiles: './src/setupTests.tsx', + coverage: { + include: ['src'], + exclude: [ + 'src/interface', + 'src/__tests__', + 'src/**/*constants.ts', + 'src/**/*enum.ts', + 'src/vite-*.ts', + 'src/App.tsx', + 'src/core/ShellRoutingSync.tsx', + 'src/i18n.ts', + 'src/main.tsx', + 'src/pages/Layout.tsx', + 'src/routes.tsx', + ], + }, + }, + resolve: { + alias: { + '@': path.resolve(__dirname, 'src'), + }, + mainFields: ['module'], + }, +}); diff --git a/yarn.lock b/yarn.lock index 98800e0a3df0..430945bb113e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3198,7 +3198,22 @@ dependencies: "@floating-ui/utils" "^0.2.5" -"@floating-ui/dom@1.6.3", "@floating-ui/dom@^1.0.1", "@floating-ui/dom@^1.6.1": +"@floating-ui/core@^1.6.0": + version "1.6.8" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.8.tgz#aa43561be075815879305965020f492cdb43da12" + integrity sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA== + dependencies: + "@floating-ui/utils" "^0.2.8" + +"@floating-ui/dom@1.6.11": + version "1.6.11" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.11.tgz#8631857838d34ee5712339eb7cbdfb8ad34da723" + integrity sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.8" + +"@floating-ui/dom@^1.0.1", "@floating-ui/dom@^1.6.1": version "1.6.3" resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef" integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw== @@ -3223,6 +3238,11 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.5.tgz#105c37d9d9620ce69b7f692a20c821bf1ad2cbf9" integrity sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ== +"@floating-ui/utils@^0.2.8": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62" + integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig== + "@fortawesome/fontawesome-free@^5.11.2": version "5.15.4" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" @@ -5363,12 +5383,12 @@ "@ovhcloud/ods-common-stencil" "17.2.2" "@ovhcloud/ods-common-theming" "17.2.2" -"@ovhcloud/ods-components@18.0.0": - version "18.0.0" - resolved "https://registry.npmjs.org/@ovhcloud/ods-components/-/ods-components-18.0.0.tgz#b0e4da6c35c19004f35bac6b34abb1f78c6d1af0" - integrity sha512-Nhgi8iMX/+tWJb6D8WSN8qNqC32XEwdDL0rc7o9V0OwcXPwSqu7QtTYKB+1s1kGTDxfyl7HGrSDYbqgUI0niMw== +"@ovhcloud/ods-components@^18.3.0": + version "18.3.0" + resolved "https://registry.yarnpkg.com/@ovhcloud/ods-components/-/ods-components-18.3.0.tgz#f5fa856bb45ad7df3ebe421d64ab334f41c7206c" + integrity sha512-E2bDV7RDnNty8fR7Fbvkxug2pySmsy4BQIt9rY0VTZWtcbaUlazmKbr+l+TjeL7vRxiPR4+9xLidI1kwt26O9A== dependencies: - "@floating-ui/dom" "1.6.3" + "@floating-ui/dom" "1.6.11" "@stencil/core" "4.16.0" google-libphonenumber "3.2.35" tom-select "2.3.1" @@ -5389,10 +5409,10 @@ dependencies: "@ovhcloud/ods-common-theming" "17.2.2" -"@ovhcloud/ods-themes@18.0.0": - version "18.0.0" - resolved "https://registry.npmjs.org/@ovhcloud/ods-themes/-/ods-themes-18.0.0.tgz#0a7c658e0e9d572262ed41896fee4819c2764167" - integrity sha512-0PfXUyF6bX9emb/a6S16QThKsSXyvrNYT3n1zQF/le8tMXP7292TGKIgqXhsZmkcD9tCdD6VLXuJTS8Zv3a5Yg== +"@ovhcloud/ods-themes@^18.3.0": + version "18.3.0" + resolved "https://registry.yarnpkg.com/@ovhcloud/ods-themes/-/ods-themes-18.3.0.tgz#804e3502e6791f7ec2efc24abb107d27cd4e02e0" + integrity sha512-mTxtcM4tCUPk98x65PeslXqGONJraTryXgkbgbZuvtOYf9SgVl+zFJfyisD2sYGuJvVf6hJP1NvJkyrxOUqtSw== "@ovhcloud/reket-axios-client@^0.2.1": version "0.2.1" @@ -6289,6 +6309,11 @@ resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.19.2.tgz#0c896535473291cb41f152c180bedd5680a3b273" integrity sha512-baiMx18+IMuD1yyvOGaHM9QrVUPGGG0jC+z+IPHnRJWUAUvaKuWKyE8gjDj2rzv3sz9zOGoRSPgeBVHRhZnBlA== +"@remix-run/router@1.21.0": + version "1.21.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.0.tgz#c65ae4262bdcfe415dbd4f64ec87676e4a56e2b5" + integrity sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA== + "@remix-run/router@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.9.0.tgz#9033238b41c4cbe1e961eccb3f79e2c588328cf6" @@ -6827,14 +6852,6 @@ resolved "https://registry.npmjs.org/@stencil/core/-/core-4.16.0.tgz#79c430d5875e0ce3a7666607b6fb53512890577b" integrity sha512-gXaC5IrquV/Hw5JIZTCWkM5lJEbBQtnvHLhDebjar6A6+YBqxah04dardS+YUNVuRbnE6Hcja7KKiAXT3oVsvw== -"@storybook/addon-a11y@8.0.4": - version "8.0.4" - resolved "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-8.0.4.tgz#2e62ab86a016a9ed6e4b52d61e0549c2568b0923" - integrity sha512-5OyZNzjNXjNUD9vBfjxFnJjMMcBFYWyI4zy5qmJcbAvBv/COiXNfNg2cr2YPNtU5WfA6nsaIESfHFGBHI3GDAg== - dependencies: - "@storybook/addon-highlight" "8.0.4" - axe-core "^4.2.0" - "@storybook/addon-actions@7.5.3": version "7.5.3" resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-7.5.3.tgz#e0d0d819488d1d19918b23469b3ea6610fee5f07" @@ -6970,13 +6987,6 @@ "@storybook/global" "^5.0.0" "@storybook/preview-api" "7.5.3" -"@storybook/addon-highlight@8.0.4": - version "8.0.4" - resolved "https://registry.npmjs.org/@storybook/addon-highlight/-/addon-highlight-8.0.4.tgz#32f21a1f850394e83277a1cd553a33c86cb603f4" - integrity sha512-tnEiVaJlXL07v8JBox+QtRPVruoy0YovOTAOWY7fKDiKzF1I9wLaJjQF3wOsvwspHTHu00OZw2gsazgXiH4wLQ== - dependencies: - "@storybook/global" "^5.0.0" - "@storybook/addon-interactions@7.5.3": version "7.5.3" resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-7.5.3.tgz#5aef96b3fa24aaafb88c0fc501f6a7e8cfa2a342" @@ -8453,6 +8463,11 @@ resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.51.16.tgz#d855d00e7939c1a442c2e8ae3ad1a5bd603d003b" integrity sha512-ajwuq4WnkNCMj/Hy3KR8d3RtZ6PSKc1dD2vs2T408MdjgKzQ3klVoL6zDgVO7X+5jlb5zfgcO3thh4ojPhfIaw== +"@tanstack/query-devtools@5.59.20": + version "5.59.20" + resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.59.20.tgz#a827ac682ec1268fc9c99e7b6eb739f35b5606aa" + integrity sha512-vxhuQ+8VV4YWQSFxQLsuM+dnEKRY7VeRzpNabFXdhEwsBYLrjXlF1pM38A8WyKNLqZy8JjyRO8oP4Wd/oKHwuQ== + "@tanstack/react-query-devtools@5.29.2": version "5.29.2" resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.29.2.tgz#ff9e6a113a4828d4b62f4861e0fb2c05b79b37dc" @@ -8467,6 +8482,13 @@ dependencies: "@tanstack/query-devtools" "5.51.16" +"@tanstack/react-query-devtools@^5.50.1": + version "5.60.5" + resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.60.5.tgz#fe398b4896a292fbe835d3fd4799e929de94c25a" + integrity sha512-lzANl0ih3CNKBGUoXhhkAAHI1Y4Yqs9Jf3iuTUsGiPpmF0RWXTeYFaQxc+h1PhJz3VwYrIYCwmPoNts0mSjSuA== + dependencies: + "@tanstack/query-devtools" "5.59.20" + "@tanstack/react-query@5.51.11": version "5.51.11" resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.51.11.tgz#8ab2cf6a4baa7a99b5682addf31328525f43242c" @@ -11352,11 +11374,6 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== -axe-core@^4.2.0: - version "4.10.0" - resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.10.0.tgz#d9e56ab0147278272739a000880196cdfe113b59" - integrity sha512-Mr2ZakwQ7XUAjp7pAwQWRhhK8mQQ6JAaNWSjmjxil0R8BPioMtQsTLOolGYkji1rcL++3dCqZA3zWqpT+9Ew6g== - axios@^0.21.1: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -24395,6 +24412,14 @@ react-responsive@^9.0.0-beta.6: prop-types "^15.6.1" shallow-equal "^1.2.1" +react-router-dom@^6.24.1: + version "6.28.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.28.0.tgz#f73ebb3490e59ac9f299377062ad1d10a9f579e6" + integrity sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg== + dependencies: + "@remix-run/router" "1.21.0" + react-router "6.28.0" + react-router-dom@^6.25.1: version "6.26.2" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.26.2.tgz#a6e3b0cbd6bfd508e42b9342099d015a0ac59680" @@ -24425,6 +24450,13 @@ react-router@6.26.2: dependencies: "@remix-run/router" "1.19.2" +react-router@6.28.0: + version "6.28.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.28.0.tgz#29247c86d7ba901d7e5a13aa79a96723c3e59d0d" + integrity sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg== + dependencies: + "@remix-run/router" "1.21.0" + react-router@^6.21.3: version "6.22.1" resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.22.1.tgz#a5ff849bfe709438f7e139421bb28138209662c7" @@ -29996,4 +30028,4 @@ zustand@^4.5.5: zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== \ No newline at end of file + integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==