mirror of
https://github.com/45Drives/cockpit-navigator.git
synced 2025-07-30 00:55:30 +02:00
add context menu
This commit is contained in:
parent
b96902391e
commit
116a422320
86
navigator/src/components/ContextMenu.vue
Normal file
86
navigator/src/components/ContextMenu.vue
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<transition enter-active-class="origin-top-left transition ease-out duration-100" enter-from-class="transform opacity-0 scale-95"
|
||||||
|
enter-to-class="transform opacity-100 scale-100" leave-active-class="origin-top-left transition ease-in duration-75"
|
||||||
|
leave-from-class="transform opacity-100 scale-100" leave-to-class="transform opacity-0 scale-95">
|
||||||
|
<div v-if="show" class="fixed inset-0 bg-transparent" @click="$emit('hide')">
|
||||||
|
<div class="fixed z-20 max-w-sm flex flex-col items-stretch bg-default shadow-lg divide-y divide-default position-contextmenu">
|
||||||
|
<div class="flex items-stretch">
|
||||||
|
<button :disabled="!pathHistory?.backAllowed()" @click="$emit('browserAction', 'back')" :class="{'grow flex items-center justify-center p-2': true, 'hover:bg-red-600/10': pathHistory?.backAllowed()}">
|
||||||
|
<ArrowLeftIcon class="size-icon icon-default" />
|
||||||
|
</button>
|
||||||
|
<button :disabled="!pathHistory?.forwardAllowed()" @click="$emit('browserAction', 'forward')" :class="{'grow flex items-center justify-center p-2': true, 'hover:bg-red-600/10': pathHistory?.forwardAllowed()}">
|
||||||
|
<ArrowRightIcon class="size-icon icon-default" />
|
||||||
|
</button>
|
||||||
|
<button @click="$emit('browserAction', 'up')" class="grow hover:bg-red-600/10 flex items-center justify-center p-2">
|
||||||
|
<ArrowUpIcon class="size-icon icon-default" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col items-stretch">
|
||||||
|
<!-- general actions -->
|
||||||
|
<button v-if="entry?.path !== '/'" @click="$emit('browserAction', 'editPermissions', entry)" class="context-menu-button">
|
||||||
|
Edit permissions
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div v-if="entry?.resolvedType === 'f'" class="flex flex-col items-stretch">
|
||||||
|
<!-- regular file actions -->
|
||||||
|
<button @click="$emit('browserAction', 'edit', entry)" class="context-menu-button">
|
||||||
|
Edit contents
|
||||||
|
</button>
|
||||||
|
<button @click="$emit('browserAction', 'download', entry)" class="context-menu-button">
|
||||||
|
Download
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="entry?.resolvedType === 'd'" class="flex flex-col items-stretch">
|
||||||
|
<!-- directory actions -->
|
||||||
|
<button @click="$emit('browserAction', 'cd', entry)" class="context-menu-button">
|
||||||
|
Open
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div v-if="entry?.type === 'l'" class="flex flex-col items-stretch">
|
||||||
|
<!-- link actions -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { inject } from 'vue'
|
||||||
|
import { ArrowLeftIcon, ArrowRightIcon, ArrowUpIcon } from '@heroicons/vue/solid';
|
||||||
|
import { pathHistoryInjectionKey } from '../keys';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
show: Boolean,
|
||||||
|
event: Object,
|
||||||
|
entry: Object,
|
||||||
|
},
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const pathHistory = inject(pathHistoryInjectionKey);
|
||||||
|
|
||||||
|
return {
|
||||||
|
pathHistory,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
ArrowLeftIcon,
|
||||||
|
ArrowRightIcon,
|
||||||
|
ArrowUpIcon,
|
||||||
|
},
|
||||||
|
emits: [
|
||||||
|
'hide',
|
||||||
|
'browserAction',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
div.position-contextmenu {
|
||||||
|
top: v-bind(`${event?.clientY ?? 0}px`);
|
||||||
|
left: v-bind(`${event?.clientX ?? 0}px`);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.context-menu-button {
|
||||||
|
@apply text-default hover:bg-red-600/10 font-normal px-4 py-2 text-sm text-left;
|
||||||
|
}
|
||||||
|
</style>
|
@ -4,14 +4,14 @@
|
|||||||
:class="{ 'select-none dir-entry': true, '!bg-red-600/10': hover && !entry.selected, '!bg-red-600/20': hover && entry.selected, 'dir-entry-selected': entry.selected, 'suppress-border-t': suppressBorderT, 'suppress-border-b': suppressBorderB }">
|
:class="{ 'select-none dir-entry': true, '!bg-red-600/10': hover && !entry.selected, '!bg-red-600/20': hover && entry.selected, 'dir-entry-selected': entry.selected, 'suppress-border-t': suppressBorderT, 'suppress-border-b': suppressBorderB }">
|
||||||
<td class="!pl-1 relative">
|
<td class="!pl-1 relative">
|
||||||
<div :class="[entry.cut ? 'line-through' : '', 'flex items-center gap-1']">
|
<div :class="[entry.cut ? 'line-through' : '', 'flex items-center gap-1']">
|
||||||
<div class="w-6" v-for="i in Array(level).fill(0)" v-memo="[level]"></div>
|
<div class="w-6" v-for="i in Array(level).fill(0).keys()" :key="i" v-memo="[level]"></div>
|
||||||
<div class="relative w-6" :class="[entry.cut ? 'text-gray-500/50' : 'icon-default']">
|
<div class="relative w-6" :class="[entry.cut ? 'text-gray-500/50' : 'icon-default']">
|
||||||
<FolderIcon v-if="entry.resolvedType === 'd'" class="size-icon" />
|
<FolderIcon v-if="entry.resolvedType === 'd'" class="size-icon" />
|
||||||
<DocumentIcon v-else class="size-icon" />
|
<DocumentIcon v-else class="size-icon" />
|
||||||
<LinkIcon v-if="entry.type === 'l'" class="w-2 h-2 absolute right-0 bottom-0 text-default" />
|
<LinkIcon v-if="entry.type === 'l'" class="w-2 h-2 absolute right-0 bottom-0 text-default" />
|
||||||
</div>
|
</div>
|
||||||
<button class="z-10 icon-default" v-if="entry.resolvedType === 'd'" @click.stop="toggleShowEntries" @mouseenter="hover = true"
|
<button class="z-10 icon-default" v-if="entry.resolvedType === 'd'" @click.stop="toggleShowEntries"
|
||||||
@mouseleave="hover = false">
|
@mouseenter="hover = true" @mouseleave="hover = false">
|
||||||
<ChevronDownIcon v-if="!showEntries" class="size-icon" />
|
<ChevronDownIcon v-if="!showEntries" class="size-icon" />
|
||||||
<ChevronUpIcon v-else class="size-icon" />
|
<ChevronUpIcon v-else class="size-icon" />
|
||||||
</button>
|
</button>
|
||||||
@ -27,31 +27,21 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="absolute left-0 top-0 bottom-0 w-full max-w-[50vw]" @mouseup.stop
|
<div class="absolute left-0 top-0 bottom-0 w-full max-w-[50vw]" @mouseup.stop
|
||||||
@click.prevent="$emit('directoryViewAction', 'toggleSelected', entry, $event)"
|
@click.prevent="$emit('directoryViewAction', 'toggleSelected', entry, $event)"
|
||||||
|
@contextmenu.prevent.stop="$emit('browserAction', 'contextMenu', entry, $event)"
|
||||||
@dblclick="doubleClickCallback" @mouseenter="hover = true" @mouseleave="hover = false"
|
@dblclick="doubleClickCallback" @mouseenter="hover = true" @mouseleave="hover = false"
|
||||||
ref="selectIntersectElement" />
|
ref="selectIntersectElement" />
|
||||||
</td>
|
</td>
|
||||||
<td v-if="settings?.directoryView?.cols?.mode" class="font-mono">{{ entry.modeStr
|
<td v-if="settings?.directoryView?.cols?.mode" class="font-mono">{{ entry.modeStr }}</td>
|
||||||
}}</td>
|
<td v-if="settings?.directoryView?.cols?.owner">{{ entry.owner }}</td>
|
||||||
<td v-if="settings?.directoryView?.cols?.owner">{{ entry.owner }}
|
<td v-if="settings?.directoryView?.cols?.group">{{ entry.group }} </td>
|
||||||
</td>
|
<td v-if="settings?.directoryView?.cols?.size" class="font-mono text-right">{{ entry.sizeHuman }}</td>
|
||||||
<td v-if="settings?.directoryView?.cols?.group">{{ entry.group }}
|
<td v-if="settings?.directoryView?.cols?.btime">{{ entry.btimeStr }}</td>
|
||||||
</td>
|
<td v-if="settings?.directoryView?.cols?.mtime">{{ entry.mtimeStr }}</td>
|
||||||
<td v-if="settings?.directoryView?.cols?.size" class="font-mono text-right">{{
|
<td v-if="settings?.directoryView?.cols?.atime">{{ entry.atimeStr }}</td>
|
||||||
entry.sizeHuman
|
|
||||||
}}</td>
|
|
||||||
<td v-if="settings?.directoryView?.cols?.btime">{{
|
|
||||||
entry.btimeStr
|
|
||||||
}}</td>
|
|
||||||
<td v-if="settings?.directoryView?.cols?.mtime">{{
|
|
||||||
entry.mtimeStr
|
|
||||||
}}</td>
|
|
||||||
<td v-if="settings?.directoryView?.cols?.atime">{{
|
|
||||||
entry.atimeStr
|
|
||||||
}}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<component :is="DirectoryEntryList" v-if="entry.resolvedType === 'd' && showEntries" :host="host" :path="entry.path"
|
<component :is="DirectoryEntryList" v-if="entry.resolvedType === 'd' && showEntries" :host="host"
|
||||||
:isChild="true" :sortCallback="inheritedSortCallback" :searchFilterRegExp="searchFilterRegExp"
|
:path="entry.path" :isChild="true" :sortCallback="inheritedSortCallback"
|
||||||
@startProcessing="(...args) => $emit('startProcessing', ...args)"
|
:searchFilterRegExp="searchFilterRegExp" @startProcessing="(...args) => $emit('startProcessing', ...args)"
|
||||||
@stopProcessing="(...args) => $emit('stopProcessing', ...args)" @cancelShowEntries="showEntries = false"
|
@stopProcessing="(...args) => $emit('stopProcessing', ...args)" @cancelShowEntries="showEntries = false"
|
||||||
ref="directoryEntryListRef" :level="level + 1" :selectedCount="selectedCount"
|
ref="directoryEntryListRef" :level="level + 1" :selectedCount="selectedCount"
|
||||||
@browserAction="(...args) => $emit('browserAction', ...args)"
|
@browserAction="(...args) => $emit('browserAction', ...args)"
|
||||||
@ -59,8 +49,10 @@
|
|||||||
</template>
|
</template>
|
||||||
<div v-else class="select-none dir-entry flex flex-col items-center overflow-hidden dir-entry-width p-2"
|
<div v-else class="select-none dir-entry flex flex-col items-center overflow-hidden dir-entry-width p-2"
|
||||||
:class="{ '!bg-red-600/10': hover && !entry.selected, '!bg-red-600/20': hover && entry.selected, 'dir-entry-selected': entry.selected, '!border-t-transparent': suppressBorderT, '!border-b-transparent': suppressBorderB, '!border-l-transparent': suppressBorderL, '!border-r-transparent': suppressBorderR }">
|
:class="{ '!bg-red-600/10': hover && !entry.selected, '!bg-red-600/20': hover && entry.selected, 'dir-entry-selected': entry.selected, '!border-t-transparent': suppressBorderT, '!border-b-transparent': suppressBorderB, '!border-l-transparent': suppressBorderL, '!border-r-transparent': suppressBorderR }">
|
||||||
<div class="w-full" @dblclick="doubleClickCallback" @click.prevent="$emit('directoryViewAction', 'toggleSelected', entry, $event)"
|
<div class="w-full" @dblclick="doubleClickCallback"
|
||||||
@mouseup.stop @mouseenter="hover = true" @mouseleave="hover = false" ref="selectIntersectElement">
|
@click.prevent="$emit('directoryViewAction', 'toggleSelected', entry, $event)" @mouseup.stop
|
||||||
|
@contextmenu.prevent.stop="$emit('browserAction', 'contextMenu', entry, $event)"
|
||||||
|
@mouseenter="hover = true" @mouseleave="hover = false" ref="selectIntersectElement">
|
||||||
<div class="relative w-full" :class="[entry.cut ? 'text-gray-500/50' : 'icon-default']">
|
<div class="relative w-full" :class="[entry.cut ? 'text-gray-500/50' : 'icon-default']">
|
||||||
<FolderIcon v-if="entry.resolvedType === 'd'" class="w-full h-auto" />
|
<FolderIcon v-if="entry.resolvedType === 'd'" class="w-full h-auto" />
|
||||||
<DocumentIcon v-else class="w-full h-auto" />
|
<DocumentIcon v-else class="w-full h-auto" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="h-full" @keydown="keyHandler($event)" tabindex="-1" :class="{ '!cursor-wait': processing }">
|
<div class="h-full" @keydown="keyHandler($event)" tabindex="-1" :class="{ '!cursor-wait': processing }">
|
||||||
<DragSelectArea class="h-full" @selectRectangle="selectRectangle" @mouseup.exact="deselectAll">
|
<DragSelectArea class="h-full" @selectRectangle="selectRectangle" @mouseup.exact="deselectAll" @contextmenu.prevent="$emit('browserAction', 'contextMenu', { host, path, name: `Current directory (${path.split('/').pop() || '/'})` }, $event)">
|
||||||
<Table :key="host + path" v-if="settings.directoryView?.view === 'list'" emptyText="No entries." noHeader stickyHeaders
|
<Table :key="host + path" v-if="settings.directoryView?.view === 'list'" emptyText="No entries." noHeader stickyHeaders
|
||||||
noShrink noShrinkHeight="h-full">
|
noShrink noShrinkHeight="h-full">
|
||||||
<template #thead>
|
<template #thead>
|
||||||
|
@ -16,20 +16,19 @@ If not, see <https://www.gnu.org/licenses/>.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ModalPopup :showModal="show" :headerText="entry?.nameHTML" @apply="apply"
|
<ModalPopup :showModal="show" :headerText="entry?.nameHTML ?? entry?.name" @apply="apply" @cancel="$emit('hide')">
|
||||||
@cancel="$emit('hide')">
|
|
||||||
<div class="flex flex-col space-y-content items-start">
|
<div class="flex flex-col space-y-content items-start">
|
||||||
<FileModeMatrix v-model="mode" />
|
<FileModeMatrix v-model="mode" />
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-sm font-medium">Owner</label>
|
<label class="block text-sm font-medium">Owner</label>
|
||||||
<select class="input-textlike" v-model="owner">
|
<select class="input-textlike" v-model="owner">
|
||||||
<option v-for="user in users" :value="user.user">{{ user.pretty }}</option>
|
<option v-for="user in users" :key="user.pretty" :value="user.user">{{ user.pretty }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-sm font-medium">Group</label>
|
<label class="block text-sm font-medium">Group</label>
|
||||||
<select class="input-textlike" v-model="group">
|
<select class="input-textlike" v-model="group">
|
||||||
<option v-for="group in groups" :value="group.group">{{ group.pretty }}</option>
|
<option v-for="group in groups" :key="group.pretty" :value="group.group">{{ group.pretty }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,9 +19,10 @@ If not, see <https://www.gnu.org/licenses/>.
|
|||||||
<TransitionRoot as="div" class="fixed inset-0 z-10 overflow-visible" :show="showModal">
|
<TransitionRoot as="div" class="fixed inset-0 z-10 overflow-visible" :show="showModal">
|
||||||
<TransitionChild as="template" enter="ease-out duration-500" enter-from="opacity-0" enter-to="opacity-100"
|
<TransitionChild as="template" enter="ease-out duration-500" enter-from="opacity-0" enter-to="opacity-100"
|
||||||
leave="ease-in duration-500" leave-from="opacity-100" leave-to="opacity-0">
|
leave="ease-in duration-500" leave-from="opacity-100" leave-to="opacity-0">
|
||||||
<div class="fixed z-10 inset-0 bg-neutral-500/75 dark:bg-black/50 transition-opacity" />
|
<div class="fixed z-10 inset-0 bg-neutral-500/75 dark:bg-black/50 transition-opacity pointer" />
|
||||||
</TransitionChild>
|
</TransitionChild>
|
||||||
<div @click.self="$emit('close')" class="fixed z-10 inset-0 overflow-hidden flex items-end sm:items-center justify-center px-4 pb-20 sm:p-0">
|
<div @click.self="$emit('close')"
|
||||||
|
class="fixed z-10 inset-0 overflow-hidden flex items-end sm:items-center justify-center px-4 pb-20 sm:p-0">
|
||||||
<TransitionChild as="template" enter="ease-out duration-300"
|
<TransitionChild as="template" enter="ease-out duration-300"
|
||||||
enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-90"
|
enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-90"
|
||||||
enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-100"
|
enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-100"
|
||||||
|
@ -18,7 +18,7 @@ export async function getUsers() {
|
|||||||
return;
|
return;
|
||||||
users.push({ user: record.replace(/^[^\\]+\\/, ""), domain: true, pretty: record.replace(/^[^\\]+\\/, "") + " (domain)" });
|
users.push({ user: record.replace(/^[^\\]+\\/, ""), domain: true, pretty: record.replace(/^[^\\]+\\/, "") + " (domain)" });
|
||||||
})
|
})
|
||||||
} catch {}
|
} catch { }
|
||||||
users.sort((a, b) => a.pretty.localeCompare(b.pretty));
|
users.sort((a, b) => a.pretty.localeCompare(b.pretty));
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</ModalPopup>
|
</ModalPopup>
|
||||||
<FilePermissions :show="filePermissions.show" @hide="filePermissions.close" :entry="filePermissions.entry" />
|
<FilePermissions :show="filePermissions.show" @hide="filePermissions.close" :entry="filePermissions.entry" />
|
||||||
|
<ContextMenu @browserAction="handleAction" :show="contextMenu.show" @hide="contextMenu.close" :entry="contextMenu.entry" :event="contextMenu.event" />
|
||||||
<Teleport to="#footer-buttons">
|
<Teleport to="#footer-buttons">
|
||||||
<IconToggle v-model="darkMode" v-slot="{ value }">
|
<IconToggle v-model="darkMode" v-slot="{ value }">
|
||||||
<MoonIcon v-if="value" class="size-icon icon-default" />
|
<MoonIcon v-if="value" class="size-icon icon-default" />
|
||||||
@ -120,6 +121,7 @@ import IconToggle from '../components/IconToggle.vue';
|
|||||||
import ModalPopup from '../components/ModalPopup.vue';
|
import ModalPopup from '../components/ModalPopup.vue';
|
||||||
import { fileDownload } from '@45drives/cockpit-helpers';
|
import { fileDownload } from '@45drives/cockpit-helpers';
|
||||||
import FilePermissions from '../components/FilePermissions.vue';
|
import FilePermissions from '../components/FilePermissions.vue';
|
||||||
|
import ContextMenu from '../components/ContextMenu.vue';
|
||||||
|
|
||||||
const encodePartial = (string) =>
|
const encodePartial = (string) =>
|
||||||
encodeURIComponent(string)
|
encodeURIComponent(string)
|
||||||
@ -200,6 +202,25 @@ export default {
|
|||||||
filePermissions.resetTimeoutHandle = setTimeout(() => filePermissions.resetTimeoutHandle = filePermissions.entry = null, 500);
|
filePermissions.resetTimeoutHandle = setTimeout(() => filePermissions.resetTimeoutHandle = filePermissions.entry = null, 500);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const contextMenu = reactive({
|
||||||
|
show: false,
|
||||||
|
entry: null,
|
||||||
|
event: null,
|
||||||
|
resetTimeoutHandle: null,
|
||||||
|
open: (entry, event) => {
|
||||||
|
clearTimeout(contextMenu.resetTimeoutHandle);
|
||||||
|
contextMenu.entry = entry;
|
||||||
|
contextMenu.event = event;
|
||||||
|
contextMenu.show = true;
|
||||||
|
},
|
||||||
|
close: () => {
|
||||||
|
contextMenu.show = false;
|
||||||
|
contextMenu.resetTimeoutHandle = setTimeout(() => {
|
||||||
|
contextMenu.resetTimeoutHandle = contextMenu.entry = null;
|
||||||
|
contextMenu.resetTimeoutHandle = contextMenu.event = null;
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const cd = ({ path, host }) => {
|
const cd = ({ path, host }) => {
|
||||||
const newHost = host ?? (pathHistory.current().host);
|
const newHost = host ?? (pathHistory.current().host);
|
||||||
@ -230,14 +251,6 @@ export default {
|
|||||||
console.log('download', `${host}:${path}`);
|
console.log('download', `${host}:${path}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const openFilePrompt = (entry) => {
|
|
||||||
openFilePromptModal.open(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
const openFilePermissions = (entry) => {
|
|
||||||
filePermissions.open(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
const getSelected = () => directoryViewRef.value?.getSelected?.() ?? [];
|
const getSelected = () => directoryViewRef.value?.getSelected?.() ?? [];
|
||||||
|
|
||||||
const handleAction = (action, ...args) => {
|
const handleAction = (action, ...args) => {
|
||||||
@ -249,14 +262,26 @@ export default {
|
|||||||
openEditor(...args);
|
openEditor(...args);
|
||||||
break;
|
break;
|
||||||
case 'editPermissions':
|
case 'editPermissions':
|
||||||
openFilePermissions(...args);
|
filePermissions.open(...args);
|
||||||
break;
|
break;
|
||||||
case 'openFilePrompt':
|
case 'openFilePrompt':
|
||||||
openFilePrompt(...args);
|
openFilePromptModal.open(...args);
|
||||||
break;
|
break;
|
||||||
case 'download':
|
case 'download':
|
||||||
download(...args);
|
download(...args);
|
||||||
break;
|
break;
|
||||||
|
case 'contextMenu':
|
||||||
|
contextMenu.open(...args);
|
||||||
|
break;
|
||||||
|
case 'back':
|
||||||
|
back();
|
||||||
|
break;
|
||||||
|
case 'forward':
|
||||||
|
forward();
|
||||||
|
break;
|
||||||
|
case 'up':
|
||||||
|
up();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.error('Unknown browserAction:', action, args);
|
console.error('Unknown browserAction:', action, args);
|
||||||
break;
|
break;
|
||||||
@ -296,14 +321,13 @@ export default {
|
|||||||
forwardHistoryDropdown,
|
forwardHistoryDropdown,
|
||||||
openFilePromptModal,
|
openFilePromptModal,
|
||||||
filePermissions,
|
filePermissions,
|
||||||
|
contextMenu,
|
||||||
cd,
|
cd,
|
||||||
back,
|
back,
|
||||||
forward,
|
forward,
|
||||||
up,
|
up,
|
||||||
openEditor,
|
openEditor,
|
||||||
download,
|
download,
|
||||||
openFilePrompt,
|
|
||||||
openFilePermissions,
|
|
||||||
getSelected,
|
getSelected,
|
||||||
handleAction,
|
handleAction,
|
||||||
}
|
}
|
||||||
@ -326,6 +350,7 @@ export default {
|
|||||||
ViewGridIcon,
|
ViewGridIcon,
|
||||||
ModalPopup,
|
ModalPopup,
|
||||||
FilePermissions,
|
FilePermissions,
|
||||||
|
ContextMenu,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user