fleet/frontend/components/FileUploader/FileUploader.tsx
Gabriel Hernandez a292e704de
add startup assistant to the UI (#17731)
relates to #9147

add the setup assistant page to the UI. This includes:

- new setup assistant page
- uploaded profile and release device manually form
- preview for setup assistant flow

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [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] Added/updated tests
- [x] Manual QA for all new/changed functionality

---------

Co-authored-by: Martin Angers <martin.n.angers@gmail.com>
2024-03-26 14:46:33 +00:00

94 lines
2.4 KiB
TypeScript

import React from "react";
import classnames from "classnames";
import Button from "components/buttons/Button";
import Card from "components/Card";
import { GraphicNames } from "components/graphics";
import Graphic from "components/Graphic";
const baseClass = "file-uploader";
type ISupportedGraphicNames = Extract<
GraphicNames,
| "file-configuration-profile"
| "file-sh"
| "file-ps1"
| "file-py"
| "file-script"
| "file-pdf"
| "file-pkg"
| "file-p7m"
| "file-pem"
>;
interface IFileUploaderProps {
graphicName: ISupportedGraphicNames | ISupportedGraphicNames[];
message: string;
additionalInfo?: string;
/** Controls the loading spinner on the upload button */
isLoading?: boolean;
/** A comma seperated string of one or more file types accepted to upload.
* This is the same as the html accept attribute.
* https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/accept
*/
accept?: string;
/** The text to display on the upload button */
buttonMessage?: string;
className?: string;
onFileUpload: (files: FileList | null) => void;
}
/**
* A component that encapsulates the UI for uploading a file.
*/
const FileUploader = ({
graphicName: graphicNames,
message,
additionalInfo,
isLoading = false,
accept,
buttonMessage = "Upload",
className,
onFileUpload,
}: IFileUploaderProps) => {
const classes = classnames(baseClass, className);
const renderGraphics = () => {
const graphicNamesArr =
typeof graphicNames === "string" ? [graphicNames] : graphicNames;
return graphicNamesArr.map((graphicName) => (
<Graphic
key={`${graphicName}-graphic`}
className={`${baseClass}__graphic`}
name={graphicName}
/>
));
};
return (
<Card color="gray" className={classes}>
<div className={`${baseClass}__graphics`}>{renderGraphics()}</div>
<p className={`${baseClass}__message`}>{message}</p>
{additionalInfo && (
<p className={`${baseClass}__additional-info`}>{additionalInfo}</p>
)}
<Button
className={`${baseClass}__upload-button`}
variant="brand"
isLoading={isLoading}
>
<label htmlFor="upload-file">{buttonMessage}</label>
</Button>
<input
accept={accept}
id="upload-file"
type="file"
onChange={(e) => {
onFileUpload(e.target.files);
e.target.value = "";
}}
/>
</Card>
);
};
export default FileUploader;