diff --git a/web/packages/teleport/src/Discover/SelectResource/SelectResource.tsx b/web/packages/teleport/src/Discover/SelectResource/SelectResource.tsx
index 42d1d22882a29..a9682b527b7fd 100644
--- a/web/packages/teleport/src/Discover/SelectResource/SelectResource.tsx
+++ b/web/packages/teleport/src/Discover/SelectResource/SelectResource.tsx
@@ -19,9 +19,10 @@ import { useLocation, useHistory } from 'react-router';
import * as Icons from 'design/Icon';
import styled from 'styled-components';
-import { Box, Flex, Text, Popover, Link } from 'design';
+import { Box, Flex, Text, Link } from 'design';
import useTeleport from 'teleport/useTeleport';
+import { ToolTipNoPermBadge } from 'teleport/components/ToolTipNoPermBadge';
import { Acl } from 'teleport/services/user';
import {
ResourceKind,
@@ -151,7 +152,7 @@ export function SelectResource(props: SelectResourceProps) {
Guided
)}
{!r.hasAccess && (
-
}
@@ -228,59 +229,6 @@ const ClearSearch = ({ onClick }: { onClick(): void }) => {
);
};
-const ToolTip: React.FC = ({ children }) => {
- const [anchorEl, setAnchorEl] = useState();
- const open = Boolean(anchorEl);
-
- function handlePopoverOpen(event) {
- setAnchorEl(event.currentTarget);
- }
-
- function handlePopoverClose() {
- setAnchorEl(null);
- }
-
- return (
- <>
-
@@ -2487,6 +2488,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2523,6 +2525,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2558,6 +2561,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2599,6 +2603,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2640,6 +2645,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2681,6 +2687,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2722,6 +2729,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2763,6 +2771,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2803,6 +2812,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2844,6 +2854,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2885,6 +2896,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2926,6 +2938,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -2969,6 +2982,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3013,6 +3027,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3057,6 +3072,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3101,6 +3117,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3145,6 +3162,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3189,6 +3207,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3233,6 +3252,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3277,6 +3297,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3321,6 +3342,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3365,6 +3387,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3409,6 +3432,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3453,6 +3477,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3497,6 +3522,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3535,6 +3561,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3579,6 +3606,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3623,6 +3651,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3667,6 +3696,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3711,6 +3741,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3755,6 +3786,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3799,6 +3831,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3837,6 +3870,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3881,6 +3915,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -3925,6 +3960,7 @@ exports[`render with no access 1`] = `
>
Lacking Permissions
@@ -4098,6 +4134,18 @@ exports[`render with partial access 1`] = `
justify-content: center;
}
+.c20 {
+ box-sizing: border-box;
+ background-color: red;
+ border-top-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+ position: absolute;
+ padding: 0px 6px;
+ top: 0px;
+ right: 0px;
+ font-size: 10px;
+}
+
.c6 {
display: grid;
grid-template-columns: repeat(auto-fill,320px);
@@ -4192,17 +4240,6 @@ exports[`render with partial access 1`] = `
opacity: 0.6;
}
-.c20 {
- position: absolute;
- background: red;
- padding: 0px 6px;
- border-top-right-radius: 8px;
- border-bottom-left-radius: 8px;
- top: 0px;
- right: 0px;
- font-size: 10px;
-}
-
@@ -4557,6 +4594,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4598,6 +4636,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4639,6 +4678,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4680,6 +4720,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4723,6 +4764,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4767,6 +4809,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4811,6 +4854,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4855,6 +4899,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4899,6 +4944,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4943,6 +4989,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -4987,6 +5034,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5031,6 +5079,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5075,6 +5124,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5119,6 +5169,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5163,6 +5214,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5207,6 +5259,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5251,6 +5304,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5289,6 +5343,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5333,6 +5388,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5377,6 +5433,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5421,6 +5478,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5465,6 +5523,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5509,6 +5568,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5553,6 +5613,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5591,6 +5652,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5635,6 +5697,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
@@ -5679,6 +5742,7 @@ exports[`render with partial access 1`] = `
>
Lacking Permissions
diff --git a/web/packages/teleport/src/IntegrationEnroll/IntegrationEnroll.story.tsx b/web/packages/teleport/src/IntegrationEnroll/IntegrationEnroll.story.tsx
new file mode 100644
index 0000000000000..3400e616deee7
--- /dev/null
+++ b/web/packages/teleport/src/IntegrationEnroll/IntegrationEnroll.story.tsx
@@ -0,0 +1,30 @@
+/**
+ * Copyright 2023 Gravitational, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { MemoryRouter } from 'react-router';
+
+import { IntegrationEnroll } from './IntegrationEnroll';
+
+export default {
+ title: 'Teleport/Integrations',
+};
+
+export const Enroll = () => (
+
+
+
+);
diff --git a/web/packages/teleport/src/IntegrationEnroll/IntegrationEnroll.tsx b/web/packages/teleport/src/IntegrationEnroll/IntegrationEnroll.tsx
new file mode 100644
index 0000000000000..d176a1a30efb8
--- /dev/null
+++ b/web/packages/teleport/src/IntegrationEnroll/IntegrationEnroll.tsx
@@ -0,0 +1,41 @@
+/**
+ * Copyright 2023 Gravitational, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Box } from 'design';
+
+import {
+ FeatureBox,
+ FeatureHeader,
+ FeatureHeaderTitle,
+} from 'teleport/components/Layout';
+
+import { IntegrationTiles } from './IntegrationTiles';
+import { NoCodeIntegrationDescription } from './common';
+
+export function IntegrationEnroll() {
+ return (
+
+
+ Select Integration Type
+
+
+
+
+
+
+ );
+}
diff --git a/web/packages/teleport/src/IntegrationEnroll/IntegrationTiles.test.tsx b/web/packages/teleport/src/IntegrationEnroll/IntegrationTiles.test.tsx
new file mode 100644
index 0000000000000..8113c4c20143d
--- /dev/null
+++ b/web/packages/teleport/src/IntegrationEnroll/IntegrationTiles.test.tsx
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2023 Gravitational, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { MemoryRouter } from 'react-router';
+import { render, screen } from 'design/utils/testing';
+
+import { IntegrationTiles } from './IntegrationTiles';
+
+test('render', async () => {
+ render(
+
+
+
+ );
+
+ expect(screen.getByText(/amazon web services/i)).toBeInTheDocument();
+ expect(screen.queryByText(/no permission/i)).not.toBeInTheDocument();
+ expect(screen.getByRole('img')).toBeInTheDocument();
+ expect(screen.getByRole('link')).toBeInTheDocument();
+
+ const tile = screen.getByTestId('tile');
+ expect(tile).toBeEnabled();
+ expect(tile.getAttribute('href')).toBeTruthy();
+});
+
+test('render disabled', async () => {
+ render(
+
+
+
+ );
+
+ expect(screen.getByText(/lacking permission/i)).toBeInTheDocument();
+ expect(screen.queryByRole('link')).not.toBeInTheDocument();
+
+ const tile = screen.getByTestId('tile');
+ expect(tile).not.toHaveAttribute('href');
+
+ // The element has disabled attribute, but it's in the format `disabled=""`
+ // so "toBeDisabled" interprets it as false.
+ // eslint-disable-next-line jest-dom/prefer-enabled-disabled
+ expect(tile).toHaveAttribute('disabled');
+});
diff --git a/web/packages/teleport/src/IntegrationEnroll/IntegrationTiles.tsx b/web/packages/teleport/src/IntegrationEnroll/IntegrationTiles.tsx
new file mode 100644
index 0000000000000..69fde068658dd
--- /dev/null
+++ b/web/packages/teleport/src/IntegrationEnroll/IntegrationTiles.tsx
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2023 Gravitational, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Text, Image } from 'design';
+import awsIcon from 'design/assets/images/icons/aws.svg';
+
+import cfg from 'teleport/config';
+import { ToolTipNoPermBadge } from 'teleport/components/ToolTipNoPermBadge';
+
+import { IntegrationTile } from './common';
+
+// IntegrationTiles is plural but at the moment we only
+// support aws-oidc. Expecting this to grow.
+export function IntegrationTiles({
+ hasAccess = true,
+}: {
+ hasAccess?: boolean;
+}) {
+ return (
+
+
+
+ Amazon Web Services
+
+ OIDC
+
+ {!hasAccess && (
+
+ )}
+
+ );
+}
diff --git a/web/packages/teleport/src/IntegrationEnroll/common.tsx b/web/packages/teleport/src/IntegrationEnroll/common.tsx
new file mode 100644
index 0000000000000..150d244161916
--- /dev/null
+++ b/web/packages/teleport/src/IntegrationEnroll/common.tsx
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2023 Gravitational, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import { Flex, Text, Box } from 'design';
+import styled from 'styled-components';
+
+export type IntegrationTypes = 'aws-oidc';
+
+export const IntegrationTile = styled(Flex).attrs({
+ 'data-testid': 'tile',
+})`
+ color: inherit;
+ text-decoration: none;
+ flex-direction: column;
+ align-items: center;
+ position: relative;
+ border-radius: 4px;
+ height: 170px;
+ width: 170px;
+ background-color: ${({ theme }) => theme.colors.buttons.secondary.default};
+ text-align: center;
+ cursor: pointer;
+
+ ${props => {
+ const pointerEvents = props.disabled ? 'none' : null;
+ if (props.$exists) {
+ return { pointerEvents };
+ }
+
+ return `
+ opacity: ${props.disabled ? '0.45' : '1'};
+ &:hover {
+ background-color: ${props.theme.colors.buttons.secondary.hover};
+ }
+ `;
+ }}
+`;
+
+export const NoCodeIntegrationDescription = () => (
+
+
+ No-Code Integrations
+
+
+ Hosted Integrations eliminate the setup work so you can quickly connect
+ applications to Teleport for alerting and other useful functions. This
+ list is short for now, but it will grow with time!
+
+
+);
diff --git a/web/packages/teleport/src/IntegrationEnroll/index.ts b/web/packages/teleport/src/IntegrationEnroll/index.ts
new file mode 100644
index 0000000000000..dc480dcb10b22
--- /dev/null
+++ b/web/packages/teleport/src/IntegrationEnroll/index.ts
@@ -0,0 +1,21 @@
+/**
+ * Copyright 2023 Gravitational, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// export as default for use with React.lazy
+export { IntegrationEnroll as default } from './IntegrationEnroll';
+export { IntegrationTiles } from './IntegrationTiles';
+
+export * from './common';
diff --git a/web/packages/teleport/src/components/ToolTipNoPermBadge/ToolTipNoPermBadge.story.tsx b/web/packages/teleport/src/components/ToolTipNoPermBadge/ToolTipNoPermBadge.story.tsx
new file mode 100644
index 0000000000000..700d4ee47da55
--- /dev/null
+++ b/web/packages/teleport/src/components/ToolTipNoPermBadge/ToolTipNoPermBadge.story.tsx
@@ -0,0 +1,51 @@
+/*
+Copyright 2019 Gravitational, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React from 'react';
+import styled from 'styled-components';
+import { Box } from 'design';
+
+import { ToolTipNoPermBadge } from './ToolTipNoPermBadge';
+
+export default {
+ title: 'Teleport/ToolTip',
+};
+
+export const NoPermissionBadgeString = () => (
+
+ I'm a sample container
+
+
+);
+
+export const NoPermissionBadgeComp = () => (
+
+ I'm a sample container
+ I'm a box component with too much padding}
+ />
+
+);
+
+const SomeBox = styled.div`
+ width: 240px;
+ border-radius: 8px;
+ padding: 16px;
+ display: flex;
+ position: relative;
+ align-items: center;
+ background: rgba(255, 255, 255, 0.05);
+`;
diff --git a/web/packages/teleport/src/components/ToolTipNoPermBadge/ToolTipNoPermBadge.test.tsx b/web/packages/teleport/src/components/ToolTipNoPermBadge/ToolTipNoPermBadge.test.tsx
new file mode 100644
index 0000000000000..1e8857c795dad
--- /dev/null
+++ b/web/packages/teleport/src/components/ToolTipNoPermBadge/ToolTipNoPermBadge.test.tsx
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2023 Gravitational, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import styled from 'styled-components';
+import { render, screen, userEvent } from 'design/utils/testing';
+
+import { ToolTipNoPermBadge } from './ToolTipNoPermBadge';
+
+test('hovering renders tooltip msg and unhovering makes it disappear', async () => {
+ render(
+
+
+
+ );
+
+ expect(screen.queryByTestId('tooltip-msg')).not.toBeInTheDocument();
+
+ const badge = screen.getByTestId('tooltip');
+
+ await userEvent.hover(badge);
+ expect(screen.getByTestId('tooltip-msg')).toBeInTheDocument();
+
+ await userEvent.unhover(badge);
+ expect(screen.queryByTestId('tooltip-msg')).not.toBeInTheDocument();
+});
+
+const SomeBox = styled.div`
+ width: 240px;
+ padding: 16px;
+`;
diff --git a/web/packages/teleport/src/components/ToolTipNoPermBadge/ToolTipNoPermBadge.tsx b/web/packages/teleport/src/components/ToolTipNoPermBadge/ToolTipNoPermBadge.tsx
new file mode 100644
index 0000000000000..8e0c126fc9335
--- /dev/null
+++ b/web/packages/teleport/src/components/ToolTipNoPermBadge/ToolTipNoPermBadge.tsx
@@ -0,0 +1,86 @@
+/**
+ * Copyright 2023 Gravitational, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React, { useState } from 'react';
+import styled from 'styled-components';
+import { Text, Popover, Box } from 'design';
+
+type Props = {
+ borderRadius?: number;
+};
+
+export const ToolTipNoPermBadge: React.FC
= ({
+ children,
+ borderRadius = 2,
+}) => {
+ const [anchorEl, setAnchorEl] = useState();
+ const open = Boolean(anchorEl);
+
+ function handlePopoverOpen(event) {
+ setAnchorEl(event.currentTarget);
+ }
+
+ function handlePopoverClose() {
+ setAnchorEl(null);
+ }
+
+ return (
+ <>
+
+ Lacking Permissions
+
+ `pointer-events: none;`}
+ onClose={handlePopoverClose}
+ open={open}
+ anchorEl={anchorEl}
+ anchorOrigin={{
+ vertical: 'bottom',
+ horizontal: 'left',
+ }}
+ transformOrigin={{
+ vertical: 'top',
+ horizontal: 'left',
+ }}
+ >
+
+ {children}
+
+
+ >
+ );
+};
+
+const StyledOnHover = styled(Text)`
+ background-color: white;
+ color: black;
+ max-width: 350px;
+`;
diff --git a/web/packages/teleport/src/components/ToolTipNoPermBadge/index.ts b/web/packages/teleport/src/components/ToolTipNoPermBadge/index.ts
new file mode 100644
index 0000000000000..f085834ad415d
--- /dev/null
+++ b/web/packages/teleport/src/components/ToolTipNoPermBadge/index.ts
@@ -0,0 +1,17 @@
+/**
+ * Copyright 2023 Gravitational, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { ToolTipNoPermBadge } from './ToolTipNoPermBadge';
diff --git a/web/packages/teleport/src/features.tsx b/web/packages/teleport/src/features.tsx
index 14cdb34e10d6e..1f86fb3bf61ff 100644
--- a/web/packages/teleport/src/features.tsx
+++ b/web/packages/teleport/src/features.tsx
@@ -86,7 +86,7 @@ const AuthConnectors = React.lazy(
() => import(/* webpackChunkName: "auth-connectors" */ './AuthConnectors')
);
const Locks = React.lazy(
- () => import(/* webpackChunkName: "lazy" */ './Locks')
+ () => import(/* webpackChunkName: "locks" */ './Locks')
);
const NewLock = React.lazy(
() => import(/* webpackChunkName: "newLock" */ './Locks/NewLock')
@@ -103,6 +103,10 @@ const Discover = React.lazy(
const Integrations = React.lazy(
() => import(/* webpackChunkName: "integrations" */ './Integrations')
);
+const IntegrationEnroll = React.lazy(
+ () =>
+ import(/* webpackChunkName: "integration-enroll" */ './IntegrationEnroll')
+);
// ****************************
// Resource Features
@@ -425,6 +429,36 @@ export class FeatureIntegrations implements TeleportFeature {
}
}
+export class FeatureIntegrationEnroll implements TeleportFeature {
+ category = NavigationCategory.Management;
+ section = ManagementSection.Access;
+
+ route = {
+ title: 'Enroll New Integration',
+ path: cfg.routes.integrationEnroll,
+ exact: false,
+ component: () => ,
+ };
+
+ hasAccess(flags: FeatureFlags) {
+ return flags.enrollIntegrations;
+ }
+
+ navigationItem = {
+ title: 'Enroll New Integration',
+ icon: ,
+ getLink() {
+ return cfg.getIntegrationEnrollRoute(null);
+ },
+ };
+
+ // getRoute allows child class extending this
+ // parent class to refer to this parent's route.
+ getRoute() {
+ return this.route;
+ }
+}
+
// - Activity
export class FeatureRecordings implements TeleportFeature {
@@ -591,6 +625,7 @@ export function getOSSFeatures(): TeleportFeature[] {
new FeatureNewLock(),
new FeatureIntegrations(),
new FeatureDiscover(),
+ new FeatureIntegrationEnroll(),
// - Activity
new FeatureRecordings(),
diff --git a/web/packages/teleport/src/teleportContext.tsx b/web/packages/teleport/src/teleportContext.tsx
index 62296519787ac..f757289082fb3 100644
--- a/web/packages/teleport/src/teleportContext.tsx
+++ b/web/packages/teleport/src/teleportContext.tsx
@@ -108,6 +108,7 @@ class TeleportContext implements types.Context {
plugins: false,
integrations: false,
deviceTrust: false,
+ enrollIntegrationsOrPlugins: false,
enrollIntegrations: false,
};
}
@@ -132,7 +133,8 @@ class TeleportContext implements types.Context {
discover: userContext.hasDiscoverAccess(),
plugins: userContext.getPluginsAccess().list,
integrations: userContext.getIntegrationsAccess().list,
- enrollIntegrations:
+ enrollIntegrations: userContext.getIntegrationsAccess().create,
+ enrollIntegrationsOrPlugins:
userContext.getPluginsAccess().create ||
userContext.getIntegrationsAccess().create,
deviceTrust: userContext.getDeviceTrustAccess().list,
diff --git a/web/packages/teleport/src/types.ts b/web/packages/teleport/src/types.ts
index 937d703059c6a..9c41d0ff02a70 100644
--- a/web/packages/teleport/src/types.ts
+++ b/web/packages/teleport/src/types.ts
@@ -91,6 +91,7 @@ export interface FeatureFlags {
discover: boolean;
plugins: boolean;
integrations: boolean;
+ enrollIntegrationsOrPlugins: boolean;
enrollIntegrations: boolean;
deviceTrust: boolean;
}