maintain contextMenu state within component

This commit is contained in:
joshuaboud 2022-06-22 13:37:25 -03:00
parent c42cff88eb
commit b91e24b4ee
No known key found for this signature in database
GPG Key ID: 17EFB59E2A8BF50E
2 changed files with 50 additions and 40 deletions

View File

@ -23,12 +23,13 @@ If not, see <https://www.gnu.org/licenses/>.
leave-active-class="origin-top-left transition ease-in duration-75" leave-active-class="origin-top-left transition ease-in duration-75"
leave-from-class="transform opacity-100 scale-100" leave-from-class="transform opacity-100 scale-100"
leave-to-class="transform opacity-0 scale-95" leave-to-class="transform opacity-0 scale-95"
@after-leave="reset"
> >
<div <div
v-if="show" v-if="show"
class="fixed inset-0 bg-transparent" class="fixed inset-0 bg-transparent"
@click="$emit('hide')" @click="show = false"
@contextmenu.prevent="$emit('hide')" @contextmenu.prevent="show = false"
> >
<div <div
class="fixed z-20 max-w-sm flex flex-col items-stretch bg-default shadow-lg divide-y divide-default position-contextmenu"> class="fixed z-20 max-w-sm flex flex-col items-stretch bg-default shadow-lg divide-y divide-default position-contextmenu">
@ -214,7 +215,7 @@ If not, see <https://www.gnu.org/licenses/>.
</template> </template>
<script> <script>
import { inject } from 'vue' import { inject, ref, computed } from 'vue'
import { import {
ArrowLeftIcon, ArrowLeftIcon,
ArrowRightIcon, ArrowRightIcon,
@ -235,16 +236,45 @@ import { pathHistoryInjectionKey } from '../keys';
export default { export default {
props: { props: {
show: Boolean, currentPath: Object,
event: Object,
selection: Array,
currentDirEntry: Object,
}, },
setup(props, { emit }) { setup(props, { emit }) {
const pathHistory = inject(pathHistoryInjectionKey); const pathHistory = inject(pathHistoryInjectionKey);
const show = ref();
const event = ref();
const selection = ref();
const currentDirEntry = computed(() => ({
...props.currentPath,
name: `Current directory (${props.currentPath.path.split('/').pop()})`
}));
/**
* Open the context menu
*
* @param {MouseEvent} event_ - event triggering the menu to be opened
* @param {DirectoryEntryObj[]} selection_ - items selected at event trigger
*/
const open = (event_, selection_) => {
event.value = event_;
selection.value = [...selection_];
show.value = true;
}
const reset = () => {
event.value = null;
selection.value = [];
}
return { return {
// data
pathHistory, pathHistory,
show,
event,
selection,
currentDirEntry,
// methods
open,
reset,
} }
}, },
components: { components: {

View File

@ -190,12 +190,9 @@
@hide="nameEditor.close" @hide="nameEditor.close"
/> />
<ContextMenu <ContextMenu
:show="contextMenu.show" :currentPath="pathHistory.current() ?? { path: '/', host: 'localhost' }"
:selection="contextMenu.selection"
:event="contextMenu.event"
:currentDirEntry="{ ...pathHistory.current(), name: `Current directory (${pathHistory.current().path.split('/').pop()})` }"
@browserAction="handleAction" @browserAction="handleAction"
@hide="contextMenu.close" ref="contextMenuRef"
/> />
<ModalPrompt ref="modalPromptRef" /> <ModalPrompt ref="modalPromptRef" />
<Teleport to="#footer-buttons"> <Teleport to="#footer-buttons">
@ -290,10 +287,10 @@ export default {
const darkMode = inject('darkModeInjectionKey'); const darkMode = inject('darkModeInjectionKey');
const settings = inject(settingsInjectionKey); const settings = inject(settingsInjectionKey);
const notifications = inject(notificationsInjectionKey); const notifications = inject(notificationsInjectionKey);
const pathHistory = inject(pathHistoryInjectionKey);
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const pathHistory = inject(pathHistoryInjectionKey);
const directoryViewRef = ref();
const searchFilterStr = ref(""); const searchFilterStr = ref("");
const searchFilterRegExp = ref(/^/g); const searchFilterRegExp = ref(/^/g);
const backHistoryDropdown = reactive({ const backHistoryDropdown = reactive({
@ -404,25 +401,8 @@ export default {
}, 500); }, 500);
}, },
}); });
const contextMenu = reactive({ const directoryViewRef = ref();
show: false, const contextMenuRef = ref();
selection: [],
event: null,
resetTimeoutHandle: null,
open: (event) => {
clearTimeout(contextMenu.resetTimeoutHandle);
contextMenu.selection = getSelected();
contextMenu.event = event;
contextMenu.show = true;
},
close: () => {
contextMenu.show = false;
contextMenu.resetTimeoutHandle = setTimeout(() => {
contextMenu.resetTimeoutHandle = contextMenu.selection = [];
contextMenu.resetTimeoutHandle = contextMenu.event = null;
}, 500);
},
});
const modalPromptRef = ref(); const modalPromptRef = ref();
const cd = ({ path, host }) => { const cd = ({ path, host }) => {
@ -455,7 +435,6 @@ export default {
return `cockpit-navigator-dowload_${now.getFullYear()}-${now.getMonth()+1}-${now.getDay()}_${now.getHours()}-${now.getMinutes()}-${now.getSeconds()}.zip`; return `cockpit-navigator-dowload_${now.getFullYear()}-${now.getMonth()+1}-${now.getDay()}_${now.getHours()}-${now.getMinutes()}-${now.getSeconds()}.zip`;
} }
let items = [].concat(selection); // forces to be array let items = [].concat(selection); // forces to be array
console.log(items);
if (items.length > 1) { if (items.length > 1) {
const dirs = items.filter(item => item.type === 'd').map(item => item.path); const dirs = items.filter(item => item.type === 'd').map(item => item.path);
if (dirs.length) { if (dirs.length) {
@ -464,7 +443,6 @@ export default {
items = items.filter(item => !containedRegex.test(item.path)); items = items.filter(item => !containedRegex.test(item.path));
} }
const { common, relativePaths } = commonPath(items.map(item => item.path)); const { common, relativePaths } = commonPath(items.map(item => item.path));
console.log(common, relativePaths);
streamProcDownload(['zip', '-rq', '-', ...relativePaths], getZipName(), { superuser: 'try', directory: common }); streamProcDownload(['zip', '-rq', '-', ...relativePaths], getZipName(), { superuser: 'try', directory: common });
} else { } else {
let { path, name, host, resolvedType } = items[0]; let { path, name, host, resolvedType } = items[0];
@ -539,7 +517,6 @@ export default {
); );
if (!result) if (!result)
return; // cancelled return; // cancelled
console.log(result);
try { try {
const parentPath = parentEntry.resolvedType === 'd' ? parentEntry.resolvedPath : parentEntry.path.split('/').slice(0, -1).join('/'); const parentPath = parentEntry.resolvedType === 'd' ? parentEntry.resolvedPath : parentEntry.path.split('/').slice(0, -1).join('/');
const path = `${parentPath}/${result.linkName}` const path = `${parentPath}/${result.linkName}`
@ -579,7 +556,8 @@ export default {
download(...args); download(...args);
break; break;
case 'contextMenu': case 'contextMenu':
contextMenu.open(...args); const [event] = [...args];
contextMenuRef.value.open(event, getSelected());
break; break;
case 'back': case 'back':
back(); back();
@ -636,11 +614,10 @@ export default {
return { return {
cockpit, cockpit,
console, // data
darkMode, darkMode,
settings, settings,
pathHistory, pathHistory,
directoryViewRef,
searchFilterStr, searchFilterStr,
searchFilterRegExp, searchFilterRegExp,
backHistoryDropdown, backHistoryDropdown,
@ -649,8 +626,11 @@ export default {
confirm, confirm,
filePermissions, filePermissions,
nameEditor, nameEditor,
contextMenu, // component refs
directoryViewRef,
contextMenuRef,
modalPromptRef, modalPromptRef,
// methods
cd, cd,
back, back,
forward, forward,