From 19415f312a5cffa1e527f6a31d526c294a58ca9d Mon Sep 17 00:00:00 2001 From: Tudor Stanciu Date: Sun, 10 Nov 2024 23:21:37 +0200 Subject: [PATCH] Refactor ReleaseNotesContainer to TypeScript, implement SWR for data fetching, and update release note structure --- .../releaseNotes/ReleaseNotesContainer.js | 35 ------------------- .../releaseNotes/ReleaseNotesContainer.tsx | 32 +++++++++++++++++ frontend/src/types/dtos.ts | 6 ++++ frontend/src/utils/api.js | 1 - 4 files changed, 38 insertions(+), 36 deletions(-) delete mode 100644 frontend/src/features/about/releaseNotes/ReleaseNotesContainer.js create mode 100644 frontend/src/features/about/releaseNotes/ReleaseNotesContainer.tsx diff --git a/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.js b/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.js deleted file mode 100644 index 39e849b..0000000 --- a/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.js +++ /dev/null @@ -1,35 +0,0 @@ -import React, { useState, useEffect } from "react"; -import PropTypes from "prop-types"; -import ReleaseNotesList from "./ReleaseNotesList"; -import TimelineComponent from "../timeline/TimelineComponent"; -import { routes, get } from "../../../utils/api"; - -const sort = releases => releases.sort((a, b) => new Date(b.date) - new Date(a.date)); - -const ReleaseNotesContainer = ({ view }) => { - const [state, setState] = useState({ data: [], loaded: false }); - - useEffect(() => { - if (state.loaded) return; - get(routes.releaseNotes, { - onCompleted: data => setState({ data, loaded: true }) - }); - }, [state.loaded]); - - return ( - <> - {state.loaded && - (view === "timeline" ? ( - - ) : ( - - ))} - - ); -}; - -ReleaseNotesContainer.propTypes = { - view: PropTypes.string -}; - -export default ReleaseNotesContainer; diff --git a/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.tsx b/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.tsx new file mode 100644 index 0000000..62c2efc --- /dev/null +++ b/frontend/src/features/about/releaseNotes/ReleaseNotesContainer.tsx @@ -0,0 +1,32 @@ +import React, { useState, useEffect } from "react"; +import ReleaseNotesList from "./ReleaseNotesList"; +import TimelineComponent from "../timeline/TimelineComponent"; +import { routes, get, endpoints } from "../../../utils/api"; +import useSWR from "swr"; +import { fetcher } from "utils/swr"; +import { blip } from "utils"; +import { dtos } from "types"; + +const sort = (releases: dtos.ReleaseNote[]) => + releases.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); + +type Props = { + view: string; +}; + +const ReleaseNotesContainer: React.FC = ({ view }) => { + const { data, isLoading } = useSWR(endpoints.system.releaseNotes, fetcher, { + revalidateOnFocus: false, + onError: err => blip.error(err.message) + }); + + if (isLoading || !data) return null; + + return ( + <> + {view === "timeline" ? : } + + ); +}; + +export default ReleaseNotesContainer; diff --git a/frontend/src/types/dtos.ts b/frontend/src/types/dtos.ts index 6b90b65..95679d4 100644 --- a/frontend/src/types/dtos.ts +++ b/frontend/src/types/dtos.ts @@ -7,3 +7,9 @@ export type SystemVersion = { api: SystemVersionElement; server: SystemVersionElement; }; + +export type ReleaseNote = { + version: string; + date: string; + notes: string[]; +}; diff --git a/frontend/src/utils/api.js b/frontend/src/utils/api.js index ded593a..035df60 100644 --- a/frontend/src/utils/api.js +++ b/frontend/src/utils/api.js @@ -11,7 +11,6 @@ const securityRoute = `${apiHost}/security`; const routes = { permissions: `${securityRoute}/permissions`, - releaseNotes: `${systemRoute}/release-notes`, resetCache: `${systemRoute}/reset-cache`, machines: `${networkRoute}/machines`, wakeMachine: `${powerActionsRoute}/wake`,