Display fetched deployments data in deployments tab (#24)
Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
parent
af021d3357
commit
d2187cbec2
@ -2,7 +2,6 @@ import React, { useCallback, useMemo, useState } from 'react';
|
|||||||
|
|
||||||
import { Button, Typography } from '@material-tailwind/react';
|
import { Button, Typography } from '@material-tailwind/react';
|
||||||
|
|
||||||
import deploymentData from '../../../assets/deployments.json';
|
|
||||||
import DeploymentDetailsCard from './deployments/DeploymentDetailsCard';
|
import DeploymentDetailsCard from './deployments/DeploymentDetailsCard';
|
||||||
import FilterForm, {
|
import FilterForm, {
|
||||||
FilterValue,
|
FilterValue,
|
||||||
@ -15,17 +14,21 @@ const DEFAULT_FILTER_VALUE: FilterValue = {
|
|||||||
status: StatusOptions.ALL_STATUS,
|
status: StatusOptions.ALL_STATUS,
|
||||||
};
|
};
|
||||||
|
|
||||||
const DeploymentsTabPanel = () => {
|
const DeploymentsTabPanel = ({
|
||||||
|
deployments,
|
||||||
|
}: {
|
||||||
|
deployments: DeploymentDetails[];
|
||||||
|
}) => {
|
||||||
const [filterValue, setFilterValue] = useState(DEFAULT_FILTER_VALUE);
|
const [filterValue, setFilterValue] = useState(DEFAULT_FILTER_VALUE);
|
||||||
|
|
||||||
const productionDeployment = useMemo(() => {
|
const productionDeployment = useMemo(() => {
|
||||||
return deploymentData.find((deployment) => {
|
return deployments.find((deployment) => {
|
||||||
return deployment.isProduction === true;
|
return deployment.isProduction === true;
|
||||||
}) as DeploymentDetails;
|
}) as DeploymentDetails;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const filteredDeployments = useMemo<DeploymentDetails[]>(() => {
|
const filteredDeployments = useMemo<DeploymentDetails[]>(() => {
|
||||||
return deploymentData.filter((deployment) => {
|
return deployments.filter((deployment) => {
|
||||||
// Searched branch filter
|
// Searched branch filter
|
||||||
const branchMatch =
|
const branchMatch =
|
||||||
!filterValue.searchedBranch ||
|
!filterValue.searchedBranch ||
|
||||||
@ -36,7 +39,8 @@ const DeploymentsTabPanel = () => {
|
|||||||
// Status filter
|
// Status filter
|
||||||
const statusMatch =
|
const statusMatch =
|
||||||
filterValue.status === StatusOptions.ALL_STATUS ||
|
filterValue.status === StatusOptions.ALL_STATUS ||
|
||||||
deployment.status === filterValue.status;
|
// TODO: match status field types
|
||||||
|
(deployment.status as unknown as StatusOptions) === filterValue.status;
|
||||||
|
|
||||||
const dateMatch =
|
const dateMatch =
|
||||||
!filterValue.updateAtRange ||
|
!filterValue.updateAtRange ||
|
||||||
|
@ -5,7 +5,7 @@ import { Typography, Button, Chip } from '@material-tailwind/react';
|
|||||||
import ActivityCard from './ActivityCard';
|
import ActivityCard from './ActivityCard';
|
||||||
import activityDetails from '../../../assets/activities.json';
|
import activityDetails from '../../../assets/activities.json';
|
||||||
import { ProjectDetails } from '../../../types/project';
|
import { ProjectDetails } from '../../../types/project';
|
||||||
import { relativeTime } from '../../../utils/time';
|
import { relativeTimeMs } from '../../../utils/time';
|
||||||
|
|
||||||
interface OverviewProps {
|
interface OverviewProps {
|
||||||
project: ProjectDetails;
|
project: ProjectDetails;
|
||||||
@ -63,9 +63,7 @@ const OverviewTabPanel = ({ project }: OverviewProps) => {
|
|||||||
<div className="flex justify-between p-2 text-sm">
|
<div className="flex justify-between p-2 text-sm">
|
||||||
<p>^ Created</p>
|
<p>^ Created</p>
|
||||||
<p>
|
<p>
|
||||||
{/* TODO: Use following time conversion wherever required */}
|
{relativeTimeMs(project.createdAt)} by ^ {project.createdBy}
|
||||||
{relativeTime(new Date(Number(project.createdAt)).toISOString())} by
|
|
||||||
^ {project.createdBy}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,7 +46,7 @@ const ProjectTabs = ({ project }: ProjectTabsProps) => {
|
|||||||
<OverviewTabPanel project={project} />
|
<OverviewTabPanel project={project} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<DeploymentsTabPanel />
|
<DeploymentsTabPanel deployments={project.deployments} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<Database />
|
<Database />
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
ChipProps,
|
ChipProps,
|
||||||
} from '@material-tailwind/react';
|
} from '@material-tailwind/react';
|
||||||
|
|
||||||
import { relativeTime } from '../../../../utils/time';
|
import { relativeTimeMs } from '../../../../utils/time';
|
||||||
import ConfirmDialog from '../../../shared/ConfirmDialog';
|
import ConfirmDialog from '../../../shared/ConfirmDialog';
|
||||||
import DeploymentDialogBodyCard from './DeploymentDialogBodyCard';
|
import DeploymentDialogBodyCard from './DeploymentDialogBodyCard';
|
||||||
import { DeploymentDetails, Status } from '../../../../types/project';
|
import { DeploymentDetails, Status } from '../../../../types/project';
|
||||||
@ -58,7 +58,7 @@ const DeploymentDetailsCard = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="col-span-1 flex items-center">
|
<div className="col-span-1 flex items-center">
|
||||||
<Typography color="gray" className="grow">
|
<Typography color="gray" className="grow">
|
||||||
{relativeTime(deployment.updatedAt)} ^ {deployment.author}
|
{relativeTimeMs(deployment.updatedAt)} ^ {deployment.author}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Menu placement="bottom-start">
|
<Menu placement="bottom-start">
|
||||||
<MenuHandler>
|
<MenuHandler>
|
||||||
|
@ -5,7 +5,7 @@ import HorizontalLine from '../components/HorizontalLine';
|
|||||||
import { IconButton, Typography } from '@material-tailwind/react';
|
import { IconButton, Typography } from '@material-tailwind/react';
|
||||||
import ProjectSearchBar from '../components/projects/ProjectSearchBar';
|
import ProjectSearchBar from '../components/projects/ProjectSearchBar';
|
||||||
import { useGQLClient } from '../context/GQLClientContext';
|
import { useGQLClient } from '../context/GQLClientContext';
|
||||||
import { ProjectDetails } from '../types/project';
|
import { Environments, ProjectDetails } from '../types/project';
|
||||||
|
|
||||||
const ProjectSearch = () => {
|
const ProjectSearch = () => {
|
||||||
const client = useGQLClient();
|
const client = useGQLClient();
|
||||||
@ -21,6 +21,17 @@ const ProjectSearch = () => {
|
|||||||
|
|
||||||
const updatedProjectsPromises = projects.map(async (project: any) => {
|
const updatedProjectsPromises = projects.map(async (project: any) => {
|
||||||
const { deployments } = await client.getDeployments(String(project.id));
|
const { deployments } = await client.getDeployments(String(project.id));
|
||||||
|
const updatedDeployments = deployments.map((deployment: any) => {
|
||||||
|
return {
|
||||||
|
...deployment,
|
||||||
|
isProduction: deployment.environment === Environments.PRODUCTION,
|
||||||
|
author: '',
|
||||||
|
commit: {
|
||||||
|
hash: '',
|
||||||
|
message: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...project,
|
...project,
|
||||||
@ -28,7 +39,7 @@ const ProjectSearch = () => {
|
|||||||
icon: '',
|
icon: '',
|
||||||
title: project.name,
|
title: project.name,
|
||||||
organization: orgName,
|
organization: orgName,
|
||||||
deployments,
|
deployments: updatedDeployments,
|
||||||
url: '',
|
url: '',
|
||||||
domain: null,
|
domain: null,
|
||||||
createdBy: project.owner.name,
|
createdBy: project.owner.name,
|
||||||
|
@ -30,6 +30,7 @@ export interface DeploymentDetails {
|
|||||||
isProduction: boolean;
|
isProduction: boolean;
|
||||||
status: Status;
|
status: Status;
|
||||||
branch: string;
|
branch: string;
|
||||||
|
environment: Environments;
|
||||||
isCurrent: boolean;
|
isCurrent: boolean;
|
||||||
commit: {
|
commit: {
|
||||||
hash: string;
|
hash: string;
|
||||||
@ -46,9 +47,9 @@ export enum Status {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum Environments {
|
export enum Environments {
|
||||||
PRODUCTION = 'production',
|
PRODUCTION = 'Production',
|
||||||
PREVIEW = 'preview',
|
PREVIEW = 'Preview',
|
||||||
DEVELOPMENT = 'development',
|
DEVELOPMENT = 'Development',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EnvironmentVariable {
|
export interface EnvironmentVariable {
|
||||||
|
@ -9,3 +9,13 @@ import { DateTime } from 'luxon';
|
|||||||
export const relativeTime = (time: string) => {
|
export const relativeTime = (time: string) => {
|
||||||
return DateTime.fromISO(time).toRelative();
|
return DateTime.fromISO(time).toRelative();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts time in millisecond format to a human-readable relative time with respect to the current time.
|
||||||
|
*
|
||||||
|
* @param {string} time - The input time in millisecond.
|
||||||
|
* @returns {string} - A human-readable relative time string.
|
||||||
|
*/
|
||||||
|
export const relativeTimeMs = (time: string) => {
|
||||||
|
return relativeTime(new Date(Number(time)).toISOString());
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user