()
| 645 | } |
| 646 | |
| 647 | func (m *statusModel) renderMigratingSection() string { |
| 648 | // Filter instances with MIGRATING status |
| 649 | var migratingInstances []api.Instance |
| 650 | for _, instance := range m.instances { |
| 651 | if instance.Status == "MIGRATING" && !instance.ProgressStartedAt.IsZero() { |
| 652 | migratingInstances = append(migratingInstances, instance) |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | if len(migratingInstances) == 0 { |
| 657 | return "" |
| 658 | } |
| 659 | |
| 660 | var b strings.Builder |
| 661 | b.WriteString("\n") |
| 662 | b.WriteString(primaryStyle.Bold(true).Render("Migrating Instances:")) |
| 663 | b.WriteString("\n\n") |
| 664 | |
| 665 | for _, instance := range migratingInstances { |
| 666 | // Use instance ID for migrating progress bars (each instance gets its own) |
| 667 | progressBarKey := "migrating-" + instance.ID |
| 668 | m.ensureProgressBar(progressBarKey) |
| 669 | progressBar := m.progressBars[progressBarKey] |
| 670 | |
| 671 | // Calculate progress using the GetProgress method |
| 672 | migratingExpectedDuration := utils.EstimateInstanceMigrationDuration(instance.Storage) |
| 673 | progressPercent := utils.GetProgress(instance.ProgressStartedAt, migratingExpectedDuration) |
| 674 | |
| 675 | // Calculate time remaining |
| 676 | elapsed := time.Since(instance.ProgressStartedAt) |
| 677 | remaining := migratingExpectedDuration - elapsed |
| 678 | if remaining < 0 { |
| 679 | remaining = 0 |
| 680 | } |
| 681 | remainingMinutes := int(remaining.Minutes()) |
| 682 | if remainingMinutes < 1 { |
| 683 | remainingMinutes = 1 |
| 684 | } |
| 685 | |
| 686 | // Render instance name (grey, unbolded) |
| 687 | b.WriteString(fmt.Sprintf(" %s\n", SubtleTextStyle().Render(instance.Name))) |
| 688 | |
| 689 | // Render progress bar |
| 690 | b.WriteString(fmt.Sprintf(" %s\n", progressBar.ViewAs(progressPercent))) |
| 691 | |
| 692 | // Render message (compressed) |
| 693 | message := fmt.Sprintf(" ~%d min total, ~%d min remaining", |
| 694 | int(migratingExpectedDuration.Minutes()), |
| 695 | remainingMinutes, |
| 696 | ) |
| 697 | b.WriteString(m.styles.timestamp.Render(message)) |
| 698 | b.WriteString("\n\n") |
| 699 | } |
| 700 | |
| 701 | return b.String() |
| 702 | } |
| 703 | |
| 704 | func (m *statusModel) renderEventsSection() string { |
no test coverage detected