diff --git a/web/packages/teleport/src/Integrations/IntegrationList.tsx b/web/packages/teleport/src/Integrations/IntegrationList.tsx index 4ae1ee07320f4..a99842ebc918b 100644 --- a/web/packages/teleport/src/Integrations/IntegrationList.tsx +++ b/web/packages/teleport/src/Integrations/IntegrationList.tsx @@ -69,7 +69,7 @@ export function IntegrationList(props: Props) { } function getRowStyle(row: IntegrationLike): React.CSSProperties { - if (row.kind !== 'okta') return; + if (row.kind !== 'okta' && row.kind !== IntegrationKind.AwsOidc) return; return { cursor: 'pointer' }; } diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/Details/Agents.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/Details/Agents.tsx index dae7b472525e1..f0f8da56e941f 100644 --- a/web/packages/teleport/src/Integrations/status/AwsOidc/Details/Agents.tsx +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/Details/Agents.tsx @@ -18,6 +18,9 @@ import Table, { LabelCell } from 'design/DataTable'; +{ + /* TODO MBERG */ +} export function Agents() { return ( . */ -import { useEffect, useState } from 'react'; -import { useParams } from 'react-router'; - -import Table, { LabelCell } from 'design/DataTable'; -import { SortType } from 'design/DataTable/types'; -import { SearchPanel } from 'shared/components/Search'; - -import { useServerSidePagination } from 'teleport/components/hooks'; -import { AwsResource } from 'teleport/Integrations/status/AwsOidc/StatCard'; -import { - IntegrationDiscoveryRule, - IntegrationKind, - integrationService, -} from 'teleport/services/integrations'; - export function Rules() { const { name, resourceKind } = useParams<{ type: IntegrationKind; @@ -38,83 +40,67 @@ export function Rules() { resourceKind: AwsResource; }>(); - const [search, setSearch] = useState(''); - const [sort, setSort] = useState({ - fieldName: 'region', - dir: 'ASC', - }); + const [regionFilter, setRegionFilter] = useState([]); const serverSidePagination = useServerSidePagination({ pageSize: 20, - fetchFunc: async (_, params) => { + fetchFunc: async () => { const { rules, nextKey } = await integrationService.fetchIntegrationRules( name, resourceKind, - params + regionFilter ); return { agents: rules, nextKey }; }, clusterId: '', - params: { search, sort }, + params: {}, }); useEffect(() => { serverSidePagination.fetch(); - }, [search, sort]); + }, [regionFilter]); return ( - - data={serverSidePagination.fetchedData.agents || undefined} - columns={[ - { - key: 'region', - headerText: 'Region', - isSortable: true, - }, - { - key: 'labelMatcher', - headerText: getResourceTerm(resourceKind), - isSortable: true, - onSort: (a, b) => { - const aStr = a.labelMatcher.toString(); - const bStr = b.labelMatcher.toString(); - - if (aStr < bStr) { - return -1; - } - if (aStr > bStr) { - return 1; - } - - return 0; - }, - render: ({ labelMatcher }) => ( - `${l.name}:${l.value}`)} /> + <> + ({ + value: r as Regions, + label: ( + +
{awsRegionMap[r]}  
+
{r}
+
), - }, - ]} - emptyText={`No ${resourceKind} data`} - isSearchable - fetching={{ - fetchStatus: serverSidePagination.fetchStatus, - onFetchNext: serverSidePagination.fetchNext, - onFetchPrev: serverSidePagination.fetchPrev, - }} - serversideProps={{ - sort: sort, - setSort: setSort, - serversideSearchPanel: ( - - ), - }} - /> + }))} + onChange={regions => setRegionFilter(regions)} + selected={regionFilter} + label="Region" + tooltip="Filter by region" + /> + + data={serverSidePagination.fetchedData.agents || undefined} + columns={[ + { + key: 'region', + headerText: 'Region', + }, + { + key: 'labelMatcher', + headerText: getResourceTerm(resourceKind), + render: ({ labelMatcher }) => ( + `${l.name}:${l.value}`)} /> + ), + }, + ]} + emptyText={`No ${resourceKind} data`} + fetching={{ + fetchStatus: serverSidePagination.fetchStatus, + onFetchNext: serverSidePagination.fetchNext, + onFetchPrev: serverSidePagination.fetchPrev, + }} + /> + ); } diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/EnrollCard.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/EnrollCard.tsx new file mode 100644 index 0000000000000..c5301daf7dc47 --- /dev/null +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/EnrollCard.tsx @@ -0,0 +1,50 @@ +import { useHistory } from 'react-router'; +import styled from 'styled-components'; + +import { ButtonBorder, Card, Flex, H2, ResourceIcon } from 'design'; + +import cfg from 'teleport/config'; +import { AwsResource } from 'teleport/Integrations/status/AwsOidc/StatCard'; + +type EnrollCardProps = { + resource: AwsResource; +}; + +export function EnrollCard({ resource }: EnrollCardProps) { + const history = useHistory(); + + const handleClick = () => { + history.push({ + pathname: cfg.routes.discover, + state: { searchKeywords: resource }, + }); + }; + + // todo (michellescripts) update enroll design once ready + return ( + + + + +

{resource.toUpperCase()}

+
+ + Enroll {resource.toUpperCase()} + +
+
+ ); +} + +const Enroll = styled(Card)` + width: 33%; + background-color: ${props => props.theme.colors.levels.surface}; + padding: 12px; + border-radius: ${props => props.theme.radii[2]}px; + border: ${props => `1px solid ${props.theme.colors.levels.surface}`}; + + &:hover { + background-color: ${props => props.theme.colors.levels.elevated}; + box-shadow: ${({ theme }) => theme.boxShadow[2]}; + } +`; diff --git a/web/packages/teleport/src/Integrations/status/AwsOidc/StatCard.tsx b/web/packages/teleport/src/Integrations/status/AwsOidc/StatCard.tsx index 83e3f3153db50..30a345c157f9e 100644 --- a/web/packages/teleport/src/Integrations/status/AwsOidc/StatCard.tsx +++ b/web/packages/teleport/src/Integrations/status/AwsOidc/StatCard.tsx @@ -24,6 +24,7 @@ import * as Icons from 'design/Icon'; import { ResourceIcon } from 'design/ResourceIcon'; import cfg from 'teleport/config'; +import { EnrollCard } from 'teleport/Integrations/status/AwsOidc/EnrollCard'; import history from 'teleport/services/history'; import { IntegrationKind, @@ -48,6 +49,10 @@ export function StatCard({ name, resource, summary }: StatCardProps) { : undefined; const term = getResourceTerm(resource); + if (!foundResource(summary)) { + return ; + } + return ( props.theme.colors.levels.surface}; diff --git a/web/packages/teleport/src/config.ts b/web/packages/teleport/src/config.ts index fcb75700f2e46..157f1bffab5ad 100644 --- a/web/packages/teleport/src/config.ts +++ b/web/packages/teleport/src/config.ts @@ -1051,14 +1051,14 @@ const cfg = { getIntegrationRulesUrl( name: string, resourceType: AwsResource, - params?: UrlResourcesParams + regionFilter: string[] ) { const clusterId = cfg.proxyCluster; return generateResourcePath(cfg.api.integrationRulesPath, { clusterId, name, resourceType, - ...params, + regionFilter, }); }, diff --git a/web/packages/teleport/src/generateResourcePath.ts b/web/packages/teleport/src/generateResourcePath.ts index 25ac573dcb8c6..4900e40321bb0 100644 --- a/web/packages/teleport/src/generateResourcePath.ts +++ b/web/packages/teleport/src/generateResourcePath.ts @@ -65,6 +65,8 @@ export default function generateResourcePath( .replace(':searchAsRoles?', processedParams.searchAsRoles || '') .replace(':sort?', processedParams.sort || '') .replace(':startKey?', params.startKey || '') + // todo mberg - marco hmw handle regions ? + .replace(':regionPrefix?', params.regionPrefix || '') .replace( ':includedResourceMode?', processedParams.includedResourceMode || '' diff --git a/web/packages/teleport/src/services/integrations/integrations.ts b/web/packages/teleport/src/services/integrations/integrations.ts index b8fa8721c8bc1..b5347178915a9 100644 --- a/web/packages/teleport/src/services/integrations/integrations.ts +++ b/web/packages/teleport/src/services/integrations/integrations.ts @@ -417,10 +417,10 @@ export const integrationService = { fetchIntegrationRules( name: string, resourceType: AwsResource, - params?: UrlResourcesParams + region: string[] ): Promise { return api - .get(cfg.getIntegrationRulesUrl(name, resourceType, params)) + .get(cfg.getIntegrationRulesUrl(name, resourceType, region)) .then(resp => { return { rules: resp?.rules || [],