diff --git a/packages/online-shell/src/discover/Discover.css b/packages/online-shell/src/discover/Discover.css index 1c33945b..b4fee40b 100644 --- a/packages/online-shell/src/discover/Discover.css +++ b/packages/online-shell/src/discover/Discover.css @@ -38,6 +38,14 @@ font-style: italic; } +.discover-loading-compact { + margin-top: 0 !important; +} + +.discover-loading-compact div { + padding: 0; +} + .discover-group-label { text-align: left; color: rgb(117, 117, 117); diff --git a/packages/online-shell/src/discover/Discover.tsx b/packages/online-shell/src/discover/Discover.tsx index 028da83d..f19eb7a7 100644 --- a/packages/online-shell/src/discover/Discover.tsx +++ b/packages/online-shell/src/discover/Discover.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' import { Alert, Card, @@ -6,39 +6,50 @@ import { EmptyState, EmptyStateBody, EmptyStateIcon, - List, PageSection, PageSectionVariants, - Panel, - PanelHeader, - PanelMain, - PanelMainBody, Title, EmptyStateHeader, + Tabs, + TabTitleText, + Tab, } from '@patternfly/react-core' import { CubesIcon } from '@patternfly/react-icons' -import { HawtioLoadingCard } from '@hawtio/react' import { discoverService } from './discover-service' import { DiscoverToolbar } from './DiscoverToolbar' import { DiscoverContext, useDisplayItems } from './context' -import { DiscoverGroupList } from './DiscoverGroupList' -import { DiscoverPodItem } from './DiscoverPodItem' +import { DiscoverProjectContent } from './DiscoverProjectContent' +import { DiscoverLoadingPanel } from './DiscoverLoadingPanel' export const Discover: React.FunctionComponent = () => { - const { error, isLoading, discoverGroups, setDiscoverGroups, discoverPods, setDiscoverPods, filters, setFilters } = + const { error, isLoading, refreshing, setRefreshing, discoverProjects, setDiscoverProjects, filters, setFilters } = useDisplayItems() + const [activeTabKey, setActiveTabKey] = React.useState('') + + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number, + ) => { + setActiveTabKey(`${tabIndex}`) + } + + useEffect(() => { + if (isLoading || error || discoverProjects.length === 0) return + + setActiveTabKey(activeKey => { + if (activeKey.length === 0) return discoverProjects[0].name + + const projects = discoverProjects.filter(p => p.name === activeKey) + if (projects.length === 0) return discoverProjects[0].name // active key no longer in projects + + return activeKey + }) + }, [isLoading, error, discoverProjects, filters]) if (isLoading) { return ( - - Waiting for Hawtio Containers ... - - - - - - + ) } @@ -63,17 +74,17 @@ export const Discover: React.FunctionComponent = () => { - {discoverGroups.length + discoverPods.length === 0 && ( + {discoverProjects.length === 0 && ( { )} - {discoverGroups.length > 0 && } - - {discoverPods.length > 0 && ( - - {discoverPods.map(pod => { - return - })} - + {discoverProjects.length > 0 && ( + + {discoverProjects.map(discoverProject => ( + {discoverProject.name}} + key={`discover-project-${discoverProject.name}`} + > + + + ))} + )} diff --git a/packages/online-shell/src/discover/DiscoverGroupList.tsx b/packages/online-shell/src/discover/DiscoverGroupList.tsx index ac95b8d1..248a36de 100644 --- a/packages/online-shell/src/discover/DiscoverGroupList.tsx +++ b/packages/online-shell/src/discover/DiscoverGroupList.tsx @@ -1,41 +1,53 @@ -import React, { useContext } from 'react' +import React, { useState } from 'react' import { Accordion, AccordionContent, AccordionItem, AccordionToggle, List } from '@patternfly/react-core' import { DiscoverGroup } from './globals' import { DiscoverGroupLabel } from './DiscoverGroupLabel' import { DiscoverPodItem } from './DiscoverPodItem' import './Discover.css' -import { DiscoverContext } from './context' -export const DiscoverGroupList: React.FunctionComponent = () => { - const { discoverGroups, setDiscoverGroups } = useContext(DiscoverContext) +interface DiscoverGroupListProps { + groups: DiscoverGroup[] +} + +export const DiscoverGroupList: React.FunctionComponent = (props: DiscoverGroupListProps) => { + const [hidden, setHidden] = useState([]) const onToggle = (group: DiscoverGroup) => { - const groups = [...discoverGroups] + const newHidden = [...hidden] - groups.forEach(g => { - if (g.uid === group.uid) g.expanded = !g.expanded - }) + const index = newHidden.indexOf(group.uid) + if (index === -1) { + // Since no uid in hidden then expanded by default + // then add to hidden to hide + newHidden.push(group.uid) + } else { + newHidden.splice(index, 1) + } + + setHidden(newHidden) + } - setDiscoverGroups(groups) + const isHidden = (group: DiscoverGroup): boolean => { + return hidden.indexOf(group.uid) > -1 } - if (discoverGroups.length === 0) return <> + if (props.groups.length === 0) return <> return ( - {discoverGroups.map(group => { + {props.groups.map(group => { return ( { onToggle(group) }} - isExpanded={group.expanded} + isExpanded={!isHidden(group)} id={'item-' + group.name} > - + {group.replicas.map(replica => ( diff --git a/packages/online-shell/src/discover/DiscoverLoadingPanel.tsx b/packages/online-shell/src/discover/DiscoverLoadingPanel.tsx new file mode 100644 index 00000000..ca118764 --- /dev/null +++ b/packages/online-shell/src/discover/DiscoverLoadingPanel.tsx @@ -0,0 +1,25 @@ +import React from 'react' +import { Panel, PanelHeader, PanelMain, PanelMainBody } from '@patternfly/react-core' +import { HawtioLoadingCard } from '@hawtio/react' + +interface DiscoverLoadingPanelProps { + compact?: boolean +} + +export const DiscoverLoadingPanel: React.FunctionComponent = ( + props: DiscoverLoadingPanelProps, +) => { + let classNames = 'discover-loading' + if (props.compact) classNames = classNames + ' discover-loading-compact' + + return ( + + Waiting for Hawtio Containers ... + + + + + + + ) +} diff --git a/packages/online-shell/src/discover/DiscoverPodConnect.tsx b/packages/online-shell/src/discover/DiscoverPodConnect.tsx index ea54256e..2f60aa47 100644 --- a/packages/online-shell/src/discover/DiscoverPodConnect.tsx +++ b/packages/online-shell/src/discover/DiscoverPodConnect.tsx @@ -22,7 +22,7 @@ export const DiscoverPodConnect: React.FunctionComponent { const connectionNames: string[] = mgmtService.refreshConnections(props.pod.mPod) - const mgmtError = props.pod.mPod?.getManagementError() + const mgmtError = props.pod.mPod?.mgmtError const [isOpen, setIsOpen] = React.useState(false) @@ -39,7 +39,7 @@ export const DiscoverPodConnect: React.FunctionComponent { return ( mgmtService.podStatus(props.pod.mPod) !== 'Running' || - !props.pod.mPod.getManagement().status.managed || + !props.pod.mPod.management.status.managed || connectionNames.length === 0 || mgmtError !== null ) diff --git a/packages/online-shell/src/discover/DiscoverPodItem.tsx b/packages/online-shell/src/discover/DiscoverPodItem.tsx index 3b458d9f..09a4aded 100644 --- a/packages/online-shell/src/discover/DiscoverPodItem.tsx +++ b/packages/online-shell/src/discover/DiscoverPodItem.tsx @@ -17,24 +17,24 @@ interface DiscoverPodItemProps { export const DiscoverPodItem: React.FunctionComponent = (props: DiscoverPodItemProps) => { const nodeLabel = (): ReactNode => { - if (props.pod.mPod.getSpec()?.nodeName) { + if (props.pod.mPod.spec?.nodeName) { return ( - - {props.pod.mPod.getSpec()?.nodeName} + + {props.pod.mPod.spec?.nodeName} ) } - return props.pod.mPod.getStatus()?.hostIP + return props.pod.mPod.status?.hostIP } const containersLabel = (): ReactNode => { - const total = props.pod.mPod.getSpec()?.containers.length || 0 + const total = props.pod.mPod.spec?.containers.length || 0 return `${total} container${total !== 1 ? 's' : ''}` } const routesLabel = (): ReactNode => { - if (!props.pod.mPod.getManagement().status.managed) { + if (!props.pod.mPod.management.status.managed) { return (