fleet/frontend/pages/SoftwarePage/components/AddSoftwareForm/helpers.ts
Gabriel Hernandez 7f803e4629
UI software install feature integrations and polish (#18906)
relates to #18677

implement UI API integrations and polish tasks for the software install
feature. These include various tasks to finish up this feature on the UI
and ensure its working correctly

- [x] Manual QA for all new/changed functionality
2024-05-10 16:18:24 +01:00

163 lines
4.3 KiB
TypeScript

import validator from "validator";
// @ts-ignore
import validateQuery from "components/forms/validators/validate_query";
import { getPlatformDisplayName } from "utilities/file/fileUtils";
import { IAddSoftwareFormData, IFormValidation } from "./AddSoftwareForm";
type IAddSoftwareFormValidatorKey = Exclude<
keyof IAddSoftwareFormData,
"installScript"
>;
type IMessageFunc = (formData: IAddSoftwareFormData) => string;
type IValidationMessage = string | IMessageFunc;
interface IValidation {
name: string;
isValid: (
formData: IAddSoftwareFormData,
enabledPreInstallCondition?: boolean,
enabledPostInstallScript?: boolean
) => boolean;
message?: IValidationMessage;
}
/** configuration defines validations for each filed in the form. It defines rules
* to determine if a field is valid, and rules for generating an error message.
*/
const FORM_VALIDATION_CONFIG: Record<
IAddSoftwareFormValidatorKey,
{ validations: IValidation[] }
> = {
software: {
validations: [
{
name: "required",
isValid: (formData) => formData.software !== null,
},
],
},
preInstallCondition: {
validations: [
{
name: "required",
isValid: (
formData: IAddSoftwareFormData,
enabledPreInstallCondition
) => {
if (!enabledPreInstallCondition) {
return true;
}
return (
formData.preInstallCondition !== undefined &&
!validator.isEmpty(formData.preInstallCondition)
);
},
message: (formData) => {
// we dont want an error message until the user has interacted with
// the field. This is why we check for undefined here.
if (formData.preInstallCondition === undefined) {
return "";
}
return "Pre-install condition is required when enabled.";
},
},
{
name: "invalidQuery",
isValid: (formData, enabledPreInstallCondition) => {
if (!enabledPreInstallCondition) {
return true;
}
return (
formData.preInstallCondition !== undefined &&
validateQuery(formData.preInstallCondition).valid
);
},
message: (formData) =>
validateQuery(formData.preInstallCondition).error,
},
],
},
postInstallScript: {
validations: [
{
name: "required",
message: (formData) => {
// we dont want an error message until the user has interacted with
// the field. This is why we check for undefined here.
if (formData.postInstallScript === undefined) {
return "";
}
return "Post-install script is required when enabled.";
},
isValid: (formData, _, enabledPostInstallScript) => {
if (!enabledPostInstallScript) {
return true;
}
return (
formData.postInstallScript !== undefined &&
!validator.isEmpty(formData.postInstallScript)
);
},
},
],
},
};
const getErrorMessage = (
formData: IAddSoftwareFormData,
message?: IValidationMessage
) => {
if (message === undefined || typeof message === "string") {
return message;
}
return message(formData);
};
export const generateFormValidation = (
formData: IAddSoftwareFormData,
showingPreInstallCondition: boolean,
showingPostInstallScript: boolean
) => {
const formValidation: IFormValidation = {
isValid: true,
software: {
isValid: false,
},
};
Object.keys(FORM_VALIDATION_CONFIG).forEach((key) => {
const objKey = key as keyof typeof FORM_VALIDATION_CONFIG;
const failedValidation = FORM_VALIDATION_CONFIG[objKey].validations.find(
(validation) =>
!validation.isValid(
formData,
showingPreInstallCondition,
showingPostInstallScript
)
);
if (!failedValidation) {
formValidation[objKey] = {
isValid: true,
};
} else {
formValidation.isValid = false;
formValidation[objKey] = {
isValid: false,
message: getErrorMessage(formData, failedValidation.message),
};
}
});
return formValidation;
};
export const getFileDetails = (file: File) => {
return {
name: file.name,
platform: getPlatformDisplayName(file),
};
};