Skip to content

Commit

Permalink
issue table added (#136) (#135)
Browse files Browse the repository at this point in the history
Signed-off-by: Abhay Soni <[email protected]>
  • Loading branch information
Abhay-soni-developer authored Jul 28, 2022
1 parent 376b04f commit e160dd3
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 31 deletions.
6 changes: 6 additions & 0 deletions src/api/GitlabCIApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ContributorData,
MergeRequest,
PipelineObject,
IssueObject
} from '../components/types';

export interface PipelineSummary {
Expand All @@ -25,6 +26,10 @@ export interface LanguagesSummary {
getLanguagesData: any;
}

export interface IssuesSummary {
getIssuesData: IssueObject[]
}

export const GitlabCIApiRef = createApiRef<GitlabCIApi>({
id: 'plugin.gitlabci.service',
});
Expand All @@ -48,4 +53,5 @@ export type GitlabCIApi = {
pipelineID: string,
): Promise<Object | undefined>;
getProjectDetails(projectSlug: string): Promise<Object | undefined>;
getIssuesSummary(projectID: string): Promise<IssuesSummary | undefined>;
};
45 changes: 35 additions & 10 deletions src/api/GitlabCIClient.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import {
PipelineSummary,
GitlabCIApi,
ContributorsSummary,
LanguagesSummary,
MergeRequestsSummary,
MergeRequestsStatusSummary,
} from './GitlabCIApi';
import { DiscoveryApi } from '@backstage/core-plugin-api';
import {
ContributorData,
MergeRequest,
PipelineObject,
} from '../components/types';
import { IssueObject } from './../components/types';
import {
ContributorsSummary,
GitlabCIApi,
IssuesSummary,
LanguagesSummary,
MergeRequestsStatusSummary,
MergeRequestsSummary,
PipelineSummary,
} from './GitlabCIApi';

export class GitlabCIClient implements GitlabCIApi {
discoveryApi: DiscoveryApi;
Expand All @@ -37,7 +39,7 @@ export class GitlabCIClient implements GitlabCIApi {
);
if (response.status === 200) {
return (await response.json()) as T;
}
}
return [];
}

Expand All @@ -62,6 +64,29 @@ export class GitlabCIClient implements GitlabCIApi {
};
}

async getIssuesSummary(
projectId: string,
): Promise<IssuesSummary | undefined> {
const issuesObject = await this.callApi<IssueObject[]>(
`projects/${projectId}/issues`,
{},
);

let projectObj: any = await this.callApi<Object>(
'projects/' + projectId,
{},
);
if (issuesObject) {
issuesObject.forEach((element: IssueObject) => {
element.project_name = projectObj?.name;
});
}

return {
getIssuesData: issuesObject!,
};
}

async getProjectName(projectID?: string): Promise<string | undefined> {
let projectObj: any = await this.callApi<Object>(
'projects/' + projectID,
Expand Down Expand Up @@ -142,7 +167,7 @@ export class GitlabCIClient implements GitlabCIApi {

async getProjectDetails(projectSlug?: string): Promise<Object | undefined> {
let projectDetails: any;
if(projectSlug){
if (projectSlug) {
projectDetails = await this.callApi<Object>(
'projects/' + encodeURIComponent(projectSlug),
{},
Expand Down
13 changes: 7 additions & 6 deletions src/components/GitlabCI/GitlabCI.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import React from 'react';
import { Content, Page } from '@backstage/core-components';
import { Grid } from '@material-ui/core';
import {
Page,
Content,
} from '@backstage/core-components';
import React from 'react';
import {
ContributorsCard,
IssuesTable,
LanguagesCard,
MergeRequestsTable,
PipelinesTable,
MergeRequestStats,
PipelinesTable,
} from '../widgets';

export const GitlabCI = () => (
Expand All @@ -31,6 +29,9 @@ export const GitlabCI = () => (
<Grid item md={12}>
<MergeRequestsTable />
</Grid>
<Grid item md={12}>
<IssuesTable />
</Grid>
</Grid>
</Content>
</Page>
Expand Down
26 changes: 26 additions & 0 deletions src/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,30 @@ export type PipelineObject = {
updated_at: string;
};

export type IssueObject = {
id: string;
project_name: string;
project_id: string;
title: string;
state: IssueState;
type: IssueType;
description: string;
created_at: string;
updated_at: string;
author: Author;
web_url: string;
};

type Author = {
id: string;
username: string;
name: string;
avatar_url: string;
web_url: string;
};

export type MergeRequestState = 'opened' | 'closed' | 'all';

export type IssueState = 'opened' | 'closed';

export type IssueType = 'issue' | 'incident' | 'test_case';
89 changes: 89 additions & 0 deletions src/components/widgets/IssuesTable/IssuesTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { Progress, Table, TableColumn } from '@backstage/core-components';
import { useApi } from '@backstage/core-plugin-api';
import Alert from '@material-ui/lab/Alert';
import React from 'react';
import { useAsync } from 'react-use';
import { GitlabCIApiRef } from '../../../api';
import { gitlabAppData, gitlabAppSlug } from '../../gitlabAppData';
import { IssueObject } from '../../types';
import { getElapsedTime } from '../../utils';
import { AuthorColumn, IssueStateIndicator, IssueTitle } from './columns';

// export type IssueObject = {
// id: string;
// project_id: string;
// title: string;
// state: IssueState;
// type: IssueType;
// description: string;
// created_at: string;
// updated_at: string;
// author: Author;
// };

export const DenseTable = ({
issuesObjects,
projectName,
}: {
issuesObjects: IssueObject[];
projectName: string | undefined;
}) => {
const columns: TableColumn<IssueObject>[] = [
{ title: 'Issue ID', field: 'id' },
{ title: 'Title', render: IssueTitle },
{ title: 'Author', render: AuthorColumn },
{ title: 'Created At', field: 'created_at' },
{ title: 'Issue Type', field: 'type' },
{ title: 'Issue Status', render: IssueStateIndicator },
];

const title = 'Gitlab Issues: ' + projectName;

const data = issuesObjects.map(issue => ({
...issue,
created_at: getElapsedTime(issue.created_at),
}));

return (
<Table
title={title}
options={{ search: true, paging: true }}
columns={columns}
data={data}
/>
);
};

export const IssuesTable = ({}) => {
const { project_id } = gitlabAppData();
const { project_slug } = gitlabAppSlug();

const GitlabCIAPI = useApi(GitlabCIApiRef);

const { value, loading, error } = useAsync(async (): Promise<{
data: IssueObject[];
projectName: string;
}> => {
let projectDetails: any = await GitlabCIAPI.getProjectDetails(project_slug);
let projectId = project_id ? project_id : projectDetails?.id;
let projectName = await GitlabCIAPI.getProjectName(projectId);
const gitlabIssuesObject = await GitlabCIAPI.getIssuesSummary(project_id);
const data = gitlabIssuesObject?.getIssuesData;
let renderData: any = { data, projectName };

return renderData;
}, []);

if (loading) {
return <Progress />;
} else if (error) {
return <Alert severity="error">{error.message}</Alert>;
}

return (
<DenseTable
issuesObjects={value?.data || []}
projectName={value?.projectName}
/>
);
};
55 changes: 55 additions & 0 deletions src/components/widgets/IssuesTable/columns.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
Avatar,
StatusAborted,
StatusOK,
StatusPending,
TableColumn,
} from '@backstage/core-components';
import { Box, Typography } from '@material-ui/core';
import Link from '@material-ui/core/Link';
import React from 'react';
import { IssueObject } from '../../types';

export const IssueStateIndicator = (
issueObject: IssueObject,
): TableColumn<{}> => {
switch (issueObject.state) {
case 'opened':
return <StatusPending>open</StatusPending>;
case 'closed':
return <StatusOK>close</StatusOK>;
default:
return <StatusAborted />;
}
};

export function IssueTitle(issueObject: IssueObject): TableColumn<{}> {
return (
<Typography variant="body2" noWrap>
<Box ml={1} component="span">
<Link href={issueObject.web_url} target="_blank">
{issueObject.title}
</Link>
</Box>
</Typography>
);
}

export function AuthorColumn(issueObject: IssueObject): TableColumn<{}> {
return (
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Avatar
customStyles={{ width: 32, height: 32 }}
picture={issueObject.author.avatar_url}
displayName={issueObject.author.username}
/>
<Typography variant="body2" noWrap>
<Box ml={1} component="span">
<Link href={issueObject.author.web_url} target="_blank">
{issueObject.author.username}
</Link>
</Box>
</Typography>
</Box>
);
}
1 change: 1 addition & 0 deletions src/components/widgets/IssuesTable/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { IssuesTable } from './IssuesTable';
3 changes: 2 additions & 1 deletion src/components/widgets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export { LanguagesCard } from './LanguagesCard';
export { ContributorsCard } from './ContributorsCard';
export { MergeRequestStats } from './MergeRequestStats';
export { MergeRequestsTable } from './MergeRequestsTable';
export { PipelinesTable } from './PipelinesTable';
export { PipelinesTable } from './PipelinesTable';
export { IssuesTable } from "./IssuesTable";
20 changes: 10 additions & 10 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export {
gitlabPlugin,
EntityGitlabContent,
EntityGitlabLanguageCard,
EntityGitlabContributorsCard,
EntityGitlabMergeRequestsTable,
EntityGitlabMergeRequestStatsCard,
EntityGitlabPipelinesTable,
export {
EntityGitlabContent,
EntityGitlabContributorsCard,
EntityGitlabIssuesTable,
EntityGitlabLanguageCard,
EntityGitlabMergeRequestsTable,
EntityGitlabMergeRequestStatsCard,
EntityGitlabPipelinesTable,
gitlabPlugin,
} from './plugin';

export { isGitlabAvailable } from './Router';
export { isGitlabAvailable } from './Router';
18 changes: 14 additions & 4 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createPlugin,
createRoutableExtension,
createComponentExtension,
} from '@backstage/core-plugin-api';
import {
createComponentExtension, createPlugin,
createRoutableExtension
} from '@backstage/core-plugin-api';

import {
configApiRef,
Expand Down Expand Up @@ -86,4 +86,14 @@ export const EntityGitlabPipelinesTable = gitlabPlugin.provide(
import('./components/widgets/index').then((m) => m.PipelinesTable),
},
})
);

export const EntityGitlabIssuesTable = gitlabPlugin.provide(
createComponentExtension({
name: 'EntityGitlabIssuesTable',
component: {
lazy: () =>
import('./components/widgets/index').then((m) => m.IssuesTable),
},
})
);

0 comments on commit e160dd3

Please sign in to comment.