diff --git a/incident/src/components/HomePageIncidentCard/Content.test.tsx b/incident/src/components/HomePageIncidentCard/Content.test.tsx index d6687a3..724148d 100644 --- a/incident/src/components/HomePageIncidentCard/Content.test.tsx +++ b/incident/src/components/HomePageIncidentCard/Content.test.tsx @@ -2,6 +2,7 @@ import { TestApiProvider, renderInTestApp } from "@backstage/test-utils"; import React from "react"; import { IncidentApi, IncidentApiRef } from "../../api/client"; import { HomePageIncidentCardContent } from "./Content"; +import { ContextProvider } from "./Context"; const mockIncidentApi: jest.Mocked> = { request: jest.fn().mockResolvedValue({ @@ -46,7 +47,9 @@ describe("HomePageIncidentCardContent", () => { it("should render a list of live incidents", async () => { const { getByTestId } = await renderInTestApp( - + + + , ); diff --git a/incident/src/components/HomePageIncidentCard/Content.tsx b/incident/src/components/HomePageIncidentCard/Content.tsx index 36810f3..f91d4f8 100644 --- a/incident/src/components/HomePageIncidentCard/Content.tsx +++ b/incident/src/components/HomePageIncidentCard/Content.tsx @@ -6,14 +6,21 @@ import { useIncidentList } from "../../hooks/useIncidentRequest"; import { Typography, List } from "@material-ui/core"; import { IncidentListItem } from "../IncidentListItem"; import { configApiRef, useApi } from "@backstage/core-plugin-api"; +import { useHomePageIncidentCard } from "./Context"; export const HomePageIncidentCardContent = () => { + const { filterType, filter } = useHomePageIncidentCard(); const config = useApi(configApiRef); - const baseUrl = config.getOptionalString('incident.baseUrl') || "https://app.incident.io"; + const baseUrl = + config.getOptionalString("incident.baseUrl") || "https://app.incident.io"; - const query = new URLSearchParams(); - query.set(`status_category[one_of]`, "active"); - const { loading, error, value } = useIncidentList(query); + const query = React.useMemo(() => { + const params = new URLSearchParams(); + params.set(`${filterType}[one_of]`, filter); + return params; + }, [filterType, filter]); + + const { loading, error, value } = useIncidentList(query, [query]); const incidents = value?.incidents; if (loading) return ; diff --git a/incident/src/components/HomePageIncidentCard/Context.tsx b/incident/src/components/HomePageIncidentCard/Context.tsx new file mode 100644 index 0000000..4c4a69e --- /dev/null +++ b/incident/src/components/HomePageIncidentCard/Context.tsx @@ -0,0 +1,46 @@ +import React, { createContext, useContext, useMemo } from "react"; + +type HomePageIncidentCardContextValue = { + filterType: "status_category" | "status"; + filter: string; +}; + +const Context = createContext( + undefined, +); + +export const ContextProvider = (props: { + children: React.JSX.Element; + filterType?: "status_category" | "status"; + filter?: string; +}) => { + const { + children, + filterType: defaultFilterType, + filter: defaultFilter, + } = props; + + const value = useMemo( + () => ({ + filterType: defaultFilterType || "status_category", + filter: defaultFilter || "active", + }), + [defaultFilter, defaultFilterType], + ); + + return {children}; +}; + +export const useHomePageIncidentCard = () => { + const value = useContext(Context); + + if (value === undefined) { + throw new Error( + "useHomePageIncidentCard must be used within a HomePageIncidentCardContextProvider", + ); + } + + return value; +}; + +export default Context; diff --git a/incident/src/components/HomePageIncidentCard/index.ts b/incident/src/components/HomePageIncidentCard/index.ts index 7f2950d..e55805e 100644 --- a/incident/src/components/HomePageIncidentCard/index.ts +++ b/incident/src/components/HomePageIncidentCard/index.ts @@ -1 +1,2 @@ export { Content } from "./Content"; +export { ContextProvider } from "./Context"; diff --git a/incident/src/plugin.ts b/incident/src/plugin.ts index b977ab7..8633842 100644 --- a/incident/src/plugin.ts +++ b/incident/src/plugin.ts @@ -20,7 +20,10 @@ import { discoveryApiRef, fetchApiRef, } from "@backstage/core-plugin-api"; -import {CardExtensionProps, createCardExtension} from "@backstage/plugin-home-react"; +import { + CardExtensionProps, + createCardExtension, +} from "@backstage/plugin-home-react"; import { IncidentApi, IncidentApiRef } from "./api/client"; @@ -29,8 +32,8 @@ export const incidentPlugin = createPlugin({ apis: [ createApiFactory({ api: IncidentApiRef, - deps: { - discoveryApi: discoveryApiRef, + deps: { + discoveryApi: discoveryApiRef, fetchApi: fetchApiRef, }, factory: ({ discoveryApi, fetchApi }) => { @@ -55,10 +58,36 @@ export const EntityIncidentCard = incidentPlugin.provide( }), ); -export const HomePageIncidentCard: (props: CardExtensionProps) => React.JSX.Element = incidentPlugin.provide( +export const HomePageIncidentCard: ( + props: CardExtensionProps, +) => React.JSX.Element = incidentPlugin.provide( createCardExtension({ name: "HomePageIncidentCard", title: "Ongoing Incidents", components: () => import("./components/HomePageIncidentCard"), + settings: { + schema: { + type: "object", + properties: { + filterType: { + type: "string", + title: "Filter Type", + description: "Whether to filter on status category or status", + oneOf: [ + { enum: ["status_category"], title: "Status Category" }, + { enum: ["status"], title: "Status" }, + ], + default: "status_category", + }, + filter: { + type: "string", + title: "Filter", + description: + "The filter to use. This is a string that will be passed to the API.", + default: "active", + }, + }, + }, + }, }), );