Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v17] Move DeviceTrust EmptyList to OSS #50873

Merged
merged 1 commit into from
Jan 10, 2025
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
116 changes: 116 additions & 0 deletions web/packages/teleport/src/DeviceTrust/DeviceList/DeviceList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* Teleport
* Copyright (C) 2024 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 styled from 'styled-components';

import Box from 'design/Box';
import Table, { Cell } from 'design/DataTable';
import { ResourceIcon, ResourceIconName } from 'design/ResourceIcon';
import { P2 } from 'design/Text';

import {
DeviceListProps,
TrustedDeviceOSType,
} from 'teleport/DeviceTrust/types';

export const DeviceList = ({
items = [],
pageSize = 50,
pagerPosition = null,
fetchStatus = '',
fetchData,
}: DeviceListProps) => {
return (
<Table
data={items}
columns={[
{
key: 'osType',
headerText: 'OS Type',
render: ({ osType }) => <IconCell osType={osType} />,
},
{
key: 'assetTag',
headerText: 'Asset Tag',
},
{
key: 'enrollStatus',
headerText: 'Enroll Status',
render: ({ enrollStatus }) => (
<EnrollmentStatusCell status={enrollStatus} />
),
},
{
key: 'owner',
headerText: 'Owner',
},
]}
emptyText="No Devices Found"
pagination={{ pageSize, pagerPosition }}
fetching={{ onFetchMore: fetchData, fetchStatus }}
isSearchable
/>
);
};

const EnrollmentStatusCell = ({ status }: { status: string }) => {
const enrolled = status === 'enrolled';
return (
<Cell
align="left"
css={`
display: flex;
align-items: center;
`}
>
<EnrollmentIcon enrolled={enrolled} />
<P2 color={enrolled ? 'success.main' : 'error.main'}>{status}</P2>
</Cell>
);
};

export const IconCell = ({ osType }: { osType: TrustedDeviceOSType }) => {
let iconName: ResourceIconName;
switch (osType) {
case 'Windows':
iconName = 'microsoft';
break;
case 'Linux':
iconName = 'linux';
break;
case 'macOS':
iconName = 'apple';
break;
}
return (
<Cell align="left" style={{ display: 'flex', alignItems: 'center' }}>
<ResourceIcon name={iconName} width="14px" mr={3} />
{osType}
</Cell>
);
};

const EnrollmentIcon = styled(Box)<{ enrolled: boolean }>`
width: 12px;
height: 12px;
margin-right: ${p => p.theme.space[1]}px;
border-radius: 50%;
background-color: ${p =>
p.enrolled ? p.theme.colors.success.main : p.theme.colors.error.main};
};
`;
19 changes: 19 additions & 0 deletions web/packages/teleport/src/DeviceTrust/DeviceList/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Teleport
* Copyright (C) 2024 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/>.
*/

export { DeviceList } from './DeviceList';
152 changes: 5 additions & 147 deletions web/packages/teleport/src/DeviceTrust/DeviceTrustLocked.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,160 +16,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import styled from 'styled-components';
import { Box } from 'design';

import { Box, Flex, Link } from 'design';
import Table, { Cell } from 'design/DataTable';
import { Apple, Linux, Lock, Windows } from 'design/Icon';
import { IconCircle } from 'design/Icon/IconCircle';
import { P } from 'design/Text/Text';
import { FeatureBox } from 'teleport/components/Layout';

import { ButtonLockedFeature } from 'teleport/components/ButtonLockedFeature';
import {
FeatureBox,
FeatureHeader,
FeatureHeaderTitle,
} from 'teleport/components/Layout';
import {
DeviceListProps,
TrustedDeviceOSType,
} from 'teleport/DeviceTrust/types';
import { CtaEvent } from 'teleport/services/userEvent';
import { EmptyList } from './EmptyList';

export function DeviceTrustLocked() {
return (
<FeatureBox>
<FeatureHeader>
<FeatureHeaderTitle>Trusted Devices</FeatureHeaderTitle>
</FeatureHeader>
<Box
mr="6"
mb="4"
style={{
filter: 'blur(2px)',
pointerEvents: 'none',
userSelect: 'none',
height: '100px',
}}
>
<FakeDeviceList
items={generateFakeItems(15)}
fetchData={() => null}
fetchStatus={''}
/>
<Box>
<EmptyList />
</Box>
<StyledMessageContainer>
<Box p="3" borderRadius="50%">
<IconCircle Icon={Lock} size={64} />
</Box>
<P textAlign="justify">
Device Trust enables trusted and authenticated device access. When
resources are configured with the Device Trust mode “required”,
Teleport will authenticate the Trusted Device, in addition to
establishing the user's identity and enforcing the necessary roles,
and leaves an audit trail with device information. For more details,
please view{' '}
<Link
href={
'https://goteleport.com/docs/access-controls/device-trust/guide/'
}
target="_blank"
>
Device Trust documentation
</Link>
.
</P>
<Box>
<ButtonLockedFeature event={CtaEvent.CTA_TRUSTED_DEVICES}>
Unlock Device Trust with Teleport Enterprise
</ButtonLockedFeature>
</Box>
</StyledMessageContainer>
</FeatureBox>
);
}

function generateFakeItems(count) {
const items = [];
const osType = ['Windows', 'Linux', 'macOS'];

for (let i = 0; i < count; i++) {
items.push({
id: `id-${i}`,
assetTag: `CLFBDAACC${i}`,
enrollStatus: `enroll-status-${i}`,
osType: osType[i % osType.length],
});
}

return items;
}

const FakeDeviceList = ({
items = [],
pageSize = 20,
fetchStatus = '',
fetchData,
}: DeviceListProps) => {
return (
<Table
data={items}
columns={[
{
key: 'osType',
headerText: 'OS Type',
render: ({ osType }) => <IconCell osType={osType} />,
},
{
key: 'assetTag',
headerText: 'Asset Tag',
},
{
key: 'enrollStatus',
headerText: 'Enroll Status',
},
]}
emptyText="No Devices Found"
pagination={{ pageSize }}
fetching={{ onFetchMore: fetchData, fetchStatus }}
/>
);
};

const IconCell = ({ osType }: { osType: TrustedDeviceOSType }) => {
let icon;
switch (osType) {
case 'Windows':
icon = <Windows size="small" mr={1} />;
break;
case 'Linux':
icon = <Linux size="small" mr={1} />;
break;
default:
icon = <Apple size="small" mr={1} />;
}
return (
<Cell align="left" style={{ display: 'flex' }}>
{icon} {osType}
</Cell>
);
};

const StyledMessageContainer = styled(Flex)`
position: relative;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
background-color: ${({ theme }) => theme.colors.levels.elevated};
flex-direction: column;
justify-content: center;
align-items: center;
padding: 24px;
gap: 24px;
width: 600px;
box-shadow:
0 5px 5px -3px rgba(0, 0, 0, 0.2),
0 8px 10px 1px rgba(0, 0, 0, 0.14),
0 3px 14px 2px rgba(0, 0, 0, 0.12);
border-radius: 8px;
`;
Loading
Loading