| Sean McCullough | 618bfb2 | 2025-06-25 20:52:30 +0000 | [diff] [blame] | 1 | /** |
| 2 | * Demo module for sketch-container-status component |
| 3 | */ |
| 4 | |
| 5 | import { DemoModule } from "./demo-framework/types"; |
| 6 | import { |
| 7 | demoUtils, |
| 8 | sampleContainerState, |
| 9 | lightUsageState, |
| 10 | heavyUsageState, |
| 11 | } from "./demo-fixtures/index"; |
| 12 | |
| 13 | const demo: DemoModule = { |
| 14 | title: "Container Status Demo", |
| 15 | description: "Display container status information with usage statistics", |
| 16 | imports: ["../sketch-container-status"], |
| 17 | styles: ["/dist/tailwind.css"], |
| 18 | |
| 19 | setup: async (container: HTMLElement) => { |
| 20 | // Create demo sections |
| 21 | const basicSection = demoUtils.createDemoSection( |
| 22 | "Basic Container Status", |
| 23 | "Shows current container state with usage information", |
| 24 | ); |
| 25 | |
| 26 | const variationsSection = demoUtils.createDemoSection( |
| 27 | "Usage Variations", |
| 28 | "Different usage levels and states", |
| 29 | ); |
| 30 | |
| 31 | // Basic status component |
| 32 | const basicStatus = document.createElement( |
| 33 | "sketch-container-status", |
| 34 | ) as any; |
| 35 | basicStatus.id = "basic-status"; |
| 36 | basicStatus.state = sampleContainerState; |
| 37 | |
| 38 | // Light usage status |
| 39 | const lightStatus = document.createElement( |
| 40 | "sketch-container-status", |
| 41 | ) as any; |
| 42 | lightStatus.id = "light-status"; |
| 43 | lightStatus.state = lightUsageState; |
| 44 | |
| 45 | const lightLabel = document.createElement("h4"); |
| 46 | lightLabel.textContent = "Light Usage"; |
| banksean | 1ee0bc6 | 2025-07-22 23:24:18 +0000 | [diff] [blame] | 47 | lightLabel.style.cssText = |
| 48 | "margin: 20px 0 10px 0; color: var(--demo-label-color);"; |
| Sean McCullough | 618bfb2 | 2025-06-25 20:52:30 +0000 | [diff] [blame] | 49 | |
| 50 | // Heavy usage status |
| 51 | const heavyStatus = document.createElement( |
| 52 | "sketch-container-status", |
| 53 | ) as any; |
| 54 | heavyStatus.id = "heavy-status"; |
| 55 | heavyStatus.state = heavyUsageState; |
| Sean McCullough | 4957749 | 2025-06-26 17:13:28 -0700 | [diff] [blame] | 56 | heavyStatus.lastCommit = { |
| 57 | hash: "deadbeef", |
| 58 | pushedBranch: "user/sketch/really-long-branch-name-that-stains-layout", |
| 59 | }; |
| Sean McCullough | 618bfb2 | 2025-06-25 20:52:30 +0000 | [diff] [blame] | 60 | const heavyLabel = document.createElement("h4"); |
| 61 | heavyLabel.textContent = "Heavy Usage"; |
| banksean | 1ee0bc6 | 2025-07-22 23:24:18 +0000 | [diff] [blame] | 62 | heavyLabel.style.cssText = |
| 63 | "margin: 20px 0 10px 0; color: var(--demo-label-color);"; |
| Sean McCullough | 618bfb2 | 2025-06-25 20:52:30 +0000 | [diff] [blame] | 64 | |
| 65 | // Control buttons for interaction |
| 66 | const controlsDiv = document.createElement("div"); |
| 67 | controlsDiv.style.cssText = "margin-top: 20px;"; |
| 68 | |
| 69 | const updateBasicButton = demoUtils.createButton( |
| 70 | "Update Basic Status", |
| 71 | () => { |
| 72 | const updatedState = { |
| 73 | ...sampleContainerState, |
| 74 | message_count: sampleContainerState.message_count + 1, |
| 75 | total_usage: { |
| 76 | ...sampleContainerState.total_usage!, |
| 77 | messages: sampleContainerState.total_usage!.messages + 1, |
| 78 | total_cost_usd: Number( |
| 79 | (sampleContainerState.total_usage!.total_cost_usd + 0.05).toFixed( |
| 80 | 2, |
| 81 | ), |
| 82 | ), |
| 83 | }, |
| 84 | }; |
| 85 | basicStatus.state = updatedState; |
| 86 | }, |
| 87 | ); |
| 88 | |
| 89 | const toggleSSHButton = demoUtils.createButton("Toggle SSH Status", () => { |
| 90 | const currentState = basicStatus.state; |
| 91 | basicStatus.state = { |
| 92 | ...currentState, |
| 93 | ssh_available: !currentState.ssh_available, |
| 94 | ssh_error: currentState.ssh_available ? "Connection failed" : undefined, |
| 95 | }; |
| 96 | }); |
| 97 | |
| 98 | const resetButton = demoUtils.createButton("Reset to Defaults", () => { |
| 99 | basicStatus.state = sampleContainerState; |
| 100 | lightStatus.state = lightUsageState; |
| 101 | heavyStatus.state = heavyUsageState; |
| 102 | }); |
| 103 | |
| 104 | controlsDiv.appendChild(updateBasicButton); |
| 105 | controlsDiv.appendChild(toggleSSHButton); |
| 106 | controlsDiv.appendChild(resetButton); |
| 107 | |
| 108 | // Assemble the demo |
| 109 | basicSection.appendChild(basicStatus); |
| 110 | basicSection.appendChild(controlsDiv); |
| 111 | |
| 112 | variationsSection.appendChild(lightLabel); |
| 113 | variationsSection.appendChild(lightStatus); |
| 114 | variationsSection.appendChild(heavyLabel); |
| 115 | variationsSection.appendChild(heavyStatus); |
| 116 | |
| 117 | container.appendChild(basicSection); |
| 118 | container.appendChild(variationsSection); |
| 119 | |
| 120 | // Add some real-time updates |
| 121 | const updateInterval = setInterval(() => { |
| 122 | const states = [basicStatus, lightStatus, heavyStatus]; |
| 123 | states.forEach((status) => { |
| 124 | if (status.state) { |
| 125 | const updatedState = { |
| 126 | ...status.state, |
| 127 | message_count: |
| 128 | status.state.message_count + Math.floor(Math.random() * 2), |
| 129 | }; |
| 130 | if (Math.random() > 0.7) { |
| 131 | // 30% chance to update |
| 132 | status.state = updatedState; |
| 133 | } |
| 134 | } |
| 135 | }); |
| 136 | }, 3000); |
| 137 | |
| 138 | // Store interval for cleanup |
| 139 | (container as any).demoInterval = updateInterval; |
| 140 | }, |
| 141 | |
| 142 | cleanup: async () => { |
| 143 | // Clear any intervals |
| 144 | const container = document.getElementById("demo-container"); |
| 145 | if (container && (container as any).demoInterval) { |
| 146 | clearInterval((container as any).demoInterval); |
| 147 | delete (container as any).demoInterval; |
| 148 | } |
| 149 | }, |
| 150 | }; |
| 151 | |
| 152 | export default demo; |