diff --git a/client/public/locales/en/translation.json b/client/public/locales/en/translation.json index e917fbdf85..86e2827e03 100644 --- a/client/public/locales/en/translation.json +++ b/client/public/locales/en/translation.json @@ -359,6 +359,7 @@ "unknown": "Unknown", "unsuitableForContainers": "Unsuitable for containers", "uploadApplicationFile": "Upload your application file", + "uploadYamlFile": "Upload your YAML file", "url": "URL", "user": "User", "version": "Version", diff --git a/client/src/app/pages/assessment/AssessmentSettings.tsx b/client/src/app/pages/assessment/AssessmentSettings.tsx index 3b83122e6e..7a25a8e4ad 100644 --- a/client/src/app/pages/assessment/AssessmentSettings.tsx +++ b/client/src/app/pages/assessment/AssessmentSettings.tsx @@ -48,6 +48,7 @@ import { useLocalTableControls } from "@app/hooks/table-controls"; import { NotificationsContext } from "@app/components/NotificationsContext"; import { getAxiosErrorMessage } from "@app/utils/utils"; import { Questionnaire } from "@app/api/models"; +import { ImportQuestionnaireForm } from "./import-questionnaire-form/import-questionnaire-form"; export const AssessmentSettings: React.FC = () => { const { t } = useTranslation(); @@ -373,7 +374,9 @@ export const AssessmentSettings: React.FC = () => { isOpen={isImportModal} onClose={() => setIsImportModal(false)} > - TODO Import questionnaire component + setIsImportModal(false)} + > void; +} +export interface ImportQuestionnaireFormValues { + yamlFile: IReadFile; +} + +export const yamlFileSchema: yup.SchemaOf = yup.object({ + fileName: yup.string().required(), + fullFile: yup.mixed(), + loadError: yup.mixed(), + loadPercentage: yup.number(), + loadResult: yup.mixed<"danger" | "success" | undefined>(), + data: yup.string(), + responseID: yup.number(), +}); + +export const ImportQuestionnaireForm: React.FC< + ImportQuestionnaireFormProps +> = ({ onSaved }) => { + const { t } = useTranslation(); + const { pushNotification } = React.useContext(NotificationsContext); + + const [filename, setFilename] = React.useState(); + const [isFileRejected, setIsFileRejected] = useState(false); + const validationSchema: yup.SchemaOf = yup + .object() + .shape({ + yamlFile: yamlFileSchema, + }); + const methods = useForm({ + resolver: yupResolver(validationSchema), + mode: "onChange", + }); + + const { + handleSubmit, + formState: { isSubmitting, isValidating, isValid, isDirty }, + getValues, + setValue, + control, + watch, + setFocus, + clearErrors, + trigger, + reset, + } = methods; + + const { mutateAsync: createYamlFileAsync } = useCreateFileMutation(); + + const handleFileUpload = async (file: File) => { + setFilename(file.name); + const formFile = new FormData(); + formFile.append("file", file); + + const newYamlFile: IReadFile = { + fileName: file.name, + fullFile: file, + }; + + return createYamlFileAsync({ + formData: formFile, + file: newYamlFile, + }); + }; + + const onSubmit = (values: ImportQuestionnaireFormValues) => { + console.log("values", values); + }; + return ( +
+ ( + { + const currentFile = event[0]; + if (currentFile.file.size > 1000000) { + methods.setError("yamlFile", { + type: "custom", + message: "Max file size of 1 MB exceeded.", + }); + } + setIsFileRejected(true); + }, + }} + validated={isFileRejected || error ? "error" : "default"} + onFileInputChange={async (_, file) => { + console.log("uploading file", file); + handleFileUpload(file) + .then((res) => { + // setValue("yamlFile", res); + setFocus("yamlFile"); + clearErrors("yamlFile"); + trigger("yamlFile"); + }) + .catch((err) => { + // setValue("yamlFile", null); + }); + }} + onClearClick={() => { + console.log("clearing file"); + // onChange(0); + // setFilename("default.png"); + // setValue("imageID", null); + // setIsImageFileRejected(false); + }} + browseButtonText="Upload" + /> + )} + /> + + {isFileRejected && ( + + + + You should select a YAML file. + + + + )} + + + + + ); +};