mirror of
https://github.com/khairul169/garage-webui.git
synced 2026-06-12 13:36:21 +07:00
Merge cc5177edeb28ea1ca84f08b4995e2c4d768c7227 into ee420fbf2946e9f79977615cee5e29192d7da478
This commit is contained in:
commit
53670e3289
@ -292,7 +292,7 @@ func getBucketCredentials(bucket string) (aws.CredentialsProvider, error) {
|
|||||||
return cacheData.(aws.CredentialsProvider), nil
|
return cacheData.(aws.CredentialsProvider), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := utils.Garage.Fetch("/v2/GetBucketInfo?globalAlias="+bucket, &utils.FetchOptions{})
|
body, err := utils.Garage.Fetch("/v2/GetBucketInfo?id="+bucket, &utils.FetchOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,13 +18,13 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const Actions = ({ prefix }: Props) => {
|
const Actions = ({ prefix }: Props) => {
|
||||||
const { bucketName } = useBucketContext();
|
const { bucket } = useBucketContext();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const putObject = usePutObject(bucketName, {
|
const putObject = usePutObject(bucket, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success("File uploaded!");
|
toast.success("File uploaded!");
|
||||||
queryClient.invalidateQueries({ queryKey: ["browse", bucketName] });
|
queryClient.invalidateQueries({ queryKey: ["browse", bucket.id] });
|
||||||
},
|
},
|
||||||
onError: handleError,
|
onError: handleError,
|
||||||
});
|
});
|
||||||
@ -76,7 +76,7 @@ type CreateFolderActionProps = {
|
|||||||
|
|
||||||
const CreateFolderAction = ({ prefix }: CreateFolderActionProps) => {
|
const CreateFolderAction = ({ prefix }: CreateFolderActionProps) => {
|
||||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||||
const { bucketName } = useBucketContext();
|
const { bucket } = useBucketContext();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const form = useForm<CreateFolderSchema>({
|
const form = useForm<CreateFolderSchema>({
|
||||||
@ -88,10 +88,10 @@ const CreateFolderAction = ({ prefix }: CreateFolderActionProps) => {
|
|||||||
if (isOpen) form.setFocus("name");
|
if (isOpen) form.setFocus("name");
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
|
||||||
const createFolder = usePutObject(bucketName, {
|
const createFolder = usePutObject(bucket, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success("Folder created!");
|
toast.success("Folder created!");
|
||||||
queryClient.invalidateQueries({ queryKey: ["browse", bucketName] });
|
queryClient.invalidateQueries({ queryKey: ["browse", bucket.id] });
|
||||||
onClose();
|
onClose();
|
||||||
form.reset();
|
form.reset();
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {
|
|||||||
UseMutationOptions,
|
UseMutationOptions,
|
||||||
useQuery,
|
useQuery,
|
||||||
} from "@tanstack/react-query";
|
} from "@tanstack/react-query";
|
||||||
|
import { Bucket } from "../../types";
|
||||||
import {
|
import {
|
||||||
GetObjectsResult,
|
GetObjectsResult,
|
||||||
PutObjectPayload,
|
PutObjectPayload,
|
||||||
@ -11,18 +12,18 @@ import {
|
|||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const useBrowseObjects = (
|
export const useBrowseObjects = (
|
||||||
bucket: string,
|
bucket: Bucket,
|
||||||
options?: UseBrowserObjectOptions
|
options?: UseBrowserObjectOptions
|
||||||
) => {
|
) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["browse", bucket, options],
|
queryKey: ["browse", bucket.id, options],
|
||||||
queryFn: () =>
|
queryFn: () =>
|
||||||
api.get<GetObjectsResult>(`/browse/${bucket}`, { params: options }),
|
api.get<GetObjectsResult>(`/browse/${bucket.id}`, { params: options }),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePutObject = (
|
export const usePutObject = (
|
||||||
bucket: string,
|
bucket: Bucket,
|
||||||
options?: UseMutationOptions<any, Error, PutObjectPayload>
|
options?: UseMutationOptions<any, Error, PutObjectPayload>
|
||||||
) => {
|
) => {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
@ -32,19 +33,19 @@ export const usePutObject = (
|
|||||||
formData.append("file", body.file);
|
formData.append("file", body.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.put(`/browse/${bucket}/${body.key}`, { body: formData });
|
return api.put(`/browse/${bucket.id}/${body.key}`, { body: formData });
|
||||||
},
|
},
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useDeleteObject = (
|
export const useDeleteObject = (
|
||||||
bucket: string,
|
bucket: Bucket,
|
||||||
options?: UseMutationOptions<any, Error, { key: string; recursive?: boolean }>
|
options?: UseMutationOptions<any, Error, { key: string; recursive?: boolean }>
|
||||||
) => {
|
) => {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: (data) =>
|
mutationFn: (data) =>
|
||||||
api.delete(`/browse/${bucket}/${data.key}`, {
|
api.delete(`/browse/${bucket.id}/${data.key}`, {
|
||||||
params: { recursive: data.recursive },
|
params: { recursive: data.recursive },
|
||||||
}),
|
}),
|
||||||
...options,
|
...options,
|
||||||
|
|||||||
@ -17,14 +17,14 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ObjectActions = ({ prefix = "", object, end }: Props) => {
|
const ObjectActions = ({ prefix = "", object, end }: Props) => {
|
||||||
const { bucketName } = useBucketContext();
|
const { bucket, bucketName } = useBucketContext();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const isDirectory = object.objectKey.endsWith("/");
|
const isDirectory = object.objectKey.endsWith("/");
|
||||||
|
|
||||||
const deleteObject = useDeleteObject(bucketName, {
|
const deleteObject = useDeleteObject(bucket, {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success("Object deleted!");
|
toast.success("Object deleted!");
|
||||||
queryClient.invalidateQueries({ queryKey: ["browse", bucketName] });
|
queryClient.invalidateQueries({ queryKey: ["browse", bucket.id] });
|
||||||
},
|
},
|
||||||
onError: handleError,
|
onError: handleError,
|
||||||
});
|
});
|
||||||
@ -61,13 +61,15 @@ const ObjectActions = ({ prefix = "", object, end }: Props) => {
|
|||||||
</Dropdown.Toggle>
|
</Dropdown.Toggle>
|
||||||
|
|
||||||
<Dropdown.Menu className="gap-y-1">
|
<Dropdown.Menu className="gap-y-1">
|
||||||
<Dropdown.Item
|
{bucketName && (
|
||||||
onClick={() =>
|
<Dropdown.Item
|
||||||
shareDialog.open({ key: object.objectKey, prefix })
|
onClick={() =>
|
||||||
}
|
shareDialog.open({ key: object.objectKey, prefix })
|
||||||
>
|
}
|
||||||
<Share2 /> Share
|
>
|
||||||
</Dropdown.Item>
|
<Share2 /> Share
|
||||||
|
</Dropdown.Item>
|
||||||
|
)}
|
||||||
<Dropdown.Item
|
<Dropdown.Item
|
||||||
className="text-error bg-error/10"
|
className="text-error bg-error/10"
|
||||||
onClick={onDelete}
|
onClick={onDelete}
|
||||||
|
|||||||
@ -21,8 +21,8 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ObjectList = ({ prefix, onPrefixChange }: Props) => {
|
const ObjectList = ({ prefix, onPrefixChange }: Props) => {
|
||||||
const { bucketName } = useBucketContext();
|
const { bucket } = useBucketContext();
|
||||||
const { data, error, isLoading } = useBrowseObjects(bucketName, {
|
const { data, error, isLoading } = useBrowseObjects(bucket, {
|
||||||
prefix,
|
prefix,
|
||||||
limit: 1000,
|
limit: 1000,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -18,7 +18,7 @@ const ShareDialog = () => {
|
|||||||
const [domain, setDomain] = useState(bucketName);
|
const [domain, setDomain] = useState(bucketName);
|
||||||
|
|
||||||
const websitePort = config?.s3_web?.bind_addr?.split(":").pop() || "80";
|
const websitePort = config?.s3_web?.bind_addr?.split(":").pop() || "80";
|
||||||
const rootDomain = config?.s3_web?.root_domain;
|
const rootDomain = config?.s3_web?.root_domain || "";
|
||||||
|
|
||||||
const domains = useMemo(
|
const domains = useMemo(
|
||||||
() => [
|
() => [
|
||||||
|
|||||||
@ -70,7 +70,7 @@ const WebsiteAccessSection = () => {
|
|||||||
|
|
||||||
<ToggleField form={form} name="websiteAccess" label="Enabled" />
|
<ToggleField form={form} name="websiteAccess" label="Enabled" />
|
||||||
|
|
||||||
{isEnabled && (
|
{isEnabled && bucketName && (
|
||||||
<>
|
<>
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<InputField
|
<InputField
|
||||||
|
|||||||
@ -40,7 +40,9 @@ const ManageBucketPage = () => {
|
|||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const { data, error, isLoading, refetch } = useBucket(id);
|
const { data, error, isLoading, refetch } = useBucket(id);
|
||||||
|
|
||||||
const name = data?.globalAliases[0];
|
const name =
|
||||||
|
data?.globalAliases?.at(0) ||
|
||||||
|
data?.keys?.at(0)?.bucketLocalAliases?.at(0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -30,7 +30,7 @@ const BucketsPage = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
buckets = buckets.sort((a, b) => a.aliases[0].localeCompare(b.aliases[0]));
|
buckets = buckets.sort((a, b) => (a.aliases.at(0) || "").localeCompare(b.aliases.at(0) || ""));
|
||||||
|
|
||||||
return buckets;
|
return buckets;
|
||||||
}, [data, search]);
|
}, [data, search]);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user