diff --git a/changes/28929-fleet-desktop-errors b/changes/28929-fleet-desktop-errors
new file mode 100644
index 0000000000..47a9d8d7e6
--- /dev/null
+++ b/changes/28929-fleet-desktop-errors
@@ -0,0 +1 @@
+- Fleet Desktop: Added device user API error state to replace generic Fleet UI error state
diff --git a/frontend/components/ActivityDetails/InstallDetails/AppInstallDetails/AppInstallDetails.tsx b/frontend/components/ActivityDetails/InstallDetails/AppInstallDetails/AppInstallDetails.tsx
index 8cb56bb83b..373a88c6af 100644
--- a/frontend/components/ActivityDetails/InstallDetails/AppInstallDetails/AppInstallDetails.tsx
+++ b/frontend/components/ActivityDetails/InstallDetails/AppInstallDetails/AppInstallDetails.tsx
@@ -3,6 +3,7 @@
import React from "react";
import { useQuery } from "react-query";
+import { AxiosError } from "axios";
import { SoftwareInstallStatus } from "interfaces/software";
import mdmApi from "services/entities/mdm";
@@ -13,6 +14,7 @@ import Button from "components/buttons/Button";
import Icon from "components/Icon";
import Textarea from "components/Textarea";
import DataError from "components/DataError/DataError";
+import DeviceUserError from "components/DeviceUserError";
import Spinner from "components/Spinner/Spinner";
import { IMdmCommandResult } from "interfaces/mdm";
import { IActivityDetails } from "interfaces/activity";
@@ -43,9 +45,9 @@ export const AppInstallDetails = ({
software_title = "",
deviceAuthToken,
}: IAppInstallDetails) => {
- const { data: result, isLoading, isError } = useQuery<
+ const { data: result, isLoading, isError, error } = useQuery<
IMdmCommandResult,
- Error
+ AxiosError
>(
["mdm_command_results", command_uuid],
async () => {
@@ -74,8 +76,27 @@ export const AppInstallDetails = ({
if (isLoading) {
return ;
- } else if (isError) {
- return ;
+ }
+
+ if (isError) {
+ if (error?.status === 404) {
+ return deviceAuthToken ? (
+
+ ) : (
+
+ );
+ }
+
+ if (error?.status === 401) {
+ return deviceAuthToken ? (
+
+ ) : (
+
+ );
+ }
} else if (!result) {
// FIXME: It's currently possible that the command results API response is empty for pending
// commands. As a temporary workaround to handle this case, we'll ignore the empty response and
diff --git a/frontend/components/ActivityDetails/InstallDetails/SoftwareInstallDetails/SoftwareInstallDetails.tsx b/frontend/components/ActivityDetails/InstallDetails/SoftwareInstallDetails/SoftwareInstallDetails.tsx
index 54d5195b5a..697b1647d8 100644
--- a/frontend/components/ActivityDetails/InstallDetails/SoftwareInstallDetails/SoftwareInstallDetails.tsx
+++ b/frontend/components/ActivityDetails/InstallDetails/SoftwareInstallDetails/SoftwareInstallDetails.tsx
@@ -19,6 +19,7 @@ import Button from "components/buttons/Button";
import Icon from "components/Icon";
import Textarea from "components/Textarea";
import DataError from "components/DataError/DataError";
+import DeviceUserError from "components/DeviceUserError";
import Spinner from "components/Spinner/Spinner";
import {
INSTALL_DETAILS_STATUS_ICONS,
@@ -121,18 +122,36 @@ export const SoftwareInstallDetails = ({
if (isLoading) {
return ;
- } else if (isError && error?.status === 404) {
- return (
-
- );
- } else if (isError) {
- return ;
- } else if (!result) {
+ }
+
+ if (isError) {
+ if (error?.status === 404) {
+ return deviceAuthToken ? (
+
+ ) : (
+
+ );
+ }
+
+ if (error?.status === 401) {
+ return deviceAuthToken ? (
+
+ ) : (
+
+ );
+ }
+ }
+
+ if (!result) {
// FIXME: Find a better solution for this.
- return ;
+ return deviceAuthToken ? (
+
+ ) : (
+
+ );
}
return (
diff --git a/frontend/components/DataError/DataError.tsx b/frontend/components/DataError/DataError.tsx
index 56dfdd4408..58bd049063 100644
--- a/frontend/components/DataError/DataError.tsx
+++ b/frontend/components/DataError/DataError.tsx
@@ -88,7 +88,9 @@ const DataError = ({
<>
{children || (
<>
- {description}
+ {description && (
+ {description}
+ )}
{!excludeIssueLink && (
If this keeps happening, please
diff --git a/frontend/components/DeviceUserError/DeviceUserError.tsx b/frontend/components/DeviceUserError/DeviceUserError.tsx
index 7df7cc38ea..b34d6c2511 100644
--- a/frontend/components/DeviceUserError/DeviceUserError.tsx
+++ b/frontend/components/DeviceUserError/DeviceUserError.tsx
@@ -14,8 +14,8 @@ const DeviceUserError = (): JSX.Element => {
This URL is invalid or expired.
- To access your device information, please click “My Device” from the
- Fleet Desktop menu icon.
+ To access your device information, please click
+ “My Device” from the Fleet Desktop menu icon.
diff --git a/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/SelectSoftwareModal/SelectSoftwareModal.tsx b/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/SelectSoftwareModal/SelectSoftwareModal.tsx
index 7fb520667e..ec38ffa133 100644
--- a/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/SelectSoftwareModal/SelectSoftwareModal.tsx
+++ b/frontend/pages/ManageControlsPage/SetupExperience/cards/InstallSoftware/components/SelectSoftwareModal/SelectSoftwareModal.tsx
@@ -56,7 +56,6 @@ const SelectSoftwareModal = ({
selectedSoftwareIds
);
} catch (e) {
- console.log("error");
renderFlash("error", "Couldn't save software. Please try again.");
}
setIsSaving(false);
diff --git a/frontend/pages/hosts/details/cards/Certificates/Certificates.tsx b/frontend/pages/hosts/details/cards/Certificates/Certificates.tsx
index 49c4610c5b..e0d2d706d2 100644
--- a/frontend/pages/hosts/details/cards/Certificates/Certificates.tsx
+++ b/frontend/pages/hosts/details/cards/Certificates/Certificates.tsx
@@ -10,6 +10,7 @@ import { HostPlatform } from "interfaces/platform";
import Card from "components/Card";
import CardHeader from "components/CardHeader";
import DataError from "components/DataError";
+import DeviceUserError from "components/DeviceUserError";
import CertificatesTable from "./CertificatesTable";
@@ -47,7 +48,13 @@ const CertificatesCard = ({
onSortChange,
}: ICertificatesProps) => {
const renderContent = () => {
- if (isError) return ;
+ if (isError) {
+ return isMyDevicePage ? (
+
+ ) : (
+
+ );
+ }
return (
- {isError && }
+ {isError &&
+ (isMyDevicePage ? (
+
+ ) : (
+
+ ))}
{!isError && (
;
+ return ; // Only shown on DeviceUserPage not HostDetailsPage
}
if (isEmpty || !selfServiceData) {