Skip to content

Commit

Permalink
Merge pull request #1665 from florinnania/add-sign-in-button-in-entit…
Browse files Browse the repository at this point in the history
…y-github-related-cards

Add sign in button in entity GitHub related cards
  • Loading branch information
Xantier authored Oct 15, 2024
2 parents ea08cae + 3b922f5 commit d3307d4
Show file tree
Hide file tree
Showing 15 changed files with 252 additions and 9 deletions.
7 changes: 7 additions & 0 deletions .changeset/wise-seahorses-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@roadiehq/backstage-plugin-github-pull-requests': minor
'@roadiehq/backstage-plugin-security-insights': minor
'@roadiehq/backstage-plugin-github-insights': minor
---

Add SignIn button to all Github related cards from entity overwiew page.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ import { defaultIntegrationsConfig } from '../../../mocks/scmIntegrationsApiMock

const mockGithubAuth = {
getAccessToken: async (_: string[]) => 'test-token',
sessionState$: jest.fn(() => ({
subscribe: (fn: (a: string) => void) => {
fn('SignedIn');
return { unsubscribe: jest.fn() };
},
})),
};

const apis: [AnyApiRef, Partial<unknown>][] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ import {
GITHUB_INSIGHTS_ANNOTATION,
} from '../../utils/isGithubInsightsAvailable';
import { useEntity } from '@backstage/plugin-catalog-react';
import {
GithubNotAuthorized,
useGithubLoggedIn,
} from '../../../hooks/useGithubLoggedIn';

