148 lines
4.7 KiB
TypeScript
148 lines
4.7 KiB
TypeScript
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
import { Deployment, Domain } from 'gql-client';
|
|
import { useOutletContext } from 'react-router-dom';
|
|
|
|
import DeploymentDetailsCard from 'components/projects/project/deployments/DeploymentDetailsCard';
|
|
import FilterForm, {
|
|
FilterValue,
|
|
StatusOptions,
|
|
} from 'components/projects/project/deployments/FilterForm';
|
|
import { OutletContextType } from '../../../../types/types';
|
|
import { useGQLClient } from 'context/GQLClientContext';
|
|
import { Button } from 'components/shared/Button';
|
|
import { RefreshIcon } from 'components/shared/CustomIcon';
|
|
|
|
const DEFAULT_FILTER_VALUE: FilterValue = {
|
|
searchedBranch: '',
|
|
status: StatusOptions.ALL_STATUS,
|
|
};
|
|
const FETCH_DEPLOYMENTS_INTERVAL = 5000;
|
|
|
|
const DeploymentsTabPanel = () => {
|
|
const client = useGQLClient();
|
|
|
|
const { project } = useOutletContext<OutletContextType>();
|
|
|
|
const [filterValue, setFilterValue] = useState(DEFAULT_FILTER_VALUE);
|
|
const [deployments, setDeployments] = useState<Deployment[]>([]);
|
|
const [prodBranchDomains, setProdBranchDomains] = useState<Domain[]>([]);
|
|
|
|
const fetchDeployments = useCallback(async () => {
|
|
const { deployments } = await client.getDeployments(project.id);
|
|
setDeployments(deployments);
|
|
}, [client, project]);
|
|
|
|
const fetchProductionBranchDomains = useCallback(async () => {
|
|
const { domains } = await client.getDomains(project.id, {
|
|
branch: project.prodBranch,
|
|
});
|
|
setProdBranchDomains(domains);
|
|
}, [client, project]);
|
|
|
|
useEffect(() => {
|
|
fetchProductionBranchDomains();
|
|
fetchDeployments();
|
|
|
|
const interval = setInterval(() => {
|
|
fetchDeployments();
|
|
}, FETCH_DEPLOYMENTS_INTERVAL);
|
|
|
|
return () => {
|
|
clearInterval(interval);
|
|
};
|
|
}, [fetchDeployments, fetchProductionBranchDomains]);
|
|
|
|
const currentDeployment = useMemo(() => {
|
|
return deployments.find((deployment) => {
|
|
return deployment.isCurrent === true;
|
|
});
|
|
}, [deployments]);
|
|
|
|
const filteredDeployments = useMemo<Deployment[]>(() => {
|
|
return deployments.filter((deployment) => {
|
|
// Searched branch filter
|
|
const branchMatch =
|
|
!filterValue.searchedBranch ||
|
|
deployment.branch
|
|
.toLowerCase()
|
|
.includes(filterValue.searchedBranch.toLowerCase());
|
|
|
|
// Status filter
|
|
const statusMatch =
|
|
filterValue.status === StatusOptions.ALL_STATUS ||
|
|
// TODO: match status field types
|
|
(deployment.status as unknown as StatusOptions) === filterValue.status;
|
|
|
|
const startDate =
|
|
filterValue.updateAtRange instanceof Array
|
|
? filterValue.updateAtRange[0]
|
|
: null;
|
|
const endDate =
|
|
filterValue.updateAtRange instanceof Array
|
|
? filterValue.updateAtRange[1]
|
|
: null;
|
|
|
|
const dateMatch =
|
|
!filterValue.updateAtRange ||
|
|
(new Date(Number(deployment.createdAt)) >= startDate! &&
|
|
new Date(Number(deployment.createdAt)) <= endDate!);
|
|
|
|
return branchMatch && statusMatch && dateMatch;
|
|
});
|
|
}, [filterValue, deployments]);
|
|
|
|
const handleResetFilters = useCallback(() => {
|
|
setFilterValue(DEFAULT_FILTER_VALUE);
|
|
}, []);
|
|
|
|
const onUpdateDeploymentToProd = async () => {
|
|
await fetchDeployments();
|
|
};
|
|
|
|
return (
|
|
<section className="h-full">
|
|
<FilterForm
|
|
value={filterValue}
|
|
onChange={(value) => setFilterValue(value)}
|
|
/>
|
|
<div className="mt-2 h-full">
|
|
{Boolean(filteredDeployments.length) ? (
|
|
filteredDeployments.map((deployment, key) => {
|
|
return (
|
|
<DeploymentDetailsCard
|
|
deployment={deployment}
|
|
key={key}
|
|
currentDeployment={currentDeployment!}
|
|
onUpdate={onUpdateDeploymentToProd}
|
|
project={project}
|
|
prodBranchDomains={prodBranchDomains}
|
|
/>
|
|
);
|
|
})
|
|
) : (
|
|
// TODO: Update the height based on the layout, need to re-styling the layout similar to create project layout
|
|
<div className="h-3/4 bg-base-bg-alternate flex flex-col rounded-xl items-center justify-center text-center gap-5">
|
|
<div className="space-y-1">
|
|
<p className="font-medium tracking-[-0.011em] text-elements-high-em">
|
|
No deployments found
|
|
</p>
|
|
<p className="text-sm tracking-[-0.006em] text-elements-mid-em">
|
|
Please change your search query or filters.
|
|
</p>
|
|
</div>
|
|
<Button
|
|
variant="tertiary"
|
|
leftIcon={<RefreshIcon />}
|
|
onClick={handleResetFilters}
|
|
>
|
|
Reset filters
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
export default DeploymentsTabPanel;
|