diff --git a/web/packages/teleport/src/Discover/SelectResource/SelectResource.tsx b/web/packages/teleport/src/Discover/SelectResource/SelectResource.tsx
index d8fa09e0645e3..0efc30f646a22 100644
--- a/web/packages/teleport/src/Discover/SelectResource/SelectResource.tsx
+++ b/web/packages/teleport/src/Discover/SelectResource/SelectResource.tsx
@@ -16,7 +16,12 @@
* along with this program. If not, see .
*/
-import { useEffect, useState, type ComponentPropsWithoutRef } from 'react';
+import {
+ useEffect,
+ useMemo,
+ useState,
+ type ComponentPropsWithoutRef,
+} from 'react';
import { useHistory, useLocation } from 'react-router';
import styled from 'styled-components';
@@ -64,6 +69,15 @@ type UrlLocationState = {
searchKeywords: string;
};
+function getDefaultResources(
+ includeEnterpriseResources: boolean
+): ResourceSpec[] {
+ const RESOURCES = includeEnterpriseResources
+ ? BASE_RESOURCES
+ : [...BASE_RESOURCES, ...SAML_APPLICATIONS];
+ return RESOURCES;
+}
+
export function SelectResource({ onSelect }: SelectResourceProps) {
const ctx = useTeleport();
const location = useLocation();
@@ -71,20 +85,34 @@ export function SelectResource({ onSelect }: SelectResourceProps) {
const { preferences } = useUser();
const [search, setSearch] = useState('');
- const RESOURCES = !cfg.isEnterprise
- ? BASE_RESOURCES
- : [...BASE_RESOURCES, ...SAML_APPLICATIONS];
const { acl, authType } = ctx.storeUser.state;
const platform = getPlatform();
- const [resources, setResources] = useState(
- addHasAccessField(acl, filterResources(platform, authType, RESOURCES))
+ const defaultResources: ResourceSpec[] = useMemo(
+ () =>
+ sortResources(
+ // Apply access check to each resource.
+ addHasAccessField(
+ acl,
+ filterResources(
+ platform,
+ authType,
+ getDefaultResources(cfg.isEnterprise)
+ )
+ ),
+ preferences,
+ storageService.getOnboardDiscover()
+ ),
+ [acl, authType, platform, preferences]
);
+ const [resources, setResources] = useState(defaultResources);
// a user must be able to create tokens AND have access to create at least one
// type of resource in order to be considered eligible to "add resources"
- const canAddResources = acl.tokens.create && resources.some(r => r.hasAccess);
+ const canAddResources = useMemo(
+ () => acl.tokens.create && defaultResources.some(r => r.hasAccess),
+ [acl, defaultResources]
+ );
- const [defaultResources, setDefaultResources] = useState([]);
const [showApp, setShowApp] = useState(false);
function onSearch(s: string, customList?: ResourceSpec[]) {
@@ -104,15 +132,6 @@ export function SelectResource({ onSelect }: SelectResourceProps) {
}
useEffect(() => {
- // Apply access check to each resource.
- const onboardDiscover = storageService.getOnboardDiscover();
- const sortedResources = sortResources(
- resources,
- preferences,
- onboardDiscover
- );
- setDefaultResources(sortedResources);
-
// A user can come to this screen by clicking on
// a `add ` button.
// We sort the list by the specified resource type,
@@ -128,7 +147,7 @@ export function SelectResource({ onSelect }: SelectResourceProps) {
) {
const sortedResourcesByKind = sortResourcesByKind(
resourceKindSpecifiedByUrlLoc,
- sortedResources
+ defaultResources
);
onSearch(resourceKindSpecifiedByUrlLoc, sortedResourcesByKind);
return;
@@ -136,11 +155,11 @@ export function SelectResource({ onSelect }: SelectResourceProps) {
const searchKeywordSpecifiedByUrlLoc = location.state?.searchKeywords;
if (searchKeywordSpecifiedByUrlLoc) {
- onSearch(searchKeywordSpecifiedByUrlLoc, sortedResources);
+ onSearch(searchKeywordSpecifiedByUrlLoc, defaultResources);
return;
}
- setResources(sortedResources);
+ setResources(defaultResources);
// Processing of the lists should only happen once on init.
// User perms remain static and URL loc state does not change.
// eslint-disable-next-line react-hooks/exhaustive-deps