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 Vue from "vue";
|
||||||
import axios from 'axios'
|
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>
|
<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>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "PageIndex",
|
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>
|
</script>
|
||||||
|
|||||||
Loading…
Reference in New Issue