github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/OverviewTableStatus.tsx (about) 1 import React from "react" 2 import { Link } from "react-router-dom" 3 import styled from "styled-components" 4 import { ReactComponent as CheckmarkSmallSvg } from "./assets/svg/checkmark-small.svg" 5 import { ReactComponent as CloseSvg } from "./assets/svg/close.svg" 6 import { ReactComponent as NotAllowedSvg } from "./assets/svg/not-allowed.svg" 7 import { ReactComponent as PendingSvg } from "./assets/svg/pending.svg" 8 import { ReactComponent as WarningSvg } from "./assets/svg/warning.svg" 9 import { Hold } from "./Hold" 10 import { usePathBuilder } from "./PathBuilder" 11 import { PendingBuildDescription } from "./status" 12 import { Color, FontSize, Glow, SizeUnit, spin } from "./style-helpers" 13 import { formatBuildDuration } from "./time" 14 import Tooltip from "./Tooltip" 15 import { ResourceStatus } from "./types" 16 17 const StatusMsg = styled.div` 18 text-overflow: ellipsis; 19 overflow: hidden; 20 ` 21 const StyledOverviewTableStatus = styled(Link)` 22 color: inherit; 23 text-decoration: none; 24 display: flex; 25 align-items: center; 26 font-size: ${FontSize.small}; 27 line-height: ${FontSize.small}; 28 text-align: left; 29 white-space: nowrap; 30 overflow: hidden; 31 width: 100%; 32 33 &:hover { 34 text-decoration: underline; 35 } 36 37 & + & { 38 margin-top: -8px; 39 } 40 41 &.is-healthy { 42 svg { 43 fill: ${Color.green}; 44 } 45 } 46 &.is-building, 47 &.is-pending { 48 svg { 49 fill: ${Color.grayLightest}; 50 animation: ${spin} 4s linear infinite; 51 width: 80%; 52 } 53 } 54 &.is-pending { 55 ${StatusMsg} { 56 animation: ${Glow.opacity} 2s linear infinite; 57 } 58 } 59 &.is-error { 60 color: ${Color.red}; 61 svg { 62 fill: ${Color.red}; 63 } 64 } 65 &.is-none { 66 color: ${Color.gray50}; 67 } 68 &.is-disabled { 69 color: ${Color.gray60}; 70 } 71 ` 72 const StatusIcon = styled.span` 73 display: flex; 74 align-items: center; 75 margin-right: ${SizeUnit(0.2)}; 76 width: ${SizeUnit(0.5)}; 77 flex-shrink: 0; 78 79 svg { 80 width: 100%; 81 } 82 ` 83 84 type OverviewTableStatusProps = { 85 status: ResourceStatus 86 resourceName: string 87 lastBuildDur?: moment.Duration | null 88 isBuild?: boolean 89 hold?: Hold | null 90 } 91 92 export default function OverviewTableStatus(props: OverviewTableStatusProps) { 93 let { status, lastBuildDur, isBuild, resourceName, hold } = props 94 let icon = null 95 let msg = "" 96 let tooltip = "" 97 let classes = "" 98 99 switch (status) { 100 case ResourceStatus.Building: 101 icon = <PendingSvg role="presentation" /> 102 msg = isBuild ? "Updating…" : "Runtime Deploying" 103 classes = "is-building" 104 break 105 106 case ResourceStatus.None: 107 break 108 109 case ResourceStatus.Pending: 110 icon = <PendingSvg role="presentation" /> 111 if (isBuild) { 112 msg = "Update Pending" 113 tooltip = PendingBuildDescription(hold) 114 } else { 115 msg = "Runtime Pending" 116 } 117 classes = "is-pending" 118 break 119 120 case ResourceStatus.Warning: { 121 let buildDurText = lastBuildDur 122 ? ` in ${formatBuildDuration(lastBuildDur)}` 123 : "" 124 icon = ( 125 <WarningSvg 126 role="presentation" 127 fill={Color.yellow} 128 width="10px" 129 height="10px" 130 /> 131 ) 132 msg = isBuild ? `Updated${buildDurText}` : "Runtime Ready" 133 classes = "is-warning" 134 break 135 } 136 137 case ResourceStatus.Healthy: 138 let buildDurText = lastBuildDur 139 ? ` in ${formatBuildDuration(lastBuildDur)}` 140 : "" 141 icon = <CheckmarkSmallSvg role="presentation" /> 142 msg = isBuild ? `Updated${buildDurText}` : "Runtime Ready" 143 classes = "is-healthy" 144 break 145 146 case ResourceStatus.Unhealthy: 147 icon = <CloseSvg role="presentation" /> 148 msg = isBuild ? "Update error" : "Runtime error" 149 classes = "is-error" 150 break 151 152 case ResourceStatus.Disabled: 153 icon = <NotAllowedSvg role="presentation" /> 154 msg = "Disabled" 155 classes = "is-disabled" 156 break 157 158 default: 159 msg = "" 160 } 161 162 const pb = usePathBuilder() 163 let url = pb.encpath`/r/${resourceName}/overview` 164 165 if (!msg) return null 166 167 let content = ( 168 <StyledOverviewTableStatus to={url} className={classes}> 169 <StatusIcon>{icon}</StatusIcon> 170 <StatusMsg>{msg}</StatusMsg> 171 </StyledOverviewTableStatus> 172 ) 173 174 if (tooltip) { 175 return <Tooltip title={tooltip}>{content}</Tooltip> 176 } 177 178 return content 179 }