Skip to content

Commit

Permalink
refactor(web): migrate contexts to TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
dgdavid committed Dec 26, 2024
1 parent 7a412fd commit d477ff1
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 37 deletions.
7 changes: 1 addition & 6 deletions web/src/context/app.jsx → web/src/context/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 (
<InstallerClientProvider>
<QueryClientProvider client={queryClient}>
Expand Down
6 changes: 2 additions & 4 deletions web/src/context/auth.jsx → web/src/context/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 }),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) [2023] SUSE LLC
* Copyright (c) [2023-2024] SUSE LLC
*
* All Rights Reserved.
*
Expand Down Expand Up @@ -41,7 +41,7 @@ const ClientStatus = () => {

describe("installer context", () => {
beforeEach(() => {
createDefaultClient.mockImplementation(() => {
(createDefaultClient as jest.Mock).mockImplementation(() => {
return {
onConnect: jest.fn(),
onDisconnect: jest.fn(),
Expand Down
44 changes: 19 additions & 25 deletions web/src/context/installer.jsx → web/src/context/installer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) [2021-2023] SUSE LLC
* Copyright (c) [2021-2024] SUSE LLC
*
* All Rights Reserved.
*
Expand All @@ -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
Expand All @@ -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");
Expand All @@ -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");
Expand All @@ -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);
Expand Down

0 comments on commit d477ff1

Please sign in to comment.