Initial draft directory select dialog
parent
c19e5e16c8
commit
ca7d263c5b
@ -0,0 +1,73 @@
|
||||
package two.pm.traqtor.editor;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
|
||||
import two.pm.traqtor.editor.dto.ApiError;
|
||||
import two.pm.traqtor.editor.dto.manager.file.DirectoryDTO;
|
||||
|
||||
@Path("api/file-manager")
|
||||
public class FileManagerResource {
|
||||
|
||||
@ConfigProperty(name = "file-manager.home")
|
||||
String home;
|
||||
|
||||
@Path("list-dir")
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response listDir(@QueryParam("path") String path, @QueryParam("hidden") Boolean withHidden)
|
||||
throws InterruptedException {
|
||||
|
||||
if (withHidden != null) {
|
||||
withHidden = true;
|
||||
} else {
|
||||
withHidden = false;
|
||||
}
|
||||
|
||||
if (path == null) {
|
||||
path = "";
|
||||
}
|
||||
|
||||
java.nio.file.Path basePath = Paths.get(home);
|
||||
java.nio.file.Path resolved = basePath.resolve(path);
|
||||
|
||||
if (resolved == null) {
|
||||
return Response.ok(new ApiError("Can not resolve " + path.toUpperCase())).status(Status.BAD_REQUEST)
|
||||
.build();
|
||||
}
|
||||
File targetDir = new File(resolved.toAbsolutePath().toString());
|
||||
if (!targetDir.exists()) {
|
||||
return Response.ok(new ApiError("Directory does not exist")).status(Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
File[] files = targetDir.listFiles();
|
||||
ArrayList<DirectoryDTO> result = new ArrayList<>();
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
if (f.getName().startsWith(".")) {
|
||||
if (withHidden) {
|
||||
result.add(new DirectoryDTO(f.getName(),
|
||||
(basePath.relativize(Paths.get(f.getAbsolutePath()))).toString()));
|
||||
}
|
||||
} else {
|
||||
result.add(new DirectoryDTO(f.getName(),
|
||||
(basePath.relativize(Paths.get(f.getAbsolutePath()))).toString()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return Response.ok(result).build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package two.pm.traqtor.editor.dto;
|
||||
|
||||
public class ApiError {
|
||||
|
||||
public String message;
|
||||
|
||||
public ApiError() {
|
||||
}
|
||||
|
||||
public ApiError(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package two.pm.traqtor.editor.dto.manager.file;
|
||||
|
||||
public class DirectoryDTO {
|
||||
|
||||
public String name;
|
||||
public String path;
|
||||
|
||||
public DirectoryDTO() {
|
||||
}
|
||||
|
||||
public DirectoryDTO(String name, String path) {
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,4 +1,8 @@
|
||||
import Vue from 'vue'
|
||||
import axios from 'axios'
|
||||
import Vue from "vue";
|
||||
import axios from "axios";
|
||||
|
||||
Vue.prototype.$axios = axios
|
||||
Vue.prototype.$axios = axios;
|
||||
const api = axios.create({ baseURL: "/api/" });
|
||||
Vue.prototype.$api = api;
|
||||
|
||||
export { axios, api };
|
||||
|
||||
@ -1,9 +1,113 @@
|
||||
<template>
|
||||
<q-page class="flex flex-center"> </q-page>
|
||||
<q-page class="flex flex-center">
|
||||
<q-btn
|
||||
round
|
||||
stack
|
||||
flat
|
||||
style="width: 240px; height: 240px"
|
||||
@click="showTextLoading"
|
||||
>
|
||||
<q-icon name="folder_open" size="5em" />
|
||||
<div>Open workspace</div>
|
||||
</q-btn>
|
||||
<q-dialog
|
||||
v-model="bar2"
|
||||
persistent
|
||||
transition-show="flip-down"
|
||||
transition-hide="flip-up"
|
||||
>
|
||||
<q-card style="min-width: 25vw">
|
||||
<q-bar>
|
||||
Select workspace folder
|
||||
<q-space />
|
||||
<q-btn dense flat icon="close" v-close-popup>
|
||||
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
|
||||
<q-card-section class="q-pa-none" v-show="!loading">
|
||||
<transition
|
||||
appear
|
||||
enter-active-class="animated fadeIn"
|
||||
leave-active-class="animated fadeOut"
|
||||
>
|
||||
<div>
|
||||
<q-scroll-area
|
||||
dark
|
||||
class="bg-dark text-white rounded-borders"
|
||||
style="height: 205px; min-width: 300px"
|
||||
>
|
||||
<q-list flat separator v-show="!loading">
|
||||
<q-item
|
||||
clickable
|
||||
v-ripple
|
||||
v-for="dir in dirList"
|
||||
:key="dir.name"
|
||||
@click="listDir(dir.path)"
|
||||
>
|
||||
<q-item-section side v-if="dir.back === true">
|
||||
<q-icon name="chevron_left" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label>{{ dir.name }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-icon name="chevron_right" v-if="dir.back !== true" />
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-scroll-area>
|
||||
</div>
|
||||
</transition>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="loading" style="min-height: 205px">
|
||||
<q-inner-loading :showing="loading" style="min-height: 50px">
|
||||
<q-spinner-gears size="50px" />
|
||||
</q-inner-loading>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn flat>select</q-btn>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "PageIndex",
|
||||
data() {
|
||||
return {
|
||||
dirList: [],
|
||||
bar2: false,
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showTextLoading() {
|
||||
this.bar2 = true;
|
||||
this.listDir();
|
||||
},
|
||||
listDir(currentDir) {
|
||||
var self = this;
|
||||
self.loading = true;
|
||||
this.$api
|
||||
.get("file-manager/list-dir", { params: { path: currentDir } })
|
||||
.then((response) => {
|
||||
self.loading = false;
|
||||
const back = [{ name: "Back", path: currentDir + "/..", back: true }];
|
||||
self.dirList = back.concat(response.data);
|
||||
})
|
||||
.catch(() => {
|
||||
this.$q.notify({
|
||||
color: "negative",
|
||||
position: "top",
|
||||
message: "Loading failed",
|
||||
icon: "report_problem",
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue