forked from cerc-io/snowballtools-base
List latest commits from project repo in overview tab (#55)
This commit is contained in:
parent
1c9597739b
commit
7e522aa45d
@ -188,7 +188,7 @@ type Mutation {
|
||||
updateEnvironmentVariable(environmentVariableId: String!, data: UpdateEnvironmentVariableInput!): Boolean!
|
||||
removeEnvironmentVariable(environmentVariableId: String!): Boolean!
|
||||
updateDeploymentToProd(deploymentId: String!): Boolean!
|
||||
addProject(projectDetails: AddProjectInput): Boolean!
|
||||
addProject(data: AddProjectInput): Boolean!
|
||||
updateProject(projectId: String!, projectDetails: UpdateProjectInput): Boolean!
|
||||
redeployToProd(deploymentId: String!): Boolean!
|
||||
deleteProject(projectId: String!): Boolean!
|
||||
|
@ -3,31 +3,24 @@ import React from 'react';
|
||||
import { Typography, IconButton } from '@material-tailwind/react';
|
||||
|
||||
import { relativeTime } from '../../../utils/time';
|
||||
|
||||
interface ActivityDetails {
|
||||
author: string;
|
||||
authorAvatar: string;
|
||||
createdAt: string;
|
||||
branch: string;
|
||||
message: string;
|
||||
}
|
||||
import { GitCommitDetails } from '../../../types/project';
|
||||
|
||||
interface ActivityCardProps {
|
||||
activity: ActivityDetails;
|
||||
activity: GitCommitDetails;
|
||||
}
|
||||
|
||||
const ActivityCard = ({ activity }: ActivityCardProps) => {
|
||||
return (
|
||||
<div className="group flex hover:bg-gray-200 rounded mt-1">
|
||||
<div className="w-4">{activity.authorAvatar}</div>
|
||||
<div className="w-4">^</div>
|
||||
|
||||
<div className="grow">
|
||||
<Typography>{activity.author}</Typography>
|
||||
<Typography>{activity.commit.author?.name}</Typography>
|
||||
<Typography variant="small" color="gray">
|
||||
{relativeTime(activity.createdAt)} ^ {activity.branch}
|
||||
{relativeTime(activity.commit.author!.date!)} ^ {activity.branch.name}
|
||||
</Typography>
|
||||
<Typography variant="small" color="gray">
|
||||
{activity.message}
|
||||
{activity.commit.message}
|
||||
</Typography>
|
||||
</div>
|
||||
<div className="mr-2 self-center hidden group-hover:block">
|
||||
|
@ -1,11 +1,14 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Project } from 'gql-client';
|
||||
|
||||
import { Typography, Button, Chip } from '@material-tailwind/react';
|
||||
|
||||
import ActivityCard from './ActivityCard';
|
||||
import activityDetails from '../../../assets/activities.json';
|
||||
import { relativeTimeMs } from '../../../utils/time';
|
||||
import { useOctokit } from '../../../context/OctokitContext';
|
||||
import { GitCommitDetails } from '../../../types/project';
|
||||
|
||||
const COMMITS_PER_PAGE = 4;
|
||||
|
||||
interface OverviewProps {
|
||||
project: Project;
|
||||
@ -15,6 +18,58 @@ interface OverviewProps {
|
||||
const IS_DOMAIN_SETUP = false;
|
||||
|
||||
const OverviewTabPanel = ({ project }: OverviewProps) => {
|
||||
const { octokit } = useOctokit();
|
||||
const [activities, setActivities] = useState<GitCommitDetails[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!octokit) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Save repo commits in DB and avoid using GitHub API in frontend
|
||||
// TODO: Figure out fetching latest commits for all branches
|
||||
const fetchRepoActivity = async () => {
|
||||
const [owner, repo] = project.repository.split('/');
|
||||
|
||||
// Get all branches in project repo
|
||||
const result = await octokit.rest.repos.listBranches({
|
||||
owner,
|
||||
repo,
|
||||
});
|
||||
|
||||
// Get first 4 commits from repo branches
|
||||
const commitsByBranchPromises = result.data.map(async (branch) => {
|
||||
const result = await octokit.rest.repos.listCommits({
|
||||
owner,
|
||||
repo,
|
||||
sha: branch.commit.sha,
|
||||
per_page: COMMITS_PER_PAGE,
|
||||
});
|
||||
|
||||
return result.data.map((data) => ({
|
||||
...data,
|
||||
branch,
|
||||
}));
|
||||
});
|
||||
|
||||
const commitsByBranch = await Promise.all(commitsByBranchPromises);
|
||||
const commitsWithBranch = commitsByBranch.flat();
|
||||
|
||||
// Order commits by date and set latest 4 commits in activity section
|
||||
const orderedCommits = commitsWithBranch
|
||||
.sort(
|
||||
(a, b) =>
|
||||
new Date(b.commit.author!.date!).getTime() -
|
||||
new Date(a.commit.author!.date!).getTime(),
|
||||
)
|
||||
.slice(0, COMMITS_PER_PAGE);
|
||||
|
||||
setActivities(orderedCommits);
|
||||
};
|
||||
|
||||
fetchRepoActivity();
|
||||
}, [octokit, project]);
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-5">
|
||||
<div className="col-span-3 p-2">
|
||||
@ -86,8 +141,8 @@ const OverviewTabPanel = ({ project }: OverviewProps) => {
|
||||
</button>
|
||||
</div>
|
||||
<div className="p-2">
|
||||
{activityDetails.map((activity, key) => {
|
||||
return <ActivityCard activity={activity} key={key} />;
|
||||
{activities.map((activity, index) => {
|
||||
return <ActivityCard activity={activity} key={index} />;
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -44,6 +44,21 @@ export interface GitRepositoryDetails {
|
||||
default_branch?: string;
|
||||
}
|
||||
|
||||
export interface GitBranchDetails {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface GitCommitDetails {
|
||||
branch: GitBranchDetails;
|
||||
commit: {
|
||||
author: {
|
||||
name?: string;
|
||||
date?: string;
|
||||
} | null;
|
||||
message: string;
|
||||
};
|
||||
}
|
||||
|
||||
export enum GitSelect {
|
||||
GITHUB = 'github',
|
||||
GITEA = 'gitea',
|
||||
|
@ -194,15 +194,15 @@ export class GQLClient {
|
||||
return data;
|
||||
}
|
||||
|
||||
async addProject (projectDetails: AddProjectInput): Promise<AddProjectResponse> {
|
||||
const { data } = await this.client.mutate({
|
||||
async addProject (data: AddProjectInput): Promise<AddProjectResponse> {
|
||||
const result = await this.client.mutate({
|
||||
mutation: addProject,
|
||||
variables: {
|
||||
projectDetails
|
||||
data
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
return result.data;
|
||||
}
|
||||
|
||||
async updateProject (projectId: string, projectDetails: UpdateProjectInput): Promise<UpdateProjectResponse> {
|
||||
|
@ -43,8 +43,8 @@ mutation ($deploymentId: String!) {
|
||||
`;
|
||||
|
||||
export const addProject = gql`
|
||||
mutation ($projectDetails: AddProjectInput) {
|
||||
addProject(projectDetails: $projectDetails)
|
||||
mutation ($data: AddProjectInput) {
|
||||
addProject(data: $data)
|
||||
}`;
|
||||
|
||||
export const updateProjectMutation = gql`
|
||||
|
Loading…
Reference in New Issue
Block a user