File handling cleanup (#3240)

* fix google sites connector

* minior cleanup

* rm comments
This commit is contained in:
pablodanswer 2024-11-24 20:06:47 -08:00 committed by GitHub
parent c32b93fcc3
commit b625ee32a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 45 additions and 53 deletions

View File

@ -115,7 +115,6 @@ export default function AddConnector({
// State for managing credentials and files // State for managing credentials and files
const [currentCredential, setCurrentCredential] = const [currentCredential, setCurrentCredential] =
useState<Credential<any> | null>(null); useState<Credential<any> | null>(null);
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
const [createConnectorToggle, setCreateConnectorToggle] = useState(false); const [createConnectorToggle, setCreateConnectorToggle] = useState(false);
// Fetch credentials data // Fetch credentials data
@ -258,6 +257,13 @@ export default function AddConnector({
refreshFreq: (refreshFreq ?? defaultRefreshFreqMinutes) * 60, refreshFreq: (refreshFreq ?? defaultRefreshFreqMinutes) * 60,
}; };
// File-specific handling
const selectedFiles = Array.isArray(values.file_locations)
? values.file_locations
: values.file_locations
? [values.file_locations]
: [];
// Google sites-specific handling // Google sites-specific handling
if (connector == "google_sites") { if (connector == "google_sites") {
const response = await submitGoogleSite( const response = await submitGoogleSite(
@ -276,13 +282,11 @@ export default function AddConnector({
} }
return; return;
} }
// File-specific handling // File-specific handling
if (connector == "file" && selectedFiles.length > 0) { if (connector == "file") {
const response = await submitFiles( const response = await submitFiles(
selectedFiles, selectedFiles,
setPopup, setPopup,
setSelectedFiles,
name, name,
access_type, access_type,
groups groups
@ -427,8 +431,6 @@ export default function AddConnector({
<DynamicConnectionForm <DynamicConnectionForm
values={formikProps.values} values={formikProps.values}
config={configuration} config={configuration}
setSelectedFiles={setSelectedFiles}
selectedFiles={selectedFiles}
connector={connector} connector={connector}
currentCredential={ currentCredential={
currentCredential || currentCredential ||

View File

@ -7,6 +7,7 @@ interface FileInputProps {
label: string; label: string;
optional?: boolean; optional?: boolean;
description?: string; description?: string;
isZip?: boolean;
} }
export default function FileInput({ export default function FileInput({
@ -14,6 +15,7 @@ export default function FileInput({
label, label,
optional = false, optional = false,
description, description,
isZip = false, // Default to false for multiple file uploads
}: FileInputProps) { }: FileInputProps) {
const [field, meta, helpers] = useField(name); const [field, meta, helpers] = useField(name);
@ -28,10 +30,22 @@ export default function FileInput({
</label> </label>
{description && <CredentialSubText>{description}</CredentialSubText>} {description && <CredentialSubText>{description}</CredentialSubText>}
<FileUpload <FileUpload
selectedFiles={field.value ? [field.value] : []} selectedFiles={
Array.isArray(field.value)
? field.value
: field.value
? [field.value]
: []
}
setSelectedFiles={(files: File[]) => { setSelectedFiles={(files: File[]) => {
helpers.setValue(files[0] || null); if (isZip) {
helpers.setValue(files[0] || null);
} else {
helpers.setValue(files);
}
}} }}
multiple={!isZip} // Allow multiple files if not a zip
accept={isZip ? ".zip" : undefined} // Only accept zip files if isZip is true
/> />
{meta.touched && meta.error && ( {meta.touched && meta.error && (
<div className="text-red-500 text-sm mt-1">{meta.error}</div> <div className="text-red-500 text-sm mt-1">{meta.error}</div>

View File

@ -11,8 +11,6 @@ import { RenderField } from "./FieldRendering";
export interface DynamicConnectionFormProps { export interface DynamicConnectionFormProps {
config: ConnectionConfiguration; config: ConnectionConfiguration;
selectedFiles: File[];
setSelectedFiles: Dispatch<SetStateAction<File[]>>;
values: any; values: any;
connector: ConfigurableSources; connector: ConfigurableSources;
currentCredential: Credential<any> | null; currentCredential: Credential<any> | null;
@ -20,8 +18,6 @@ export interface DynamicConnectionFormProps {
const DynamicConnectionForm: FC<DynamicConnectionFormProps> = ({ const DynamicConnectionForm: FC<DynamicConnectionFormProps> = ({
config, config,
selectedFiles,
setSelectedFiles,
values, values,
connector, connector,
currentCredential, currentCredential,
@ -48,8 +44,6 @@ const DynamicConnectionForm: FC<DynamicConnectionFormProps> = ({
key={field.name} key={field.name}
field={field} field={field}
values={values} values={values}
selectedFiles={selectedFiles}
setSelectedFiles={setSelectedFiles}
connector={connector} connector={connector}
currentCredential={currentCredential} currentCredential={currentCredential}
/> />
@ -73,8 +67,6 @@ const DynamicConnectionForm: FC<DynamicConnectionFormProps> = ({
key={field.name} key={field.name}
field={field} field={field}
values={values} values={values}
selectedFiles={selectedFiles}
setSelectedFiles={setSelectedFiles}
connector={connector} connector={connector}
currentCredential={currentCredential} currentCredential={currentCredential}
/> />

View File

@ -20,8 +20,6 @@ import {
interface TabsFieldProps { interface TabsFieldProps {
tabField: TabOption; tabField: TabOption;
values: any; values: any;
selectedFiles: File[];
setSelectedFiles: Dispatch<SetStateAction<File[]>>;
connector: ConfigurableSources; connector: ConfigurableSources;
currentCredential: Credential<any> | null; currentCredential: Credential<any> | null;
} }
@ -29,8 +27,6 @@ interface TabsFieldProps {
const TabsField: FC<TabsFieldProps> = ({ const TabsField: FC<TabsFieldProps> = ({
tabField, tabField,
values, values,
selectedFiles,
setSelectedFiles,
connector, connector,
currentCredential, currentCredential,
}) => { }) => {
@ -101,8 +97,6 @@ const TabsField: FC<TabsFieldProps> = ({
key={subField.name} key={subField.name}
field={subField} field={subField}
values={values} values={values}
selectedFiles={selectedFiles}
setSelectedFiles={setSelectedFiles}
connector={connector} connector={connector}
currentCredential={currentCredential} currentCredential={currentCredential}
/> />
@ -119,8 +113,6 @@ const TabsField: FC<TabsFieldProps> = ({
interface RenderFieldProps { interface RenderFieldProps {
field: any; field: any;
values: any; values: any;
selectedFiles: File[];
setSelectedFiles: Dispatch<SetStateAction<File[]>>;
connector: ConfigurableSources; connector: ConfigurableSources;
currentCredential: Credential<any> | null; currentCredential: Credential<any> | null;
} }
@ -128,8 +120,6 @@ interface RenderFieldProps {
export const RenderField: FC<RenderFieldProps> = ({ export const RenderField: FC<RenderFieldProps> = ({
field, field,
values, values,
selectedFiles,
setSelectedFiles,
connector, connector,
currentCredential, currentCredential,
}) => { }) => {
@ -147,8 +137,6 @@ export const RenderField: FC<RenderFieldProps> = ({
<TabsField <TabsField
tabField={field} tabField={field}
values={values} values={values}
selectedFiles={selectedFiles}
setSelectedFiles={setSelectedFiles}
connector={connector} connector={connector}
currentCredential={currentCredential} currentCredential={currentCredential}
/> />
@ -157,15 +145,10 @@ export const RenderField: FC<RenderFieldProps> = ({
const fieldContent = ( const fieldContent = (
<> <>
{field.type === "file" ? ( {field.type === "zip" || field.type === "file" ? (
<FileUpload
name={field.name}
selectedFiles={selectedFiles}
setSelectedFiles={setSelectedFiles}
/>
) : field.type === "zip" ? (
<FileInput <FileInput
name={field.name} name={field.name}
isZip={field.type === "zip"}
label={label} label={label}
optional={field.optional} optional={field.optional}
description={description} description={description}

View File

@ -7,7 +7,6 @@ import { AccessType } from "@/lib/types";
export const submitFiles = async ( export const submitFiles = async (
selectedFiles: File[], selectedFiles: File[],
setPopup: (popup: PopupSpec) => void, setPopup: (popup: PopupSpec) => void,
setSelectedFiles: (files: File[]) => void,
name: string, name: string,
access_type: string, access_type: string,
groups?: number[] groups?: number[]
@ -102,7 +101,6 @@ export const submitFiles = async (
return false; return false;
} }
setSelectedFiles([]);
setPopup({ setPopup({
type: "success", type: "success",
message: "Successfully uploaded files!", message: "Successfully uploaded files!",

View File

@ -8,6 +8,8 @@ interface FileUploadProps {
setSelectedFiles: (files: File[]) => void; setSelectedFiles: (files: File[]) => void;
message?: string; message?: string;
name?: string; name?: string;
multiple?: boolean;
accept?: string;
} }
export const FileUpload: FC<FileUploadProps> = ({ export const FileUpload: FC<FileUploadProps> = ({
@ -15,6 +17,8 @@ export const FileUpload: FC<FileUploadProps> = ({
selectedFiles, selectedFiles,
setSelectedFiles, setSelectedFiles,
message, message,
multiple = true,
accept,
}) => { }) => {
const [dragActive, setDragActive] = useState(false); const [dragActive, setDragActive] = useState(false);
const { setFieldValue } = useFormikContext(); const { setFieldValue } = useFormikContext();
@ -23,14 +27,17 @@ export const FileUpload: FC<FileUploadProps> = ({
<div> <div>
<Dropzone <Dropzone
onDrop={(acceptedFiles) => { onDrop={(acceptedFiles) => {
setSelectedFiles(acceptedFiles); const filesToSet = multiple ? acceptedFiles : [acceptedFiles[0]];
setSelectedFiles(filesToSet);
setDragActive(false); setDragActive(false);
if (name) { if (name) {
setFieldValue(name, acceptedFiles); setFieldValue(name, multiple ? filesToSet : filesToSet[0]);
} }
}} }}
onDragLeave={() => setDragActive(false)} onDragLeave={() => setDragActive(false)}
onDragEnter={() => setDragActive(true)} onDragEnter={() => setDragActive(true)}
multiple={multiple}
accept={accept ? { [accept]: [] } : undefined}
> >
{({ getRootProps, getInputProps }) => ( {({ getRootProps, getInputProps }) => (
<section> <section>
@ -45,7 +52,9 @@ export const FileUpload: FC<FileUploadProps> = ({
<input {...getInputProps()} /> <input {...getInputProps()} />
<b className="text-emphasis"> <b className="text-emphasis">
{message || {message ||
"Drag and drop some files here, or click to select files"} `Drag and drop ${
multiple ? "some files" : "a file"
} here, or click to select ${multiple ? "files" : "a file"}`}
</b> </b>
</div> </div>
</section> </section>
@ -54,7 +63,9 @@ export const FileUpload: FC<FileUploadProps> = ({
{selectedFiles.length > 0 && ( {selectedFiles.length > 0 && (
<div className="mt-4"> <div className="mt-4">
<h2 className="text-sm font-bold">Selected Files</h2> <h2 className="text-sm font-bold">
Selected File{multiple ? "s" : ""}
</h2>
<ul> <ul>
{selectedFiles.map((file) => ( {selectedFiles.map((file) => (
<div key={file.name} className="flex"> <div key={file.name} className="flex">

View File

@ -6,7 +6,7 @@ import { Credential } from "@/lib/connectors/credentials"; // Import Credential
export function isLoadState(connector_name: string): boolean { export function isLoadState(connector_name: string): boolean {
// TODO: centralize connector metadata like this somewhere instead of hardcoding it here // TODO: centralize connector metadata like this somewhere instead of hardcoding it here
const loadStateConnectors = ["web", "xenforo"]; const loadStateConnectors = ["web", "xenforo", "file"];
if (loadStateConnectors.includes(connector_name)) { if (loadStateConnectors.includes(connector_name)) {
return true; return true;
} }
@ -78,11 +78,6 @@ export interface FileOption extends Option {
default?: string; default?: string;
} }
export interface ZipOption extends Option {
type: "zip";
default?: string;
}
export interface StringTabOption extends Option { export interface StringTabOption extends Option {
type: "string_tab"; type: "string_tab";
default?: string; default?: string;
@ -101,7 +96,6 @@ export interface TabOption extends Option {
| NumberOption | NumberOption
| SelectOption | SelectOption
| FileOption | FileOption
| ZipOption
| StringTabOption | StringTabOption
)[]; )[];
}[]; }[];
@ -118,7 +112,6 @@ export interface ConnectionConfiguration {
| NumberOption | NumberOption
| SelectOption | SelectOption
| FileOption | FileOption
| ZipOption
| TabOption | TabOption
)[]; )[];
advanced_values: ( advanced_values: (
@ -128,7 +121,6 @@ export interface ConnectionConfiguration {
| NumberOption | NumberOption
| SelectOption | SelectOption
| FileOption | FileOption
| ZipOption
| TabOption | TabOption
)[]; )[];
overrideDefaultFreq?: number; overrideDefaultFreq?: number;
@ -750,10 +742,10 @@ For example, specifying .*-support.* as a "channel" will cause the connector to
description: "Configure Google Sites connector", description: "Configure Google Sites connector",
values: [ values: [
{ {
type: "zip", type: "file",
query: "Enter the zip path:", query: "Enter the zip path:",
label: "Zip Path", label: "File Locations",
name: "zip_path", name: "file_locations",
optional: false, optional: false,
description: description:
"Upload a zip file containing the HTML of your Google Site", "Upload a zip file containing the HTML of your Google Site",