From 32fed66477b5f07864162e21ea37353577ddc14a Mon Sep 17 00:00:00 2001 From: mkljczk Date: Wed, 4 Dec 2024 16:56:32 +0100 Subject: [PATCH] pl-fe: migrate about page to tanstack query Signed-off-by: mkljczk --- packages/pl-fe/src/actions/about.test.ts | 44 --------------- packages/pl-fe/src/actions/about.ts | 55 ------------------- .../src/api/hooks/pl-fe/use-about-page.ts | 19 +++++++ packages/pl-fe/src/api/index.ts | 2 +- packages/pl-fe/src/features/about/index.tsx | 24 +++----- 5 files changed, 27 insertions(+), 117 deletions(-) delete mode 100644 packages/pl-fe/src/actions/about.test.ts delete mode 100644 packages/pl-fe/src/actions/about.ts create mode 100644 packages/pl-fe/src/api/hooks/pl-fe/use-about-page.ts diff --git a/packages/pl-fe/src/actions/about.test.ts b/packages/pl-fe/src/actions/about.test.ts deleted file mode 100644 index edc1c939c..000000000 --- a/packages/pl-fe/src/actions/about.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -// import MockAdapter from 'axios-mock-adapter'; -import { Map as ImmutableMap } from 'immutable'; - -// import { staticClient } from 'pl-fe/api'; -import { mockStore } from 'pl-fe/jest/test-helpers'; - -import { - FETCH_ABOUT_PAGE_REQUEST, - // FETCH_ABOUT_PAGE_SUCCESS, - FETCH_ABOUT_PAGE_FAIL, - fetchAboutPage, -} from './about'; - -describe('fetchAboutPage()', () => { - // it('creates the expected actions on success', () => { - - // const mock = new MockAdapter(staticClient); - - // mock.onGet('/instance/about/index.html') - // .reply(200, '

Hello world

'); - - // const expectedActions = [ - // { type: FETCH_ABOUT_PAGE_REQUEST, slug: 'index' }, - // { type: FETCH_ABOUT_PAGE_SUCCESS, slug: 'index', html: '

Hello world

