import React, { useState } from 'react'; import { Menu, MenuHandler, MenuList, MenuItem, Typography, Chip, ChipProps, } from '@material-tailwind/react'; import toast from 'react-hot-toast'; import { Environment, Project, Domain } from 'gql-client'; import { relativeTimeMs } from '../../../../utils/time'; import ConfirmDialog from '../../../shared/ConfirmDialog'; import DeploymentDialogBodyCard from './DeploymentDialogBodyCard'; import AssignDomainDialog from './AssignDomainDialog'; import { DeploymentDetails, Status } from '../../../../types/project'; import { useGQLClient } from '../../../../context/GQLClientContext'; interface DeployDetailsCardProps { deployment: DeploymentDetails; currentDeployment: DeploymentDetails; onUpdate: () => Promise; project: Project; prodBranchDomains: Domain[]; } const STATUS_COLORS: { [key in Status]: ChipProps['color'] } = { [Status.BUILDING]: 'blue', [Status.READY]: 'green', [Status.ERROR]: 'red', }; const DeploymentDetailsCard = ({ deployment, currentDeployment, onUpdate, project, prodBranchDomains, }: DeployDetailsCardProps) => { const client = useGQLClient(); const [changeToProduction, setChangeToProduction] = useState(false); const [redeployToProduction, setRedeployToProduction] = useState(false); const [rollbackDeployment, setRollbackDeployment] = useState(false); const [assignDomainDialog, setAssignDomainDialog] = useState(false); const updateDeployment = async () => { const isUpdated = await client.updateDeploymentToProd(deployment.id); if (isUpdated) { await onUpdate(); toast.success('Deployment changed to production'); } else { toast.error('Unable to change deployment to production'); } }; const redeployToProd = async () => { const isRedeployed = await client.redeployToProd(deployment.id); if (isRedeployed) { await onUpdate(); toast.success('Redeployed to production'); } else { toast.error('Unable to redeploy to production'); } }; const rollbackDeploymentHandler = async () => { const isRollbacked = await client.rollbackDeployment( project.id, deployment.id, ); if (isRollbacked) { await onUpdate(); toast.success('Deployment rolled back'); } else { toast.error('Unable to rollback deployment'); } }; return (
{deployment.url} ^} />
{deployment.environment === Environment.Production ? `Production ${deployment.isCurrent ? '(Current)' : ''}` : 'Preview'}
^ {deployment.branch} ^ {deployment.commitHash} {deployment.commit.message}
{relativeTimeMs(deployment.createdAt)} ^ {deployment.createdBy.name} ^ Visit setAssignDomainDialog(!assignDomainDialog)} > ^ Assign domain {!(deployment.environment === Environment.Production) && ( setChangeToProduction(!changeToProduction)} > ^ Change to production )}
setRedeployToProduction(!redeployToProduction)} disabled={ !( deployment.environment === Environment.Production && deployment.isCurrent ) } > ^ Redeploy to production {deployment.environment === Environment.Production && ( setRollbackDeployment(!rollbackDeployment)} disabled={deployment.isCurrent} > ^ Rollback to this version )}
setChangeToProduction((preVal) => !preVal)} open={changeToProduction} confirmButtonTitle="Change" color="blue" handleConfirm={async () => { await updateDeployment(); setChangeToProduction((preVal) => !preVal); }} >
Upon confirmation, this deployment will be changed to production. The new deployment will be associated with these domains: {prodBranchDomains.length > 0 && prodBranchDomains.map((value) => { return ( ^ {value.name} ); })}
setRedeployToProduction((preVal) => !preVal)} open={redeployToProduction} confirmButtonTitle="Redeploy" color="blue" handleConfirm={async () => { await redeployToProd(); setRedeployToProduction((preVal) => !preVal); }} >
Upon confirmation, new deployment will be created with the same source code as current deployment. These domains will point to your new deployment: {deployment.domain?.name && ( {deployment.domain?.name} )}
setRollbackDeployment((preVal) => !preVal)} open={rollbackDeployment} confirmButtonTitle="Rollback" color="blue" handleConfirm={async () => { await rollbackDeploymentHandler(); setRollbackDeployment((preVal) => !preVal); }} >
Upon confirmation, this deployment will replace your current deployment These domains will point to your new deployment: ^ {currentDeployment.domain?.name}
setAssignDomainDialog(!assignDomainDialog)} />
); }; export default DeploymentDetailsCard;