github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/web/src/OverviewLogPane.stories.tsx (about) 1 import React, { Component, useEffect, useState } from "react" 2 import { MemoryRouter } from "react-router" 3 import { 4 EMPTY_FILTER_TERM, 5 FilterLevel, 6 FilterSet, 7 FilterSource, 8 } from "./logfilters" 9 import LogStore, { LogStoreProvider } from "./LogStore" 10 import OverviewLogPane from "./OverviewLogPane" 11 import { StarredResourceMemoryProvider } from "./StarredResourcesContext" 12 import { appendLines } from "./testlogs" 13 import { LogLevel } from "./types" 14 15 export default { 16 title: "New UI/Overview/OverviewLogPane", 17 decorators: [ 18 (Story: any) => ( 19 <MemoryRouter initialEntries={["/"]}> 20 <div 21 style={{ 22 margin: "-1rem", 23 height: "80vh", 24 width: "80vw", 25 border: "thin solid #ccc", 26 }} 27 > 28 <Story /> 29 </div> 30 </MemoryRouter> 31 ), 32 ], 33 } 34 35 let defaultFilter: FilterSet = { 36 source: FilterSource.all, 37 level: FilterLevel.all, 38 term: EMPTY_FILTER_TERM, 39 } 40 41 export const ThreeLines = () => { 42 let logStore = new LogStore() 43 appendLines(logStore, "fe", "line 1\n", "line2\n", "line3\n") 44 return ( 45 <LogStoreProvider value={logStore}> 46 <OverviewLogPane manifestName="fe" filterSet={defaultFilter} /> 47 </LogStoreProvider> 48 ) 49 } 50 51 export const ThreeLinesAllLog = () => { 52 let logStore = new LogStore() 53 appendLines(logStore, "", "line 1\n", "line2\n", "line3\n") 54 return ( 55 <LogStoreProvider value={logStore}> 56 <OverviewLogPane manifestName="" filterSet={defaultFilter} /> 57 </LogStoreProvider> 58 ) 59 } 60 61 export const StarredResourcesLog = () => { 62 let logStore = new LogStore() 63 appendLines(logStore, "starA", "A line 1\n", "A line 2\n", "A line 3\n") 64 appendLines(logStore, "starB", "B line 1\n", "B line 2\n", "B line 3\n") 65 appendLines(logStore, "starC", "C line 1\n", "C line 2\n", "C line 3\n") 66 return ( 67 <StarredResourceMemoryProvider 68 initialValueForTesting={["starA", "starB", "starC"]} 69 > 70 <LogStoreProvider value={logStore}> 71 <OverviewLogPane manifestName="(starred)" filterSet={defaultFilter} /> 72 </LogStoreProvider> 73 </StarredResourceMemoryProvider> 74 ) 75 } 76 77 export const ManyLines = (args: any) => { 78 let logStore = new LogStore() 79 let lines = [] 80 for (let i = 0; i < args.count; i++) { 81 lines.push(`line ${i}\n`) 82 } 83 appendLines(logStore, "fe", lines) 84 return ( 85 <LogStoreProvider value={logStore}> 86 <OverviewLogPane manifestName="fe" filterSet={defaultFilter} /> 87 </LogStoreProvider> 88 ) 89 } 90 ManyLines.args = { 91 count: 1000, 92 } 93 ManyLines.argTypes = { 94 count: { control: { type: "number" } }, 95 } 96 97 export const StyledLines = () => { 98 let logStore = new LogStore() 99 let lines = [ 100 "Black: \u001b[30m text \u001b[0m\n", 101 "Red: \u001b[31m text \u001b[0m\n", 102 "Green: \u001b[32m text \u001b[0m\n", 103 "Yellow: \u001b[33m text \u001b[0m\n", 104 "Blue: \u001b[34m text \u001b[0m\n", 105 "Magenta: \u001b[35m text \u001b[0m\n", 106 "Cyan: \u001b[36m text \u001b[0m\n", 107 "White: \u001b[37m text \u001b[0m\n", 108 "Bright Black: \u001b[90m text \u001b[0m\n", 109 "Bright Red: \u001b[91m text \u001b[0m\n", 110 "Bright Green: \u001b[92m text \u001b[0m\n", 111 "Bright Yellow: \u001b[93m text \u001b[0m\n", 112 "Bright Blue: \u001b[94m text \u001b[0m\n", 113 "Bright Magenta: \u001b[95m text \u001b[0m\n", 114 "Bright Cyan: \u001b[96m text \u001b[0m\n", 115 "Bright White: \u001b[97m text \u001b[0m\n", 116 "Black BG: \u001b[40m text \u001b[0m\n", 117 "Red BG: \u001b[41m text \u001b[0m\n", 118 "Green BG: \u001b[42m text \u001b[0m\n", 119 "Yellow BG: \u001b[43m text \u001b[0m\n", 120 "Blue BG: \u001b[44m text \u001b[0m\n", 121 "Magenta BG: \u001b[45m text \u001b[0m\n", 122 "Cyan BG: \u001b[46m text \u001b[0m\n", 123 "White BG: \u001b[47m text \u001b[0m\n", 124 "Bright Black BG: \u001b[100m text \u001b[0m\n", 125 "Bright Red BG: \u001b[101m text \u001b[0m\n", 126 "Bright Green BG: \u001b[102m text \u001b[0m\n", 127 "Bright Yellow BG: \u001b[103m text \u001b[0m\n", 128 "Bright Blue BG: \u001b[104m text \u001b[0m\n", 129 "Bright Magenta BG: \u001b[105m text \u001b[0m\n", 130 "Bright Cyan BG: \u001b[106m text \u001b[0m\n", 131 "Bright White BG: \u001b[107m text \u001b[0m\n", 132 "Link: https://tilt.dev/\n", 133 'Escaped Link: <a href="https://tilt.dev/" >Tilt</a>\n', 134 'Escaped Button: <button onClick="alert(\\"you are p0wned\\")" >Tilt</button>\n', 135 "[32m➜[39m [1mLocal[22m: [36mhttp://localhost:[1m5173[22m/[39m\n", 136 ] 137 appendLines(logStore, "fe", ...lines) 138 return ( 139 <LogStoreProvider value={logStore}> 140 <OverviewLogPane manifestName="fe" filterSet={defaultFilter} /> 141 </LogStoreProvider> 142 ) 143 } 144 145 export const BuildEventLines = () => { 146 let logStore = new LogStore() 147 let lines = [ 148 { text: "Start build\n", fields: { buildEvent: "init" } }, 149 { text: "Fallback build 1\n", fields: { buildEvent: "fallback" } }, 150 { text: "Fallback build 2\n", fields: { buildEvent: "fallback" } }, 151 { text: "Fallback build 3\n", fields: { buildEvent: "fallback" } }, 152 "Build log 1\n", 153 "Build log 2\n", 154 ] 155 appendLines(logStore, "fe", ...lines) 156 return ( 157 <LogStoreProvider value={logStore}> 158 <OverviewLogPane manifestName="fe" filterSet={defaultFilter} /> 159 </LogStoreProvider> 160 ) 161 } 162 163 export const BuildFallbackLines = () => { 164 let logStore = new LogStore() 165 let lines = [ 166 { text: "Start build\n", fields: { buildEvent: "init" } }, 167 "Build log 1\n", 168 "Build log 2\n", 169 { text: "Fallback build 1\n", fields: { buildEvent: "fallback" } }, 170 { text: "Fallback build 2\n", fields: { buildEvent: "fallback" } }, 171 { text: "Fallback build 3\n", fields: { buildEvent: "fallback" } }, 172 "Build log 3\n", 173 "Build log 4\n", 174 ] 175 appendLines(logStore, "fe", ...lines) 176 return ( 177 <LogStoreProvider value={logStore}> 178 <OverviewLogPane manifestName="fe" filterSet={defaultFilter} /> 179 </LogStoreProvider> 180 ) 181 } 182 183 export const BuildFallbackLinesLong = () => { 184 let logStore = new LogStore() 185 let lines = [ 186 { text: "Start build\n", fields: { buildEvent: "init" } }, 187 "Build log 1\n", 188 "Build log 2\n", 189 { 190 text: "Fallback build 1 Fallback build 1 Fallback build 1 Fallback build 1 Fallback build 1 Fallback build 1 Fallback build 1 Fallback build 1\n", 191 fields: { buildEvent: "fallback" }, 192 }, 193 { 194 text: "Fallback build 2 Fallback build 2 Fallback build 2 Fallback build 2 Fallback build 2 Fallback build 2 Fallback build 2 Fallback build 2\n", 195 fields: { buildEvent: "fallback" }, 196 }, 197 { 198 text: "Fallback build 3 Fallback build 3 Fallback build 3 Fallback build 3 Fallback build 3 Fallback build 3 Fallback build 3 Fallback build 3 Fallback build 3\n", 199 fields: { buildEvent: "fallback" }, 200 }, 201 "Build log 3\n", 202 "Build log 4\n", 203 ] 204 appendLines(logStore, "fe", ...lines) 205 return ( 206 <LogStoreProvider value={logStore}> 207 <OverviewLogPane manifestName="fe" filterSet={defaultFilter} /> 208 </LogStoreProvider> 209 ) 210 } 211 212 export const ProgressLines = (args: any) => { 213 let [logStore, setLogStore] = useState(new LogStore()) 214 let lines = [ 215 { text: "Start build\n", fields: { progressID: "start" } }, 216 { text: `Layer 1: 0%\n`, fields: { progressID: "layer1" } }, 217 { text: `Layer 2: 0%\n`, fields: { progressID: "layer2" } }, 218 { text: `Layer 3: 0%\n`, fields: { progressID: "layer3" } }, 219 { text: `Layer 4: 0%\n`, fields: { progressID: "layer4" } }, 220 ] 221 appendLines(logStore, "fe", ...lines) 222 223 useEffect(() => { 224 let lines = [ 225 { text: "Start build\n", fields: { progressID: "start" } }, 226 { text: `Layer 1: ${args.layer1}%\n`, fields: { progressID: "layer1" } }, 227 { text: `Layer 2: ${args.layer2}%\n`, fields: { progressID: "layer2" } }, 228 { text: `Layer 3: ${args.layer3}%\n`, fields: { progressID: "layer3" } }, 229 { text: `Layer 4: ${args.layer4}%\n`, fields: { progressID: "layer4" } }, 230 ] 231 appendLines(logStore, "fe", ...lines) 232 }, [args]) 233 234 return ( 235 <LogStoreProvider value={logStore}> 236 <OverviewLogPane manifestName="fe" filterSet={defaultFilter} /> 237 </LogStoreProvider> 238 ) 239 } 240 241 ProgressLines.args = { 242 layer1: 50, 243 layer2: 40, 244 layer3: 30, 245 layer4: 20, 246 } 247 ProgressLines.argTypes = { 248 layer1: { control: { type: "number", min: 0, max: 100 } }, 249 layer2: { control: { type: "number", min: 0, max: 100 } }, 250 layer3: { control: { type: "number", min: 0, max: 100 } }, 251 layer4: { control: { type: "number", min: 0, max: 100 } }, 252 } 253 254 type ForeverLogProps = { 255 // Starting lines in the component. 256 startCount: number 257 258 // Incremental lines on each timer tick. 259 incCount: number 260 } 261 262 class ForeverLogComponent extends Component<ForeverLogProps> { 263 logStore = new LogStore() 264 lineCount = 0 265 timer: any 266 267 appendLines(count: number) { 268 let lines = [] 269 for (let i = 0; i < count; i++) { 270 lines.push({ text: `Line #${this.lineCount++}\n` }) 271 } 272 appendLines(this.logStore, "fe", lines) 273 } 274 275 componentDidMount() { 276 this.appendLines(this.props.startCount) 277 278 this.timer = setInterval(() => { 279 this.appendLines(this.props.incCount) 280 }, 1000) 281 } 282 283 componentWillUnmount() { 284 clearInterval(this.timer) 285 } 286 287 render() { 288 return ( 289 <LogStoreProvider value={this.logStore}> 290 <OverviewLogPane manifestName="fe" filterSet={defaultFilter} /> 291 </LogStoreProvider> 292 ) 293 } 294 } 295 296 export const ForeverLog = (args: ForeverLogProps) => { 297 return <ForeverLogComponent {...args} /> 298 } 299 ForeverLog.args = { 300 startCount: 1000, 301 incCount: 5, 302 } 303 ForeverLog.argTypes = { 304 startCount: { control: { type: "number" } }, 305 incCount: { control: { type: "number" } }, 306 } 307 308 export const BuildLogAndRunLog = (args: any) => { 309 let logStore = new LogStore() 310 let segments = [] 311 for (let i = 0; i < 20; i++) { 312 let level = "" 313 let lineType = "build" 314 if (i === 15) { 315 level = LogLevel.WARN 316 lineType = "build warning" 317 } else if (i === 19) { 318 level = LogLevel.ERROR 319 lineType = "build error" 320 } 321 segments.push({ 322 spanId: "build:1", 323 text: `Vigoda ${lineType} line ${i}\n`, 324 time: new Date().toString(), 325 level, 326 }) 327 } 328 for (let i = 0; i < 20; i++) { 329 let level = "" 330 let lineType = "pod" 331 if (i === 15) { 332 level = LogLevel.WARN 333 lineType = "pod warning" 334 } else if (i === 19) { 335 level = LogLevel.ERROR 336 lineType = "pod error" 337 } 338 segments.push({ 339 spanId: "pod:1", 340 text: `Vigoda ${lineType} line ${i}\n`, 341 time: new Date().toString(), 342 level, 343 }) 344 } 345 logStore.append({ 346 spans: { 347 "build:1": { manifestName: "vigoda_1" }, 348 "pod:1": { manifestName: "vigoda_1" }, 349 }, 350 segments: segments, 351 }) 352 353 return ( 354 <LogStoreProvider value={logStore}> 355 <OverviewLogPane 356 manifestName={"vigoda_1"} 357 filterSet={{ 358 source: args.source, 359 level: args.level, 360 term: args.term || EMPTY_FILTER_TERM, 361 }} 362 /> 363 </LogStoreProvider> 364 ) 365 } 366 367 BuildLogAndRunLog.args = { 368 source: "", 369 level: "", 370 term: EMPTY_FILTER_TERM, 371 } 372 373 BuildLogAndRunLog.argTypes = { 374 source: { 375 name: "Source", 376 control: { 377 type: "select", 378 options: [FilterSource.all, FilterSource.build, FilterSource.runtime], 379 }, 380 }, 381 level: { 382 name: "Level", 383 control: { 384 type: "select", 385 options: [FilterLevel.all, FilterLevel.warn, FilterLevel.error], 386 }, 387 }, 388 }