' }, - // ]; - // const store = mockStore(ImmutableMap()); - - // return store.dispatch(fetchAboutPage()).then(() => { - // expect(store.getActions()).toEqual(expectedActions); - // }); - // }); - - it('creates the expected actions on failure', () => { - const expectedActions = [ - { type: FETCH_ABOUT_PAGE_REQUEST, slug: 'asdf' }, - { type: FETCH_ABOUT_PAGE_FAIL, slug: 'asdf', error: new Error('Request failed with status code 404') }, - ]; - const store = mockStore(ImmutableMap()); - - return store.dispatch(fetchAboutPage('asdf')).catch(() => { - expect(store.getActions()).toEqual(expectedActions); - }); - }); -}); diff --git a/packages/pl-fe/src/actions/about.ts b/packages/pl-fe/src/actions/about.ts deleted file mode 100644 index abc74c13b..000000000 --- a/packages/pl-fe/src/actions/about.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { staticFetch } from '../api'; - -import type { AppDispatch, RootState } from 'pl-fe/store'; - -const FETCH_ABOUT_PAGE_REQUEST = 'FETCH_ABOUT_PAGE_REQUEST' as const; -const FETCH_ABOUT_PAGE_SUCCESS = 'FETCH_ABOUT_PAGE_SUCCESS' as const; -const FETCH_ABOUT_PAGE_FAIL = 'FETCH_ABOUT_PAGE_FAIL' as const; - -interface FetchAboutPageRequestAction { - type: typeof FETCH_ABOUT_PAGE_REQUEST; - slug: string; - locale?: string; -} - -interface FetchAboutPageSuccessAction { - type: typeof FETCH_ABOUT_PAGE_SUCCESS; - slug: string; - locale?: string; - html: string; -} - -interface FetchAboutPageFailAction { - type: typeof FETCH_ABOUT_PAGE_FAIL; - slug: string; - locale?: string; - error: unknown; -} - -const fetchAboutPage = (slug = 'index', locale?: string) => (dispatch: AppDispatch, getState: () => RootState) => { - dispatch({ type: FETCH_ABOUT_PAGE_REQUEST, slug, locale }); - - const filename = `${slug}${locale ? `.${locale}` : ''}.html`; - return staticFetch(`/instance/about/${filename}`) - .then(({ data: html }) => { - dispatch({ type: FETCH_ABOUT_PAGE_SUCCESS, slug, locale, html }); - return html; - }) - .catch(error => { - dispatch({ type: FETCH_ABOUT_PAGE_FAIL, slug, locale, error }); - throw error; - }); -}; - -type AboutAction = - | FetchAboutPageRequestAction - | FetchAboutPageSuccessAction - | FetchAboutPageFailAction; - -export { - fetchAboutPage, - FETCH_ABOUT_PAGE_REQUEST, - FETCH_ABOUT_PAGE_SUCCESS, - FETCH_ABOUT_PAGE_FAIL, - type AboutAction, -}; diff --git a/packages/pl-fe/src/api/hooks/pl-fe/use-about-page.ts b/packages/pl-fe/src/api/hooks/pl-fe/use-about-page.ts new file mode 100644 index 000000000..0f79f3761 --- /dev/null +++ b/packages/pl-fe/src/api/hooks/pl-fe/use-about-page.ts @@ -0,0 +1,19 @@ +import { useQuery } from '@tanstack/react-query'; + +import { staticFetch } from 'pl-fe/api'; + +const fetchAboutPage = async (slug: string, locale?: string) => { + const filename = `${slug}${locale ? `.${locale}` : ''}.html`; + + const { data } = await staticFetch(`/instance/about/${filename}`); + + return data; +}; + +const useAboutPage = (slug = 'index', locale?: string) => + useQuery({ + queryKey: ['pl-fe', 'aboutPages', slug, locale], + queryFn: () => fetchAboutPage(slug, locale), + }); + +export { useAboutPage }; diff --git a/packages/pl-fe/src/api/index.ts b/packages/pl-fe/src/api/index.ts index 819ba870d..efd01cce9 100644 --- a/packages/pl-fe/src/api/index.ts +++ b/packages/pl-fe/src/api/index.ts @@ -14,7 +14,7 @@ type PlfeResponse = Response & { data: string; json: T }; * No authorization is needed. */ const staticFetch = (input: URL | RequestInfo, init?: RequestInit | undefined) => { - const fullPath = buildFullPath(input.toString(), BuildConfig.FE_SUBDIRECTORY); + const fullPath = buildFullPath(input.toString(), BuildConfig.BACKEND_URL); return fetch(fullPath, init).then(async (response) => { if (!response.ok) throw { response }; diff --git a/packages/pl-fe/src/features/about/index.tsx b/packages/pl-fe/src/features/about/index.tsx index 71e3fd66c..a952f27eb 100644 --- a/packages/pl-fe/src/features/about/index.tsx +++ b/packages/pl-fe/src/features/about/index.tsx @@ -1,11 +1,10 @@ -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import { FormattedMessage } from 'react-intl'; import { useParams } from 'react-router-dom'; -import { fetchAboutPage } from 'pl-fe/actions/about'; +import { useAboutPage } from 'pl-fe/api/hooks/pl-fe/use-about-page'; import { Navlinks } from 'pl-fe/components/navlinks'; import Card from 'pl-fe/components/ui/card'; -import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch'; import { usePlFeConfig } from 'pl-fe/hooks/use-pl-fe-config'; import { useSettings } from 'pl-fe/hooks/use-settings'; @@ -13,30 +12,21 @@ import { languages } from '../preferences'; /** Displays arbitrary user-uploaded HTML on a page at `/about/:slug` */ const AboutPage: React.FC = () => { - const dispatch = useAppDispatch(); - const { slug } = useParams<{ slug?: string }>(); + const { slug = 'index' } = useParams<{ slug?: string }>(); const settings = useSettings(); const plFeConfig = usePlFeConfig(); - const [pageHtml, setPageHtml] = useState(''); const [locale, setLocale] = useState(settings.locale); const { aboutPages } = plFeConfig; - const page = aboutPages[slug || 'about']; + const page = aboutPages[slug]; const defaultLocale = page?.defaultLocale; const pageLocales = page?.locales || []; + const fetchLocale = Boolean(page && locale !== defaultLocale && pageLocales.includes(locale)); - useEffect(() => { - const fetchLocale = Boolean(page && locale !== defaultLocale && pageLocales.includes(locale)); - dispatch(fetchAboutPage(slug, fetchLocale ? locale : undefined)).then(html => { - setPageHtml(html); - }).catch(error => { - // TODO: Better error handling. 404 page? - setPageHtml('

Page not found

'); - }); - }, [locale, slug]); + const { data: pageHtml } = useAboutPage(slug, fetchLocale ? locale : undefined); const alsoAvailable = (defaultLocale) && (
@@ -67,7 +57,7 @@ const AboutPage: React.FC = () => {
-
+ {pageHtml &&
} {alsoAvailable}