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`,