diff --git a/plugins/firehydrant/README.md b/plugins/firehydrant/README.md index 572e873c83..aaab8b7d0e 100644 --- a/plugins/firehydrant/README.md +++ b/plugins/firehydrant/README.md @@ -26,11 +26,11 @@ yarn add @backstage/plugin-firehydrant ```ts // In packages/app/src/components/catalog/EntityPage.tsx -import { FirehydrantPage } from '@backstage/plugin-firehydrant'; +import { FirehydrantCard } from '@backstage/plugin-firehydrant'; // Add to code as a grid item - + ; ``` @@ -38,19 +38,12 @@ import { FirehydrantPage } from '@backstage/plugin-firehydrant'; ```yaml proxy: -'/firehydrant/api': - target: 'https://api.firehydrant.io/v1/' - changeOrigin: true - headers: - # Supply the token you generated from https://app.firehydrant.io/organizations/bots - Authorization: Bearer ${FIREHYDRANT_BOT_TOKEN} -``` - -as well as the default url configuration to `app-config.yaml`: - -```yaml -firehydrant: - baseUrl: https://api.firehydrant.io + '/firehydrant/api': + target: 'https://api.firehydrant.io/v1/' + changeOrigin: true + headers: + # Supply the token you generated from https://app.firehydrant.io/organizations/bots + Authorization: Bearer ${FIREHYDRANT_BOT_TOKEN} ``` Note: if you are not using environment variables, you can directly type the API Bot Token into `app-config.yaml`: diff --git a/plugins/firehydrant/api-report.md b/plugins/firehydrant/api-report.md index 32b21b9906..6cd8270178 100644 --- a/plugins/firehydrant/api-report.md +++ b/plugins/firehydrant/api-report.md @@ -8,10 +8,10 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { RouteRef } from '@backstage/core-plugin-api'; -// Warning: (ae-missing-release-tag) "FirehydrantPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// Warning: (ae-missing-release-tag) "FirehydrantCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const FirehydrantPage: () => JSX.Element; +export const FirehydrantCard: () => JSX.Element; // Warning: (ae-missing-release-tag) "firehydrantPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index f2f2dfe84b..a5531ac0bc 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -4,6 +4,7 @@ "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", + "private": false, "publishConfig": { "access": "public", "main": "dist/index.esm.js", @@ -27,7 +28,7 @@ "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.45", - "moment": "^2.29.1", + "luxon": "^1.27.0", "react": "^16.13.1", "react-dom": "^16.13.1", "react-use": "^17.2.4" diff --git a/plugins/firehydrant/src/api/index.ts b/plugins/firehydrant/src/api/index.ts index e5e664aed8..b78e81a024 100644 --- a/plugins/firehydrant/src/api/index.ts +++ b/plugins/firehydrant/src/api/index.ts @@ -97,19 +97,18 @@ export class FireHydrantAPIClient implements FireHydrantAPI { incidents: [] as Incident[], }; - if (response.ok) { - if (json.data?.length === 0) { - return servicesData; - } - - servicesData.service = json.data[0]; - - const incidentsJson = await this.getServiceIncidents({ - serviceId: json.data[0].id, - }); - - servicesData.incidents = incidentsJson; + if (json.data?.length === 0) { + return servicesData; } + + servicesData.service = json.data[0]; + + const incidentsJson = await this.getServiceIncidents({ + serviceId: json.data[0].id, + }); + + servicesData.incidents = incidentsJson; + return servicesData; } diff --git a/plugins/firehydrant/src/components/ServiceAnalytics/ServiceAnalytics.tsx b/plugins/firehydrant/src/components/ServiceAnalytics/ServiceAnalytics.tsx index 996d705a9a..e5818ef484 100644 --- a/plugins/firehydrant/src/components/ServiceAnalytics/ServiceAnalytics.tsx +++ b/plugins/firehydrant/src/components/ServiceAnalytics/ServiceAnalytics.tsx @@ -15,17 +15,18 @@ */ import React from 'react'; import { makeStyles } from '@material-ui/core/styles'; -import moment, { Moment } from 'moment'; -import Alert from '@material-ui/lab/Alert'; -import { Table, TableColumn, Progress } from '@backstage/core-components'; +import { DateTime } from 'luxon'; +import { + ResponseErrorPanel, + Table, + TableColumn, + Progress, +} from '@backstage/core-components'; const useStyles = makeStyles({ container: { overflow: 'auto', width: '100%', - '& h5': { - fontSize: '18px !important', - }, '& td': { minWidth: '145px', }, @@ -41,8 +42,8 @@ export const DenseTable = ({ endDate, }: { service: object; - startDate: Moment; - endDate: Moment; + startDate: DateTime; + endDate: DateTime; }) => { const classes = useStyles(); @@ -60,7 +61,9 @@ export const DenseTable = ({
; } else if (error) { - return {error.message}; + return ; } - - const startDate = moment().subtract(30, 'days').utc(); - const endDate = moment().utc(); + const startDate = DateTime.now().minus({ days: 30 }).toUTC(); + const endDate = DateTime.now().toUTC(); // Transform and format the data to display in the table if (value.id) { @@ -140,7 +142,7 @@ export const ServiceAnalytics = ({ ? calcHealthiness({ mttm: value.mttm, incidents: value.count, - range: endDate.diff(startDate, 'seconds'), + range: endDate.diff(startDate, 'seconds').as('seconds'), }) : '100%', impacted: value.total_time ? secondsToDhms(value.total_time) : '-', diff --git a/plugins/firehydrant/src/components/ServiceDetailsCard/ServiceDetailsCard.tsx b/plugins/firehydrant/src/components/ServiceDetailsCard/ServiceDetailsCard.tsx index dba81fa88f..b70c578e11 100644 --- a/plugins/firehydrant/src/components/ServiceDetailsCard/ServiceDetailsCard.tsx +++ b/plugins/firehydrant/src/components/ServiceDetailsCard/ServiceDetailsCard.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ import React, { useEffect, useState } from 'react'; -import moment from 'moment'; +import { DateTime } from 'luxon'; import { ServiceAnalytics } from '../ServiceAnalytics/ServiceAnalytics'; import { Box, @@ -32,20 +32,22 @@ import { Incident } from '../types'; import { ServiceIncidentsResponse } from '../../api/types'; import { useServiceDetails } from '../serviceDetails'; import { useServiceAnalytics } from '../serviceAnalytics'; -import { InfoCard, Progress } from '@backstage/core-components'; +import { + InfoCard, + Link, + Progress, + ResponseErrorPanel, +} from '@backstage/core-components'; import { configApiRef, useApi } from '@backstage/core-plugin-api'; const useStyles = makeStyles(theme => ({ - infoCard: { - height: '342px', - }, button: { color: '#3b2492', display: 'grid', gridGap: '4px', textAlign: 'center', justifyItems: 'center', - width: '102px', + width: '105px', backgroundColor: theme.palette.type === 'dark' ? '#f1edff' : '', '&:hover, &:focus': { backgroundColor: '#f1edff', @@ -59,7 +61,8 @@ const useStyles = makeStyles(theme => ({ }, border: '1px solid #3b2492', borderRadius: '5px', - padding: '10px', + padding: '8px 10px', + textTransform: 'none', }, buttonLink: { backgroundColor: '#3b2492', @@ -101,28 +104,18 @@ const useStyles = makeStyles(theme => ({ alignItems: 'center', padding: '10px', background: '#f1edff', - color: theme.palette.type === 'dark' ? '#3b2492' : '#fff', + color: '#3b2492', }, })); -const ServiceWarning = ({ text }: { text: string }) => { - const classes = useStyles(); - return ( -
- -   {text} -
- ); -}; - const ServiceAnalyticsView = ({ serviceId, startDate, endDate, }: { serviceId: string; - startDate: moment.Moment; - endDate: moment.Moment; + startDate: DateTime; + endDate: DateTime; }) => { const { loading: analyticsLoading, @@ -130,8 +123,8 @@ const ServiceAnalyticsView = ({ error: analyticsError, } = useServiceAnalytics({ serviceId, - startDate: startDate.format('YYYY-MM-DD'), - endDate: endDate.format('YYYY-MM-DD'), + startDate: startDate.toFormat('YYYY-MM-DD'), + endDate: endDate.toFormat('YYYY-MM-DD'), }); return ( @@ -153,8 +146,8 @@ export const ServiceDetailsCard = () => { configApi.getOptionalString('firehydrant.baseUrl') || 'https://app.firehydrant.io'; - const startDate = moment().subtract(30, 'days').utc(); - const endDate = moment().utc(); + const startDate = DateTime.now().minus({ days: 30 }).toUTC(); + const endDate = DateTime.now().toUTC(); // The Backstage service name in FireHydrant is a unique formatted string // that requires the entity's kind, name, and namespace. @@ -181,9 +174,7 @@ export const ServiceDetailsCard = () => { } if (error) { - return ( - - ); + return ; } const headerText: string = showServiceDetails @@ -197,9 +188,12 @@ export const ServiceDetailsCard = () => { )},"value":${JSON.stringify(value?.service?.id)}}]}`; return ( - + {!showServiceDetails && !loading && ( - +
+ +   This service does not exist in FireHydrant. +
)} {showServiceDetails && ( { className={classes.buttonLink} color="default" href={serviceIncidentsLink} + startIcon={} target="_blank" variant="outlined" > - View service incidents   - + View service incidents @@ -230,9 +224,14 @@ export const ServiceDetailsCard = () => { {incidents && incidents?.slice(0, 5).map((incident: Incident, index: number) => ( ))} @@ -240,34 +239,55 @@ export const ServiceDetailsCard = () => { View in FireHydrant - - - Declare an incident - - + + + + + Declare an incident + + + + - - View all incidents - + + + + + + View all incidents + + + {showServiceDetails && ( - - - View Service Details - + + + + + + View Service Details + + + )} diff --git a/plugins/firehydrant/src/index.ts b/plugins/firehydrant/src/index.ts index 3b9b584fb8..465e42f1ae 100644 --- a/plugins/firehydrant/src/index.ts +++ b/plugins/firehydrant/src/index.ts @@ -13,4 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { firehydrantPlugin, FirehydrantPage } from './plugin'; +export { firehydrantPlugin, FirehydrantCard } from './plugin'; diff --git a/plugins/firehydrant/src/plugin.ts b/plugins/firehydrant/src/plugin.ts index e4794ab4ce..4277c1833f 100644 --- a/plugins/firehydrant/src/plugin.ts +++ b/plugins/firehydrant/src/plugin.ts @@ -18,7 +18,7 @@ import { createApiFactory, createPlugin, discoveryApiRef, - createRoutableExtension, + createComponentExtension, } from '@backstage/core-plugin-api'; import { rootRouteRef } from './routes'; @@ -37,10 +37,13 @@ export const firehydrantPlugin = createPlugin({ }, }); -export const FirehydrantPage = firehydrantPlugin.provide( - createRoutableExtension({ - component: () => - import('./components/ServiceDetailsCard').then(m => m.ServiceDetailsCard), - mountPoint: rootRouteRef, +export const FirehydrantCard = firehydrantPlugin.provide( + createComponentExtension({ + component: { + lazy: () => + import('./components/ServiceDetailsCard').then( + m => m.ServiceDetailsCard, + ), + }, }), );