✨ Add functionality to create files/folders
This commit is contained in:
parent
4e29f826fd
commit
38a74e55cd
|
@ -74,6 +74,33 @@ export class FileSocketHandler extends AgentSocketHandler {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
agentSocket.on("createFile", async (stackName: unknown, path: unknown, isFolder: unknown, fileName: unknown, callback) => {
|
||||
try {
|
||||
checkLogin(socket);
|
||||
|
||||
if (typeof(path) !== "string") {
|
||||
throw new ValidationError("Path must be a string");
|
||||
}
|
||||
if (typeof(isFolder) !== "boolean") {
|
||||
throw new ValidationError("isFolder must be a boolean");
|
||||
}
|
||||
if (typeof(fileName) !== "string") {
|
||||
throw new ValidationError("File Name must be a string");
|
||||
}
|
||||
|
||||
const stack = await this.getStack(server, stackName);
|
||||
await stack.newFile(path, fileName, isFolder);
|
||||
|
||||
callbackResult({
|
||||
ok: true,
|
||||
}, callback);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
log.warn("agent", e.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async getStack(server : DockgeServer, stackName: unknown) {
|
||||
|
|
|
@ -585,4 +585,15 @@ export class Stack {
|
|||
await fsAsync.writeFile(f, content);
|
||||
return true;
|
||||
}
|
||||
|
||||
async newFile(p: string, fileName: string, isFolder: boolean) {
|
||||
const f = path.join(this.dataDir, p, fileName);
|
||||
if (!await fileExists(f)) {
|
||||
if (isFolder) {
|
||||
await fsAsync.mkdir(f);
|
||||
} else {
|
||||
await fsAsync.writeFile(f, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,12 @@ export class ValidationError extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
export class FileAccessError extends Error {
|
||||
constructor(message : string) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
export function callbackError(error : unknown, callback : unknown) {
|
||||
if (typeof(callback) !== "function") {
|
||||
log.error("console", "Callback is not a function");
|
||||
|
|
|
@ -12,7 +12,11 @@ export default defineComponent({
|
|||
return {
|
||||
files: [],
|
||||
selected: [],
|
||||
currentPath: "/"
|
||||
currentPath: "/",
|
||||
newFileData: {
|
||||
isFolder: false,
|
||||
fileName: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -23,6 +27,16 @@ export default defineComponent({
|
|||
endpoint() {
|
||||
return this.$route.params.endpoint || "";
|
||||
},
|
||||
|
||||
newFileLabel() {
|
||||
return this.newFileData.isFolder ? {
|
||||
title: "createFolder",
|
||||
placeholder: "folderName",
|
||||
} : {
|
||||
title: "createFile",
|
||||
placeholder: "fileName",
|
||||
};
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.loadDir("/");
|
||||
|
@ -65,7 +79,30 @@ export default defineComponent({
|
|||
this.currentPath = dir;
|
||||
this.files = res.files;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
openNewFileModel(isFolder: boolean = false) {
|
||||
this.newFileData.isFolder = isFolder;
|
||||
this.newFileData.fileName = "";
|
||||
this.newFileData.fileName = "";
|
||||
this.$refs.createFileModal.show();
|
||||
},
|
||||
|
||||
newFile() {
|
||||
// Check file
|
||||
const filter = this.files.filter(f => f.name === this.newFileData.fileName);
|
||||
if (filter.length > 0) {
|
||||
this.$root.toastError("File Exist");
|
||||
return;
|
||||
}
|
||||
this.$root.emitAgent(this.endpoint, "createFile", this.stackName, this.currentPath, this.newFileData.isFolder
|
||||
, this.newFileData.fileName, (res) => {
|
||||
if (res.ok) {
|
||||
this.$root.toastSuccess("Created");
|
||||
this.loadDir(this.currentPath);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@ -77,11 +114,11 @@ export default defineComponent({
|
|||
<p class="tips">这里只会展示位于 ${DATA} (/opt/docker/[stackName]) 目录的文件</p>
|
||||
<div>
|
||||
<div class="btn-group me-2">
|
||||
<button class="btn btn-dark">
|
||||
<button class="btn btn-dark" @click="openNewFileModel(false)">
|
||||
<font-awesome-icon icon="file" />
|
||||
{{ $t("newFile") }}
|
||||
</button>
|
||||
<button class="btn btn-dark">
|
||||
<button class="btn btn-dark" @click="openNewFileModel(true)">
|
||||
<font-awesome-icon icon="folder" />
|
||||
{{ $t("newFolder") }}
|
||||
</button>
|
||||
|
@ -124,6 +161,12 @@ export default defineComponent({
|
|||
</div>
|
||||
|
||||
<FileEditor ref="fileEditor" :endpoint="endpoint" :stack-name="stackName" />
|
||||
<Confirm ref="createFileModal" :title="$t(newFileLabel.title)" @yes="newFile">
|
||||
<input
|
||||
v-model="newFileData.fileName" class="form-control"
|
||||
:placeholder="$t(newFileLabel.placeholder)"
|
||||
/>
|
||||
</Confirm>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue