UI – Exclude self-service URL path from DUP when not a valid option for the host (#25383)

## For #24421

- Filter out self-service path in this case
- Remove a number of redundant states by having local variables depend
on useQuery's internal state


![ezgif-7-e252c26029](https://github.com/user-attachments/assets/ad1b2012-3604-4250-a227-d2f66a84bc86)

- [x] Changes file added for user-visible changes in `changes/`
- [x] Manual QA for all new/changed functionality

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
This commit is contained in:
jacobshandling 2025-01-13 14:48:39 -08:00 committed by GitHub
parent 8c4275a467
commit 7b1fa550ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 23 additions and 26 deletions

View file

@ -0,0 +1 @@
* Push correct paths to the URL on the my device page when self-service is not enabled for the host.

View file

@ -58,14 +58,14 @@ import DeviceUserBanners from "./components/DeviceUserBanners";
const baseClass = "device-user";
const PREMIUM_TABS = [
const PREMIUM_TAB_PATHS = [
PATHS.DEVICE_USER_DETAILS,
PATHS.DEVICE_USER_DETAILS_SELF_SERVICE,
PATHS.DEVICE_USER_DETAILS_SOFTWARE,
PATHS.DEVICE_USER_DETAILS_POLICIES,
] as const;
const FREE_TABS = [
const FREE_TAB_PATHS = [
PATHS.DEVICE_USER_DETAILS,
PATHS.DEVICE_USER_DETAILS_SOFTWARE,
] as const;
@ -97,13 +97,10 @@ const DeviceUserPage = ({
NotificationContext
);
const [isPremiumTier, setIsPremiumTier] = useState(false);
const [showInfoModal, setShowInfoModal] = useState(false);
const [showEnrollMdmModal, setShowEnrollMdmModal] = useState(false);
const [refetchStartTime, setRefetchStartTime] = useState<number | null>(null);
const [showRefetchSpinner, setShowRefetchSpinner] = useState(false);
const [orgLogoURL, setOrgLogoURL] = useState("");
const [orgContactURL, setOrgContactURL] = useState("");
const [selectedPolicy, setSelectedPolicy] = useState<IHostPolicy | null>(
null
);
@ -113,10 +110,6 @@ const DeviceUserPage = ({
false
);
const [showCreateLinuxKeyModal, setShowCreateLinuxKeyModal] = useState(false);
const [globalConfig, setGlobalConfig] = useState<IDeviceGlobalConfig | null>(
null
);
const [hasSelfService, setSelfService] = useState(false);
const [isTriggeringCreateLinuxKey, setIsTriggeringCreateLinuxKey] = useState(
false
);
@ -172,7 +165,7 @@ const DeviceUserPage = ({
};
const {
data: { host } = { host: undefined },
data: dupResponse,
isLoading: isLoadingHost,
error: loadingDeviceUserError,
refetch: refetchHostDetails,
@ -191,20 +184,8 @@ const DeviceUserPage = ({
retry: false,
// TODO: refactor to use non-refetch data directly in the component and remove
// unnecesary derived states for values that aren't related to the refetch status
onSuccess: ({
license,
org_logo_url,
org_contact_url,
global_config,
host: responseHost,
self_service,
}) => {
onSuccess: ({ host: responseHost }) => {
setShowRefetchSpinner(isRefetching(responseHost));
setIsPremiumTier(license.tier === "premium");
setOrgLogoURL(org_logo_url);
setOrgContactURL(org_contact_url);
setGlobalConfig(global_config);
setSelfService(self_service);
if (isRefetching(responseHost)) {
// If the API reports that a Fleet refetch request is pending, we want to check back for fresh
// host details. Here we set a one second timeout and poll the API again using
@ -253,6 +234,16 @@ const DeviceUserPage = ({
}
);
const {
host,
license,
org_logo_url: orgLogoURL = "",
org_contact_url: orgContactURL = "",
global_config: globalConfig = null as IDeviceGlobalConfig | null,
self_service: hasSelfService = false,
} = dupResponse || {};
const isPremiumTier = license?.tier === "premium";
const summaryData = normalizeEmptyValues(pick(host, HOST_SUMMARY_DATA));
const aboutData = normalizeEmptyValues(pick(host, HOST_ABOUT_DATA));
@ -355,9 +346,14 @@ const DeviceUserPage = ({
// TODO: We should probably have a standard way to handle this on all pages. Do we want to show
// a premium-only message in the case that a user tries direct navigation to a premium-only page
// or silently redirect as below?
const tabPaths = isPremiumTier
? PREMIUM_TABS.map((t) => t(deviceAuthToken))
: FREE_TABS.map((t) => t(deviceAuthToken));
let tabPaths = (isPremiumTier
? PREMIUM_TAB_PATHS
: FREE_TAB_PATHS
).map((t) => t(deviceAuthToken));
if (!hasSelfService) {
tabPaths = tabPaths.filter((path) => !path.includes("self-service"));
}
const findSelectedTab = (pathname: string) =>
findIndex(tabPaths, (x) => x.startsWith(pathname.split("?")[0]));
if (!isLoadingHost && host && findSelectedTab(location.pathname) === -1) {