Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 35 additions & 28 deletions web/packages/shared/components/UnifiedResources/FilterPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import React, { useState } from 'react';
import styled from 'styled-components';
import { ButtonBorder, ButtonPrimary, ButtonSecondary } from 'design/Button';
import { SortDir } from 'design/DataTable/types';
import { Text, Flex, Box } from 'design';
import { Text, Flex } from 'design';
import Menu, { MenuItem } from 'design/Menu';
import { StyledCheckbox } from 'design/Checkbox';
import {
Expand Down Expand Up @@ -62,6 +62,7 @@ interface FilterPanelProps {
setCurrentViewMode: (viewMode: ViewMode) => void;
expandAllLabels: boolean;
setExpandAllLabels: (expandAllLabels: boolean) => void;
hideViewModeOptions: boolean;
}

export function FilterPanel({
Expand All @@ -75,6 +76,7 @@ export function FilterPanel({
setCurrentViewMode,
expandAllLabels,
setExpandAllLabels,
hideViewModeOptions,
}: FilterPanelProps) {
const { sort, kinds } = params;

Expand Down Expand Up @@ -118,34 +120,39 @@ export function FilterPanel({
/>
</Flex>
<Flex gap={2} alignItems="center">
<Box mr={1}>{BulkActions}</Box>
{currentViewMode === ViewMode.VIEW_MODE_LIST && (
<ButtonBorder
size="small"
css={`
border: none;
color: ${props => props.theme.colors.text.slightlyMuted};
text-transform: none;
padding-left: ${props => props.theme.space[2]}px;
padding-right: ${props => props.theme.space[2]}px;
height: 22px;
`}
onClick={() => setExpandAllLabels(!expandAllLabels)}
>
<Flex alignItems="center" width="100%">
{expandAllLabels ? (
<ArrowsIn size="small" mr={1} />
) : (
<ArrowsOut size="small" mr={1} />
)}
{expandAllLabels ? 'Collapse ' : 'Expand '} All Labels
</Flex>
</ButtonBorder>
<Flex mr={1}>{BulkActions}</Flex>
{!hideViewModeOptions && (
<>
{currentViewMode === ViewMode.VIEW_MODE_LIST && (
<ButtonBorder
size="small"
css={`
border: none;
color: ${props => props.theme.colors.text.slightlyMuted};
text-transform: none;
padding-left: ${props => props.theme.space[2]}px;
padding-right: ${props => props.theme.space[2]}px;
height: 22px;
font-size: 12px;
`}
onClick={() => setExpandAllLabels(!expandAllLabels)}
>
<Flex alignItems="center" width="100%">
{expandAllLabels ? (
<ArrowsIn size="small" mr={1} />
) : (
<ArrowsOut size="small" mr={1} />
)}
{expandAllLabels ? 'Collapse ' : 'Expand '} All Labels
</Flex>
</ButtonBorder>
)}
<ViewModeSwitch
currentViewMode={currentViewMode}
setCurrentViewMode={setCurrentViewMode}
/>
</>
)}
<ViewModeSwitch
currentViewMode={currentViewMode}
setCurrentViewMode={setCurrentViewMode}
/>
<SortMenu
onDirChange={onSortOrderButtonClicked}
onChange={onSortFieldChange}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import React, {
useCallback,
Children,
PropsWithChildren,
useRef,
} from 'react';

import styled from 'styled-components';
Expand Down Expand Up @@ -77,6 +78,10 @@ const INITIAL_FETCH_SIZE = 48;
// increment by 24 every fetch
export const FETCH_MORE_SIZE = 24;

// The breakpoint at which to force the card view. This is to improve responsiveness
// since list view looks cluttered on narrow viewports.
const FORCE_CARD_VIEW_BREAKPOINT = 800;

export const PINNING_NOT_SUPPORTED_MESSAGE =
'This cluster does not support pinning resources. To enable, upgrade to 14.1 or newer.';

Expand Down Expand Up @@ -171,11 +176,14 @@ export function UnifiedResources(props: UnifiedResourcesProps) {
bulkActions = [],
} = props;

const containerRef = useRef<HTMLDivElement>();

const { setTrigger } = useInfiniteScroll({
fetch: fetchResources,
});

const [selectedResources, setSelectedResources] = useState<string[]>([]);
const [forceCardView, setForceCardView] = useState(false);

const pinnedResourcesGetter =
pinning.kind === 'supported'
Expand Down Expand Up @@ -353,10 +361,27 @@ export function UnifiedResources(props: UnifiedResourcesProps) {
unifiedResourcePreferences.labelsViewMode ===
LabelsViewMode.LABELS_VIEW_MODE_EXPANDED;

useEffect(() => {
const resizeObserver = new ResizeObserver(entries => {
const container = entries[0];
if (container.contentRect.width <= FORCE_CARD_VIEW_BREAKPOINT) {
setForceCardView(true);
} else {
setForceCardView(false);
}
});

resizeObserver.observe(containerRef.current);
return () => {
resizeObserver.disconnect();
};
}, []);

const ViewComponent =
unifiedResourcePreferences.viewMode === ViewMode.VIEW_MODE_LIST
? ListView
: CardsView;
unifiedResourcePreferences.viewMode === ViewMode.VIEW_MODE_CARD ||
forceCardView
? CardsView
: ListView;

return (
<div
Expand All @@ -365,7 +390,9 @@ export function UnifiedResources(props: UnifiedResourcesProps) {
width: 100%;
max-width: 1800px;
margin: 0 auto;
min-width: 450px;
`}
ref={containerRef}
>
<ErrorsContainer>
{resourcesFetchAttempt.status === 'failed' && (
Expand Down Expand Up @@ -417,6 +444,7 @@ export function UnifiedResources(props: UnifiedResourcesProps) {
: LabelsViewMode.LABELS_VIEW_MODE_COLLAPSED
);
}}
hideViewModeOptions={forceCardView}
BulkActions={
<>
{selectedResources.length > 0 && (
Expand All @@ -430,9 +458,12 @@ export function UnifiedResources(props: UnifiedResourcesProps) {
textTransform="none"
onClick={() => action(getSelectedResources())}
disabled={disabled}
size="small"
css={`
border: none;
color: ${props => props.theme.colors.brand};
height: 22px;
font-size: 12px;
`}
>
<Icon size="small" color="brand" mr={2} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@

.SearchPanel {
width: 100%;
@container (min-width: 800px) {
@container (min-width: 801px) {
width: 70%;
min-width: 800px;
}
}
36 changes: 30 additions & 6 deletions web/packages/teleport/src/Main/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import React, {
useEffect,
useMemo,
useState,
createContext,
useContext,
} from 'react';
import styled from 'styled-components';
import { Indicator } from 'design';
Expand Down Expand Up @@ -263,12 +265,34 @@ function FeatureRoutes({ lockedFeatures }: { lockedFeatures: LockedFeatures }) {
return <Switch>{routes}</Switch>;
}

export const ContentMinWidth = styled.div`
min-width: 1250px;
display: flex;
flex-direction: column;
flex: 1;
`;
// This context allows children components to disable this min-width in case they want to be able to shrink smaller.
type MinWidthContextState = {
setEnforceMinWidth: (enforceMinWidth: boolean) => void;
};

const ContentMinWidthContext = createContext<MinWidthContextState>(null);

export const useContentMinWidthContext = () =>
useContext(ContentMinWidthContext);

const ContentMinWidth = ({ children }: { children: ReactNode }) => {
const [enforceMinWidth, setEnforceMinWidth] = useState(true);

return (
<ContentMinWidthContext.Provider value={{ setEnforceMinWidth }}>
<div
css={`
display: flex;
flex-direction: column;
flex: 1;
${enforceMinWidth ? 'min-width: 1250px;' : ''}
`}
>
{children}
</div>
</ContentMinWidthContext.Provider>
);
};

export const HorizontalSplit = styled.div`
display: flex;
Expand Down
2 changes: 1 addition & 1 deletion web/packages/teleport/src/Main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

export {
Main as default,
ContentMinWidth,
useContentMinWidthContext,
HorizontalSplit,
StyledIndicator,
} from './Main';
Expand Down
13 changes: 12 additions & 1 deletion web/packages/teleport/src/UnifiedResources/UnifiedResources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import React, { useCallback, useState } from 'react';
import React, { useCallback, useState, useEffect } from 'react';

import { Flex } from 'design';

Expand All @@ -38,6 +38,7 @@ import {
FeatureHeaderTitle,
FeatureBox,
} from 'teleport/components/Layout';
import { useContentMinWidthContext } from 'teleport/Main';
import AgentButtonAdd from 'teleport/components/AgentButtonAdd';
import { SearchResource } from 'teleport/Discover/SelectResource';
import { encodeUrlQueryParams } from 'teleport/components/hooks/useUrlFiltering';
Expand Down Expand Up @@ -99,6 +100,16 @@ function ClusterResources({
const teleCtx = useTeleport();
const flags = teleCtx.getFeatureFlags();

const { setEnforceMinWidth } = useContentMinWidthContext();

useEffect(() => {
setEnforceMinWidth(false);

return () => {
setEnforceMinWidth(true);
};
}, []);

const pinningNotSupported = storageService.arePinnedResourcesDisabled();
const {
getClusterPinnedResources,
Expand Down