Compare commits

..

5 Commits

Author SHA1 Message Date
b08a527199 file size only one decimal 2021-07-27 21:55:05 +02:00
53969946d2 fixed breadcrum 2021-07-27 21:44:24 +02:00
a24ed03e1f added file size 2021-07-27 21:24:20 +02:00
c20e894d52 code gen linter fix 2021-07-27 21:22:13 +02:00
abbcaf9166 added spectre css 2021-07-27 19:24:52 +02:00
14 changed files with 555 additions and 484 deletions

View File

@@ -5,7 +5,7 @@ generates:
src/generated/graphql.tsx: src/generated/graphql.tsx:
hooks: hooks:
afterOneFileWrite: afterOneFileWrite:
- yarn run eslint --fix src/generated/graphql.tsx - yarn run eslint --fix --no-ignore src/generated/graphql.tsx
plugins: plugins:
- "typescript" - "typescript"
- "typescript-operations" - "typescript-operations"

View File

@@ -17,6 +17,7 @@
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"spectre.css": "^0.5.9",
"typescript": "^4.1.2", "typescript": "^4.1.2",
"web-vitals": "^1.0.1" "web-vitals": "^1.0.1"
}, },
@@ -57,5 +58,6 @@
"apollo": "^2.33.4", "apollo": "^2.33.4",
"eslint": "^7.31.0", "eslint": "^7.31.0",
"eslint-plugin-react": "^7.24.0" "eslint-plugin-react": "^7.24.0"
} },
"proxy": "http://localhost:8080"
} }

View File

@@ -4,8 +4,8 @@ import FileBrowser from "./components/FileBrowser"
const App: React.FC = () => { const App: React.FC = () => {
return ( return (
<div className="App"> <div className="container">
<FileBrowser></FileBrowser> <FileBrowser/>
</div> </div>
) )
} }

View File

@@ -0,0 +1,38 @@
import React from "react"
import PropTypes from "prop-types"
interface Props{
path: string
onDirClick?: (path: string) => void
}
const Breadcrum: React.FC<Props> = (props) => {
const parts = props.path.split("/").filter(e=>e.length > 0)
return (
<ul className="breadcrumb">
<li className="breadcrumb-item">
<a onClick={()=>{
props.onDirClick?.("/")
}}>
Root
</a>
</li>
{parts.map((e,i,arr)=>(
<li key={e} className="breadcrumb-item">
<a onClick={()=>{
if (i != arr.length - 1){
props.onDirClick?.("/"+arr.slice(0,i-1).join("/"))
}
}}>{e}</a>
</li>))}
</ul>
)
}
Breadcrum.propTypes = {
path: PropTypes.string.isRequired,
onDirClick: PropTypes.func
}
export default Breadcrum

View File

