wip: list files in bucket

This commit is contained in:
zhaoyupeng
2024-10-10 18:00:49 +08:00
parent efe7800b59
commit 8bc2a2541d
13 changed files with 279 additions and 70 deletions

View File

@ -1,6 +1,16 @@
import {Button, Input, makeStyles, MenuItem, MenuList, mergeClasses, tokens, Tooltip} from "@fluentui/react-components"
import {
Button,
Input,
makeStyles,
Menu,
MenuItem,
MenuList, MenuPopover, MenuProps,
mergeClasses, PositioningImperativeRef,
tokens,
Tooltip
} from "@fluentui/react-components"
import {DatabaseLinkRegular, DismissRegular} from "@fluentui/react-icons";
import {useState} from "react";
import React, {useState} from "react";
import {Connection} from "../../interfaces/connection";
import {useToast} from "../../message";
import {Dial} from "../../api";
@ -15,7 +25,6 @@ const useStyles = makeStyles({
},
content: {
height: "100%",
minWidth: "22rem",
width: "25rem",
display: "flex",
flexDirection: "column",
@ -38,7 +47,7 @@ const useStyles = makeStyles({
items_one: {
marginLeft: "0.5rem",
marginRight: "0.5rem",
"&:hover":{
"&:hover": {
color: tokens.colorNeutralForeground2BrandPressed,
},
"&.active": {
@ -94,6 +103,11 @@ export function ConnectionList() {
conn_update({...item, active: false})
}
async function handleRightClick(e: React.MouseEvent<HTMLDivElement>, item: Connection) {
e.preventDefault()
console.log('[DEBUG] right click connection =', item, 'event =', e)
console.log(`[DEBUG] click position: [${e.pageX}, ${e.pageY}]`)
}
return (
<div className={styles.list}>
@ -115,14 +129,17 @@ export function ConnectionList() {
<MenuList>
{conn_list.filter(item => item.name.includes(conn_filter)).map(item => {
return <MenuItem
className={item.active? mergeClasses(styles.items_one, "active"):styles.items_one}
className={item.active ? mergeClasses(styles.items_one, "active") : styles.items_one}
onClick={async () => {
await handleSelect(item)
}}
onDoubleClick={async () => {
await handleConnect(item)
}}
icon={<DatabaseLinkRegular />}
onContextMenu={async (e) => {
await handleRightClick(e, item)
}}
icon={<DatabaseLinkRegular/>}
key={item.id}>
{item.name}
<Tooltip

View File

@ -1,40 +0,0 @@
import {makeStyles, MenuItem, MenuList, tokens} from "@fluentui/react-components";
import {useStoreBucket} from "../../store/bucket";
import {ArchiveRegular} from "@fluentui/react-icons";
const useStyles = makeStyles({
buckets: {
height: "100%",
width: "100%",
},
bucket_items: {
width: "100%",
},
bucket_item: {
width: "100%",
"&:first-child": {
marginTop: "0.5rem",
},
"&:hover": {
color: tokens.colorNeutralForeground2BrandPressed,
},
"& > span:nth-child(2)": {
maxWidth: '100% !important',
},
},
})
export function Bucket() {
const styles = useStyles();
const {bucket_list} = useStoreBucket()
return <div className={styles.buckets}>
<MenuList className={styles.bucket_items}>
{bucket_list.map(((item, idx) => {
return <MenuItem className={styles.bucket_item} icon={<ArchiveRegular/>} style={{width: '100%'}}
key={idx}>{item.name}</MenuItem>
}))}
</MenuList>
</div>
}

View File

@ -1,6 +1,8 @@
import {Path} from "./path";
import {Bucket} from "./bucket";
import {ListComponent} from "./list";
import {makeStyles} from "@fluentui/react-components";
import {useStoreBucket} from "../../store/bucket";
import {useStoreFile} from "../../store/file";
const useStyles = makeStyles({
content: {
@ -13,9 +15,17 @@ const useStyles = makeStyles({
})
export function Content() {
const styles = useStyles()
const {bucket_list} = useStoreBucket()
const {bucket, file_list} = useStoreFile()
return <div className={styles.content}>
<Path />
<Bucket />
<Path/>
{
bucket.name ?
<ListComponent type={'file'} list={file_list.map(item => item.name)}/> :
<ListComponent type={'bucket'} list={bucket_list.map(item => item.name)}/>
}
</div>
}

View File

@ -0,0 +1,73 @@
import {makeStyles, MenuItem, MenuList, Text, tokens} from "@fluentui/react-components";
import {ArchiveRegular, DocumentBulletListRegular} from "@fluentui/react-icons";
import {VirtualizerScrollView} from "@fluentui/react-components/unstable";
import React from "react";
const useStyles = makeStyles({
container: {
marginTop: '0.5rem',
maxWidth: 'calc(100vw - 25rem - 1px)',
},
row: {
height: '32px',
display: 'flex',
marginLeft: '0.5rem',
marginRight: '0.5rem',
},
item: {
width: '100%',
maxWidth: '100%',
"&:hover": {
color: tokens.colorNeutralForeground2BrandPressed,
}
},
text: {
overflow: 'hidden',
width: 'calc(100vw - 32rem)',
display: "block",
}
})
export interface ListComponentProps {
type: "bucket" | "file"
list: string[],
}
export function ListComponent(props: ListComponentProps) {
const styles = useStyles();
async function handleClick(item: string) {
console.log('[DEBUG] bucket click =', item);
}
function handleRightClick(e: React.MouseEvent<HTMLDivElement>, string: string) {
e.preventDefault()
}
return <MenuList className={styles.container}>
<VirtualizerScrollView
numItems={props.list.length}
itemSize={32}
container={{role: 'list', style: {maxHeight: 'calc(100vh - 9rem)'}}}
>
{(idx) => {
return <div
className={styles.row} key={idx}
onClick={async () => {
await handleClick(props.list[idx])
}}
onContextMenu={async (e) => {
handleRightClick(e, props.list[idx])
}}>
<MenuItem className={styles.item}
icon={props.type === 'bucket' ? <ArchiveRegular/> : <DocumentBulletListRegular/>}>
<Text truncate wrap={false} className={styles.text}>
{props.list[idx]}
</Text>
</MenuItem>
</div>
}}
</VirtualizerScrollView>
</MenuList>
}

View File

@ -11,4 +11,7 @@ export interface Connection {
export interface Bucket {
name: string;
created_at: number;
}
export interface S3File {
name:string;
}

View File

@ -0,0 +1,12 @@
import {create} from 'zustand'
import {Bucket, S3File} from "../interfaces/connection";
interface StoreFile {
bucket: Bucket;
file_list: S3File[];
}
export const useStoreFile = create<StoreFile>()((set) => ({
bucket: {name: '', created_at: 0},
file_list: [],
}))