(prices []PriceInfo)
| 1320 | } |
| 1321 | |
| 1322 | func (v *PricingView) renderPriceTable(prices []PriceInfo) string { |
| 1323 | // padV pads s to exactly n visual columns using lipgloss.Width so that |
| 1324 | // multi-byte characters like "–" are measured correctly. |
| 1325 | padV := func(s string, n int) string { |
| 1326 | w := lipgloss.Width(s) |
| 1327 | if w >= n { |
| 1328 | return truncate(s, n) |
| 1329 | } |
| 1330 | return s + strings.Repeat(" ", n-w) |
| 1331 | } |
| 1332 | |
| 1333 | header := lipgloss.NewStyle().Foreground(colorYellow).Bold(true).Render( |
| 1334 | padV("Model", 24) + " " + padV("Price", 10) + " " + padV("Unit", 5) + " " + |
| 1335 | padV("Upfront", 10) + " " + padV("Yr", 4) + " " + "Option") |
| 1336 | |
| 1337 | rows := []string{header} |
| 1338 | for _, p := range prices { |
| 1339 | upfront := p.UpfrontFee |
| 1340 | if upfront == "0" || upfront == "" { |
| 1341 | upfront = "–" |
| 1342 | } |
| 1343 | yr := p.Year |
| 1344 | if yr == "" { |
| 1345 | yr = "–" |
| 1346 | } |
| 1347 | opt := p.PurchaseOption |
| 1348 | if opt == "" { |
| 1349 | opt = "–" |
| 1350 | } |
| 1351 | if p.InterruptionMaxPct != "" { |
| 1352 | if opt == "–" { |
| 1353 | opt = fmt.Sprintf("Interrupt %s%%", p.InterruptionMaxPct) |
| 1354 | } else { |
| 1355 | opt = fmt.Sprintf("%s Interrupt %s%%", opt, p.InterruptionMaxPct) |
| 1356 | } |
| 1357 | } |
| 1358 | |
| 1359 | isSpot := strings.EqualFold(p.PricingModel, "spot") |
| 1360 | priceColor := colorGreen |
| 1361 | if isSpot { |
| 1362 | priceColor = colorRed |
| 1363 | } |
| 1364 | |
| 1365 | row := padV(p.PricingModel, 24) + " " + |
| 1366 | lipgloss.NewStyle().Foreground(priceColor).Render(padV(p.Price, 10)) + " " + |
| 1367 | padV(p.Unit, 5) + " " + |
| 1368 | padV(upfront, 10) + " " + |
| 1369 | padV(yr, 4) + " " + |
| 1370 | opt |
| 1371 | |
| 1372 | if isSpot { |
| 1373 | row = lipgloss.NewStyle().Foreground(colorRed).Render(padV(p.PricingModel, 24)) + " " + |
| 1374 | lipgloss.NewStyle().Foreground(priceColor).Render(padV(p.Price, 10)) + " " + |
| 1375 | padV(p.Unit, 5) + " " + |
| 1376 | padV(upfront, 10) + " " + |
| 1377 | padV(yr, 4) + " " + |
| 1378 | lipgloss.NewStyle().Foreground(colorRed).Render(opt) |
| 1379 | } |
no test coverage detected