feat: Added layered prompt support(#2659)

This commit is contained in:
ArthurMousatov 2023-08-23 00:47:36 -04:00
parent 184b7c14f2
commit df8349e352
17 changed files with 80 additions and 66 deletions

View File

@ -90,10 +90,10 @@ export default {
}; };
}, },
watch: { watch: {
show(val, old) { currentPrompt(val, old) {
this.active = val === "search"; this.active = val.prompt === "search";
if (old === "search" && !this.active) { if (old.prompt === "search" && !this.active) {
if (this.reload) { if (this.reload) {
this.setReload(true); this.setReload(true);
} }
@ -116,8 +116,8 @@ export default {
}, },
}, },
computed: { computed: {
...mapState(["user", "show"]), ...mapState(["user"]),
...mapGetters(["isListing"]), ...mapGetters(["isListing", "currentPrompt"]),
boxes() { boxes() {
return boxes; return boxes;
}, },

View File

@ -133,9 +133,9 @@ export default {
}, },
computed: { computed: {
...mapState(["user"]), ...mapState(["user"]),
...mapGetters(["isLogged"]), ...mapGetters(["isLogged", "currentPrompt"]),
active() { active() {
return this.$store.state.show === "sidebar"; return this.currentPrompt.prompt === "sidebar";
}, },
signup: () => signup, signup: () => signup,
version: () => version, version: () => version,

View File

@ -11,7 +11,7 @@
<slot /> <slot />
<div id="dropdown" :class="{ active: this.$store.state.show === 'more' }"> <div id="dropdown" :class="{ active: this.currentPrompt.prompt === 'more' }">
<slot name="actions" /> <slot name="actions" />
</div> </div>
@ -25,7 +25,7 @@
<div <div
class="overlay" class="overlay"
v-show="this.$store.state.show == 'more'" v-show="this.currentPrompt.prompt == 'more'"
@click="$store.commit('closeHovers')" @click="$store.commit('closeHovers')"
/> />
</header> </header>
@ -35,6 +35,7 @@
import { logoURL } from "@/utils/constants"; import { logoURL } from "@/utils/constants";
import Action from "@/components/header/Action"; import Action from "@/components/header/Action";
import { mapGetters } from "vuex";
export default { export default {
name: "header-bar", name: "header-bar",
@ -52,6 +53,9 @@ export default {
this.$store.commit("showHover", "sidebar"); this.$store.commit("showHover", "sidebar");
}, },
}, },
computed: {
...mapGetters(["currentPrompt"]),
}
}; };
</script> </script>

View File

@ -37,8 +37,8 @@ import buttons from "@/utils/buttons";
export default { export default {
name: "delete", name: "delete",
computed: { computed: {
...mapGetters(["isListing", "selectedCount"]), ...mapGetters(["isListing", "selectedCount", "currentPrompt"]),
...mapState(["req", "selected", "showConfirm"]), ...mapState(["req", "selected"]),
}, },
methods: { methods: {
...mapMutations(["closeHovers"]), ...mapMutations(["closeHovers"]),
@ -50,7 +50,7 @@ export default {
await api.remove(this.$route.path); await api.remove(this.$route.path);
buttons.success("delete"); buttons.success("delete");
this.showConfirm(); this.currentPrompt?.confirm();
this.closeHovers(); this.closeHovers();
return; return;
} }

View File

@ -11,7 +11,7 @@
v-for="(ext, format) in formats" v-for="(ext, format) in formats"
:key="format" :key="format"
class="button button--block" class="button button--block"
@click="showConfirm(format)" @click="currentPrompt.confirm(format)"
v-focus v-focus
> >
{{ ext }} {{ ext }}
@ -21,7 +21,7 @@
</template> </template>
<script> <script>
import { mapState } from "vuex"; import { mapGetters } from "vuex";
export default { export default {
name: "download", name: "download",
@ -38,6 +38,8 @@ export default {
}, },
}; };
}, },
computed: mapState(["showConfirm"]), computed: {
...mapGetters(["currentPrompt"]),
},
}; };
</script> </script>

View File

@ -9,6 +9,17 @@
</div> </div>
<div class="card-action"> <div class="card-action">
<div v-if="user.perm.create">
<button
class="button button--flat"
@click="$store.commit('showHover', 'newDir')"
:aria-label="$t('sidebar.newFolder')"
:title="$t('sidebar.newFolder')"
>
<i class="material-icons">create_new_folder</i>
<span>{{ $t("sidebar.newFolder") }}</span>
</button>
</div>
<button <button
class="button button--flat button--grey" class="button button--flat button--grey"
@click="$store.commit('closeHovers')" @click="$store.commit('closeHovers')"
@ -46,7 +57,7 @@ export default {
dest: null, dest: null,
}; };
}, },
computed: mapState(["req", "selected"]), computed: mapState(["req", "selected", "user"]),
methods: { methods: {
move: async function (event) { move: async function (event) {
event.preventDefault(); event.preventDefault();

View File

@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<component ref="currentComponent" :is="currentComponent"></component> <component ref="getCurrentPrompt" :is="getCurrentPrompt"></component>
<div v-show="showOverlay" @click="resetPrompts" class="overlay"></div> <div v-show="showOverlay" @click="resetPrompts" class="overlay"></div>
</div> </div>
</template> </template>
@ -20,7 +20,7 @@ import ReplaceRename from "./ReplaceRename";
import Share from "./Share"; import Share from "./Share";
import Upload from "./Upload"; import Upload from "./Upload";
import ShareDelete from "./ShareDelete"; import ShareDelete from "./ShareDelete";
import { mapState } from "vuex"; import { mapGetters, mapState } from "vuex";
import buttons from "@/utils/buttons"; import buttons from "@/utils/buttons";
export default { export default {
@ -52,7 +52,7 @@ export default {
}, },
created() { created() {
window.addEventListener("keydown", (event) => { window.addEventListener("keydown", (event) => {
if (this.show == null) return; if (this.currentPrompt == null) return;
let prompt = this.$refs.currentComponent; let prompt = this.$refs.currentComponent;
@ -64,7 +64,7 @@ export default {
// Enter // Enter
if (event.keyCode == 13) { if (event.keyCode == 13) {
switch (this.show) { switch (this.currentPrompt.prompt) {
case "delete": case "delete":
prompt.submit(); prompt.submit();
break; break;
@ -82,31 +82,15 @@ export default {
}); });
}, },
computed: { computed: {
...mapState(["show", "plugins"]), ...mapState(["plugins"]),
currentComponent: function () { ...mapGetters(["currentPrompt"]),
const matched =
[
"info",
"help",
"delete",
"rename",
"move",
"copy",
"newFile",
"newDir",
"download",
"replace",
"replace-rename",
"share",
"upload",
"share-delete",
].indexOf(this.show) >= 0;
return (matched && this.show) || null;
},
showOverlay: function () { showOverlay: function () {
return ( return (
this.show !== null && this.show !== "search" && this.show !== "more" this.currentPrompt !== null &&
this.currentPrompt.prompt
!== "search" &&
this.currentPrompt.prompt
!== "more"
); );
}, },
}, },

View File

@ -19,7 +19,7 @@
</button> </button>
<button <button
class="button button--flat button--blue" class="button button--flat button--blue"
@click="showAction" @click="currentPrompt.action"
:aria-label="$t('buttons.continue')" :aria-label="$t('buttons.continue')"
:title="$t('buttons.continue')" :title="$t('buttons.continue')"
> >
@ -27,7 +27,7 @@
</button> </button>
<button <button
class="button button--flat button--red" class="button button--flat button--red"
@click="showConfirm" @click="currentPrompt.confirm"
:aria-label="$t('buttons.replace')" :aria-label="$t('buttons.replace')"
:title="$t('buttons.replace')" :title="$t('buttons.replace')"
> >
@ -38,10 +38,10 @@
</template> </template>
<script> <script>
import { mapState } from "vuex"; import { mapGetters } from "vuex";
export default { export default {
name: "replace", name: "replace",
computed: mapState(["showConfirm", "showAction"]), computed: mapGetters(["currentPrompt"]),
}; };
</script> </script>

View File

@ -19,7 +19,7 @@
</button> </button>
<button <button
class="button button--flat button--blue" class="button button--flat button--blue"
@click="(event) => showConfirm(event, 'rename')" @click="(event) => currentPrompt.confirm(event, 'rename')"
:aria-label="$t('buttons.rename')" :aria-label="$t('buttons.rename')"
:title="$t('buttons.rename')" :title="$t('buttons.rename')"
> >
@ -27,7 +27,7 @@
</button> </button>
<button <button
class="button button--flat button--red" class="button button--flat button--red"
@click="(event) => showConfirm(event, 'overwrite')" @click="(event) => currentPrompt.confirm(event, 'overwrite')"
:aria-label="$t('buttons.replace')" :aria-label="$t('buttons.replace')"
:title="$t('buttons.replace')" :title="$t('buttons.replace')"
> >
@ -38,10 +38,10 @@
</template> </template>
<script> <script>
import { mapState } from "vuex"; import { mapGetters } from "vuex";
export default { export default {
name: "replace-rename", name: "replace-rename",
computed: mapState(["showConfirm"]), computed: mapGetters(["currentPrompt"]),
}; };
</script> </script>

View File

@ -25,16 +25,16 @@
</template> </template>
<script> <script>
import { mapState } from "vuex"; import { mapGetters } from "vuex";
export default { export default {
name: "share-delete", name: "share-delete",
computed: { computed: {
...mapState(["showConfirm"]), ...mapGetters(["currentPrompt"]),
}, },
methods: { methods: {
submit: function () { submit: function () {
this.showConfirm(); this.currentPrompt?.confirm();
}, },
}, },
}; };

View File

@ -43,6 +43,9 @@ const getters = {
return files.sort((a, b) => a.progress - b.progress); return files.sort((a, b) => a.progress - b.progress);
}, },
currentPrompt: (state) => {
return state.prompts.length > 0 ? state.prompts[state.prompts.length - 1] : null;
},
}; };
export default getters; export default getters;

View File

@ -20,10 +20,8 @@ const state = {
reload: false, reload: false,
selected: [], selected: [],
multiple: false, multiple: false,
show: null, prompts: [],
showShell: false, showShell: false,
showConfirm: null,
showAction: null,
}; };
export default new Vuex.Store({ export default new Vuex.Store({

View File

@ -4,6 +4,8 @@ import moment from "moment";
const mutations = { const mutations = {
closeHovers: (state) => { closeHovers: (state) => {
state.show = null; state.show = null;
state.prompts.pop();
console.log(state.prompts);
state.showConfirm = null; state.showConfirm = null;
state.showAction = null; state.showAction = null;
}, },
@ -13,10 +15,16 @@ const mutations = {
showHover: (state, value) => { showHover: (state, value) => {
if (typeof value !== "object") { if (typeof value !== "object") {
state.show = value; state.show = value;
state.prompts.push({
prompt: value,
confirm: null,
action: null
});
return; return;
} }
state.show = value.prompt; state.show = value.prompt;
state.prompts.push(value);
state.showConfirm = value.confirm; state.showConfirm = value.confirm;
if (value.action !== undefined) { if (value.action !== undefined) {
state.showAction = value.action; state.showAction = value.action;
@ -24,9 +32,11 @@ const mutations = {
}, },
showError: (state) => { showError: (state) => {
state.show = "error"; state.show = "error";
state.prompts.push("error");
}, },
showSuccess: (state) => { showSuccess: (state) => {
state.show = "success"; state.show = "success";
state.prompts.push("success");
}, },
setLoading: (state, value) => { setLoading: (state, value) => {
state.loading = value; state.loading = value;

View File

@ -50,7 +50,7 @@ export default {
}; };
}, },
computed: { computed: {
...mapState(["req", "reload", "loading", "show"]), ...mapState(["req", "reload", "loading"]),
currentView() { currentView() {
if (this.req.type == undefined) { if (this.req.type == undefined) {
return null; return null;

View File

@ -30,7 +30,7 @@ export default {
UploadFiles, UploadFiles,
}, },
computed: { computed: {
...mapGetters(["isLogged", "progress"]), ...mapGetters(["isLogged", "progress", "currentPrompt"]),
...mapState(["user"]), ...mapState(["user"]),
isExecEnabled: () => enableExec, isExecEnabled: () => enableExec,
}, },
@ -38,7 +38,7 @@ export default {
$route: function () { $route: function () {
this.$store.commit("resetSelected"); this.$store.commit("resetSelected");
this.$store.commit("multiple", false); this.$store.commit("multiple", false);
if (this.$store.state.show !== "success") if (this.currentPrompt.prompt !== "success")
this.$store.commit("closeHovers"); this.$store.commit("closeHovers");
}, },
}, },

View File

@ -143,7 +143,7 @@
</template> </template>
<script> <script>
import { mapState } from "vuex"; import { mapGetters, mapState } from "vuex";
import { files as api } from "@/api"; import { files as api } from "@/api";
import { resizePreview } from "@/utils/constants"; import { resizePreview } from "@/utils/constants";
import url from "@/utils/url"; import url from "@/utils/url";
@ -177,7 +177,8 @@ export default {
}; };
}, },
computed: { computed: {
...mapState(["req", "user", "oldReq", "jwt", "loading", "show"]), ...mapState(["req", "user", "oldReq", "jwt", "loading"]),
...mapGetters(["currentPrompt"]),
hasPrevious() { hasPrevious() {
return this.previousLink !== ""; return this.previousLink !== "";
}, },
@ -195,7 +196,7 @@ export default {
return api.getDownloadURL(this.req, true); return api.getDownloadURL(this.req, true);
}, },
showMore() { showMore() {
return this.$store.state.show === "more"; return this.currentPrompt.prompt === "more";
}, },
isResizeEnabled() { isResizeEnabled() {
return resizePreview; return resizePreview;
@ -247,7 +248,7 @@ export default {
this.$router.replace({ path: this.nextLink }); this.$router.replace({ path: this.nextLink });
}, },
key(event) { key(event) {
if (this.show !== null) { if (this.currentPrompt !== null) {
return; return;
} }

View File

@ -37,7 +37,7 @@
</form> </form>
</div> </div>
<div v-if="$store.state.show === 'deleteUser'" class="card floating"> <div v-if="this.currentPrompt.prompt === 'deleteUser'" class="card floating">
<div class="card-content"> <div class="card-content">
<p>Are you sure you want to delete this user?</p> <p>Are you sure you want to delete this user?</p>
</div> </div>
@ -61,7 +61,7 @@
</template> </template>
<script> <script>
import { mapState, mapMutations } from "vuex"; import { mapState, mapMutations, mapGetters } from "vuex";
import { users as api, settings } from "@/api"; import { users as api, settings } from "@/api";
import UserForm from "@/components/settings/UserForm"; import UserForm from "@/components/settings/UserForm";
import Errors from "@/views/Errors"; import Errors from "@/views/Errors";
@ -89,6 +89,7 @@ export default {
return this.$route.path === "/settings/users/new"; return this.$route.path === "/settings/users/new";
}, },
...mapState(["loading"]), ...mapState(["loading"]),
...mapGetters(["currentPrompt"])
}, },
watch: { watch: {
$route: "fetchData", $route: "fetchData",