ui impl for labels include all (#41836)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #40724 

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
This commit is contained in:
Jahziel Villasana-Espinoza
2026-03-18 15:16:25 -04:00
committed by GitHub
parent 02a9eb8769
commit 8d646cd165
6 changed files with 70 additions and 7 deletions
+3
View File
@@ -159,6 +159,7 @@ const DEFAULT_APP_STORE_APP_MOCK: IAppStoreApp = {
failed: 3,
},
labels_include_any: null,
labels_include_all: null,
labels_exclude_any: null,
};
@@ -183,6 +184,7 @@ const DEFAULT_APP_STORE_APP_ANDROID_MOCK: IAppStoreApp = {
categories: null,
labels_include_any: null,
labels_exclude_any: null,
labels_include_all: null,
configuration: '{ workProfileWidgets: "WORK_PROFILE_WIDGETS_ALLOWED" }',
};
@@ -256,6 +258,7 @@ const DEFAULT_SOFTWARE_PACKAGE_MOCK: ISoftwarePackage = {
url: "https://fakeurl.testpackageurlforfalconapp.fake/test/package",
hash_sha256: "abcd1234",
labels_include_any: null,
labels_include_all: null,
labels_exclude_any: null,
install_during_setup: undefined,
};
+2
View File
@@ -142,6 +142,7 @@ export interface ISoftwarePackage {
automatic_install_policies?: ISoftwareInstallPolicy[] | null;
install_during_setup?: boolean;
labels_include_any: ILabelSoftwareTitle[] | null;
labels_include_all: ILabelSoftwareTitle[] | null;
labels_exclude_any: ILabelSoftwareTitle[] | null;
categories?: SoftwareCategory[] | null;
fleet_maintained_app_id?: number | null;
@@ -172,6 +173,7 @@ export interface IAppStoreApp {
} | null;
version?: string;
labels_include_any: ILabelSoftwareTitle[] | null;
labels_include_all: ILabelSoftwareTitle[] | null;
labels_exclude_any: ILabelSoftwareTitle[] | null;
categories?: SoftwareCategory[] | null;
configuration?: string;
@@ -473,6 +473,7 @@ describe("Edit Auto Update Config Modal", () => {
auto_update_enabled: false,
labels_include_any: [],
labels_exclude_any: [],
labels_include_all: [],
fleet_id: 1,
});
});
@@ -514,6 +515,7 @@ describe("Edit Auto Update Config Modal", () => {
auto_update_window_end: "04:00",
labels_include_any: [],
labels_exclude_any: [],
labels_include_all: [],
fleet_id: 1,
});
});
@@ -547,6 +549,7 @@ describe("Edit Auto Update Config Modal", () => {
auto_update_enabled: false,
labels_include_any: [],
labels_exclude_any: [],
labels_include_all: [],
fleet_id: 1,
});
});
@@ -13,6 +13,7 @@ describe("SoftwareTitleDetailsPage helpers", () => {
software_package: {
labels_include_any: null,
labels_exclude_any: null,
labels_include_all: null,
name: "TestPackage.pkg",
title_id: 2,
version: "1.0.0",
@@ -79,6 +80,7 @@ describe("SoftwareTitleDetailsPage helpers", () => {
icon_url: "https://example.com/icon.png",
labels_exclude_any: null,
labels_include_any: null,
labels_include_all: null,
},
source: "apps",
hosts_count: 10,
+39 -7
View File
@@ -83,6 +83,7 @@ export const getTargetType = (
if (!softwareInstaller) return "All hosts";
return !softwareInstaller.labels_include_any &&
!softwareInstaller.labels_include_all &&
!softwareInstaller.labels_exclude_any
? "All hosts"
: "Custom";
@@ -94,9 +95,9 @@ export const getCustomTarget = (
) => {
if (!softwareInstaller) return "labelsIncludeAny";
return softwareInstaller.labels_include_any
? "labelsIncludeAny"
: "labelsExcludeAny";
if (softwareInstaller.labels_include_any) return "labelsIncludeAny";
if (softwareInstaller.labels_include_all) return "labelsIncludeAll";
return "labelsExcludeAny";
};
// Used in EditSoftwareModal and PackageForm
@@ -106,14 +107,23 @@ export const generateSelectedLabels = (
if (
!softwareInstaller ||
(!softwareInstaller.labels_include_any &&
!softwareInstaller.labels_include_all &&
!softwareInstaller.labels_exclude_any)
) {
return {};
}
const customTypeKey = softwareInstaller.labels_include_any
? "labels_include_any"
: "labels_exclude_any";
let customTypeKey:
| "labels_include_any"
| "labels_include_all"
| "labels_exclude_any";
if (softwareInstaller.labels_include_any) {
customTypeKey = "labels_include_any";
} else if (softwareInstaller.labels_include_all) {
customTypeKey = "labels_include_all";
} else {
customTypeKey = "labels_exclude_any";
}
return (
softwareInstaller[customTypeKey]?.reduce<Record<string, boolean>>(
@@ -145,7 +155,21 @@ export const generateHelpText = (
);
}
// this is the case for labelsExcludeAny
if (customTarget === "labelsIncludeAll") {
return !automaticInstall ? (
<>
Software will only be available for install on hosts that{" "}
<b>have all</b> of these labels:
</>
) : (
<>
Software will only be installed on hosts that <b>have all</b> of these
labels:
</>
);
}
// labelsExcludeAny
return !automaticInstall ? (
<>
Software will only be available for install on hosts that{" "}
@@ -164,11 +188,19 @@ export const CUSTOM_TARGET_OPTIONS: IDropdownOption[] = [
{
value: "labelsIncludeAny",
label: "Include any",
helpText: "Hosts that have any of the selected labels.",
disabled: false,
},
{
value: "labelsIncludeAll",
label: "Include all",
helpText: "Hosts that have all of the selected labels.",
disabled: false,
},
{
value: "labelsExcludeAny",
label: "Exclude any",
helpText: "Hosts that don't have any of the selected labels.",
disabled: false,
},
];
+21
View File
@@ -162,6 +162,7 @@ interface IAddFleetMaintainedAppPostBody {
self_service?: boolean;
automatic_install?: boolean;
labels_include_any?: string[];
labels_include_all?: string[];
labels_exclude_any?: string[];
categories: string[];
}
@@ -175,6 +176,7 @@ export interface IAddAppStoreAppPostBody {
// No automatic_install on add Android app
automatic_install?: boolean;
labels_include_any?: string[];
labels_include_all?: string[];
labels_exclude_any?: string[];
categories?: SoftwareCategory[];
}
@@ -185,6 +187,7 @@ export interface IEditAppStoreAppPostBody {
self_service?: boolean;
// No automatic_install on edit VPP or android app
labels_include_any?: string[];
labels_include_all?: string[];
labels_exclude_any?: string[];
categories?: SoftwareCategory[];
display_name?: string;
@@ -219,6 +222,8 @@ const handleAndroidForm = (
const selectedLabels = listNamesFromSelectedLabels(formData.labelTargets);
if (formData.customTarget === "labelsIncludeAny") {
body.labels_include_any = selectedLabels;
} else if (formData.customTarget === "labelsIncludeAll") {
body.labels_include_all = selectedLabels;
} else {
body.labels_exclude_any = selectedLabels;
}
@@ -250,6 +255,8 @@ const handleVppAppForm = (teamId: number, formData: ISoftwareVppFormData) => {
const selectedLabels = listNamesFromSelectedLabels(formData.labelTargets);
if (formData.customTarget === "labelsIncludeAny") {
body.labels_include_any = selectedLabels;
} else if (formData.customTarget === "labelsIncludeAll") {
body.labels_include_all = selectedLabels;
} else {
body.labels_exclude_any = selectedLabels;
}
@@ -299,6 +306,8 @@ const handleEditPackageForm = (
if (data.targetType === "All hosts") {
if (orignalPackage.labels_include_any) {
formData.append("labels_include_any", "");
} else if (orignalPackage.labels_include_all) {
formData.append("labels_include_all", "");
} else {
formData.append("labels_exclude_any", "");
}
@@ -310,6 +319,8 @@ const handleEditPackageForm = (
let labelKey = "";
if (data.customTarget === "labelsIncludeAny") {
labelKey = "labels_include_any";
} else if (data.customTarget === "labelsIncludeAll") {
labelKey = "labels_include_all";
} else {
labelKey = "labels_exclude_any";
}
@@ -346,12 +357,15 @@ const handleAutoUpdateConfigAppStoreAppForm = (
const selectedLabels = listNamesFromSelectedLabels(formData.labelTargets);
if (formData.customTarget === "labelsIncludeAny") {
body.labels_include_any = selectedLabels;
} else if (formData.customTarget === "labelsIncludeAll") {
body.labels_include_all = selectedLabels;
} else {
body.labels_exclude_any = selectedLabels;
}
} else {
body.labels_exclude_any = [];
body.labels_include_any = [];
body.labels_include_all = [];
}
};
@@ -371,12 +385,15 @@ const handleEditAppStoreAppForm = (
const selectedLabels = listNamesFromSelectedLabels(formData.labelTargets);
if (formData.customTarget === "labelsIncludeAny") {
body.labels_include_any = selectedLabels;
} else if (formData.customTarget === "labelsIncludeAll") {
body.labels_include_all = selectedLabels;
} else {
body.labels_exclude_any = selectedLabels;
}
} else {
body.labels_exclude_any = [];
body.labels_include_any = [];
body.labels_include_all = [];
}
};
@@ -552,6 +569,8 @@ export default {
let labelKey = "";
if (data.customTarget === "labelsIncludeAny") {
labelKey = "labels_include_any";
} else if (data.customTarget === "labelsIncludeAll") {
labelKey = "labels_include_all";
} else {
labelKey = "labels_exclude_any";
}
@@ -796,6 +815,8 @@ export default {
const selectedLabels = listNamesFromSelectedLabels(formData.labelTargets);
if (formData.customTarget === "labelsIncludeAny") {
body.labels_include_any = selectedLabels;
} else if (formData.customTarget === "labelsIncludeAll") {
body.labels_include_all = selectedLabels;
} else {
body.labels_exclude_any = selectedLabels;
}