Skip to content

Commit f87cc7b

Browse files
Upstream sync
Merge upstream main into fork main
2 parents e8acf8b + 2299f9c commit f87cc7b

5 files changed

Lines changed: 43 additions & 8 deletions

File tree

src/components/Topbar/index.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import UserInfo from "@/components/UserInfo";
22
import OscarColors, { OscarStyles } from "@/styles";
3-
import { RefreshCcwIcon } from "lucide-react";
43
import { useEffect } from "react";
54
import { Link, useLocation } from "react-router-dom";
5+
import AnimatedRefreshCw from "../ui/animatedRefreshCw";
66

77
interface GenericTopbarProps {
88
customHeader?: React.ReactNode;
@@ -39,10 +39,7 @@ function GenericTopbar({ customHeader, defaultHeader, refresher, children, secon
3939
<Link to="#"
4040
onClick={() => refresher()}
4141
>
42-
<RefreshCcwIcon size={16}
43-
onMouseEnter={(e) => {e.currentTarget.style.transform = 'rotate(90deg)'}}
44-
onMouseLeave={(e) => {e.currentTarget.style.transform = 'rotate(0deg)'}}
45-
/>
42+
<AnimatedRefreshCw size={16} />
4643
</Link>)
4744
}
4845
</div>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { RefreshCw } from "lucide-react";
2+
import { cn } from "@/lib/utils";
3+
4+
interface AnimatedRefreshCwProps {
5+
size?: number;
6+
className?: string;
7+
}
8+
9+
function AnimatedRefreshCw({ size = 16, className }: AnimatedRefreshCwProps) {
10+
return (
11+
<RefreshCw
12+
size={size}
13+
className={cn("transition-transform duration-500 hover:rotate-180", className)}
14+
/>
15+
);
16+
}
17+
18+
export default AnimatedRefreshCw;

src/contexts/Minio/MinioContext.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export type MinioProviderData = {
7272
createBucket: (bucketName: Bucket_oscar) => Promise<void>;
7373
updateBucketsVisibilityControl: (bucketName: Bucket_oscar) => Promise<void>;
7474
updateBuckets: () => Promise<void>;
75+
refreshBucketItems: boolean;
76+
setRefreshBucketItems: (value: boolean) => void;
7577
getBucketItems: (
7678
bucketName: string,
7779
path: string
@@ -110,6 +112,7 @@ export const MinioProvider = ({ children }: { children: React.ReactNode }) => {
110112
const [bucketsAreLoading, setBucketsAreLoading] = useState<boolean>(false);
111113
const [uploadProgress, setUploadProgress] = useState<UploadBatchProgress | null>(null);
112114
const [bucketsLoadingError, setBucketsLoadingError] = useState<boolean>(false);
115+
const [refreshBucketItems, setRefreshBucketItems] = useState<boolean>(false);
113116

114117
const [bucketsFilter, setBucketsFilter] = useState<BucketsFilterProps>({
115118
myBuckets: false,
@@ -534,6 +537,8 @@ export const MinioProvider = ({ children }: { children: React.ReactNode }) => {
534537
createFolder,
535538
updateBuckets,
536539
updateBucketsVisibilityControl,
540+
setRefreshBucketItems,
541+
refreshBucketItems,
537542
getBucketItems,
538543
deleteBucket,
539544
uploadFiles,

src/pages/ui/minio/components/BucketContent/index.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
Trash,
1111
Download,
1212
DownloadIcon,
13+
LoaderPinwheel,
1314
} from "lucide-react";
1415
import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert";
1516
import OscarColors from "@/styles";
@@ -44,9 +45,11 @@ export type BucketItem =
4445

4546
export default function BucketContent() {
4647
const { name: bucketName, path } = useSelectedBucket();
48+
const [isLoading, setIsLoading] = useState(true);
4749

4850
const {
4951
getBucketItems,
52+
refreshBucketItems,
5053
downloadAndZipFolders,
5154
buckets,
5255
uploadFiles,
@@ -64,6 +67,7 @@ export default function BucketContent() {
6467

6568
useEffect(() => {
6669
if (bucketName) {
70+
setIsLoading(true);
6771
getBucketItems(bucketName, path).then(({ items, folders }) => {
6872
const combinedItems = [
6973
...(folders?.map((folder) => {
@@ -87,10 +91,11 @@ export default function BucketContent() {
8791
return res;
8892
}) || []),
8993
];
94+
setIsLoading(false);
9095
setItems(combinedItems);
9196
});
9297
}
93-
}, [bucketName, getBucketItems, buckets, path]);
98+
}, [bucketName, getBucketItems, buckets, path, refreshBucketItems]);
9499

95100
const handleDrop = (event: React.DragEvent<HTMLDivElement>) => {
96101
event.preventDefault();
@@ -232,6 +237,11 @@ export default function BucketContent() {
232237
}}
233238
itemNames={itemsToDelete.map((item) => item.Name)}
234239
/>
240+
{isLoading ?
241+
<div className="flex items-center justify-center h-full w-full">
242+
<LoaderPinwheel className="animate-spin" size={60} color={OscarColors.Green3} />
243+
</div>
244+
:
235245
<GenericTable
236246
data={items.map((item) => {
237247
return {
@@ -365,6 +375,7 @@ export default function BucketContent() {
365375
},
366376
]}
367377
/>
378+
}
368379
<UploadFileDialog
369380
progress={uploadProgress}
370381
onClose={clearUploadProgress}

src/pages/ui/minio/components/Topbar.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ import { Button } from "@/components/ui/button";
2121
import { useAuth } from "@/contexts/AuthContext";
2222
import { shortenFullname } from "@/lib/utils";
2323
import GenPresignedURLPopover from "./GenPresignedURLPopover";
24+
import AnimatedRefreshCw from "@/components/ui/animatedRefreshCw";
2425

2526

2627
function MinioTopbar() {
2728
const { name, path } = useSelectedBucket();
28-
const { updateBuckets, bucketsOSCAR, bucketsFilter, setBucketsFilter } = useMinio();
29+
const { updateBuckets, bucketsOSCAR, bucketsFilter, setBucketsFilter, refreshBucketItems, setRefreshBucketItems } = useMinio();
2930
const pathSegments = path ? path.split("/").filter(Boolean) : [];
3031
const [serviceAssociate, setServiceAssociate] = useState<boolean>(true)
3132
const {authData} = useAuth();
@@ -110,7 +111,7 @@ function MinioTopbar() {
110111
secondaryRow={
111112
!isOnRoot ? (
112113
<div className="flex flex-col w-full ">
113-
<nav className="grid grid-cols-[auto_1fr] my-[6px] mx-1 items-center text-sm gap-0 border rounded-lg border-gray-300 bg-gray-50 shadow-sm overflow-hidden" aria-label="Breadcrumb">
114+
<nav className="grid grid-cols-[auto_1fr_auto] my-[6px] mx-1 items-center text-sm gap-0 border rounded-lg border-gray-300 bg-gray-50 shadow-sm overflow-hidden" aria-label="Breadcrumb">
114115
<Link
115116
to={`/ui/minio/${name}`}
116117
className="font-bold no-underline hover:text-gray-900 hover:bg-gray-100 px-0 py-2 transition-all duration-200 border-r border-gray-300 bg-white"
@@ -126,6 +127,9 @@ function MinioTopbar() {
126127
{breadcrumbs.length > 0 && breadcrumbs ? breadcrumbs : <Slash size={12} className="pt-[2px] text-gray-400" aria-hidden="true" />}
127128
</div>
128129
</div>
130+
<Button variant="outline" size="sm" onClick={() => setRefreshBucketItems(!refreshBucketItems)} title="Refresh" className="group text-gray-600 hover:text-gray-800 hover:bg-gray-200 border-y-0 border-r-0 border-l border-l-gray-300 rounded-none" >
131+
<AnimatedRefreshCw size={16} className="group-hover:rotate-180"/>
132+
</Button>
129133
</nav>
130134
</div>
131135
)

0 commit comments

Comments
 (0)