diff --git a/frontend/pages/hosts/ManageHostsPage/helpers.ts b/frontend/pages/hosts/ManageHostsPage/helpers.ts
index 59d6b96189..d312e937f7 100644
--- a/frontend/pages/hosts/ManageHostsPage/helpers.ts
+++ b/frontend/pages/hosts/ManageHostsPage/helpers.ts
@@ -24,7 +24,7 @@ export const isValidPemCertificate = (cert: string): boolean => {
return regexPemHeader.test(cert) && regexPemFooter.test(cert);
};
-const hasStatusKey = (value: unknown): value is { status: number } => {
+export const hasStatusKey = (value: unknown): value is { status: number } => {
return (
typeof value === "object" &&
value !== null &&
diff --git a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx
index 912dcaeb6d..e9a921cdf4 100644
--- a/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx
+++ b/frontend/pages/hosts/details/HostDetailsPage/HostDetailsPage.tsx
@@ -33,7 +33,7 @@ import { IHostPolicy } from "interfaces/policy";
import { IQueryStats } from "interfaces/query_stats";
import { IHostSoftware } from "interfaces/software";
import { ITeam } from "interfaces/team";
-import { IHostUpcomingActivity } from "interfaces/activity";
+import { ActivityType, IHostUpcomingActivity } from "interfaces/activity";
import {
IHostCertificate,
CERTIFICATES_DEFAULT_SORT,
@@ -163,6 +163,7 @@ const HostDetailsPage = ({
config,
currentUser,
isGlobalAdmin = false,
+ isGlobalMaintainer,
isGlobalObserver,
isPremiumTier = false,
isOnlyObserver,
@@ -836,6 +837,12 @@ const HostDetailsPage = ({
router.push(navPath);
};
+ const isHostTeamAdmin = permissions.isTeamAdmin(currentUser, host?.team_id);
+ const isHostTeamMaintainer = permissions.isTeamMaintainer(
+ currentUser,
+ host?.team_id
+ );
+
/* Context team id might be different that host's team id
Observer plus must be checked against host's team id */
const isGlobalOrHostsTeamObserverPlus =
@@ -969,6 +976,12 @@ const HostDetailsPage = ({
? pastActivitiesIsError
: upcomingActivitiesIsError
}
+ canCancelActivities={
+ isGlobalAdmin ||
+ isGlobalMaintainer ||
+ isHostTeamAdmin ||
+ isHostTeamMaintainer
+ }
upcomingCount={upcomingActivities?.count || 0}
onChangeTab={onChangeActivityTab}
onNextPage={() => setActivityPage(activityPage + 1)}
@@ -1204,6 +1217,16 @@ const HostDetailsPage = ({
hostId={host.id}
activity={selectedCancelActivity}
onCancelActivity={() => refetchUpcomingActivities()}
+ onSuccessCancel={(activity) => {
+ // only for windows and linux hosts we want to refetch host details
+ if (
+ (activity.type === ActivityType.RanScript &&
+ host.platform === "windows") ||
+ host.platform === "linux"
+ ) {
+ refetchHostDetails();
+ }
+ }}
onExit={() => setSelectedCancelActivity(null)}
/>
)}
diff --git a/frontend/pages/hosts/details/HostDetailsPage/modals/CancelActivityModal/CancelActivityModal.tsx b/frontend/pages/hosts/details/HostDetailsPage/modals/CancelActivityModal/CancelActivityModal.tsx
index c9eae117fd..ed9419e52e 100644
--- a/frontend/pages/hosts/details/HostDetailsPage/modals/CancelActivityModal/CancelActivityModal.tsx
+++ b/frontend/pages/hosts/details/HostDetailsPage/modals/CancelActivityModal/CancelActivityModal.tsx
@@ -17,7 +17,8 @@ const baseClass = "cancel-activity-modal";
interface ICancelActivityModalProps {
hostId: number;
activity: IHostUpcomingActivity;
- onCancelActivity: () => void;
+ onCancelActivity: (activity: IHostUpcomingActivity) => void;
+ onSuccessCancel: (activity: IHostUpcomingActivity) => void;
onExit: () => void;
}
@@ -25,6 +26,7 @@ const CancelActivityModal = ({
hostId,
activity,
onCancelActivity,
+ onSuccessCancel,
onExit,
}: ICancelActivityModalProps) => {
const { renderFlash } = useContext(NotificationContext);
@@ -37,10 +39,11 @@ const CancelActivityModal = ({
try {
await activitiesAPI.cancelHostActivity(hostId, activity.uuid);
renderFlash("success", "Activity successfully canceled.");
+ onSuccessCancel(activity);
} catch (err) {
renderFlash("error", getErrorMessage(err));
}
- onCancelActivity();
+ onCancelActivity(activity);
onExit();
};
diff --git a/frontend/pages/hosts/details/HostDetailsPage/modals/CancelActivityModal/helpers.ts b/frontend/pages/hosts/details/HostDetailsPage/modals/CancelActivityModal/helpers.ts
index d38446e394..5ac4761514 100644
--- a/frontend/pages/hosts/details/HostDetailsPage/modals/CancelActivityModal/helpers.ts
+++ b/frontend/pages/hosts/details/HostDetailsPage/modals/CancelActivityModal/helpers.ts
@@ -1,4 +1,4 @@
-import { isAxiosError } from "axios";
+import { hasStatusKey } from "pages/hosts/ManageHostsPage/helpers";
const DEFAULT_ERR_MESSAGE = "Couldn't cancel activity. Please try again.";
const LOCK_WIPE_ERR_MESSAGE =
@@ -8,7 +8,7 @@ const ACTIVITY_ALREADY_HAPPENED_ERR_MESSAGE =
// eslint-disable-next-line import/prefer-default-export
export const getErrorMessage = (err: unknown) => {
- if (isAxiosError(err)) {
+ if (hasStatusKey(err)) {
if (err.status === 404) return ACTIVITY_ALREADY_HAPPENED_ERR_MESSAGE;
// display server error message if error is 400
diff --git a/frontend/pages/hosts/details/cards/Activity/Activity.tsx b/frontend/pages/hosts/details/cards/Activity/Activity.tsx
index b5963e2696..a35a90891f 100644
--- a/frontend/pages/hosts/details/cards/Activity/Activity.tsx
+++ b/frontend/pages/hosts/details/cards/Activity/Activity.tsx
@@ -39,6 +39,7 @@ interface IActivityProps {
isError?: boolean;
className?: string;
upcomingCount: number;
+ canCancelActivities: boolean;
onChangeTab: (index: number, last: number, event: Event) => void;
onNextPage: () => void;
onPreviousPage: () => void;
@@ -53,6 +54,7 @@ const Activity = ({
isError,
className,
upcomingCount,
+ canCancelActivities,
onChangeTab,
onNextPage,
onPreviousPage,
@@ -107,6 +109,7 @@ const Activity = ({
isError={isError}
onNextPage={onNextPage}
onPreviousPage={onPreviousPage}
+ canCancelActivities={canCancelActivities}
/>
diff --git a/frontend/pages/hosts/details/cards/Activity/UpcomingActivityFeed/UpcomingActivityFeed.tsx b/frontend/pages/hosts/details/cards/Activity/UpcomingActivityFeed/UpcomingActivityFeed.tsx
index 083b93bbc7..8f0206c46e 100644
--- a/frontend/pages/hosts/details/cards/Activity/UpcomingActivityFeed/UpcomingActivityFeed.tsx
+++ b/frontend/pages/hosts/details/cards/Activity/UpcomingActivityFeed/UpcomingActivityFeed.tsx
@@ -1,8 +1,7 @@
-import React, { useContext } from "react";
+import React from "react";
import { IHostUpcomingActivity } from "interfaces/activity";
import { IHostUpcomingActivitiesResponse } from "services/entities/activities";
-import { AppContext } from "context/app";
import DataError from "components/DataError";
import Pagination from "components/Pagination";
@@ -16,6 +15,7 @@ const baseClass = "upcoming-activity-feed";
interface IUpcomingActivityFeedProps {
activities?: IHostUpcomingActivitiesResponse;
isError?: boolean;
+ canCancelActivities: boolean;
onShowDetails: ShowActivityDetailsHandler;
onCancel: (activity: IHostUpcomingActivity) => void;
onNextPage: () => void;
@@ -25,17 +25,12 @@ interface IUpcomingActivityFeedProps {
const UpcomingActivityFeed = ({
activities,
isError = false,
+ canCancelActivities,
onShowDetails,
onCancel,
onNextPage,
onPreviousPage,
}: IUpcomingActivityFeedProps) => {
- const {
- isTeamMaintainerOrTeamAdmin,
- isGlobalAdmin,
- isGlobalMaintainer,
- } = useContext(AppContext);
-
if (isError) {
return