const useStyles = makeStyles(theme => ({
infoCard: {
Expand All @@ -48,12 +52,21 @@ const ContributorsCard = () => {
const { hostname } = useEntityGithubScmIntegration(entity);
const projectAlert = isGithubInsightsAvailable(entity);
const { owner, repo } = useProjectEntity(entity);
const isLoggedIn = useGithubLoggedIn();
if (!projectAlert) {
return (
<MissingAnnotationEmptyState annotation={GITHUB_INSIGHTS_ANNOTATION} />
);
}

if (!isLoggedIn) {
return (
<InfoCard title="Contributors" className={classes.infoCard}>
<GithubNotAuthorized />
</InfoCard>
);
}

if (loading) {
return <Progress />;
} else if (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ import { defaultIntegrationsConfig } from '../../../mocks/scmIntegrationsApiMock

const mockGithubAuth = {
getAccessToken: async (_: string[]) => 'test-token',
sessionState$: jest.fn(() => ({
subscribe: (fn: (a: string) => void) => {
fn('SignedIn');
return { unsubscribe: jest.fn() };
},
})),
};

const apis: [AnyApiRef, Partial<unknown>][] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ import {
import { useRequest } from '../../../hooks/useRequest';
import { colors } from './colors';
import { useProjectEntity } from '../../../hooks/useProjectEntity';
import {
GithubNotAuthorized,
useGithubLoggedIn,
} from '../../../hooks/useGithubLoggedIn';
import {
isGithubInsightsAvailable,
GITHUB_INSIGHTS_ANNOTATION,
Expand Down Expand Up @@ -66,7 +70,7 @@ type Language = {
[key: string]: number;
};

const LanguagesCard = () => {
const LanguagesCardContent = () => {
const { entity } = useEntity();
let barWidth = 0;
const classes = useStyles();
Expand Down Expand Up @@ -154,4 +158,17 @@ const LanguagesCard = () => {
);
};

const LanguagesCard = () => {
const classes = useStyles();
const isLoggedIn = useGithubLoggedIn();

return isLoggedIn ? (
<LanguagesCardContent />
) : (
<InfoCard title="Languages" className={classes.infoCard}>
<GithubNotAuthorized />
</InfoCard>
);
};

export default LanguagesCard;
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ import { defaultIntegrationsConfig } from '../../../mocks/scmIntegrationsApiMock

const mockGithubAuth = {
getAccessToken: async (_: string[]) => 'test-token',
sessionState$: jest.fn(() => ({
subscribe: (fn: (a: string) => void) => {
fn('SignedIn');
return { unsubscribe: jest.fn() };
},
})),
};

const apis: [AnyApiRef, Partial<unknown>][] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ import {
} from '../../utils/isGithubInsightsAvailable';
import { useEntity } from '@backstage/plugin-catalog-react';
import { styles as useStyles } from '../../utils/styles';
import {
GithubNotAuthorized,
useGithubLoggedIn,
} from '../../../hooks/useGithubLoggedIn';

type Release = {
id: number;
Expand All @@ -41,7 +45,7 @@ type Release = {
name: string;
};

const ReleasesCard = () => {
const ReleasesCardContent = () => {
const classes = useStyles();
const { entity } = useEntity();

Expand Down Expand Up @@ -108,4 +112,17 @@ const ReleasesCard = () => {
);
};

const ReleasesCard = () => {
const classes = useStyles();
const isLoggedIn = useGithubLoggedIn();

return isLoggedIn ? (
<ReleasesCardContent />
) : (
<InfoCard title="Releases" className={classes.infoCard}>
<GithubNotAuthorized />
</InfoCard>
);
};

export default ReleasesCard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright 2024 Larder Software Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useEffect, useState } from 'react';
import {
useApi,
githubAuthApiRef,
SessionState,
} from '@backstage/core-plugin-api';
import { Grid, Tooltip, Button, Typography } from '@material-ui/core';

export const GithubNotAuthorized = () => {
const githubApi = useApi(githubAuthApiRef);
return (
<Grid container>
<Grid item xs={8}>
<Typography>
You are not logged into github. You need to be signed in to see the
content of this card.
</Typography>
</Grid>
<Grid item xs={4} container justifyContent="flex-end">
<Tooltip placement="top" arrow title="Sign in to Github">
<Button
variant="outlined"
color="primary"
// Calling getAccessToken instead of a plain signIn because we are going to get the correct scopes right away. No need to second request
onClick={() => githubApi.getAccessToken('repo')}
>
Sign in
</Button>
</Tooltip>
</Grid>
</Grid>
);
};

export const useGithubLoggedIn = () => {
const githubApi = useApi(githubAuthApiRef);
const [isLoggedIn, setIsLoggedIn] = useState(false);

useEffect(() => {
githubApi.getAccessToken('repo', { optional: true });
const authSubscription = githubApi.sessionState$().subscribe(state => {
if (state === SessionState.SignedIn) {
setIsLoggedIn(true);
}
});
return () => {
authSubscription.unsubscribe();
};
}, [githubApi]);

return isLoggedIn;
};
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ import { handlers } from '../../mocks/handlers';

const mockGithubAuth = {
getAccessToken: async (_: string[]) => 'test-token',
sessionState$: jest.fn(() => ({
subscribe: (fn: (a: string) => void) => {
fn('SignedIn');
return { unsubscribe: jest.fn() };
},
})),
};

const config = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { Entity } from '@backstage/catalog-model';
import { useEntity } from '@backstage/plugin-catalog-react';
import { Tooltip } from '@material-ui/core';
import { TooltipContent } from './components/TooltipContent';
import { GithubNotAuthorized, useGithubLoggedIn } from '../useGithubLoggedIn';

const useStyles = makeStyles(theme => ({
infoCard: {
Expand Down Expand Up @@ -129,14 +130,23 @@ const StatsCard = (props: Props) => {
const PullRequestsStatsCard = (props: Props) => {
const { entity } = useEntity();
const projectName = isGithubSlugSet(entity);
const isLoggedIn = useGithubLoggedIn();

if (!projectName || projectName === '') {
return (
<MissingAnnotationEmptyState
annotation={GITHUB_PULL_REQUESTS_ANNOTATION}
/>
);
}
return <StatsCard {...props} />;

return isLoggedIn ? (
<StatsCard {...props} />
) : (
<InfoCard title="GitHub Pull Requests Statistics">
<GithubNotAuthorized />
</InfoCard>
);
};

export default PullRequestsStatsCard;
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ const GRAPHQL_GITHUB_API = graphql.link('https://api.github.com/graphql');

const mockGithubAuth = {
getAccessToken: async (_: string[]) => 'test-token',
sessionState$: jest.fn(() => ({
subscribe: (fn: (a: string) => void) => {
fn('SignedIn');
return { unsubscribe: jest.fn() };
},
})),
};

const config = {
Expand Down Expand Up @@ -87,10 +93,6 @@ describe('Dependabot alerts overview', () => {
const worker = setupServer();
setupRequestMockHandlers(worker);

beforeEach(() => {
jest.resetAllMocks();
});

describe('GithubDependabotAlertsTable', () => {
beforeEach(() => {
entity = entityStub;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { useProjectEntity } from '../useProjectEntity';
import { useUrl } from '../useUrl';
import { useEntity } from '@backstage/plugin-catalog-react';
import { InfoCard, Progress } from '@backstage/core-components';
import { GithubNotAuthorized, useGithubLoggedIn } from '../useGithubLoggedIn';

const useStyles = makeStyles((theme: Theme) => ({
infoCard: {
Expand Down Expand Up @@ -207,7 +208,7 @@ export const DependabotAlertInformations: FC<DependabotAlertsProps> = ({
);
};

export const DependabotAlertsWidget = () => {
const DependabotAlertsWidgetContent = () => {
const { entity } = useEntity();
const { owner, repo } = useProjectEntity(entity);
const auth = useApi(githubAuthApiRef);
Expand Down Expand Up @@ -283,3 +284,16 @@ export const DependabotAlertsWidget = () => {
<DependabotAlertInformations repository={value} detailsUrl={detailsUrl} />
) : null;
};

export const DependabotAlertsWidget = () => {
const classes = useStyles();
const isLoggedIn = useGithubLoggedIn();

return isLoggedIn ? (
<DependabotAlertsWidgetContent />
) : (
<InfoCard title="Dependabot Alerts" className={classes.infoCard}>
<GithubNotAuthorized />
</InfoCard>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ import { EntityProvider } from '@backstage/plugin-catalog-react';

const mockGithubAuth = {
getAccessToken: async (_: string[]) => 'test-token',
sessionState$: jest.fn(() => ({
subscribe: (fn: (a: string) => void) => {
fn('SignedIn');
return { unsubscribe: jest.fn() };
},
})),
};

const config = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
SecurityInsightFilterState,
} from '../../types';
import { useEntity } from '@backstage/plugin-catalog-react';
import { GithubNotAuthorized, useGithubLoggedIn } from '../useGithubLoggedIn';

const useStyles = makeStyles(theme => ({
infoCard: {
Expand Down Expand Up @@ -71,7 +72,7 @@ const IssuesCounter: FC<IssuesCounterProps> = ({
);
};

export const SecurityInsightsWidget = () => {
const SecurityInsightsWidgetContent = () => {
const { entity } = useEntity();
const { owner, repo } = useProjectEntity(entity);
const classes = useStyles();
Expand Down Expand Up @@ -138,3 +139,16 @@ export const SecurityInsightsWidget = () => {
</InfoCard>
);
};

export const SecurityInsightsWidget = () => {
const classes = useStyles();
const isLoggedIn = useGithubLoggedIn();

return isLoggedIn ? (
<SecurityInsightsWidgetContent />
) : (
<InfoCard title="Security Insights" className={classes.infoCard}>
<GithubNotAuthorized />
</InfoCard>
);
};
Loading

0 comments on commit d3307d4

Please sign in to comment.