Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[INF-4803] StatusPage component #430

Merged
merged 4 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ably/ui",
"version": "14.1.8",
"version": "14.2.0",
"description": "Home of the Ably design system library ([design.ably.com](https://design.ably.com)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.",
"repository": {
"type": "git",
Expand Down
15 changes: 6 additions & 9 deletions src/core/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";

import Icon from "./Icon";
import _absUrl from "./url-base.js";
import Status from "./Status.js";

type FooterProps = {
paths: {
Expand All @@ -12,11 +13,14 @@ type FooterProps = {
fastestImplementation: string;
};
urlBase: string;
statusUrl: string;
};

const Footer = ({ paths, urlBase }: FooterProps) => {
const Footer = ({ paths, urlBase, statusUrl }: FooterProps) => {
const absUrl = (path) => _absUrl(path, urlBase);

// create a react hook that calls the statusUrl and returns the status of the system every minute

return (
<footer
className="bg-light-grey font-sans antialiased leading-normal"
Expand Down Expand Up @@ -215,14 +219,7 @@ const Footer = ({ paths, urlBase }: FooterProps) => {
>
System status
</a>
<iframe
className="w-20 h-20 mb-2"
src="https://status.ably.com/embed/icon"
style={{ backgroundColor: "transparent" }}
frameBorder="0"
scrolling="no"
title="System Status"
></iframe>
<Status statusUrl={statusUrl} />
</li>
</ul>
</div>
Expand Down
18 changes: 18 additions & 0 deletions src/core/Footer/Footer.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { delay, http, HttpResponse } from "msw";

import Footer from "../Footer";

import ablyStack from "../images/ably-stack.svg";
Expand All @@ -6,11 +8,26 @@ import bestSupport from "../images/best-support-2023.svg";
import fastestImplementation from "../images/fastest-implementation-2023.svg";
import highestUserAdoption from "../images/highest-user-adoption-2023.svg";

const statusUrl = "https://ntqy1wz94gjv.statuspage.io/api/v2/status.json";

export default {
title: "JS Components/Footer",
component: Footer,
parameters: {
layout: "fullscreen",
msw: {
handlers: {
status: http.get(statusUrl, async () => {
await delay();

return HttpResponse.json({
status: {
indicator: "none",
},
});
}),
},
},
},
args: {
paths: {
Expand All @@ -20,6 +37,7 @@ export default {
fastestImplementation,
highestUserAdoption,
},
statusUrl: statusUrl,
},
};

Expand Down
6 changes: 5 additions & 1 deletion src/core/Meganav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export type MeganavTheme = {
export type AbsUrl = (path: string) => string;

export type MeganavPanels = {
[index: string]: ({ paths, absUrl }) => ReactNode;
[index: string]: ({ paths, absUrl, statusUrl }) => ReactNode;
};

export type MeganavSessionState = {
Expand Down Expand Up @@ -94,6 +94,7 @@ type MeganavProps = {
loginLink?: string;
urlBase?: string;
addSearchApiKey: string;
statusUrl: string;
};

const SignIn = ({ sessionState, theme, loginLink, absUrl }: SignInProps) => {
Expand Down Expand Up @@ -155,6 +156,7 @@ const Meganav = ({
loginLink = "/login",
urlBase,
addSearchApiKey,
statusUrl,
}: MeganavProps) => {
const [sessionState, setSessionState] = useState<MeganavSessionState>();

Expand Down Expand Up @@ -195,6 +197,7 @@ const Meganav = ({
paths={paths}
theme={theme}
absUrl={absUrl}
statusUrl={statusUrl}
/>

{/* Because we load the session state through fetch, we display a placeholder until fetch returns */}
Expand All @@ -216,6 +219,7 @@ const Meganav = ({
theme={theme}
loginLink={loginLink}
absUrl={absUrl}
statusUrl={statusUrl}
/>
</div>
</nav>
Expand Down
15 changes: 14 additions & 1 deletion src/core/Meganav/Meganav.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from "react";
import { http, HttpResponse } from "msw";
import { delay, http, HttpResponse } from "msw";
import Meganav from "../Meganav";
import loadIcons from "../icons.js";
import logo from "../images/ably-logo.png";
Expand All @@ -17,6 +17,8 @@ import {
fetchSessionData,
} from "../remote-session-data.js";

const statusUrl = "https://ntqy1wz94gjv.statuspage.io/api/v2/status.json";

export default {
title: "JS Components/Meganav",
component: Meganav,
Expand Down Expand Up @@ -58,6 +60,15 @@ export default {
},
]);
}),
http.get(statusUrl, async () => {
await delay();

return HttpResponse.json({
status: {
indicator: "none",
},
});
}),
],
},
},
Expand Down Expand Up @@ -87,6 +98,7 @@ const Page = () => {
ablyStack,
awsLogo,
}}
statusUrl={statusUrl}
/>
);
};
Expand All @@ -110,6 +122,7 @@ const PageSignedIn = () => {
ablyStack,
awsLogo,
}}
statusUrl={statusUrl}
/>
);
};
Expand Down
21 changes: 12 additions & 9 deletions src/core/MeganavContentDevelopers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ import React from "react";

import Icon from "./Icon";
import { AbsUrl } from "./Meganav";
import Status from "./Status";

const MeganavContentDevelopers = ({ absUrl }: { absUrl: AbsUrl }) => (
const MeganavContentDevelopers = ({
absUrl,
statusUrl,
}: {
absUrl: AbsUrl;
statusUrl: string;
}) => (
<div className="flex max-w-screen-xl mx-auto">
<div className="ui-meganav-content-spacer"></div>
<section className="grid grid-cols-12 ui-grid-gap-x w-full">
Expand Down Expand Up @@ -181,14 +188,10 @@ const MeganavContentDevelopers = ({ absUrl }: { absUrl: AbsUrl }) => (
>
<p className="ui-meganav-media-heading">
Status
<iframe
title="Ably status"
src="https://status.ably.com/embed/icon"
style={{ backgroundColor: "transparent" }}
frameBorder="0"
scrolling="no"
className="w-24 h-24 ml-4 border-none pointer-events-none align-middle"
></iframe>
<Status
statusUrl={statusUrl}
additionalCSS="ml-4 align-middle"
/>
</p>
</a>
</li>
Expand Down
8 changes: 7 additions & 1 deletion src/core/MeganavItemsDesktop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ type MeganavDesktopItems = {
};
theme: MeganavTheme;
absUrl: AbsUrl;
statusUrl: string;
};

const MeganavDesktopItems = ({
panels,
paths,
theme,
absUrl,
statusUrl,
}: MeganavDesktopItems) => (
<ul className="hidden md:flex" data-id="meganav-items-desktop">
{MeganavData.panels.map((panel) => {
Expand All @@ -47,7 +49,11 @@ const MeganavDesktopItems = ({
id={panel.id}
data-id="meganav-panel"
>
<PanelComponent paths={paths} absUrl={absUrl} />
<PanelComponent
paths={paths}
absUrl={absUrl}
statusUrl={statusUrl}
/>
</div>
</li>
);
Expand Down
8 changes: 7 additions & 1 deletion src/core/MeganavItemsMobile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type MeganavItemsMobileProps = {
theme: MeganavTheme;
loginLink: string;
absUrl: AbsUrl;
statusUrl: string;
};

const MeganavItemsMobile = ({
Expand All @@ -33,6 +34,7 @@ const MeganavItemsMobile = ({
theme,
loginLink,
absUrl,
statusUrl,
}: MeganavItemsMobileProps) => {
const classNames = `ui-meganav-link ${theme.textColor}`;

Expand Down Expand Up @@ -144,7 +146,11 @@ const MeganavItemsMobile = ({
ariaControls={`${panel.id}-mobile`}
displayHr={displayHr}
/>
<PanelComponent paths={paths} absUrl={absUrl} />
<PanelComponent
paths={paths}
absUrl={absUrl}
statusUrl={statusUrl}
/>
</div>
</li>
);
Expand Down
69 changes: 69 additions & 0 deletions src/core/Status.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useEffect, useState } from "react";

const indicatorClass = (indicator: string) => {
switch (indicator) {
case "none":
return "bg-green-500";
case "operational":
return "bg-green-500";
case "minor":
return "bg-yellow-500";
case "major":
return "bg-orange-500";
case "critical":
return "bg-orange-800";
default:
return "bg-neutral-500";
}
};

const Status = ({
statusUrl,
additionalCSS,
}: {
statusUrl: string;
additionalCSS?: string;
}) => {
const [data, setData] = useState<string | null>(null);

useEffect(() => {
let interval;

if (statusUrl !== "") {
const fetchData = async () => {
try {
const response = await fetch(statusUrl);
const jsonData = await response.json();
setData(jsonData);
} catch (error) {
console.error("Error fetching status data:", error);
}
};

fetchData();

interval = setInterval(fetchData, 60000); // Fetch data every minute
}

return () => {
clearInterval(interval);
};
}, [statusUrl]);

return (
<a
href="https://status.ably.com"
className={`inline-block ${additionalCSS}`}
target="_blank"
rel="noreferrer"
>
<span className="flex items-center h-[1.5rem] p-[0.25rem]">
<span
className={`w-[1rem] h-[1rem] leading-[1rem] rounded-full ${!data ? "animate-pulse" : ""} ${indicatorClass(data?.status?.indicator)}`}
></span>
</span>
</a>
);
};

export default Status;
Loading
Loading