-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert Providers screen to Console page
Code changes: 1. use StandardPage list component 2. entity list is produced by merging results from k8s API and exsting Forklift inventory REST API. 3. actions in the table (kebab actions) are provided via extension point 'console.action/provider' Functional changes: 1. display all providers in one table 2. use only 'Ready' condition to describe the state of the provider Signed-off-by: Radoslaw Szwajkowski <[email protected]>
- Loading branch information
Showing
14 changed files
with
655 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,50 @@ | ||
{ | ||
"{{type}} provider {{name}} will no longer be selectable as a migration source.": "{{type}} provider {{name}} will no longer be selectable as a migration source.", | ||
"{{type}} provider {{name}} will no longer be selectable as a migration target.": "{{type}} provider {{name}} will no longer be selectable as a migration target.", | ||
"Actions": "Actions", | ||
"Add Provider": "Add Provider", | ||
"Cancel": "Cancel", | ||
"Cannot remove provider": "Cannot remove provider", | ||
"Clear all filters": "Clear all filters", | ||
"Clusters": "Clusters", | ||
"Delete": "Delete", | ||
"Delete Provider": "Delete Provider", | ||
"Edit Provider": "Edit Provider", | ||
"Endpoint": "Endpoint", | ||
"False": "False", | ||
"Filter by endpoint": "Filter by endpoint", | ||
"Filter by name": "Filter by name", | ||
"Filter by namespace": "Filter by namespace", | ||
"Hosts": "Hosts", | ||
"KubeVirt": "KubeVirt", | ||
"Loading": "Loading", | ||
"Manage Columns": "Manage Columns", | ||
"Mappings for VM Import": "Mappings for VM Import", | ||
"Name": "Name", | ||
"Namespace": "Namespace", | ||
"Networks": "Networks", | ||
"No information": "No information", | ||
"No results found": "No results found", | ||
"No results match the filter criteria. Clear all filters and try again.": "No results match the filter criteria. Clear all filters and try again.", | ||
"oVirt": "oVirt", | ||
"Permanently delete provider?": "Permanently delete provider?", | ||
"Plans for VM Import": "Plans for VM Import", | ||
"Providers": "Providers", | ||
"Providers for VM Import": "Providers for VM Import", | ||
"Ready": "Ready", | ||
"Reorder": "Reorder", | ||
"Restore default colums": "Restore default colums", | ||
"Save": "Save", | ||
"Select Filter": "Select Filter", | ||
"Select migration network": "Select migration network", | ||
"Selected columns will be displayed in the table.": "Selected columns will be displayed in the table.", | ||
"Storage": "Storage", | ||
"Table column management": "Table column management", | ||
"True": "True", | ||
"Type": "Type", | ||
"Unable to retrieve data": "Unable to retrieve data", | ||
"Virtualization": "Virtualization" | ||
"Unknown": "Unknown", | ||
"Virtualization": "Virtualization", | ||
"VMs": "VMs", | ||
"VMware": "VMware" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import React from 'react'; | ||
import { RowProps } from 'src/components/TableView'; | ||
import { useTranslation } from 'src/internal/i18n'; | ||
import { NAME, NAMESPACE, READY, TYPE, URL } from 'src/utils/constants'; | ||
|
||
import { StatusIcon } from '@migtools/lib-ui'; | ||
import { ResourceLink } from '@openshift-console/dynamic-plugin-sdk'; | ||
import { Button, Popover } from '@patternfly/react-core'; | ||
import { Td, Tr } from '@patternfly/react-table'; | ||
|
||
import { MergedProvider } from './data'; | ||
import { ProviderActions } from './providerActions'; | ||
|
||
interface CellProps { | ||
value: string; | ||
entity: MergedProvider; | ||
} | ||
const StatusCell = ({ value, entity: { conditions } }: CellProps) => { | ||
const { t } = useTranslation(); | ||
const existingConditions = Object.values(conditions).filter(Boolean); | ||
const toState = (value) => { | ||
switch (value) { | ||
case 'True': | ||
return 'Ok'; | ||
case 'False': | ||
return 'Error'; | ||
default: | ||
return 'Unknown'; | ||
} | ||
}; | ||
const label = ((value) => { | ||
switch (value) { | ||
case 'True': | ||
return t('True'); | ||
case 'False': | ||
return t('False'); | ||
default: | ||
return t('Unknown'); | ||
} | ||
})(value); | ||
return ( | ||
<Popover | ||
hasAutoWidth | ||
bodyContent={ | ||
<div> | ||
{existingConditions.length > 0 | ||
? existingConditions.map(({ message, status }) => { | ||
return <StatusIcon key={message} status={toState(status)} label={message} />; | ||
}) | ||
: t('No information')} | ||
</div> | ||
} | ||
> | ||
<Button variant="link" isInline aria-label={label}> | ||
<StatusIcon status={toState(value)} label={label} /> | ||
</Button> | ||
</Popover> | ||
); | ||
}; | ||
|
||
const TextCell = ({ value }: { value: string }) => <>{value}</>; | ||
|
||
const ProviderLink = ({ value, entity }: CellProps) => ( | ||
<ResourceLink kind={entity.kind} name={value} namespace={entity?.namespace} /> | ||
); | ||
|
||
const cellCreator = { | ||
[NAME]: ProviderLink, | ||
[READY]: StatusCell, | ||
[URL]: TextCell, | ||
[TYPE]: TextCell, | ||
[NAMESPACE]: ({ value }: CellProps) => <ResourceLink kind="Namespace" name={value} />, | ||
}; | ||
|
||
const ProviderRow = ({ columns, entity }: RowProps<MergedProvider>) => { | ||
const { t } = useTranslation(); | ||
return ( | ||
<Tr> | ||
{columns.map(({ id, toLabel }) => ( | ||
<Td key={id} dataLabel={toLabel(t)}> | ||
{cellCreator?.[id]?.({ | ||
value: entity[id], | ||
entity, | ||
}) ?? <TextCell value={String(entity[id] ?? '')} />} | ||
</Td> | ||
))} | ||
<Td modifier="fitContent"> | ||
<ProviderActions entity={entity} /> | ||
</Td> | ||
</Tr> | ||
); | ||
}; | ||
|
||
export default ProviderRow; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
import React from 'react'; | ||
import { StandardPage } from 'src/components/StandardPage'; | ||
import { Field } from 'src/components/types'; | ||
import { useTranslation } from 'src/internal/i18n'; | ||
import { ResourceConsolePageProps } from 'src/internal/k8s'; | ||
import { | ||
CLUSTER_COUNT, | ||
HOST_COUNT, | ||
NAME, | ||
NAMESPACE, | ||
NETWORK_COUNT, | ||
READY, | ||
STORAGE_COUNT, | ||
TYPE, | ||
URL, | ||
VM_COUNT, | ||
} from 'src/utils/constants'; | ||
|
||
import { Button } from '@patternfly/react-core'; | ||
|
||
import { MergedProvider, useProvidersWithInventory } from './data'; | ||
import ProviderRow from './ProviderRow'; | ||
|
||
const fieldsMetadata: Field[] = [ | ||
{ | ||
id: NAME, | ||
toLabel: (t) => t('Name'), | ||
isVisible: true, | ||
isIdentity: true, // Name is sufficient ID when Namespace is pre-selected | ||
filter: { | ||
type: 'freetext', | ||
toPlaceholderLabel: (t) => t('Filter by name'), | ||
}, | ||
sortable: true, | ||
}, | ||
{ | ||
id: NAMESPACE, | ||
toLabel: (t) => t('Namespace'), | ||
isVisible: true, | ||
isIdentity: true, | ||
filter: { | ||
type: 'freetext', | ||
toPlaceholderLabel: (t) => t('Filter by namespace'), | ||
}, | ||
sortable: true, | ||
}, | ||
{ | ||
id: READY, | ||
toLabel: (t) => t('Ready'), | ||
isVisible: true, | ||
filter: { | ||
type: 'enum', | ||
primary: true, | ||
toPlaceholderLabel: (t) => t('Ready'), | ||
values: [ | ||
{ | ||
id: 'True', | ||
toLabel: (t) => { | ||
return t('True'); | ||
}, | ||
}, | ||
{ | ||
id: 'False', | ||
toLabel: (t) => { | ||
return t('False'); | ||
}, | ||
}, | ||
{ | ||
id: 'Unknown', | ||
toLabel: (t) => { | ||
return t('Unknown'); | ||
}, | ||
}, | ||
], | ||
}, | ||
sortable: true, | ||
}, | ||
{ | ||
id: URL, | ||
toLabel: (t) => t('Endpoint'), | ||
isVisible: true, | ||
filter: { | ||
type: 'freetext', | ||
toPlaceholderLabel: (t) => t('Filter by endpoint'), | ||
}, | ||
sortable: true, | ||
}, | ||
{ | ||
id: TYPE, | ||
toLabel: (t) => t('Type'), | ||
isVisible: true, | ||
filter: { | ||
type: 'enum', | ||
primary: true, | ||
toPlaceholderLabel: (t) => t('Type'), | ||
values: [ | ||
{ id: 'vsphere', toLabel: (t) => t('VMware') }, | ||
{ id: 'ovirt', toLabel: (t) => t('oVirt') }, | ||
{ id: 'openshift', toLabel: (t) => t('KubeVirt') }, | ||
], | ||
}, | ||
sortable: true, | ||
}, | ||
{ | ||
id: VM_COUNT, | ||
toLabel: (t) => t('VMs'), | ||
isVisible: true, | ||
sortable: true, | ||
}, | ||
{ | ||
id: NETWORK_COUNT, | ||
toLabel: (t) => t('Networks'), | ||
isVisible: true, | ||
sortable: true, | ||
}, | ||
{ | ||
id: CLUSTER_COUNT, | ||
toLabel: (t) => t('Clusters'), | ||
isVisible: true, | ||
sortable: true, | ||
}, | ||
{ | ||
id: HOST_COUNT, | ||
toLabel: (t) => t('Hosts'), | ||
isVisible: false, | ||
sortable: true, | ||
}, | ||
{ | ||
id: STORAGE_COUNT, | ||
toLabel: (t) => t('Storage'), | ||
isVisible: false, | ||
sortable: true, | ||
}, | ||
]; | ||
|
||
export const ProvidersPage = ({ namespace, kind }: ResourceConsolePageProps) => { | ||
const { t } = useTranslation(); | ||
const dataSource = useProvidersWithInventory({ | ||
kind, | ||
namespace, | ||
}); | ||
|
||
return ( | ||
<StandardPage<MergedProvider> | ||
addButton={ | ||
<Button variant="primary" onClick={() => ''}> | ||
{t('Add Provider')} | ||
</Button> | ||
} | ||
dataSource={dataSource} | ||
RowMapper={ProviderRow} | ||
fieldsMetadata={fieldsMetadata} | ||
namespace={namespace} | ||
title={t('Providers')} | ||
/> | ||
); | ||
}; | ||
|
||
export default ProvidersPage; |
Oops, something went wrong.