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
20 changes: 2 additions & 18 deletions web/packages/design/src/Alert/Alert.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import styled from 'styled-components';
import PropTypes from 'prop-types';

import { space, color, width } from 'design/system';
import { fade } from 'design/theme/utils/colorManipulator';

const kind = props => {
const { kind, theme } = props;
Expand All @@ -46,14 +45,6 @@ const kind = props => {
background: theme.colors.success.main,
color: theme.colors.text.primaryInverse,
};
case 'outline-info':
return {
background: fade(theme.colors.link, 0.1),
border: `${theme.radii[1]}px solid ${theme.colors.link}`,
borderRadius: `${theme.radii[3]}px`,
boxShadow: 'none',
justifyContent: 'normal',
};
default:
return {
background: theme.colors.error.main,
Expand All @@ -66,7 +57,7 @@ const Alert = styled.div`
display: flex;
align-items: center;
justify-content: center;
border-radius: ${p => p.theme.radii[1]}px;
border-radius: 2px;
box-sizing: border-box;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.24);
margin: 0 0 24px 0;
Expand All @@ -85,13 +76,7 @@ const Alert = styled.div`
`;

Alert.propTypes = {
kind: PropTypes.oneOf([
'danger',
'info',
'warning',
'success',
'outline-info',
]),
kind: PropTypes.oneOf(['danger', 'info', 'warning', 'success']),
...color.propTypes,
...space.propTypes,
...width.propTypes,
Expand All @@ -108,4 +93,3 @@ export const Danger = props => <Alert kind="danger" {...props} />;
export const Info = props => <Alert kind="info" {...props} />;
export const Warning = props => <Alert kind="warning" {...props} />;
export const Success = props => <Alert kind="success" {...props} />;
export const OutlineInfo = props => <Alert kind="outline-info" {...props} />;
1 change: 0 additions & 1 deletion web/packages/design/src/Alert/Alert.story.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,5 @@ export const Alerts = () => (
<Alert kind="warning">Some warning message</Alert>
<Alert kind="info">Some informational message</Alert>
<Alert kind="success">This is success</Alert>
<Alert kind="outline-info">Text align it yourself</Alert>
</Box>
);
21 changes: 8 additions & 13 deletions web/packages/teleport/src/Discover/Discover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ import React from 'react';
import { Prompt } from 'react-router-dom';
import { Box } from 'design';

import { Navigation } from 'teleport/components/Wizard/Navigation';
import { FeatureBox } from 'teleport/components/Layout';

import { Navigation } from 'teleport/Discover/Navigation/Navigation';
import { SelectResource } from 'teleport/Discover/SelectResource/SelectResource';
import cfg from 'teleport/config';
import { findViewAtIndex } from 'teleport/components/Wizard/flow';

import { EViewConfigs } from './types';
import { findViewAtIndex } from './flow';

import { DiscoverProvider, useDiscover } from './useDiscover';
import { DiscoverIcon } from './SelectResource/icons';

function DiscoverContent() {
const {
Expand Down Expand Up @@ -63,16 +63,11 @@ function DiscoverContent() {
<>
<FeatureBox>
{hasSelectedResource && (
<Box mt={2} mb={7}>
<Navigation
currentStep={currentStep}
views={indexedViews}
startWithIcon={{
title: agentProps.resourceSpec.name,
component: <DiscoverIcon name={agentProps.resourceSpec.icon} />,
}}
/>
</Box>
<Navigation
currentStep={currentStep}
views={indexedViews}
selectedResource={agentProps.resourceSpec}
/>
)}
<Box>{content}</Box>
</FeatureBox>
Expand Down
58 changes: 58 additions & 0 deletions web/packages/teleport/src/Discover/Navigation/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Teleport
* Copyright (C) 2023 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React from 'react';
import styled from 'styled-components';

import { Flex } from 'design';

import { View } from '../flow';

import { StepList } from './StepList';
import { StepItem } from './StepItem';

import type { ResourceSpec } from '../SelectResource';

interface NavigationProps {
currentStep: number;
selectedResource: ResourceSpec;
views: View[];
}

const StyledNav = styled.div`
display: flex;
`;

export function Navigation(props: NavigationProps) {
let content;
if (props.views) {
content = (
<Flex mt="10px" mb="45px">
{/*
This initial StepItem is to render the first "bullet"
in this nav, which is the selected resource's icon
and name.
*/}
<StepItem selectedResource={props.selectedResource} />
<StepList views={props.views} currentStep={props.currentStep} />
</Flex>
);
}

return <StyledNav>{content}</StyledNav>;
}
117 changes: 117 additions & 0 deletions web/packages/teleport/src/Discover/Navigation/StepItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* Teleport
* Copyright (C) 2023 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React from 'react';
import Flex from 'design/Flex';

import { DiscoverIcon } from 'teleport/Discover/SelectResource/icons';
import { StepTitle, StepsContainer } from 'teleport/components/StepNavigation';
import {
Bullet,
Props as BulletProps,
} from 'teleport/components/StepNavigation/Bullet';

import { StepList } from './StepList';

import type { View } from 'teleport/Discover/flow';
import type { ResourceSpec } from '../SelectResource';

// FirstStepItemProps are the required
// props to render the first step item
// in the step navigation.
type FirstStepItemProps = {
view?: never;
currentStep?: never;
index?: never;
selectedResource: ResourceSpec;
};

// RestOfStepItemProps are the required
// props to render the rest of the step item's
// after the `FirstStepItemProps`.
type RestOfStepItemProps = {
view: View;
currentStep: number;
index: number;
selectedResource?: never;
};

export type StepItemProps = FirstStepItemProps | RestOfStepItemProps;

export function StepItem(props: StepItemProps) {
if (props.selectedResource) {
return (
<StepsContainer>
<StepTitle>
<BulletIcon
Icon={<DiscoverIcon name={props.selectedResource.icon} />}
/>
{props.selectedResource.name}
</StepTitle>
</StepsContainer>
);
}

if (props.view.hide) {
return null;
}

let isActive = props.currentStep === props.view.index;
// Make items for nested views.
// Nested views is possible when a view has it's
// own set of sub-steps.
if (props.view.views) {
return (
<StepList
views={props.view.views}
currentStep={props.currentStep}
index={props.index}
/>
);
}

const isDone = props.currentStep > props.view.index;

return (
<StepsContainer active={isDone || isActive}>
<StepTitle>
<BulletIcon
isDone={isDone}
isActive={isActive}
stepNumber={props.view.index + 1}
/>
{props.view.title}
</StepTitle>
</StepsContainer>
);
}

function BulletIcon({
isDone,
isActive,
Icon,
stepNumber,
}: BulletProps & {
Icon?: JSX.Element;
}) {
if (Icon) {
return <Flex mr={2}>{Icon}</Flex>;
}

return <Bullet isDone={isDone} isActive={isActive} stepNumber={stepNumber} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@

import React from 'react';

import { BaseView } from '../flow';

import { StepItem } from './StepItem';

interface StepListProps<T> {
views: BaseView<T>[];
import type { View } from 'teleport/Discover/flow';

interface StepListProps {
views: View[];
currentStep: number;
index?: number;
}

export function StepList<T>(props: StepListProps<T>) {
export function StepList(props: StepListProps) {
const items = [];

let startIndex = props.index || 0;
for (const view of props.views) {
items.push(
<StepItem<T>
<StepItem
key={startIndex}
view={view}
currentStep={props.currentStep}
Expand Down
Loading