diff --git a/packages/forklift-console-plugin/locales/en/plugin__forklift-console-plugin.json b/packages/forklift-console-plugin/locales/en/plugin__forklift-console-plugin.json index d68e4637a..dee68039e 100644 --- a/packages/forklift-console-plugin/locales/en/plugin__forklift-console-plugin.json +++ b/packages/forklift-console-plugin/locales/en/plugin__forklift-console-plugin.json @@ -1,5 +1,6 @@ { "{{Canceled}} canceled": "{{Canceled}} canceled", + "{{completed}} of {{total}} VMs migrated, {{canceled}} canceled": "{{completed}} of {{total}} VMs migrated, {{canceled}} canceled", "{{dateLabel}} Failed: {{value}}": "{{dateLabel}} Failed: {{value}}", "{{dateLabel}} Running: {{value}}": "{{dateLabel}} Running: {{value}}", "{{dateLabel}} Succeeded: {{value}}": "{{dateLabel}} Succeeded: {{value}}", diff --git a/packages/forklift-console-plugin/src/modules/Plans/views/details/components/MigrationsSection/components/MigrationsTable.tsx b/packages/forklift-console-plugin/src/modules/Plans/views/details/components/MigrationsSection/components/MigrationsTable.tsx index fcf6449e3..9bee53cb5 100644 --- a/packages/forklift-console-plugin/src/modules/Plans/views/details/components/MigrationsSection/components/MigrationsTable.tsx +++ b/packages/forklift-console-plugin/src/modules/Plans/views/details/components/MigrationsSection/components/MigrationsTable.tsx @@ -6,10 +6,19 @@ import { MigrationModelGroupVersionKind, PlanModelGroupVersionKind, V1beta1Migration, - V1beta1MigrationStatusConditions, } from '@kubev2v/types'; import { ResourceLink, Timestamp } from '@openshift-console/dynamic-plugin-sdk'; -import { HelperText, HelperTextItem, Split, SplitItem } from '@patternfly/react-core'; +import { + HelperText, + HelperTextItem, + Progress, + ProgressMeasureLocation, + ProgressSize, + ProgressVariant, + Split, + SplitItem, +} from '@patternfly/react-core'; +import { VirtualMachineIcon } from '@patternfly/react-icons'; import { TableComposable, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table'; export const MigrationsTable: React.FC = ({ migrations, showOwner }) => { @@ -23,6 +32,8 @@ export const MigrationsTable: React.FC = ({ migrations, sho ); } + sortMigrationsByStartedAtDate(migrations); + return ( @@ -30,9 +41,9 @@ export const MigrationsTable: React.FC = ({ migrations, sho {t('Migration')} {showOwner && {t('Owner')}} {t('Status')} - {t('VMs')} - {t('Started at')} - {t('Completed at')} + {t('VMs')} + {t('Started at')} + {t('Completed at')} @@ -58,8 +69,12 @@ export const MigrationsTable: React.FC = ({ migrations, sho )} )} - {getStatusLabel(migration?.status?.conditions)} - {migration?.status?.vms?.length || '-'} + + + + + + @@ -73,8 +88,14 @@ export const MigrationsTable: React.FC = ({ migrations, sho ); }; -const getStatusLabel = (conditions: V1beta1MigrationStatusConditions[]) => { - let phase: string; +const getMigrationPhase = (migration) => { + let phase = 'Unknown'; + + const conditions = migration?.status?.conditions; + + if (!conditions || conditions.length < 1) { + return phase; + } const phases = ['Ready', 'Running', 'Succeeded', 'Failed']; @@ -86,6 +107,31 @@ const getStatusLabel = (conditions: V1beta1MigrationStatusConditions[]) => { } }); + return phase; +}; + +const getMigrationVmsCounts = (migration) => { + const vms = migration?.status?.vms; + + if (!vms || vms.length < 1) { + return {}; + } + + const vmsCanceled = vms.filter((vm) => + (vm?.conditions || []).find((c) => c.type === 'Canceled' && c.status === 'True'), + ); + const vmsCompleted = vms.filter((vm) => vm?.completed); + + return { + completed: vmsCompleted.length, + total: vms.length, + canceled: vmsCanceled.length, + }; +}; + +const StatusLabel: React.FC<{ migration: V1beta1Migration }> = ({ migration }) => { + const phase = getMigrationPhase(migration); + return ( @@ -96,6 +142,54 @@ const getStatusLabel = (conditions: V1beta1MigrationStatusConditions[]) => { ); }; +const VMsLabel: React.FC<{ migration: V1beta1Migration }> = ({ migration }) => { + const { t } = useForkliftTranslation(); + + const phase = getMigrationPhase(migration); + let progressVariant; + + switch (phase) { + case 'Failed': + progressVariant = ProgressVariant.danger; + break; + case 'Succeeded': + progressVariant = ProgressVariant.success; + break; + } + + const counters = getMigrationVmsCounts(migration); + + if (!counters?.total || counters.total === 0) { + return <>-; + } + + return ( + + + + + + {t('{{completed}} of {{total}} VMs migrated, {{canceled}} canceled', counters)} + + + + + ); +}; + +const sortMigrationsByStartedAtDate = (migrations: V1beta1Migration[]) => { + migrations.sort((a, b) => { + const dateA = new Date(a?.status?.started); + const dateB = new Date(b?.status?.started); + return dateB.getTime() - dateA.getTime(); + }); +}; + export type MigrationTableProps = { migrations: V1beta1Migration[]; showOwner?: boolean;