Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/app/store/wshclientapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ class RpcApiType {
}

// command "remotefilecopy" [call]
RemoteFileCopyCommand(client: WshClient, data: CommandFileCopyData, opts?: RpcOpts): Promise<void> {
RemoteFileCopyCommand(client: WshClient, data: CommandFileCopyData, opts?: RpcOpts): Promise<boolean> {
return client.wshRpcCall("remotefilecopy", data, opts);
}

Expand Down
305 changes: 123 additions & 182 deletions frontend/app/view/preview/directorypreview.tsx

Large diffs are not rendered by default.

28 changes: 16 additions & 12 deletions frontend/app/view/preview/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1216,18 +1216,22 @@ const ErrorOverlay = memo(({ errorMsg, resetOverlay }: { errorMsg: ErrorMsg; res
/>
<div>{errorMsg.text}</div>
</OverlayScrollbarsComponent>
{errorMsg.buttons?.map((buttonDef) => (
<Button
className={buttonClassName}
onClick={() => {
buttonDef.onClick();
resetOverlay();
}}
key={crypto.randomUUID()}
>
{buttonDef.text}
</Button>
))}
{!!errorMsg.buttons && (
<div className="flex flex-row gap-2">
{errorMsg.buttons?.map((buttonDef) => (
<Button
className={buttonClassName}
onClick={() => {
buttonDef.onClick();
resetOverlay();
}}
key={crypto.randomUUID()}
>
{buttonDef.text}
</Button>
))}
</div>
)}
</div>

{showDismiss && (
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ require (
github.com/wavetermdev/htmltoken v0.2.0
golang.org/x/crypto v0.33.0
golang.org/x/mod v0.23.0
golang.org/x/sync v0.11.0
golang.org/x/sys v0.30.0
golang.org/x/term v0.29.0
google.golang.org/api v0.221.0
Expand Down Expand Up @@ -95,7 +96,6 @@ require (
go.uber.org/atomic v1.7.0 // indirect
golang.org/x/net v0.35.0 // indirect
golang.org/x/oauth2 v0.26.0 // indirect
golang.org/x/sync v0.11.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/time v0.10.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
Expand Down
33 changes: 18 additions & 15 deletions pkg/remote/fileshare/fileshare.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,11 @@ func Mkdir(ctx context.Context, path string) error {
}

func Move(ctx context.Context, data wshrpc.CommandFileCopyData) error {
log.Printf("Move: %v", data)
opts := data.Opts
if opts == nil {
opts = &wshrpc.FileCopyOpts{}
}
log.Printf("Move: srcuri: %v, desturi: %v, opts: %v", data.SrcUri, data.DestUri, opts)
srcClient, srcConn := CreateFileShareClient(ctx, data.SrcUri)
if srcConn == nil || srcClient == nil {
return fmt.Errorf("error creating fileshare client, could not parse source connection %s", data.SrcUri)
Expand All @@ -129,26 +133,23 @@ func Move(ctx context.Context, data wshrpc.CommandFileCopyData) error {
return fmt.Errorf("error creating fileshare client, could not parse destination connection %s", data.DestUri)
}
if srcConn.Host != destConn.Host {
finfo, err := srcClient.Stat(ctx, srcConn)
if err != nil {
return fmt.Errorf("cannot stat %q: %w", data.SrcUri, err)
}
recursive := data.Opts != nil && data.Opts.Recursive
if finfo.IsDir && data.Opts != nil && !recursive {
return fmt.Errorf("cannot move directory %q to %q without recursive flag", data.SrcUri, data.DestUri)
}
err = destClient.CopyRemote(ctx, srcConn, destConn, srcClient, data.Opts)
isDir, err := destClient.CopyRemote(ctx, srcConn, destConn, srcClient, opts)
if err != nil {
return fmt.Errorf("cannot copy %q to %q: %w", data.SrcUri, data.DestUri, err)
}
return srcClient.Delete(ctx, srcConn, recursive)
return srcClient.Delete(ctx, srcConn, opts.Recursive && isDir)
} else {
return srcClient.MoveInternal(ctx, srcConn, destConn, data.Opts)
return srcClient.MoveInternal(ctx, srcConn, destConn, opts)
}
}

func Copy(ctx context.Context, data wshrpc.CommandFileCopyData) error {
log.Printf("Copy: %v", data)
opts := data.Opts
if opts == nil {
opts = &wshrpc.FileCopyOpts{}
}
opts.Recursive = true
log.Printf("Copy: srcuri: %v, desturi: %v, opts: %v", data.SrcUri, data.DestUri, opts)
srcClient, srcConn := CreateFileShareClient(ctx, data.SrcUri)
if srcConn == nil || srcClient == nil {
return fmt.Errorf("error creating fileshare client, could not parse source connection %s", data.SrcUri)
Expand All @@ -158,9 +159,11 @@ func Copy(ctx context.Context, data wshrpc.CommandFileCopyData) error {
return fmt.Errorf("error creating fileshare client, could not parse destination connection %s", data.DestUri)
}
if srcConn.Host != destConn.Host {
return destClient.CopyRemote(ctx, srcConn, destConn, srcClient, data.Opts)
_, err := destClient.CopyRemote(ctx, srcConn, destConn, srcClient, opts)
return err
} else {
return srcClient.CopyInternal(ctx, srcConn, destConn, data.Opts)
_, err := srcClient.CopyInternal(ctx, srcConn, destConn, opts)
return err
}
}

Expand Down
17 changes: 10 additions & 7 deletions pkg/remote/fileshare/fstype/fstype.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import (
)

const (
DefaultTimeout = 30 * time.Second
FileMode os.FileMode = 0644
DirMode os.FileMode = 0755 | os.ModeDir
DefaultTimeout = 30 * time.Second
FileMode os.FileMode = 0644
DirMode os.FileMode = 0755 | os.ModeDir
RecursiveRequiredError = "recursive flag must be set for directory operations"
MergeRequiredError = "directory already exists at %q, set overwrite flag to delete the existing contents or set merge flag to merge the contents"
OverwriteRequiredError = "file already exists at %q, set overwrite flag to delete the existing file"
)

type FileShareClient interface {
Expand All @@ -40,10 +43,10 @@ type FileShareClient interface {
Mkdir(ctx context.Context, conn *connparse.Connection) error
// Move moves the file within the same connection
MoveInternal(ctx context.Context, srcConn, destConn *connparse.Connection, opts *wshrpc.FileCopyOpts) error
// Copy copies the file within the same connection
CopyInternal(ctx context.Context, srcConn, destConn *connparse.Connection, opts *wshrpc.FileCopyOpts) error
// CopyRemote copies the file between different connections
CopyRemote(ctx context.Context, srcConn, destConn *connparse.Connection, srcClient FileShareClient, opts *wshrpc.FileCopyOpts) error
// Copy copies the file within the same connection. Returns whether the copy source was a directory
CopyInternal(ctx context.Context, srcConn, destConn *connparse.Connection, opts *wshrpc.FileCopyOpts) (bool, error)
// CopyRemote copies the file between different connections. Returns whether the copy source was a directory
CopyRemote(ctx context.Context, srcConn, destConn *connparse.Connection, srcClient FileShareClient, opts *wshrpc.FileCopyOpts) (bool, error)
// Delete deletes the entry at the given path
Delete(ctx context.Context, conn *connparse.Connection, recursive bool) error
// Join joins the given parts to the connection path
Expand Down
Loading
Loading