Improve upload for subdirectory

This commit is contained in:
Tri Vo 2023-06-20 12:18:56 +07:00 committed by Lena Fuhrimann
parent c6ce282520
commit 1982236804
3 changed files with 112 additions and 14 deletions

View file

@ -30,6 +30,7 @@ func HandleBucketView(s3 S3, templates fs.FS, allowDelete bool, listRecursive bo
Objects []objectWithIcon
AllowDelete bool
Paths []string
CurrentPath string
}
return func(w http.ResponseWriter, r *http.Request) {
@ -68,6 +69,7 @@ func HandleBucketView(s3 S3, templates fs.FS, allowDelete bool, listRecursive bo
Objects: objs,
AllowDelete: allowDelete,
Paths: removeEmptyStrings(strings.Split(path, "/")),
CurrentPath: path,
}
t, err := template.ParseFS(templates, "layout.html.tmpl", "bucket.html.tmpl")

View file

@ -22,6 +22,7 @@ func HandleCreateObject(s3 S3, sseInfo SSEType) http.HandlerFunc {
return
}
file, header, err := r.FormFile("file")
path := r.FormValue("path")
if err != nil {
handleHTTPError(w, fmt.Errorf("error getting file from form: %w", err))
return
@ -50,7 +51,8 @@ func HandleCreateObject(s3 S3, sseInfo SSEType) http.HandlerFunc {
}
}
_, err = s3.PutObject(r.Context(), bucketName, header.Filename, file, -1, opts)
objectName := fmt.Sprintf("%s%s", path, header.Filename)
_, err = s3.PutObject(r.Context(), bucketName, objectName, file, -1, opts)
if err != nil {
handleHTTPError(w, fmt.Errorf("error putting object: %w", err))
return

View file

@ -1,7 +1,13 @@
{{ define "content" }}
<style>
.breadcrumb:before {
content: '/';
content: '/';
}
#notifications {
top: 20px;
right: 30px;
position: fixed;
z-index: 2
}
</style>
@ -32,7 +38,7 @@
</div>
</nav>
<div class="section" style="margin: 10px;">
<div class="section" style="margin: 10px; position: relative;">
{{ if .Objects }}
<table class="striped">
<thead>
@ -59,16 +65,18 @@
<td>{{ $object.Owner }}</td>
<td>{{ $object.LastModified }}</td>
<td>
<button class="dropdown-trigger waves-effect waves-teal btn" data-target="actions-dropdown-{{ $index }}">
Actions <i class="material-icons right">arrow_drop_down</i>
</button>
<!-- Dropdown Structure -->
<ul id="actions-dropdown-{{ $index }}" class="dropdown-content">
<li><a target="_blank" href="/api/buckets/{{ $.BucketName }}/objects/{{ $object.Key }}">Download</a></li>
{{- if $.AllowDelete }}
<li><a href="#" onclick="deleteObject({{ $.BucketName }}, {{ $object.Key }})">Delete</a></li>
{{- end }}
</ul>
{{ if not $object.IsFolder }}
<button class="dropdown-trigger waves-effect waves-teal btn" data-target="actions-dropdown-{{ $index }}">
Actions <i class="material-icons right">arrow_drop_down</i>
</button>
<!-- Dropdown Structure -->
<ul id="actions-dropdown-{{ $index }}" class="dropdown-content">
<li><a target="_blank" href="/api/buckets/{{ $.BucketName }}/objects/{{ $object.Key }}">Download</a></li>
{{- if $.AllowDelete }}
<li><a href="#" onclick="deleteObject({{ $.BucketName }}, {{ $object.Key }})">Delete</a></li>
{{- end }}
</ul>
{{ end }}
</td>
</tr>
{{ end }}
@ -77,15 +85,30 @@
{{ end }}
{{ if not .Objects }}
<p style="text-align:center;margin-top:2em;color:gray;">No objects in <strong>{{ .BucketName }}</strong> yet</p>
<p style="text-align:center;margin-top:2em;color:gray;">No objects in <strong>{{ .BucketName }}/{{ .CurrentPath }}</strong> yet</p>
{{ end }}
<div id="notifications">
<div id="notification-template" class="card" style="display: none;">
<div class="card-content" style="padding: 12px">
<span class="card-title">Uploading</span>
<p> I am a very simple card </p>
<div class="progress">
<div class="indeterminate"></div>
</div>
</div>
</div>
</div>
</div>
<div class="fixed-action-btn">
<button type="button" class="btn-floating btn-large red modal-trigger" data-target="modal-create-object">
<i class="large material-icons">add</i>
</button>
<button type="button" class="btn-floating btn-large red modal-trigger" data-target="modal-create-folder">
<i class="large material-icons">create_new_folder</i>
</button>
</div>
<div id="modal-create-object" class="modal">
@ -104,6 +127,7 @@
<div class="file-path-wrapper">
<input class="file-path validate" type="text">
</div>
<input type="hidden" name="path" value="{{ $.CurrentPath }}">
</div>
</div>
</div>
@ -117,6 +141,30 @@
</form>
</div>
<div id="modal-create-folder" class="modal">
<form id="create-folder-form" enctype="multipart/form-data">
<div class="modal-content">
<h4>Create Folder</h4>
<br>
<div class="row">
<div class="col s6">
<div class="input-field">
<input name="new-path" id="new-path" type="text">
<label for="new-path">Path</label>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="modal-close waves-effect waves-green btn-flat">Cancel</button>
<button type="submit" class="modal-close waves-effect waves-green btn">Create</button>
</div>
</form>
</div>
<script>
function deleteObject(bucketName, objectName) {
$.ajax({
@ -132,5 +180,51 @@ function deleteBucket(bucketName) {
success: function () { window.location.replace('/buckets'); }
})
}
function handleCreateFolder(event) {
event.preventDefault();
const form = event.target;
const formData = new FormData(form);
const newPath = formData.get("new-path")
let newHref = window.location.href + newPath
if(!newHref.endsWith("/")) {
newHref = newHref + "/"
}
window.location.href = newHref
}
function handleCreateObject(event) {
event.preventDefault();
const form = event.target;
const url = new URL(form.action);
const formData = new FormData(form);
createNotification(formData.get("file").name)
fetch(url, {
method: "POST",
body: formData
}).then(response => {
window.location.reload();
})
}
function createNotification(fileName) {
notificationTemplate = document.getElementById('notification-template');
notification = notificationTemplate.cloneNode(true)
notification.getElementsByTagName('p')[0].setHTML(fileName)
notification.removeAttribute("id")
notification.removeAttribute("style")
notifications = document.getElementById('notifications');
notifications.appendChild(notification)
}
window.onload = (event) => {
document.getElementById('create-folder-form').addEventListener('submit', handleCreateFolder);
document.getElementById('create-object-form').addEventListener('submit', handleCreateObject);
};
</script>
{{ end }}