mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-09 08:03:50 +00:00
feat: move S3 file within bucket (#2913)
This commit is contained in:
committed by
GitHub
parent
2870d4882d
commit
cd48fdce2e
@@ -7,7 +7,8 @@
|
||||
Loader2,
|
||||
Download,
|
||||
Trash,
|
||||
FileUp
|
||||
FileUp,
|
||||
MoveRight
|
||||
} from 'lucide-svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import { HelpersService, type UploadFilePart } from '$lib/gen'
|
||||
@@ -24,6 +25,10 @@
|
||||
let deletionModalOpen = false
|
||||
let fileDeletionInProgress = false
|
||||
|
||||
let moveModalOpen = false
|
||||
let moveDestKey: string | undefined = undefined
|
||||
let fileMoveInProgress = false
|
||||
|
||||
let uploadModalOpen = false
|
||||
let fileToUpload: File | undefined = undefined
|
||||
let fileToUploadKey: string | undefined = undefined
|
||||
@@ -89,6 +94,8 @@
|
||||
maxKeys: 1000, // fixed pages of 1000 files for now
|
||||
marker: paginationMarker
|
||||
})
|
||||
allFilesByKey = {}
|
||||
displayedFileKeys = []
|
||||
for (let file_path of availableFiles.windmill_large_files) {
|
||||
let split_path = file_path.s3.split('/')
|
||||
let parent_path: string | undefined = undefined
|
||||
@@ -210,8 +217,10 @@
|
||||
})
|
||||
} finally {
|
||||
fileDeletionInProgress = false
|
||||
deletionModalOpen = false
|
||||
}
|
||||
sendUserToast(`${fileKey} deleted from S3 bucket`)
|
||||
selectedFileKey = { s3: '' }
|
||||
const idx = displayedFileKeys.indexOf(fileKey)
|
||||
if (idx >= 0) {
|
||||
displayedFileKeys.splice(idx, 1)
|
||||
@@ -220,6 +229,27 @@
|
||||
delete allFilesByKey[fileKey]
|
||||
}
|
||||
|
||||
async function moveS3File(srcFileKey: string | undefined, destFileKey: string | undefined) {
|
||||
fileMoveInProgress = true
|
||||
if (srcFileKey === undefined || emptyString(destFileKey)) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await HelpersService.moveS3File({
|
||||
workspace: $workspaceStore!,
|
||||
srcFileKey: srcFileKey,
|
||||
destFileKey: destFileKey!
|
||||
})
|
||||
} finally {
|
||||
fileMoveInProgress = false
|
||||
moveModalOpen = false
|
||||
}
|
||||
sendUserToast(`${srcFileKey} moved to ${destFileKey}`)
|
||||
selectedFileKey = { s3: destFileKey! }
|
||||
await loadFiles()
|
||||
await loadFileMetadataPlusPreviewAsync(selectedFileKey.s3)
|
||||
}
|
||||
|
||||
async function uploadFileToS3() {
|
||||
fileUploadErrorMsg = undefined
|
||||
if (fileToUpload === undefined || fileToUploadKey === undefined) {
|
||||
@@ -497,6 +527,17 @@
|
||||
startIcon={{ icon: Download }}
|
||||
iconOnly={true}
|
||||
/>
|
||||
<Button
|
||||
title="Move file"
|
||||
variant="border"
|
||||
color="light"
|
||||
on:click={() => {
|
||||
moveDestKey = fileMetadata?.fileKey ?? ''
|
||||
moveModalOpen = true
|
||||
}}
|
||||
startIcon={{ icon: MoveRight }}
|
||||
iconOnly={true}
|
||||
/>
|
||||
<Button
|
||||
title="Delete file from S3"
|
||||
variant="border"
|
||||
@@ -504,9 +545,7 @@
|
||||
on:click={() => {
|
||||
deletionModalOpen = true
|
||||
}}
|
||||
startIcon={fileDeletionInProgress
|
||||
? { icon: Loader2, classes: 'animate-spin' }
|
||||
: { icon: Trash }}
|
||||
startIcon={{ icon: Trash }}
|
||||
iconOnly={true}
|
||||
/>
|
||||
{/if}
|
||||
@@ -588,7 +627,7 @@
|
||||
startIcon={{ icon: FileUp }}
|
||||
on:click={() => {
|
||||
uploadModalOpen = true
|
||||
}}>Upload New</Button
|
||||
}}>Upload File</Button
|
||||
>
|
||||
<Button
|
||||
disable={selectedFileKey === undefined || emptyString(selectedFileKey.s3)}
|
||||
@@ -608,8 +647,9 @@
|
||||
}}
|
||||
on:confirmed={() => {
|
||||
deleteFileFromS3(fileMetadata?.fileKey)
|
||||
deletionModalOpen = false
|
||||
}}
|
||||
keyListen={false}
|
||||
bind:loading={fileDeletionInProgress}
|
||||
>
|
||||
<div class="flex flex-col w-full space-y-4">
|
||||
<span
|
||||
@@ -618,6 +658,33 @@
|
||||
</div>
|
||||
</ConfirmationModal>
|
||||
|
||||
<ConfirmationModal
|
||||
open={moveModalOpen}
|
||||
title="Move file to new location"
|
||||
confirmationText="Move"
|
||||
on:canceled={() => {
|
||||
moveModalOpen = false
|
||||
}}
|
||||
on:confirmed={() => {
|
||||
moveS3File(fileMetadata?.fileKey, moveDestKey)
|
||||
}}
|
||||
keyListen={false}
|
||||
bind:loading={fileMoveInProgress}
|
||||
>
|
||||
<div class="flex flex-col space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="w-24">New key: </span>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="folder/nested/file.txt"
|
||||
bind:value={moveDestKey}
|
||||
class="text-2xl"
|
||||
/>
|
||||
</div>
|
||||
<span>Are you sure you want to permanently move {fileMetadata?.fileKey}?</span>
|
||||
</div>
|
||||
</ConfirmationModal>
|
||||
|
||||
<FileUploadModal
|
||||
open={uploadModalOpen}
|
||||
title="Upload file to S3 bucket"
|
||||
|
||||
@@ -4,17 +4,19 @@
|
||||
import { fade } from 'svelte/transition'
|
||||
import Button from '../button/Button.svelte'
|
||||
import Badge from '../badge/Badge.svelte'
|
||||
import { AlertTriangle } from 'lucide-svelte'
|
||||
import { AlertTriangle, Loader2 } from 'lucide-svelte'
|
||||
|
||||
export let title: string
|
||||
export let confirmationText: string
|
||||
export let keyListen: boolean = true
|
||||
export let loading: boolean = false
|
||||
|
||||
export let open: boolean = false
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
function onKeyDown(event: KeyboardEvent) {
|
||||
if (open) {
|
||||
if (open && keyListen) {
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
switch (event.key) {
|
||||
@@ -73,11 +75,24 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2 flex-row-reverse space-x-reverse mt-4">
|
||||
<Button on:click={() => dispatch('confirmed')} color="red" size="sm">
|
||||
<span>{confirmationText} <Badge>Enter</Badge></span>
|
||||
<Button disabled={loading} on:click={() => dispatch('confirmed')} color="red" size="sm">
|
||||
{#if loading}
|
||||
<Loader2 class="animate-spin" />
|
||||
{/if}
|
||||
<span
|
||||
>{confirmationText}
|
||||
{#if keyListen}<Badge>Enter</Badge>{/if}</span
|
||||
>
|
||||
</Button>
|
||||
<Button on:click={() => dispatch('canceled')} color="light" size="sm">
|
||||
<span>Cancel <Badge color="dark-gray">Escape</Badge></span>
|
||||
<Button
|
||||
disabled={loading}
|
||||
on:click={() => dispatch('canceled')}
|
||||
color="light"
|
||||
size="sm"
|
||||
>
|
||||
<span
|
||||
>Cancel {#if keyListen}<Badge color="dark-gray">Escape</Badge>{/if}</span
|
||||
>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user