From d477ff1a8f4bab2e189723a489890307f3436b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20D=C3=ADaz=20Gonz=C3=A1lez?= Date: Thu, 26 Dec 2024 15:42:19 +0000 Subject: [PATCH] refactor(web): migrate contexts to TypeScript --- web/src/context/{app.jsx => app.tsx} | 7 +-- web/src/context/{auth.jsx => auth.tsx} | 6 +-- ...{installer.test.jsx => installer.test.tsx} | 4 +- .../context/{installer.jsx => installer.tsx} | 44 ++++++++----------- 4 files changed, 24 insertions(+), 37 deletions(-) rename web/src/context/{app.jsx => app.tsx} (89%) rename web/src/context/{auth.jsx => auth.tsx} (95%) rename web/src/context/{installer.test.jsx => installer.test.tsx} (94%) rename web/src/context/{installer.jsx => installer.tsx} (75%) diff --git a/web/src/context/app.jsx b/web/src/context/app.tsx similarity index 89% rename from web/src/context/app.jsx rename to web/src/context/app.tsx index 9ba49bf1f0..70686fde79 100644 --- a/web/src/context/app.jsx +++ b/web/src/context/app.tsx @@ -20,8 +20,6 @@ * find current contact information at www.suse.com. */ -// @ts-check - import React from "react"; import { InstallerClientProvider } from "./installer"; import { InstallerL10nProvider } from "./installerL10n"; @@ -31,11 +29,8 @@ const queryClient = new QueryClient(); /** * Combines all application providers. - * - * @param {object} props - * @param {React.ReactNode} [props.children] - content to display within the provider. */ -function AppProviders({ children }) { +function AppProviders({ children }: React.PropsWithChildren) { return ( diff --git a/web/src/context/auth.jsx b/web/src/context/auth.tsx similarity index 95% rename from web/src/context/auth.jsx rename to web/src/context/auth.tsx index 536e8c054b..65154a29a7 100644 --- a/web/src/context/auth.jsx +++ b/web/src/context/auth.tsx @@ -20,8 +20,6 @@ * find current contact information at www.suse.com. */ -// @ts-check - import React, { useCallback, useEffect, useState } from "react"; const AuthContext = React.createContext(null); @@ -48,11 +46,11 @@ const AuthErrors = Object.freeze({ * @param {object} props * @param {React.ReactNode} [props.children] - content to display within the provider */ -function AuthProvider({ children }) { +function AuthProvider({ children }: React.PropsWithChildren) { const [isLoggedIn, setIsLoggedIn] = useState(undefined); const [error, setError] = useState(null); - const login = useCallback(async (password) => { + const login = useCallback(async (password: string) => { const response = await fetch("/api/auth", { method: "POST", body: JSON.stringify({ password }), diff --git a/web/src/context/installer.test.jsx b/web/src/context/installer.test.tsx similarity index 94% rename from web/src/context/installer.test.jsx rename to web/src/context/installer.test.tsx index cd55969ffd..5c4125da1e 100644 --- a/web/src/context/installer.test.jsx +++ b/web/src/context/installer.test.tsx @@ -1,5 +1,5 @@ /* - * Copyright (c) [2023] SUSE LLC + * Copyright (c) [2023-2024] SUSE LLC * * All Rights Reserved. * @@ -41,7 +41,7 @@ const ClientStatus = () => { describe("installer context", () => { beforeEach(() => { - createDefaultClient.mockImplementation(() => { + (createDefaultClient as jest.Mock).mockImplementation(() => { return { onConnect: jest.fn(), onDisconnect: jest.fn(), diff --git a/web/src/context/installer.jsx b/web/src/context/installer.tsx similarity index 75% rename from web/src/context/installer.jsx rename to web/src/context/installer.tsx index b2a96aefc2..2cbc5f5797 100644 --- a/web/src/context/installer.jsx +++ b/web/src/context/installer.tsx @@ -1,5 +1,5 @@ /* - * Copyright (c) [2021-2023] SUSE LLC + * Copyright (c) [2021-2024] SUSE LLC * * All Rights Reserved. * @@ -20,10 +20,22 @@ * find current contact information at www.suse.com. */ -// @ts-check - import React, { useState, useEffect } from "react"; -import { createDefaultClient } from "~/client"; +import { createDefaultClient, InstallerClient } from "~/client"; +import { InstallerStatus } from "~/types/status"; + +type ClientStatus = { + /** Whether the client is connected or not. */ + connected: boolean; + /** Whether the client present an error and cannot reconnect. */ + error: boolean; +}; + +type InstallerClientProviderProps = React.PropsWithChildren<{ + /** Client to connect to Agama service; if it is undefined, it instantiates a + * new one using the address registered in /run/agama/bus.address. */ + client?: InstallerClient; +}>; const InstallerClientContext = React.createContext(null); // TODO: we use a separate context to avoid changing all the codes to @@ -35,10 +47,8 @@ const InstallerClientStatusContext = React.createContext({ /** * Returns the D-Bus installer client - * - * @return {import("~/client").InstallerClient} */ -function useInstallerClient() { +function useInstallerClient(): InstallerClient { const context = React.useContext(InstallerClientContext); if (context === undefined) { throw new Error("useInstallerClient must be used within a InstallerClientProvider"); @@ -49,15 +59,8 @@ function useInstallerClient() { /** * Returns the client status. - * - * @typedef {object} ClientStatus - * @property {boolean} connected - whether the client is connected - * @property {boolean} error - whether the client present an error and cannot - * reconnect - * - * @return {ClientStatus} installer client status */ -function useInstallerClientStatus() { +function useInstallerClientStatus(): ClientStatus { const context = React.useContext(InstallerClientStatusContext); if (!context) { throw new Error("useInstallerClientStatus must be used within a InstallerClientProvider"); @@ -66,16 +69,7 @@ function useInstallerClientStatus() { return context; } -/** - * @param {object} props - * @param {import("~/client").InstallerClient|undefined} [props.client] client to connect to - * Agama service; if it is undefined, it instantiates a new one using the address - * registered in /run/agama/bus.address. - * @param {number} [props.interval=2000] - Interval in milliseconds between connection attempt - * (2000 by default). - * @param {React.ReactNode} [props.children] - content to display within the provider - */ -function InstallerClientProvider({ children, client = null }) { +function InstallerClientProvider({ children, client = null }: InstallerClientProviderProps) { const [value, setValue] = useState(client); const [connected, setConnected] = useState(false); const [error, setError] = useState(false);