mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-16 12:37:20 +00:00
fix media upload without name, add data result to uploaded payload
This commit is contained in:
@@ -220,7 +220,7 @@ export class DataController extends Controller {
|
||||
return c.notFound();
|
||||
}
|
||||
|
||||
const where = c.req.json() as any;
|
||||
const where = (await c.req.json()) as any;
|
||||
const result = await this.em.repository(entity).count(where);
|
||||
return c.json({ entity, count: result.count });
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ export class MediaApi extends ModuleApi<MediaApiOptions> {
|
||||
return (await res.blob()) as File;
|
||||
}
|
||||
|
||||
getFileUploadUrl(file: FileWithPath): string {
|
||||
getFileUploadUrl(file?: FileWithPath): string {
|
||||
if (!file) return this.getUrl("/upload");
|
||||
return this.getUrl(`/upload/${file.path}`);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,4 +10,5 @@ export * from "./api/use-api";
|
||||
export * from "./api/use-entity";
|
||||
export { useAuth } from "./schema/auth/use-auth";
|
||||
export { Api, type TApiUser, type AuthState, type ApiOptions } from "../../Api";
|
||||
export { FetchPromise } from "modules/ModuleApi";
|
||||
export type { RepoQueryIn } from "data";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { DB } from "core";
|
||||
import {
|
||||
type ComponentPropsWithRef,
|
||||
type ComponentPropsWithoutRef,
|
||||
@@ -23,6 +24,8 @@ export type FileState = {
|
||||
progress: number;
|
||||
};
|
||||
|
||||
export type FileStateWithData = FileState & { data: DB["media"] };
|
||||
|
||||
export type DropzoneRenderProps = {
|
||||
wrapperRef: RefObject<HTMLDivElement>;
|
||||
inputProps: ComponentPropsWithRef<"input">;
|
||||
@@ -50,7 +53,7 @@ export type DropzoneProps = {
|
||||
autoUpload?: boolean;
|
||||
onRejected?: (files: FileWithPath[]) => void;
|
||||
onDeleted?: (file: FileState) => void;
|
||||
onUploaded?: (files: FileState[]) => void;
|
||||
onUploaded?: (files: FileStateWithData[]) => void;
|
||||
placeholder?: {
|
||||
show?: boolean;
|
||||
text?: string;
|
||||
@@ -172,15 +175,16 @@ export function Dropzone({
|
||||
setUploading(false);
|
||||
return;
|
||||
} else {
|
||||
const uploaded: FileStateWithData[] = [];
|
||||
for (const file of pendingFiles) {
|
||||
try {
|
||||
await uploadFileProgress(file);
|
||||
uploaded.push(await uploadFileProgress(file));
|
||||
} catch (e) {
|
||||
handleUploadError(e);
|
||||
}
|
||||
}
|
||||
setUploading(false);
|
||||
onUploaded?.(files);
|
||||
onUploaded?.(uploaded);
|
||||
}
|
||||
})();
|
||||
}
|
||||
@@ -220,8 +224,8 @@ export function Dropzone({
|
||||
setFiles((prev) => prev.filter((f) => f.path !== path));
|
||||
}
|
||||
|
||||
function uploadFileProgress(file: FileState) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
function uploadFileProgress(file: FileState): Promise<FileStateWithData> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!file.body) {
|
||||
console.error("File has no body");
|
||||
reject();
|
||||
@@ -279,17 +283,19 @@ export function Dropzone({
|
||||
const response = JSON.parse(xhr.responseText);
|
||||
|
||||
console.log("Response:", file, response);
|
||||
console.log("New state", response.state);
|
||||
replaceFileState(file.path, {
|
||||
const newState = {
|
||||
...response.state,
|
||||
progress: 1,
|
||||
state: "uploaded"
|
||||
});
|
||||
};
|
||||
|
||||
replaceFileState(file.path, newState);
|
||||
resolve({ ...response, ...file, ...newState });
|
||||
} catch (e) {
|
||||
setFileState(file.path, "uploaded", 1);
|
||||
console.error("Error parsing response", e);
|
||||
reject(e);
|
||||
}
|
||||
resolve();
|
||||
} else {
|
||||
setFileState(file.path, "failed", 1);
|
||||
console.error("Upload failed with status: ", xhr.status, xhr.statusText);
|
||||
@@ -327,8 +333,8 @@ export function Dropzone({
|
||||
}
|
||||
|
||||
async function uploadFile(file: FileState) {
|
||||
await uploadFileProgress(file);
|
||||
onUploaded?.([file]);
|
||||
const result = await uploadFileProgress(file);
|
||||
onUploaded?.([result]);
|
||||
}
|
||||
|
||||
const openFileInput = () => inputRef.current?.click();
|
||||
@@ -496,9 +502,9 @@ const Preview: React.FC<PreviewProps> = ({ file, handleUpload, handleDelete }) =
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col px-1.5 py-1">
|
||||
<p className="truncate">{file.name}</p>
|
||||
<p className="truncate select-text">{file.name}</p>
|
||||
<div className="flex flex-row justify-between text-sm font-mono opacity-50 text-nowrap gap-2">
|
||||
<span className="truncate">{file.type}</span>
|
||||
<span className="truncate select-text">{file.type}</span>
|
||||
<span>{(file.size / 1024).toFixed(1)} KB</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ import { mediaItemsToFileStates } from "./helper";
|
||||
|
||||
export type DropzoneContainerProps = {
|
||||
children?: ReactNode;
|
||||
initialItems?: MediaFieldSchema[];
|
||||
initialItems?: MediaFieldSchema[] | false;
|
||||
entity?: {
|
||||
name: string;
|
||||
id: number;
|
||||
@@ -18,6 +18,7 @@ export type DropzoneContainerProps = {
|
||||
};
|
||||
media?: Pick<TAppMediaConfig, "entity_name" | "storage">;
|
||||
query?: RepoQueryIn;
|
||||
randomFilename?: boolean;
|
||||
} & Omit<Partial<DropzoneProps>, "children" | "initialItems">;
|
||||
|
||||
const DropzoneContainerContext = createContext<DropzoneRenderProps>(undefined!);
|
||||
@@ -28,6 +29,7 @@ export function DropzoneContainer({
|
||||
entity,
|
||||
query,
|
||||
children,
|
||||
randomFilename,
|
||||
...props
|
||||
}: DropzoneContainerProps) {
|
||||
const id = useId();
|
||||
@@ -57,12 +59,12 @@ export function DropzoneContainer({
|
||||
...query
|
||||
});
|
||||
|
||||
const $q = useApiQuery(selectApi, { enabled: !initialItems });
|
||||
const $q = useApiQuery(selectApi, { enabled: initialItems !== false && !initialItems });
|
||||
|
||||
const getUploadInfo = useEvent((file) => {
|
||||
const url = entity
|
||||
? api.media.getEntityUploadUrl(entity.name, entity.id, entity.field)
|
||||
: api.media.getFileUploadUrl(file);
|
||||
: api.media.getFileUploadUrl(randomFilename ? undefined : file);
|
||||
|
||||
return {
|
||||
url,
|
||||
@@ -79,7 +81,7 @@ export function DropzoneContainer({
|
||||
return api.media.deleteFile(file.path);
|
||||
});
|
||||
|
||||
const actualItems = initialItems ?? (($q.data || []) as MediaFieldSchema[]);
|
||||
const actualItems = (initialItems || $q.data || []) as MediaFieldSchema[];
|
||||
const _initialItems = mediaItemsToFileStates(actualItems, { baseUrl });
|
||||
|
||||
const key = id + JSON.stringify(_initialItems);
|
||||
|
||||
@@ -12,6 +12,7 @@ export { useDropzone as useMediaDropzone };
|
||||
export type {
|
||||
PreviewComponentProps,
|
||||
FileState,
|
||||
FileStateWithData,
|
||||
DropzoneProps,
|
||||
DropzoneRenderProps
|
||||
} from "./Dropzone";
|
||||
|
||||
Reference in New Issue
Block a user