@@ -8,9 +8,14 @@ interface Props {
const DirectoryElement: React.FC<Props> = (props) => { const DirectoryElement: React.FC<Props> = (props) => {
return ( return (
<div> <>
<td>
📂 {props.dir.name} 📂 {props.dir.name}
</div> </td>
<td>
</td>
</>
) )
} }

View File

@@ -1,17 +1,9 @@
import React from "react" import React from "react"
import { useState } from "react" import { useState } from "react"
import { useOpenDirQuery } from "../generated/graphql" import { useOpenDirQuery } from "../generated/graphql"
import Breadcrum from "./Breadcrum"
import FileBrowserElement from "./FileBrowserElement" import FileBrowserElement from "./FileBrowserElement"
function parentDir(path:string): string {
if(path.endsWith("/")){
path = path.substr(0,path.length - 1)
}
const paths = path.split("/")
paths.pop()
return paths.join("/")
}
const FileBrowser: React.FC = () => { const FileBrowser: React.FC = () => {
const [path,setPath] = useState("/") const [path,setPath] = useState("/")
@@ -23,16 +15,18 @@ const FileBrowser: React.FC = () => {
return ( return (
<div> <div>
<div onClick={()=>{ <Breadcrum path={path} onDirClick={(newPath)=>{
setPath(parentDir(path)) setPath(newPath)
}}> }}/>
..
</div>
<div> <div>
{ data?.files.map(v => (<FileBrowserElement <table className="table table-striped table-hover">
key={v?.id} <thead>
file={v} <tr>
/>))} <th>Name</th>
<th>Size</th>
</tr>
</thead>
<tbody>
{ data?.directorys.map(v => (<FileBrowserElement { data?.directorys.map(v => (<FileBrowserElement
key={v?.id} key={v?.id}
@@ -41,6 +35,13 @@ const FileBrowser: React.FC = () => {
setPath(data.id) setPath(data.id)
}} }}
/>))} />))}
{ data?.files.map(v => (<FileBrowserElement
key={v?.id}
file={v}
/>))}
</tbody>
</table>
</div> </div>
</div> </div>
) )

View File

@@ -12,7 +12,7 @@ interface Props {
const FileBrowserElement: React.FC<Props> = (props) => { const FileBrowserElement: React.FC<Props> = (props) => {
return ( return (
<div onClick={()=>{ <tr onClick={()=>{
if(props.file){ if(props.file){
props.onClick?.(props.file) props.onClick?.(props.file)
}else if(props.dir){ }else if(props.dir){
@@ -20,7 +20,7 @@ const FileBrowserElement: React.FC<Props> = (props) => {
} }
}}> }}>
{(props.file) ? <FileElement file={props.file}/>:(props.dir)?<DirectoryComponent dir={props.dir} />:<></>} {(props.file) ? <FileElement file={props.file}/>:(props.dir)?<DirectoryComponent dir={props.dir} />:<></>}
</div> </tr>
) )
} }

View File

@@ -1,6 +1,7 @@
import React from "react" import React from "react"
import PropTypes from "prop-types" import PropTypes from "prop-types"
import { File } from "../generated/graphql" import { File } from "../generated/graphql"
import sizeToReadable from "../functions/sizeToReadable"
interface Props { interface Props {
file: File file: File
@@ -8,9 +9,14 @@ interface Props {
const FileElement: React.FC<Props> = (props) => { const FileElement: React.FC<Props> = (props) => {
return ( return (
<div> <>
<td>
📄 {props.file.name} 📄 {props.file.name}
</div> </td>
<td>
{sizeToReadable(props.file.size)}
</td>
</>
) )
} }

View File

@@ -0,0 +1,7 @@
function sizeToReadable(size: number): string {
const i = Math.floor(Math.log(size) / Math.log(1024))
return (size / Math.pow(1024, i)).toFixed(1) + " " + ["B", "kB", "MB", "GB", "TB"][i]
}
export default sizeToReadable

View File

@@ -33,7 +33,7 @@ export type File = {
id: Scalars["ID"]; id: Scalars["ID"];
name?: Maybe<Scalars["String"]>; name?: Maybe<Scalars["String"]>;
parent?: Maybe<Directory>; parent?: Maybe<Directory>;
size?: Maybe<Scalars["Int"]>; size: Scalars["Int"];
}; };
export type RootQuery = { export type RootQuery = {
@@ -67,7 +67,7 @@ export type OpenDirQuery = (
{ __typename?: "RootQuery" } { __typename?: "RootQuery" }
& { files: Array<Maybe<( & { files: Array<Maybe<(
{ __typename?: "File" } { __typename?: "File" }
& Pick<File, "id" | "name"> & Pick<File, "id" | "name" | "size">
)>>, directorys: Array<Maybe<( )>>, directorys: Array<Maybe<(
{ __typename?: "Directory" } { __typename?: "Directory" }
& Pick<Directory, "id" | "name"> & Pick<Directory, "id" | "name">
@@ -80,6 +80,7 @@ export const OpenDirDocument = gql`
files(path: $path) { files(path: $path) {
id id
name name
size
} }
directorys(path: $path) { directorys(path: $path) {
id id

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,7 @@ query openDir($path: String!) {
files(path:$path){ files(path:$path){
id id
name name
size
} }
directorys(path: $path){ directorys(path: $path){
id id

View File

@@ -3,9 +3,10 @@ import ReactDOM from "react-dom"
import "./index.scss" import "./index.scss"
import App from "./App" import App from "./App"
import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client" import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client"
import "spectre.css"
const client = new ApolloClient({ const client = new ApolloClient({
uri: "http://localhost:8080/graphql", uri: "/graphql",
cache: new InMemoryCache() cache: new InMemoryCache()
}) })

View File

@@ -12959,6 +12959,11 @@ spdy@^4.0.2:
select-hose "^2.0.0" select-hose "^2.0.0"
spdy-transport "^3.0.0" spdy-transport "^3.0.0"
spectre.css@^0.5.9:
version "0.5.9"
resolved "https://registry.yarnpkg.com/spectre.css/-/spectre.css-0.5.9.tgz#86c732d093036d9fdc0a2ba570f005e4023ae6ca"
integrity sha512-9jUqwZmCnvflrxFGcK+ize43TvjwDjqMwZPVubEtSIHzvinH0TBUESm1LcOJx3Ur7bdPaeOHQIjOqBl1Y5kLFw==
split-on-first@^1.0.0: split-on-first@^1.0.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz" resolved "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz"