Compare commits

..

5 Commits

Author SHA1 Message Date
1d2f25ef04 added parent to ObjID 2022-02-07 15:51:16 +01:00
9462a74437 invalidate local cache when moving dir 2021-11-22 01:28:44 +01:00
1683c0d467 moved apollo cache in seperate file 2021-11-22 01:28:22 +01:00
615292ac24 implmented moveDir 2021-11-02 00:34:46 +01:00
6bcb41820c updated schema 2021-11-02 00:34:29 +01:00
8 changed files with 1236 additions and 1073 deletions

55
src/Cache.ts Normal file
View File

@@ -0,0 +1,55 @@
import { InMemoryCache } from "@apollo/client"
import ObjID from "./types/ObjID"
const cache = new InMemoryCache({
typePolicies:{
File:{
fields:{
id:{
merge(_,incomming){
// HACK: i use the merge function to change the id from a string to ObjID object.
// afaik apollo does not yet support custom scalar types.
if (!incomming){
return incomming
}else if (incomming instanceof ObjID){
return incomming
}else{
return ObjID.fromString(incomming as string)
}
}
}
}
},
Directory:{
fields:{
id:{
merge(_,incomming){
if (!incomming){
return incomming
}else if (incomming instanceof ObjID){
return incomming
}else{
return ObjID.fromString(incomming as string)
}
}
}
}
},
Query: {
fields: {
files: {
merge(existing, incoming){
return incoming
}
},
directorys:{
merge(existing, incoming){
return incoming
}
}
}
}
}
})
export default cache

View File

@@ -5,7 +5,7 @@ import { RouteComponentProps } from "react-router-dom"
import downloadFile from "../functions/downloadFile"
import genDownloadLink from "../functions/genDownloadLink"
import uploadFile from "../functions/uploadFile"
import { useCopyMutation, useCreateDirMutation, useDeleteDirMutation, useDeleteFileMutation, useMoveMutation, useOpenDirQuery } from "../generated/graphql"
import { useCopyMutation, useCreateDirMutation, useDeleteDirMutation, useDeleteFileMutation, useMoveDirMutation, useMoveMutation, useOpenDirQuery } from "../generated/graphql"
import Breadcrum from "./Breadcrum"
import CreateDirButton from "./CreateDirButton"
import GlobalDragAndDrop from "./GlobalDragAndDrop"
@@ -16,6 +16,7 @@ import { ReactComponent as Spinner } from "./../assets/spinner.svg"
import FileBrowserList from "./FileBrowserList"
import MoreMenu from "./MoreMenu"
import ObjID from "../types/ObjID"
import cache from "../Cache"
const FileBrowser: React.FC<RouteComponentProps> = (props) => {
const path = ObjID.fromURI(props.location.pathname)
@@ -32,6 +33,7 @@ const FileBrowser: React.FC<RouteComponentProps> = (props) => {
const [moveMutation] = useMoveMutation()
const [createDirMutation] = useCreateDirMutation()
const [deleteDirMutation] = useDeleteDirMutation()
const [moveDirMutation] = useMoveDirMutation()
const { show: showFileContext } = useContextMenu({
id: CONTEXT_MENU_FILE,
@@ -66,6 +68,7 @@ const FileBrowser: React.FC<RouteComponentProps> = (props) => {
break
case Action.FileCopy:
case Action.FileMove:
case Action.DirMove:
setSrcID(id)
setPasteAction(action)
break
@@ -80,6 +83,18 @@ const FileBrowser: React.FC<RouteComponentProps> = (props) => {
refetchDir()
setSrcID(null)
}
if (pasteAction === Action.DirMove && srcID){
await moveDirMutation({variables:{src:srcID,dest:path}})
refetchDir()
cache.evict({
id: `Directory:${srcID.toString()}` // TODO: check for a better way to generate cache ids
})
setSrcID(null)
}
break
case Action.DirDelete:
await deleteDirMutation({variables:{path:id}})

View File

@@ -12,7 +12,8 @@ export enum Action {
FileMove,
FileDownload,
FileRename,
DirDelete
DirDelete,
DirMove,
}
interface Props {
@@ -40,7 +41,7 @@ const FileBrowserContextMenu: React.FC<Props> = (props) => {
</Menu>
<Menu id={CONTEXT_MENU_DIR} animation={false} className="dark:bg-gray-400">
<Item onClick={onClick} data={Action.DirDelete} >Delete</Item>
<Item onClick={onClick} >Item 2</Item>
<Item onClick={onClick} data={Action.DirMove} >Move</Item>
<Separator />
<Item onClick={onClick} data={Action.FilePaste} disabled={!props.pasteActive}>Paste</Item>
</Menu>

View File

@@ -62,7 +62,8 @@ export type RootMutation = {
delete?: Maybe<Scalars["String"]>;
deleteDir: Scalars["String"];
login: LoginResut;
move?: Maybe<File>;
move: File;
moveDir: Array<Maybe<File>>;
};
@@ -98,6 +99,12 @@ export type RootMutationMoveArgs = {
dest: Scalars["objID"];
};
export type RootMutationMoveDirArgs = {
src: Scalars["objID"];
dest: Scalars["objID"];
};
export type RootQuery = {
__typename?: "RootQuery";
/** True if the user is authorized */
@@ -223,10 +230,24 @@ export type MoveMutationVariables = Exact<{
export type MoveMutation = (
{ __typename?: "RootMutation" }
& { move?: Maybe<(
& { move: (
{ __typename?: "File" }
& Pick<File, "id">
)> }
) }
);
export type MoveDirMutationVariables = Exact<{
src: Scalars["objID"];
dest: Scalars["objID"];
}>;
export type MoveDirMutation = (
{ __typename?: "RootMutation" }
& { moveDir: Array<Maybe<(
{ __typename?: "File" }
& Pick<File, "id">
)>> }
);
export type OpenDirQueryVariables = Exact<{
@@ -547,6 +568,40 @@ export function useMoveMutation(baseOptions?: Apollo.MutationHookOptions<MoveMut
export type MoveMutationHookResult = ReturnType<typeof useMoveMutation>;
export type MoveMutationResult = Apollo.MutationResult<MoveMutation>;
export type MoveMutationOptions = Apollo.BaseMutationOptions<MoveMutation, MoveMutationVariables>;
export const MoveDirDocument = gql`
mutation moveDir($src: objID!, $dest: objID!) {
moveDir(src: $src, dest: $dest) {
id
}
}
`
export type MoveDirMutationFn = Apollo.MutationFunction<MoveDirMutation, MoveDirMutationVariables>;
/**
* __useMoveDirMutation__
*
* To run a mutation, you first call `useMoveDirMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useMoveDirMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [moveDirMutation, { data, loading, error }] = useMoveDirMutation({
* variables: {
* src: // value for 'src'
* dest: // value for 'dest'
* },
* });
*/
export function useMoveDirMutation(baseOptions?: Apollo.MutationHookOptions<MoveDirMutation, MoveDirMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<MoveDirMutation, MoveDirMutationVariables>(MoveDirDocument, options)
}
export type MoveDirMutationHookResult = ReturnType<typeof useMoveDirMutation>;
export type MoveDirMutationResult = Apollo.MutationResult<MoveDirMutation>;
export type MoveDirMutationOptions = Apollo.BaseMutationOptions<MoveDirMutation, MoveDirMutationVariables>;
export const OpenDirDocument = gql`
query openDir($path: objID!) {
files(path: $path) {

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
mutation moveDir($src: objID!, $dest: objID!) {
moveDir(src: $src,dest: $dest){
id
}
}

View File

@@ -2,62 +2,13 @@ import React from "react"
import ReactDOM from "react-dom"
import "./index.scss"
import App from "./App"
import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client"
import { ApolloClient, ApolloProvider } from "@apollo/client"
import "react-contexify/dist/ReactContexify.css"
import ObjID from "./types/ObjID"
import cache from "./Cache"
const client = new ApolloClient({
uri: "/api/graphql",
cache: new InMemoryCache({
typePolicies:{
File:{
fields:{
id:{
merge(_,incomming){
// HACK: i use the merge function to change the id from a string to ObjID object.
// afaik apollo does not yet support custom scalar types.
if (!incomming){
return incomming
}else if (incomming instanceof ObjID){
return incomming
}else{
return ObjID.fromString(incomming as string)
}
}
}
}
},
Directory:{
fields:{
id:{
merge(_,incomming){
if (!incomming){
return incomming
}else if (incomming instanceof ObjID){
return incomming
}else{
return ObjID.fromString(incomming as string)
}
}
}
}
},
Query: {
fields: {
files: {
merge(existing, incoming){
return incoming
}
},
directorys:{
merge(existing, incoming){
return incoming
}
}
}
}
}
})
cache: cache,
})
// Disable drag and drop behaviour on document

View File

@@ -53,6 +53,30 @@ class ObjID {
return new ObjID(this.bucket,parts.join("/"))
}
/**
* Get the parent of the object. If Obj is a file then the containing directory
* if Obj is a directory it returns the parent
* @returns parent ObjID or null if already at root
*/
public parent(): ObjID | null {
if (this.key == "/") {
// Already at root. We dont have a parent
return null
}
if (this.isDirectory()) {
const parts = this.key.split("/")
const parent = new ObjID(this.bucket, parts.slice(0,-2).join("/") + "/")
parent.normalize()
return parent
} else {
const parts = this.key.split("/")
const parent = new ObjID(this.bucket, parts.slice(0,-1).join("/") + "/")
parent.normalize()
return parent
}
}
public static fromString(from: string): ObjID{
const match = stringRegex.exec(from)