| 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"; |
| 47 | lightLabel.style.cssText = "margin: 20px 0 10px 0; color: #24292f;"; |
| 48 | |
| 49 | // Heavy usage status |
| 50 | const heavyStatus = document.createElement( |
| 51 | "sketch-container-status", |
| 52 | ) as any; |
| 53 | heavyStatus.id = "heavy-status"; |
| 54 | heavyStatus.state = heavyUsageState; |
| 55 | |
| 56 | const heavyLabel = document.createElement("h4"); |
| 57 | heavyLabel.textContent = "Heavy Usage"; |
| 58 | heavyLabel.style.cssText = "margin: 20px 0 10px 0; color: #24292f;"; |
| 59 | |
| 60 | // Control buttons for interaction |
| 61 | const controlsDiv = document.createElement("div"); |
| 62 | controlsDiv.style.cssText = "margin-top: 20px;"; |
| 63 | |
| 64 | const updateBasicButton = demoUtils.createButton( |
| 65 | "Update Basic Status", |
| 66 | () => { |
| 67 | const updatedState = { |
| 68 | ...sampleContainerState, |
| 69 | message_count: sampleContainerState.message_count + 1, |
| 70 | total_usage: { |
| 71 | ...sampleContainerState.total_usage!, |
| 72 | messages: sampleContainerState.total_usage!.messages + 1, |
| 73 | total_cost_usd: Number( |
| 74 | (sampleContainerState.total_usage!.total_cost_usd + 0.05).toFixed( |
| 75 | 2, |
| 76 | ), |
| 77 | ), |
| 78 | }, |
| 79 | }; |
| 80 | basicStatus.state = updatedState; |
| 81 | }, |
| 82 | ); |
| 83 | |
| 84 | const toggleSSHButton = demoUtils.createButton("Toggle SSH Status", () => { |
| 85 | const currentState = basicStatus.state; |
| 86 | basicStatus.state = { |
| 87 | ...currentState, |
| 88 | ssh_available: !currentState.ssh_available, |
| 89 | ssh_error: currentState.ssh_available ? "Connection failed" : undefined, |
| 90 | }; |
| 91 | }); |
| 92 | |
| 93 | const resetButton = demoUtils.createButton("Reset to Defaults", () => { |
| 94 | basicStatus.state = sampleContainerState; |
| 95 | lightStatus.state = lightUsageState; |
| 96 | heavyStatus.state = heavyUsageState; |
| 97 | }); |
| 98 | |
| 99 | controlsDiv.appendChild(updateBasicButton); |
| 100 | controlsDiv.appendChild(toggleSSHButton); |
| 101 | controlsDiv.appendChild(resetButton); |
| 102 | |
| 103 | // Assemble the demo |
| 104 | basicSection.appendChild(basicStatus); |
| 105 | basicSection.appendChild(controlsDiv); |
| 106 | |
| 107 | variationsSection.appendChild(lightLabel); |
| 108 | variationsSection.appendChild(lightStatus); |
| 109 | variationsSection.appendChild(heavyLabel); |
| 110 | variationsSection.appendChild(heavyStatus); |
| 111 | |
| 112 | container.appendChild(basicSection); |
| 113 | container.appendChild(variationsSection); |
| 114 | |
| 115 | // Add some real-time updates |
| 116 | const updateInterval = setInterval(() => { |
| 117 | const states = [basicStatus, lightStatus, heavyStatus]; |
| 118 | states.forEach((status) => { |
| 119 | if (status.state) { |
| 120 | const updatedState = { |
| 121 | ...status.state, |
| 122 | message_count: |
| 123 | status.state.message_count + Math.floor(Math.random() * 2), |
| 124 | }; |
| 125 | if (Math.random() > 0.7) { |
| 126 | // 30% chance to update |
| 127 | status.state = updatedState; |
| 128 | } |
| 129 | } |
| 130 | }); |
| 131 | }, 3000); |
| 132 | |
| 133 | // Store interval for cleanup |
| 134 | (container as any).demoInterval = updateInterval; |
| 135 | }, |
| 136 | |
| 137 | cleanup: async () => { |
| 138 | // Clear any intervals |
| 139 | const container = document.getElementById("demo-container"); |
| 140 | if (container && (container as any).demoInterval) { |
| 141 | clearInterval((container as any).demoInterval); |
| 142 | delete (container as any).demoInterval; |
| 143 | } |
| 144 | }, |
| 145 | }; |
| 146 | |
| 147 | export default demo; |