Merge cc5177edeb28ea1ca84f08b4995e2c4d768c7227 into ee420fbf2946e9f79977615cee5e29192d7da478

This commit is contained in:
Ignaz "Ian" Kraft 2026-05-07 01:31:18 +02:00 committed by GitHub
commit 53670e3289
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 36 additions and 31 deletions

View File

@ -292,7 +292,7 @@ func getBucketCredentials(bucket string) (aws.CredentialsProvider, error) {
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 {
return nil, err
}

View File

@ -18,13 +18,13 @@ type Props = {
};
const Actions = ({ prefix }: Props) => {
const { bucketName } = useBucketContext();
const { bucket } = useBucketContext();
const queryClient = useQueryClient();
const putObject = usePutObject(bucketName, {
const putObject = usePutObject(bucket, {
onSuccess: () => {
toast.success("File uploaded!");
queryClient.invalidateQueries({ queryKey: ["browse", bucketName] });
queryClient.invalidateQueries({ queryKey: ["browse", bucket.id] });
},
onError: handleError,
});
@ -76,7 +76,7 @@ type CreateFolderActionProps = {
const CreateFolderAction = ({ prefix }: CreateFolderActionProps) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const { bucketName } = useBucketContext();
const { bucket } = useBucketContext();
const queryClient = useQueryClient();
const form = useForm<CreateFolderSchema>({
@ -88,10 +88,10 @@ const CreateFolderAction = ({ prefix }: CreateFolderActionProps) => {
if (isOpen) form.setFocus("name");
}, [isOpen]);
const createFolder = usePutObject(bucketName, {
const createFolder = usePutObject(bucket, {
onSuccess: () => {
toast.success("Folder created!");
queryClient.invalidateQueries({ queryKey: ["browse", bucketName] });
queryClient.invalidateQueries({ queryKey: ["browse", bucket.id] });
onClose();
form.reset();
},

View File

@ -4,6 +4,7 @@ import {
UseMutationOptions,
useQuery,
} from "@tanstack/react-query";
import { Bucket } from "../../types";
import {
GetObjectsResult,
PutObjectPayload,
@ -11,18 +12,18 @@ import {
} from "./types";
export const useBrowseObjects = (
bucket: string,
bucket: Bucket,
options?: UseBrowserObjectOptions
) => {
return useQuery({
queryKey: ["browse", bucket, options],
queryKey: ["browse", bucket.id, options],
queryFn: () =>
api.get<GetObjectsResult>(`/browse/${bucket}`, { params: options }),
api.get<GetObjectsResult>(`/browse/${bucket.id}`, { params: options }),
});
};
export const usePutObject = (
bucket: string,
bucket: Bucket,
options?: UseMutationOptions<any, Error, PutObjectPayload>
) => {
return useMutation({
@ -32,19 +33,19 @@ export const usePutObject = (
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,
});
};
export const useDeleteObject = (
bucket: string,
bucket: Bucket,
options?: UseMutationOptions<any, Error, { key: string; recursive?: boolean }>
) => {
return useMutation({
mutationFn: (data) =>
api.delete(`/browse/${bucket}/${data.key}`, {
api.delete(`/browse/${bucket.id}/${data.key}`, {
params: { recursive: data.recursive },
}),
...options,

View File

@ -17,14 +17,14 @@ type Props = {
};
const ObjectActions = ({ prefix = "", object, end }: Props) => {
const { bucketName } = useBucketContext();
const { bucket, bucketName } = useBucketContext();
const queryClient = useQueryClient();
const isDirectory = object.objectKey.endsWith("/");
const deleteObject = useDeleteObject(bucketName, {
const deleteObject = useDeleteObject(bucket, {
onSuccess: () => {
toast.success("Object deleted!");
queryClient.invalidateQueries({ queryKey: ["browse", bucketName] });
queryClient.invalidateQueries({ queryKey: ["browse", bucket.id] });
},
onError: handleError,
});
@ -61,6 +61,7 @@ const ObjectActions = ({ prefix = "", object, end }: Props) => {
</Dropdown.Toggle>
<Dropdown.Menu className="gap-y-1">
{bucketName && (
<Dropdown.Item
onClick={() =>
shareDialog.open({ key: object.objectKey, prefix })
@ -68,6 +69,7 @@ const ObjectActions = ({ prefix = "", object, end }: Props) => {
>
<Share2 /> Share
</Dropdown.Item>
)}
<Dropdown.Item
className="text-error bg-error/10"
onClick={onDelete}

View File

@ -21,8 +21,8 @@ type Props = {
};
const ObjectList = ({ prefix, onPrefixChange }: Props) => {
const { bucketName } = useBucketContext();
const { data, error, isLoading } = useBrowseObjects(bucketName, {
const { bucket } = useBucketContext();
const { data, error, isLoading } = useBrowseObjects(bucket, {
prefix,
limit: 1000,
});

View File

@ -18,7 +18,7 @@ const ShareDialog = () => {
const [domain, setDomain] = useState(bucketName);
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(
() => [

View File

@ -70,7 +70,7 @@ const WebsiteAccessSection = () => {
<ToggleField form={form} name="websiteAccess" label="Enabled" />
{isEnabled && (
{isEnabled && bucketName && (
<>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<InputField

View File

@ -40,7 +40,9 @@ const ManageBucketPage = () => {
const { id } = useParams();
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 (
<>

View File

@ -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;
}, [data, search]);

View File

@ -2,7 +2,7 @@
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,