remove copied FileUpload component (#34290)
* remove copied FileUpload component fixes: #32420 Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> * removed dependencies Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com> --------- Signed-off-by: Erik Jan de Wit <erikjan.dewit@gmail.com>
This commit is contained in:
parent
b57b0bec88
commit
2e56896b05
9 changed files with 31 additions and 517 deletions
|
@ -82,7 +82,6 @@
|
|||
"admin-ui": "file:",
|
||||
"dagre": "^0.8.5",
|
||||
"file-saver": "^2.0.5",
|
||||
"file-selector": "^1.1.0",
|
||||
"flat": "^6.0.1",
|
||||
"i18next": "^23.16.3",
|
||||
"i18next-http-backend": "^2.6.2",
|
||||
|
@ -92,7 +91,6 @@
|
|||
"p-debounce": "^4.0.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-dropzone": "^14.2.10",
|
||||
"react-hook-form": "^7.53.1",
|
||||
"react-i18next": "^15.1.0",
|
||||
"react-router-dom": "^6.27.0",
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Controller,
|
||||
FormProvider,
|
||||
useForm,
|
||||
useFormContext,
|
||||
} from "react-hook-form";
|
||||
import type KeyStoreConfig from "@keycloak/keycloak-admin-client/lib/defs/keystoreConfig";
|
||||
import { HelpItem, SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
FileUpload,
|
||||
Form,
|
||||
FormGroup,
|
||||
Modal,
|
||||
|
@ -16,12 +11,16 @@ import {
|
|||
Text,
|
||||
TextContent,
|
||||
} from "@patternfly/react-core";
|
||||
|
||||
import type KeyStoreConfig from "@keycloak/keycloak-admin-client/lib/defs/keystoreConfig";
|
||||
import { HelpItem, SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { StoreSettings } from "./StoreSettings";
|
||||
import { FileUpload } from "../../components/json-file-upload/patternfly/FileUpload";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Controller,
|
||||
FormProvider,
|
||||
useForm,
|
||||
useFormContext,
|
||||
} from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
||||
import { StoreSettings } from "./StoreSettings";
|
||||
|
||||
type GenerateKeyDialogProps = {
|
||||
clientId: string;
|
||||
|
@ -100,10 +99,10 @@ export const KeyForm = ({
|
|||
value={field.value}
|
||||
filename={filename}
|
||||
browseButtonText={t("browse")}
|
||||
onChange={(value, filename) => {
|
||||
setFilename(filename);
|
||||
onTextChange={(value) => {
|
||||
field.onChange(value);
|
||||
}}
|
||||
onFileInputChange={(_, file) => setFilename(file.name)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
FileUpload,
|
||||
Form,
|
||||
FormGroup,
|
||||
Modal,
|
||||
|
@ -10,8 +12,6 @@ import {
|
|||
} from "@patternfly/react-core";
|
||||
import { Controller, FormProvider, useForm, useWatch } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { SelectControl } from "@keycloak/keycloak-ui-shared";
|
||||
import { FileUpload } from "../../components/json-file-upload/patternfly/FileUpload";
|
||||
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
||||
import { StoreSettings } from "./StoreSettings";
|
||||
|
||||
|
@ -107,8 +107,11 @@ export const ImportKeyDialog = ({
|
|||
id="importFile"
|
||||
value={field.value.value}
|
||||
filename={field.value.filename}
|
||||
onChange={(value, filename) =>
|
||||
field.onChange({ value, filename })
|
||||
onTextChange={(value) =>
|
||||
field.onChange({ ...field.value, value })
|
||||
}
|
||||
onFileInputChange={(_, file) =>
|
||||
field.onChange({ ...field.value, filename: file.name })
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import { FormGroup } from "@patternfly/react-core";
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
import { FileUpload, FormGroup } from "@patternfly/react-core";
|
||||
import { useState } from "react";
|
||||
import { Controller, useFormContext } from "react-hook-form";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HelpItem } from "@keycloak/keycloak-ui-shared";
|
||||
import { FileUpload } from "../json-file-upload/patternfly/FileUpload";
|
||||
import type { ComponentProps } from "./components";
|
||||
import { convertToName } from "./DynamicComponents";
|
||||
|
||||
|
@ -48,9 +46,8 @@ export const FileComponent = ({
|
|||
}}
|
||||
isLoading={isLoading}
|
||||
allowEditingUploadedText={false}
|
||||
onChange={(value, filename) => {
|
||||
onTextChange={(value) => {
|
||||
field.onChange(value);
|
||||
setFilename(filename);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { CodeEditor, Language } from "@patternfly/react-code-editor";
|
||||
import {
|
||||
Button,
|
||||
DropEvent,
|
||||
FileUpload,
|
||||
FileUploadProps,
|
||||
FormGroup,
|
||||
FormHelperText,
|
||||
HelperText,
|
||||
|
@ -14,9 +17,7 @@ import {
|
|||
MouseEvent as ReactMouseEvent,
|
||||
useState,
|
||||
} from "react";
|
||||
import { DropEvent } from "react-dropzone";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FileUpload, FileUploadProps } from "./patternfly/FileUpload";
|
||||
|
||||
type FileUploadType = {
|
||||
value: string;
|
||||
|
@ -112,8 +113,8 @@ export const FileUploadForm = ({
|
|||
value={fileUpload.value}
|
||||
filename={fileUpload.filename}
|
||||
onFileInputChange={handleFileInputChange}
|
||||
onDataChange={handleTextOrDataChange}
|
||||
onTextChange={handleTextOrDataChange}
|
||||
onDataChange={(_, value) => handleTextOrDataChange(value)}
|
||||
onTextChange={(_, value) => handleTextOrDataChange(value)}
|
||||
onClearClick={handleClear}
|
||||
onReadStarted={() =>
|
||||
setFileUpload({ ...fileUpload, isLoading: true })
|
||||
|
@ -137,8 +138,8 @@ export const FileUploadForm = ({
|
|||
value={fileUpload.value}
|
||||
filename={fileUpload.filename}
|
||||
onFileInputChange={handleFileInputChange}
|
||||
onDataChange={handleTextOrDataChange}
|
||||
onTextChange={handleTextOrDataChange}
|
||||
onDataChange={(_, value) => handleTextOrDataChange(value)}
|
||||
onTextChange={(_, value) => handleTextOrDataChange(value)}
|
||||
onClearClick={handleClear}
|
||||
onReadStarted={() =>
|
||||
setFileUpload({ ...fileUpload, isLoading: true })
|
||||
|
|
|
@ -1,224 +0,0 @@
|
|||
import { fromEvent } from "file-selector";
|
||||
import { PropsWithChildren } from "react";
|
||||
import {
|
||||
DropEvent,
|
||||
DropzoneInputProps,
|
||||
DropzoneOptions,
|
||||
FileRejection,
|
||||
useDropzone,
|
||||
} from "react-dropzone";
|
||||
|
||||
import { FileUploadField, FileUploadFieldProps } from "./FileUploadField";
|
||||
import { fileReaderType, readFile } from "./fileUtils";
|
||||
|
||||
export interface FileUploadProps
|
||||
extends Omit<
|
||||
FileUploadFieldProps,
|
||||
| "children"
|
||||
| "onBrowseButtonClick"
|
||||
| "onClearButtonClick"
|
||||
| "isDragActive"
|
||||
| "containerRef"
|
||||
> {
|
||||
/** Unique id for the TextArea, also used to generate ids for accessible labels. */
|
||||
id: string;
|
||||
/** What type of file. Determines what is is passed to `onChange` and expected by `value`
|
||||
* (a string for 'text' and 'dataURL', or a File object otherwise. */
|
||||
type?: "text" | "dataURL";
|
||||
/** Value of the file's contents
|
||||
* (string if text file, File object otherwise) */
|
||||
value?: string | File;
|
||||
/** Value to be shown in the read-only filename field. */
|
||||
filename?: string;
|
||||
/** @deprecated A callback for when the file contents change. Please instead use onFileInputChange, onTextChange, onDataChange, onClearClick individually. */
|
||||
onChange?: (
|
||||
value: string | File,
|
||||
filename: string,
|
||||
event:
|
||||
| React.MouseEvent<HTMLButtonElement, MouseEvent> // Clear button was clicked
|
||||
| React.ChangeEvent<HTMLElement> // User typed in the TextArea
|
||||
| DropEvent,
|
||||
) => void;
|
||||
/** Change event emitted from the hidden \<input type="file" \> field associated with the component */
|
||||
onFileInputChange?: (event: DropEvent, file: File) => void;
|
||||
/** Callback for clicking on the FileUploadField text area. By default, prevents a click in the text area from opening file dialog. */
|
||||
onClick?: (event: React.MouseEvent) => void;
|
||||
/** Additional classes added to the FileUpload container element. */
|
||||
className?: string;
|
||||
/** Flag to show if the field is disabled. */
|
||||
isDisabled?: boolean;
|
||||
/** Flag to show if the field is read only. */
|
||||
isReadOnly?: boolean;
|
||||
/** Flag to show if a file is being loaded. */
|
||||
isLoading?: boolean;
|
||||
/** Aria-valuetext for the loading spinner */
|
||||
spinnerAriaValueText?: string;
|
||||
/** Flag to show if the field is required. */
|
||||
isRequired?: boolean;
|
||||
/** Value to indicate if the field is modified to show that validation state.
|
||||
* If set to success, field will be modified to indicate valid state.
|
||||
* If set to error, field will be modified to indicate error state.
|
||||
*/
|
||||
validated?: "success" | "error" | "default";
|
||||
/** Aria-label for the TextArea. */
|
||||
"aria-label"?: string;
|
||||
/** Placeholder string to display in the empty filename field */
|
||||
filenamePlaceholder?: string;
|
||||
/** Aria-label for the read-only filename field */
|
||||
filenameAriaLabel?: string;
|
||||
/** Text for the Browse button */
|
||||
browseButtonText?: string;
|
||||
/** Text for the Clear button */
|
||||
clearButtonText?: string;
|
||||
/** Flag to hide the built-in preview of the file (where available).
|
||||
* If true, you can use children to render an alternate preview. */
|
||||
hideDefaultPreview?: boolean;
|
||||
/** Flag to allow editing of a text file's contents after it is selected from disk */
|
||||
allowEditingUploadedText?: boolean;
|
||||
/** Additional children to render after (or instead of) the file preview. */
|
||||
children?: React.ReactNode;
|
||||
|
||||
// Props available in FileUpload but not FileUploadField:
|
||||
|
||||
/** A callback for when a selected file starts loading */
|
||||
onReadStarted?: (fileHandle: File) => void;
|
||||
/** A callback for when a selected file finishes loading */
|
||||
onReadFinished?: (fileHandle: File) => void;
|
||||
/** A callback for when the FileReader API fails */
|
||||
onReadFailed?: (error: DOMException, fileHandle: File) => void;
|
||||
/** Optional extra props to customize react-dropzone. */
|
||||
dropzoneProps?: DropzoneOptions;
|
||||
/** Clear button was clicked */
|
||||
onClearClick?: React.MouseEventHandler<HTMLButtonElement>;
|
||||
/** Text area text changed */
|
||||
onTextChange?: (text: string) => void;
|
||||
/** On data changed - if type='text' or type='dataURL' and file was loaded it will call this method */
|
||||
onDataChange?: (data: string) => void;
|
||||
}
|
||||
|
||||
export const FileUpload = ({
|
||||
id,
|
||||
type,
|
||||
value = type === fileReaderType.text || type === fileReaderType.dataURL
|
||||
? ""
|
||||
: undefined,
|
||||
filename = "",
|
||||
children = null,
|
||||
// TODO: This should be removed as part of https://github.com/keycloak/keycloak/issues/32420
|
||||
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
||||
onChange,
|
||||
onFileInputChange,
|
||||
onReadStarted,
|
||||
onReadFinished,
|
||||
onReadFailed,
|
||||
onClearClick,
|
||||
onClick = (event) => event.preventDefault(),
|
||||
onTextChange,
|
||||
onDataChange,
|
||||
dropzoneProps = {},
|
||||
...props
|
||||
}: PropsWithChildren<FileUploadProps>) => {
|
||||
const onDropAccepted = (acceptedFiles: File[], event: DropEvent) => {
|
||||
if (acceptedFiles.length > 0) {
|
||||
const fileHandle = acceptedFiles[0];
|
||||
|
||||
if (event?.type === "drop") {
|
||||
onFileInputChange?.(event, fileHandle);
|
||||
}
|
||||
if (type === fileReaderType.text || type === fileReaderType.dataURL) {
|
||||
onChange?.("", fileHandle.name, event); // Show the filename while reading
|
||||
onReadStarted?.(fileHandle);
|
||||
readFile(fileHandle, type as fileReaderType)
|
||||
.then((data) => {
|
||||
onReadFinished?.(fileHandle);
|
||||
onChange?.(data as string, fileHandle.name, event);
|
||||
onDataChange?.(data as string);
|
||||
})
|
||||
.catch((error: DOMException) => {
|
||||
onReadFailed?.(error, fileHandle);
|
||||
onReadFinished?.(fileHandle);
|
||||
onChange?.("", "", event); // Clear the filename field on a failure
|
||||
onDataChange?.("");
|
||||
});
|
||||
} else {
|
||||
onChange?.(fileHandle, fileHandle.name, event);
|
||||
}
|
||||
}
|
||||
dropzoneProps.onDropAccepted?.(acceptedFiles, event);
|
||||
};
|
||||
|
||||
const onDropRejected = (rejectedFiles: FileRejection[], event: DropEvent) => {
|
||||
if (rejectedFiles.length > 0) {
|
||||
onChange?.("", rejectedFiles[0].file.name, event);
|
||||
}
|
||||
|
||||
dropzoneProps.onDropRejected?.(rejectedFiles, event);
|
||||
};
|
||||
|
||||
const onClearButtonClick = (
|
||||
event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
|
||||
) => {
|
||||
onChange?.("", "", event);
|
||||
onClearClick?.(event);
|
||||
setFileValue("");
|
||||
};
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive, open, inputRef } =
|
||||
useDropzone({
|
||||
multiple: false,
|
||||
...dropzoneProps,
|
||||
onDropAccepted,
|
||||
onDropRejected,
|
||||
});
|
||||
|
||||
const setFileValue = (filename: string) => {
|
||||
if (!inputRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
inputRef.current.value = filename;
|
||||
};
|
||||
|
||||
const oldInputProps = getInputProps();
|
||||
const inputProps: DropzoneInputProps = {
|
||||
...oldInputProps,
|
||||
onChange: async (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
oldInputProps.onChange?.(e);
|
||||
const files = await fromEvent(e.nativeEvent);
|
||||
if (files.length === 1) {
|
||||
onFileInputChange?.(e, files[0] as File);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<FileUploadField
|
||||
{...getRootProps({
|
||||
...props,
|
||||
refKey: "containerRef",
|
||||
onClick: (event) => event.preventDefault(),
|
||||
})}
|
||||
tabIndex={undefined} // Omit the unwanted tabIndex from react-dropzone's getRootProps
|
||||
id={id}
|
||||
type={type}
|
||||
filename={filename}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
isDragActive={isDragActive}
|
||||
onBrowseButtonClick={open}
|
||||
onClearButtonClick={onClearButtonClick}
|
||||
onTextAreaClick={onClick}
|
||||
onTextChange={onTextChange}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<input
|
||||
/* hidden, necessary for react-dropzone */
|
||||
{...inputProps}
|
||||
ref={inputRef}
|
||||
/>
|
||||
{children}
|
||||
</FileUploadField>
|
||||
);
|
||||
};
|
||||
|
||||
FileUpload.displayName = "FileUpload";
|
|
@ -1,213 +0,0 @@
|
|||
import {
|
||||
Button,
|
||||
ButtonVariant,
|
||||
InputGroup,
|
||||
Spinner,
|
||||
spinnerSize,
|
||||
TextArea,
|
||||
TextAreResizeOrientation,
|
||||
TextInput,
|
||||
InputGroupItem,
|
||||
} from "@patternfly/react-core";
|
||||
import { css } from "@patternfly/react-styles";
|
||||
import styles from "@patternfly/react-styles/css/components/FileUpload/file-upload";
|
||||
import { PropsWithChildren } from "react";
|
||||
|
||||
import { fileReaderType } from "./fileUtils";
|
||||
|
||||
export interface FileUploadFieldProps
|
||||
extends Omit<React.HTMLProps<HTMLDivElement>, "value" | "onChange"> {
|
||||
/** Unique id for the TextArea, also used to generate ids for accessible labels */
|
||||
id: string;
|
||||
/** What type of file. Determines what is is expected by `value`
|
||||
* (a string for 'text' and 'dataURL', or a File object otherwise). */
|
||||
type?: "text" | "dataURL";
|
||||
/** Value of the file's contents
|
||||
* (string if text file, File object otherwise) */
|
||||
value?: string | File;
|
||||
/** Value to be shown in the read-only filename field. */
|
||||
filename?: string;
|
||||
/** A callback for when the TextArea value changes. */
|
||||
onChange?: (
|
||||
value: string,
|
||||
filename: string,
|
||||
event:
|
||||
| React.ChangeEvent<HTMLTextAreaElement> // User typed in the TextArea
|
||||
| React.MouseEvent<HTMLButtonElement, MouseEvent>, // User clicked Clear button
|
||||
) => void;
|
||||
/** Additional classes added to the FileUploadField container element. */
|
||||
className?: string;
|
||||
/** Flag to show if the field is disabled. */
|
||||
isDisabled?: boolean;
|
||||
/** Flag to show if the field is read only. */
|
||||
isReadOnly?: boolean;
|
||||
/** Flag to show if a file is being loaded. */
|
||||
isLoading?: boolean;
|
||||
/** Aria-valuetext for the loading spinner */
|
||||
spinnerAriaValueText?: string;
|
||||
/** Flag to show if the field is required. */
|
||||
isRequired?: boolean;
|
||||
/** Value to indicate if the field is modified to show that validation state.
|
||||
* If set to success, field will be modified to indicate valid state.
|
||||
* If set to error, field will be modified to indicate error state.
|
||||
*/
|
||||
validated?: "success" | "error" | "default";
|
||||
/** Aria-label for the TextArea. */
|
||||
"aria-label"?: string;
|
||||
/** Placeholder string to display in the empty filename field */
|
||||
filenamePlaceholder?: string;
|
||||
/** Aria-label for the read-only filename field */
|
||||
filenameAriaLabel?: string;
|
||||
/** Text for the Browse button */
|
||||
browseButtonText?: string;
|
||||
/** Text for the Clear button */
|
||||
clearButtonText?: string;
|
||||
/** Flag to disable the Clear button */
|
||||
isClearButtonDisabled?: boolean;
|
||||
/** Flag to hide the built-in preview of the file (where available).
|
||||
* If true, you can use children to render an alternate preview. */
|
||||
hideDefaultPreview?: boolean;
|
||||
/** Flag to allow editing of a text file's contents after it is selected from disk */
|
||||
allowEditingUploadedText?: boolean;
|
||||
/** Additional children to render after (or instead of) the file preview. */
|
||||
children?: React.ReactNode;
|
||||
|
||||
// Props available in FileUploadField but not FileUpload:
|
||||
|
||||
/** A callback for when the Browse button is clicked. */
|
||||
onBrowseButtonClick?: (
|
||||
event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
|
||||
) => void;
|
||||
/** A callback for when the Clear button is clicked. */
|
||||
onClearButtonClick?: (
|
||||
event: React.MouseEvent<HTMLButtonElement, MouseEvent>,
|
||||
) => void;
|
||||
/** A callback from when the text area is clicked. Can also be set via the onClick property of FileUpload. */
|
||||
onTextAreaClick?: (
|
||||
event: React.MouseEvent<HTMLTextAreaElement, MouseEvent>,
|
||||
) => void;
|
||||
/** Flag to show if a file is being dragged over the field */
|
||||
isDragActive?: boolean;
|
||||
/** A reference object to attach to the FileUploadField container element. */
|
||||
containerRef?: React.Ref<HTMLDivElement>;
|
||||
/** Text area text changed */
|
||||
onTextChange?: (text: string) => void;
|
||||
}
|
||||
|
||||
export const FileUploadField = ({
|
||||
id,
|
||||
type,
|
||||
value = "",
|
||||
filename = "",
|
||||
onChange,
|
||||
onBrowseButtonClick,
|
||||
onClearButtonClick,
|
||||
onTextAreaClick,
|
||||
onTextChange,
|
||||
className = "",
|
||||
isDisabled = false,
|
||||
isReadOnly = false,
|
||||
isLoading = false,
|
||||
spinnerAriaValueText,
|
||||
isRequired = false,
|
||||
isDragActive = false,
|
||||
validated = "default" as "success" | "error" | "default",
|
||||
"aria-label": ariaLabel = "File upload",
|
||||
filenamePlaceholder = "Drag a file here or browse to upload",
|
||||
filenameAriaLabel = filename ? "Read only filename" : filenamePlaceholder,
|
||||
browseButtonText = "Browse...",
|
||||
clearButtonText = "Clear",
|
||||
isClearButtonDisabled = !filename && !value,
|
||||
containerRef = null as React.Ref<HTMLDivElement>,
|
||||
allowEditingUploadedText = false,
|
||||
hideDefaultPreview = false,
|
||||
children = null,
|
||||
|
||||
...props
|
||||
}: PropsWithChildren<FileUploadFieldProps>) => {
|
||||
const onTextAreaChange = (
|
||||
newValue: string,
|
||||
event: React.ChangeEvent<HTMLTextAreaElement>,
|
||||
) => {
|
||||
onChange?.(newValue, filename, event);
|
||||
onTextChange?.(newValue);
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={css(
|
||||
styles.fileUpload,
|
||||
isDragActive && styles.modifiers.dragHover,
|
||||
isLoading && styles.modifiers.loading,
|
||||
className,
|
||||
)}
|
||||
ref={containerRef}
|
||||
{...props}
|
||||
>
|
||||
<div className={styles.fileUploadFileSelect}>
|
||||
<InputGroup>
|
||||
<InputGroupItem isFill>
|
||||
<TextInput
|
||||
// Always read-only regardless of isReadOnly prop (which is just for the TextArea)
|
||||
isDisabled={isDisabled}
|
||||
id={`${id}-filename`}
|
||||
name={`${id}-filename`}
|
||||
aria-label={filenameAriaLabel}
|
||||
placeholder={filenamePlaceholder}
|
||||
aria-describedby={`${id}-browse-button`}
|
||||
value={filename}
|
||||
readOnlyVariant="default"
|
||||
/>
|
||||
</InputGroupItem>
|
||||
<InputGroupItem>
|
||||
<Button
|
||||
id={`${id}-browse-button`}
|
||||
variant={ButtonVariant.control}
|
||||
onClick={onBrowseButtonClick}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
{browseButtonText}
|
||||
</Button>
|
||||
</InputGroupItem>
|
||||
<InputGroupItem>
|
||||
<Button
|
||||
variant={ButtonVariant.control}
|
||||
isDisabled={isDisabled || isClearButtonDisabled}
|
||||
onClick={onClearButtonClick}
|
||||
>
|
||||
{clearButtonText}
|
||||
</Button>
|
||||
</InputGroupItem>
|
||||
</InputGroup>
|
||||
</div>
|
||||
<div className={styles.fileUploadFileDetails}>
|
||||
{!hideDefaultPreview && type === fileReaderType.text && (
|
||||
<TextArea
|
||||
readOnly={isReadOnly || (!!filename && !allowEditingUploadedText)}
|
||||
disabled={isDisabled}
|
||||
isRequired={isRequired}
|
||||
resizeOrientation={TextAreResizeOrientation.vertical}
|
||||
validated={validated}
|
||||
id={id}
|
||||
name={id}
|
||||
aria-label={ariaLabel}
|
||||
value={value as string}
|
||||
onChange={(event, newValue: string) =>
|
||||
onTextAreaChange(newValue, event)
|
||||
}
|
||||
onClick={onTextAreaClick}
|
||||
/>
|
||||
)}
|
||||
{isLoading && (
|
||||
<div className={styles.fileUploadFileDetailsSpinner}>
|
||||
<Spinner
|
||||
size={spinnerSize.lg}
|
||||
aria-valuetext={spinnerAriaValueText}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
FileUploadField.displayName = "FileUploadField";
|
|
@ -1,31 +0,0 @@
|
|||
export enum fileReaderType {
|
||||
text = "text",
|
||||
dataURL = "dataURL",
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file using the FileReader API, either as a plain text string or as a DataURL string.
|
||||
* Returns a promise which will resolve with the file contents as a string or reject with a DOMException.
|
||||
*
|
||||
* @param {File} fileHandle - File object to read
|
||||
* @param {fileReaderType} type - How to read it
|
||||
*/
|
||||
export function readFile(fileHandle: File, type: fileReaderType) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = () => resolve(reader.result);
|
||||
reader.onerror = () => reject(reader.error);
|
||||
|
||||
switch (type) {
|
||||
case fileReaderType.text:
|
||||
reader.readAsText(fileHandle);
|
||||
break;
|
||||
case fileReaderType.dataURL:
|
||||
reader.readAsDataURL(fileHandle);
|
||||
break;
|
||||
default:
|
||||
reject("unknown type");
|
||||
}
|
||||
});
|
||||
}
|
|
@ -180,9 +180,6 @@ importers:
|
|||
file-saver:
|
||||
specifier: ^2.0.5
|
||||
version: 2.0.5
|
||||
file-selector:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
flat:
|
||||
specifier: ^6.0.1
|
||||
version: 6.0.1
|
||||
|
@ -210,9 +207,6 @@ importers:
|
|||
react-dom:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1(react@18.3.1)
|
||||
react-dropzone:
|
||||
specifier: ^14.2.10
|
||||
version: 14.2.10(react@18.3.1)
|
||||
react-hook-form:
|
||||
specifier: ^7.53.1
|
||||
version: 7.53.1(react@18.3.1)
|
||||
|
@ -2822,10 +2816,6 @@ packages:
|
|||
resolution: {integrity: sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
file-selector@1.1.0:
|
||||
resolution: {integrity: sha512-242AM3EcVCRwKFqAHOVxuo93MnXnINrWR3tgEllLvBV3KhL2cWynQSReigbCwLNOkBaD5oyMeDCfXuSq1PlUzw==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
filing-cabinet@5.0.2:
|
||||
resolution: {integrity: sha512-RZlFj8lzyu6jqtFBeXNqUjjNG6xm+gwXue3T70pRxw1W40kJwlgq0PSWAmh0nAnn5DHuBIecLXk9+1VKS9ICXA==}
|
||||
engines: {node: '>=18'}
|
||||
|
@ -5470,7 +5460,6 @@ snapshots:
|
|||
'@patternfly/react-table': 5.4.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
dagre: 0.8.5
|
||||
file-saver: 2.0.5
|
||||
file-selector: 1.1.0
|
||||
flat: 6.0.1
|
||||
i18next: 23.16.3
|
||||
i18next-http-backend: 2.6.2
|
||||
|
@ -5480,7 +5469,6 @@ snapshots:
|
|||
p-debounce: 4.0.0
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
react-dropzone: 14.2.10(react@18.3.1)
|
||||
react-hook-form: 7.53.1(react@18.3.1)
|
||||
react-i18next: 15.1.0(i18next@23.16.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react-router-dom: 6.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
|
@ -7594,10 +7582,6 @@ snapshots:
|
|||
dependencies:
|
||||
tslib: 2.8.0
|
||||
|
||||
file-selector@1.1.0:
|
||||
dependencies:
|
||||
tslib: 2.8.0
|
||||
|
||||
filing-cabinet@5.0.2:
|
||||
dependencies:
|
||||
app-module-path: 2.2.0
|
||||
|
|
Loading…
Reference in a new issue