fleet/frontend/pages/ManageControlsPage/MacOSSetup/cards/BootstrapPackage/BootstrapPackage.tsx

108 lines
3.1 KiB
TypeScript
Raw Normal View History

UI for bootstrap package flows (#11288) relates to #10935 This is the UI for all the flows around adding, removing, downloading, and viewing information about a bootstrap package for fleet mdm. This is pretty comprehensive but includes: ### Backend **Update `Get host/id`** to include bootstrap package name ```json { "macos_setup": { ... "bootstrap_package_name": "test.pkg" } } ``` ### Frontend **UI for ABM not being set up**: ![image](https://user-images.githubusercontent.com/1153709/234018772-3221e27b-50a4-454e-8e9f-b62c9d349010.png) **UIs for uploading, downloading, and deleting bootstrap package**: ![image](https://user-images.githubusercontent.com/1153709/234017915-871f252f-bf80-4282-9acf-5ebea12c6efa.png) ![image](https://user-images.githubusercontent.com/1153709/234018029-322a5f30-dd22-44e3-b9ae-a4af7acb68b4.png) ![image](https://user-images.githubusercontent.com/1153709/234018163-4b84a2ce-a064-4952-a63d-0c8307391052.png) **UIs for seeing bootstrap status aggregate data** ![image](https://user-images.githubusercontent.com/1153709/234018107-455d63ab-5b2c-4727-ad20-eef6b269c336.png) **UIs for filtering hosts by bootstrap status** ![image](https://user-images.githubusercontent.com/1153709/234018334-170fe93a-700e-48eb-b198-2a1cc54d31a7.png) **UIs for seeing package status on host details and my device page**: ![image](https://user-images.githubusercontent.com/1153709/234018488-7b515db4-1248-4be7-8de3-9b74bb5d4795.png) ![image](https://user-images.githubusercontent.com/1153709/234018525-d653cb2d-9ef9-437e-8eba-141e557f4f39.png) - [x] Changes file added for user-visible changes in `changes/` or `orbit/changes/`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - [x] Manual QA for all new/changed functionality --------- Co-authored-by: Roberto Dip <dip.jesusr@gmail.com> Co-authored-by: gillespi314 <73313222+gillespi314@users.noreply.github.com> Co-authored-by: Martin Angers <martin.n.angers@gmail.com>
2023-04-27 15:10:41 +00:00
import React, { useContext, useState } from "react";
import { useQuery } from "react-query";
import { AxiosResponse } from "axios";
import { IBootstrapPackageMetadata } from "interfaces/mdm";
import { IApiError } from "interfaces/errors";
import mdmAPI from "services/entities/mdm";
import { NotificationContext } from "context/notification";
import Spinner from "components/Spinner";
import BootstrapPackagePreview from "./components/BootstrapPackagePreview";
import PackageUploader from "./components/BootstrapPackageUploader";
import UploadedPackageView from "./components/UploadedPackageView";
import DeletePackageModal from "./components/DeletePackageModal";
const baseClass = "bootstrap-package";
interface IBootstrapPackageProps {
currentTeamId: number;
}
const BootstrapPackage = ({ currentTeamId }: IBootstrapPackageProps) => {
const { renderFlash } = useContext(NotificationContext);
const [showDeletePackageModal, setShowDeletePackageModal] = useState(false);
const {
data: bootstrapMetadata,
isLoading,
error,
refetch: refretchBootstrapMetadata,
} = useQuery<
IBootstrapPackageMetadata,
AxiosResponse<IApiError>,
IBootstrapPackageMetadata
>(
["bootstrap-metadata", currentTeamId],
() => mdmAPI.getBootstrapPackageMetadata(currentTeamId),
{
retry: false,
refetchOnWindowFocus: false,
cacheTime: 0,
}
);
const onUpload = () => {
refretchBootstrapMetadata();
};
const onDelete = async () => {
try {
await mdmAPI.deleteBootstrapPackage(currentTeamId);
renderFlash("success", "Successfully deleted!");
} catch {
renderFlash("error", "Couldnt delete. Please try again.");
} finally {
setShowDeletePackageModal(false);
refretchBootstrapMetadata();
}
};
// we are relying on the API to tell us this resource does not exist to
// determine if the user has uploaded a bootstrap package.
const noPackageUploaded =
(error && error.status === 404) || !bootstrapMetadata;
return (
<div className={baseClass}>
<h2>Bootstrap package</h2>
{isLoading ? (
<Spinner />
) : (
<div className={`${baseClass}__content`}>
{noPackageUploaded ? (
<>
<PackageUploader
currentTeamId={currentTeamId}
onUpload={onUpload}
/>
<div className={`${baseClass}__preview-container`}>
<BootstrapPackagePreview />
</div>
</>
) : (
<>
<UploadedPackageView
bootstrapPackage={bootstrapMetadata}
currentTeamId={currentTeamId}
onDelete={() => setShowDeletePackageModal(true)}
/>
<div className={`${baseClass}__preview-container`}>
<BootstrapPackagePreview />
</div>
</>
)}
</div>
)}
{showDeletePackageModal && (
<DeletePackageModal
onDelete={onDelete}
onCancel={() => setShowDeletePackageModal(false)}
/>
)}
</div>
);
};
export default BootstrapPackage;