Skip to content

Commit

Permalink
finish UI api integration for editing a custom package (#24929)
Browse files Browse the repository at this point in the history
relates to #24828

Finish up the UI integration for the API to edit a custom package

- [x] Manual QA for all new/changed functionality
  • Loading branch information
ghernandez345 authored Dec 19, 2024
1 parent 1e949c8 commit e6efcf7
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 9 deletions.
1 change: 1 addition & 0 deletions frontend/__mocks__/softwareMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ const DEFAULT_SOFTWARE_PACKAGE_MOCK: ISoftwarePackage = {
version: "1.2.3",
uploaded_at: "2020-01-01T00:00:00.000Z",
install_script: "sudo installer -pkg /temp/FalconSensor-6.44.pkg -target /",
uninstall_script: "sudo rm -rf /Applications/Falcon.app",
pre_install_query: "SELECT 1 FROM macos_profiles WHERE uuid='abc123';",
post_install_script:
"sudo /Applications/Falcon.app/Contents/Resources/falconctl license abc123",
Expand Down
1 change: 1 addition & 0 deletions frontend/interfaces/software.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export interface ISoftwarePackage {
version: string;
uploaded_at: string;
install_script: string;
uninstall_script: string;
pre_install_query?: string;
post_install_script?: string;
self_service: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { isAxiosError } from "axios";

import { getErrorReason } from "interfaces/errors";
import { ILabelSummary } from "interfaces/label";
import { ISoftwarePackage } from "interfaces/software";

import { NotificationContext } from "context/notification";
import softwareAPI, {
Expand All @@ -26,6 +27,12 @@ import Modal from "components/Modal";

import PackageForm from "pages/SoftwarePage/components/PackageForm";
import { IPackageFormData } from "pages/SoftwarePage/components/PackageForm/PackageForm";
import {
generateSelectedLabels,
getCustomTarget,
getTargetType,
} from "pages/SoftwarePage/components/PackageForm/helpers";

import { getErrorMessage } from "./helpers";
import ConfirmSaveChangesModal from "../ConfirmSaveChangesModal";

Expand All @@ -34,7 +41,7 @@ const baseClass = "edit-software-modal";
interface IEditSoftwareModalProps {
softwareId: number;
teamId: number;
software?: any; // TODO
software: ISoftwarePackage; // TODO
refetchSoftwareTitle: () => void;
onExit: () => void;
}
Expand Down Expand Up @@ -137,6 +144,7 @@ const EditSoftwareModal = ({
try {
await softwareAPI.editSoftwarePackage({
data: formData,
orignalPackage: software,
softwareId,
teamId,
onUploadProgress: (progressEvent) => {
Expand Down Expand Up @@ -166,7 +174,7 @@ const EditSoftwareModal = ({
if (isTimeout) {
renderFlash(
"error",
`Couldnt upload. Request timeout. Please make sure your server and load balancer timeout is long enough.`
`Couldn't upload. Request timeout. Please make sure your server and load balancer timeout is long enough.`
);
} else if (reason.includes("Fleet couldn't read the version from")) {
renderFlash(
Expand Down Expand Up @@ -203,18 +211,21 @@ const EditSoftwareModal = ({
postInstallScript: software.post_install_script || "",
uninstallScript: software.uninstall_script || "",
selfService: software.self_service || false,
targetType: getTargetType(software),
customTarget: getCustomTarget(software),
labelTargets: generateSelectedLabels(software),
});

setPendingUpdates(formData);

const onlySelfServiceUpdated =
Object.keys(updates).length === 1 && "selfService" in updates;
if (!onlySelfServiceUpdated) {
// Open the confirm save changes modal
setShowConfirmSaveChangesModal(true);
} else {
if (onlySelfServiceUpdated) {
// Proceed with saving changes (API expects only changes)
onSaveSoftwareChanges(formData);
} else {
// Open the confirm save changes modal
setShowConfirmSaveChangesModal(true);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ const SoftwarePackageCard = ({
teamId={teamId}
/>
</div>
{showEditSoftwareModal && (
{showEditSoftwareModal && softwarePackage && (
<EditSoftwareModal
softwareId={softwareId}
teamId={teamId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe("SoftwareTitleDetailsPage helpers", () => {
failed_uninstall: 1,
},
install_script: "echo foo",
uninstall_script: "echo bar",
icon_url: "https://example.com/icon.png",
automatic_install_policies: [],
last_install: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ const PackageForm = ({
const onSelectCustomTarget = (value: string) => {
const newData = { ...formData, customTarget: value };
setFormData(newData);
setFormValidation(generateFormValidation(newData));
};

const onSelectLabel = ({ name, value }: { name: string; value: boolean }) => {
Expand Down
35 changes: 33 additions & 2 deletions frontend/services/entities/software.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ISoftwareTitleDetails,
IFleetMaintainedApp,
IFleetMaintainedAppDetails,
ISoftwarePackage,
} from "interfaces/software";
import {
buildQueryStringFromParams,
Expand All @@ -18,6 +19,7 @@ import {
import { IPackageFormData } from "pages/SoftwarePage/components/PackageForm/PackageForm";
import { IAddFleetMaintainedData } from "pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/FleetMaintainedAppDetailsPage";
import { listNamesFromSelectedLabels } from "components/TargetLabelSelector/TargetLabelSelector";
import { join } from "path";

export interface ISoftwareApiParams {
page?: number;
Expand Down Expand Up @@ -281,11 +283,15 @@ export default {

if (data.targetType === "Custom") {
const selectedLabels = listNamesFromSelectedLabels(data.labelTargets);
let labelKey = "";
if (data.customTarget === "labelsIncludeAny") {
formData.append("labels_include_any", selectedLabels.join(","));
labelKey = "labels_include_any";
} else {
formData.append("labels_exclude_any", selectedLabels.join(","));
labelKey = "labels_exclude_any";
}
selectedLabels?.forEach((label) => {
formData.append(labelKey, label);
});
}

return sendRequestWithProgress({
Expand All @@ -301,13 +307,15 @@ export default {

editSoftwarePackage: ({
data,
orignalPackage,
softwareId,
teamId,
timeout,
onUploadProgress,
signal,
}: {
data: IPackageFormData;
orignalPackage: ISoftwarePackage;
softwareId: number;
teamId: number;
timeout?: number;
Expand All @@ -325,6 +333,29 @@ export default {
formData.append("post_install_script", data.postInstallScript || "");
formData.append("uninstall_script", data.uninstallScript || "");

// clear out labels if targetType is "All hosts"
if (data.targetType === "All hosts") {
if (orignalPackage.labels_include_any) {
formData.append("labels_include_any", "");
} else {
formData.append("labels_exclude_any", "");
}
}

// add custom labels if targetType is "Custom"
if (data.targetType === "Custom") {
const selectedLabels = listNamesFromSelectedLabels(data.labelTargets);
let labelKey = "";
if (data.customTarget === "labelsIncludeAny") {
labelKey = "labels_include_any";
} else {
labelKey = "labels_exclude_any";
}
selectedLabels?.forEach((label) => {
formData.append(labelKey, label);
});
}

return sendRequestWithProgress({
method: "PATCH",
path: EDIT_SOFTWARE_PACKAGE(softwareId),
Expand Down

0 comments on commit e6efcf7

Please sign in to comment.