solved issues: FullFilePreview menu , MultiSelected move action ; refactoring contextMenu

This commit is contained in:
Milos Holba
2020-12-20 16:41:30 +01:00
parent 00213824f1
commit e6ff90f6fc
13 changed files with 529 additions and 556 deletions

View File

@@ -2,391 +2,241 @@
<div :style="{ top: positionY + 'px', left: positionX + 'px' }" @click="closeAndResetContextMenu" class="contextmenu" v-show="isVisible || showFromPreview" ref="contextmenu" :class="{ 'filePreviewFixed' : showFromPreview}">
<!-- ContextMenu for File Preview -->
<div class="menu-options" id="menu-list" v-if="showFromPreview">
<ul class="menu-option-group">
<li class="menu-option" @click="renameItem" v-if="multiSelectContextMenu">
<div class="icon">
<edit2-icon size="17"></edit2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.rename') }}
</div>
</li>
<li class="menu-option" @click="moveItem">
<div class="icon">
<corner-down-right-icon size="17"></corner-down-right-icon>
</div>
<div class="text-label">
{{ $t('context_menu.move') }}
</div>
</li>
<li class="menu-option" @click="shareItem" v-if="$checkPermission('master')">
<div class="icon">
<link-icon size="17"></link-icon>
</div>
<div class="text-label">
{{
item.shared
? $t('context_menu.share_edit')
: $t('context_menu.share')
}}
</div>
</li>
<li class="menu-option" @click="deleteItem">
<div class="icon">
<trash-2-icon size="17"></trash-2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.delete') }}
</div>
</li>
</ul>
<ul class="menu-option-group">
<li class="menu-option" @click="downloadItem" v-if="!isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
<OptionGroup class="menu-option-group">
<Option @click.native="renameItem" :title="$t('context_menu.rename')" icon="rename"/>
<Option @click.native="moveItem" :title="$t('context_menu.move')" icon="move-item"/>
<Option @click.native="shareItem" v-if="$checkPermission('master')"
:title="item.shared
? $t('context_menu.share_edit')
: $t('context_menu.share')"
icon="share"/>
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash" class="menu-option"/>
</OptionGroup>
<OptionGroup >
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download"/>
</OptionGroup>
</div>
<!--ContextMenu for trash location-->
<div v-if="
$isThisLocation(['trash', 'trash-root']) && $checkPermission('master') && !showFromPreview
" id="menu-list" class="menu-options">
<ul class="menu-option-group">
<li class="menu-option" @click="$store.dispatch('restoreItem', item)" v-if="item && multiSelectContextMenu ">
<div class="icon">
<life-buoy-icon size="17"></life-buoy-icon>
</div>
<div class="text-label">
{{ $t('context_menu.restore') }}
</div>
</li>
<li class="menu-option" @click="deleteItem" v-if="item">
<div class="icon">
<trash-2-icon size="17"></trash-2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.delete') }}
</div>
</li>
<li class="menu-option" @click="$store.dispatch('emptyTrash')">
<div class="icon">
<trash-icon size="17"></trash-icon>
</div>
<div class="text-label">
{{ $t('context_menu.empty_trash') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="ItemDetail" v-if="multiSelectContextMenu">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="!isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
<div v-if="$isThisLocation(['trash', 'trash-root']) && $checkPermission('master') && !showFromPreview" id="menu-list" class="menu-options">
<!-- Single options -->
<OptionGroup v-if="multiSelectContextMenu">
<Option @click.native="restoreItem" v-if="item" :title="$t('context_menu.restore')" icon="restore"/>
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash" />
<Option @click.native="emptyTrash" :title="$t('context_menu.empty_trash')" icon="empty-trash"/>
</OptionGroup>
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail"/>
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download"/>
</OptionGroup>
<!-- Multi options -->
<OptionGroup v-if="!multiSelectContextMenu">
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash" />
<Option @click.native="emptyTrash" :title="$t('context_menu.empty_trash')" icon="empty-trash"/>
</OptionGroup>
<OptionGroup v-if="item && !multiSelectContextMenu && !hasFolder">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download"/>
</OptionGroup>
</div>
<!--ContextMenu for Base location with MASTER permission-->
<div v-if="$isThisLocation(['shared']) && $checkPermission('master') && !showFromPreview" id="menu-list" class="menu-options">
<ul class="menu-option-group" v-if="item && isFolder && multiSelectContextMenu">
<li class="menu-option" @click="addToFavourites">
<div class="icon">
<star-icon size="17"></star-icon>
</div>
<div class="text-label">
{{
isInFavourites
<!-- Single options -->
<OptionGroup class="menu-option-group" v-if="item && isFolder && multiSelectContextMenu">
<Option @click.native="addToFavourites"
:title=" isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')"
icon="favourites"/>
</OptionGroup>
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="renameItem" :title="$t('context_menu.rename')" icon="rename"/>
<Option @click.native="shareItem" :title=" item.shared ? $t('context_menu.share_edit'): $t('context_menu.share')"
icon="share"/>
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash" />
</OptionGroup>
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail" />
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download"/>
</OptionGroup>
<!-- Multi options -->
<OptionGroup class="menu-option-group" v-if="item && !hasFile && !multiSelectContextMenu">
<Option @click.native="addToFavourites"
:title=" isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')
}}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="renameItem" v-if="multiSelectContextMenu">
<div class="icon">
<edit2-icon size="17"></edit2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.rename') }}
</div>
</li>
<li class="menu-option" @click="shareItem" v-if="multiSelectContextMenu">
<div class="icon">
<link-icon size="17"></link-icon>
</div>
<div class="text-label">
{{
item.shared
? $t('context_menu.share_edit')
: $t('context_menu.share')
}}
</div>
</li>
<li class="menu-option" @click="shareCancel" v-if="this.fileInfoDetail.length > 1 && !multiSelectContextMenu">
<div class="icon">
<link-icon size="17"></link-icon>
</div>
<div class="text-label">
{{ $t('context_menu.share_cancel') }}
</div>
</li>
<li class="menu-option" @click="deleteItem">
<div class="icon">
<trash-2-icon size="17"></trash-2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.delete') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="ItemDetail" v-if="item && multiSelectContextMenu">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="!isFolder ">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
: $t('context_menu.add_to_favourites')"
icon="favourites"/>
</OptionGroup>
<OptionGroup v-if="item && !multiSelectContextMenu">
<Option @click.native="shareCancel" :title="$t('context_menu.share_cancel')" icon="share" />
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash" />
</OptionGroup>
<OptionGroup v-if="item && !multiSelectContextMenu && !hasFolder">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download"/>
</OptionGroup>
</div>
<!--ContextMenu for Base location with MASTER permission-->
<div v-if="
$isThisLocation(['base', 'participant_uploads', 'latest']) &&
$checkPermission('master') && !showFromPreview
" id="menu-list" class="menu-options">
<ul class="menu-option-group" v-if="!$isThisLocation(['participant_uploads', 'latest'])">
<li class="menu-option" @click="addToFavourites" v-if="item && isFolder && multiSelectContextMenu ">
<div class="icon">
<star-icon size="17"></star-icon>
</div>
<div class="text-label">
{{
isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')
}}
</div>
</li>
<li class="menu-option" @click="createFolder">
<div class="icon">
<folder-plus-icon size="17"></folder-plus-icon>
</div>
<div class="text-label">
{{ $t('context_menu.create_folder') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="renameItem" v-if="multiSelectContextMenu">
<div class="icon">
<edit2-icon size="17"></edit2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.rename') }}
</div>
</li>
<li class="menu-option" @click="moveItem">
<div class="icon">
<corner-down-right-icon size="17"></corner-down-right-icon>
</div>
<div class="text-label">
{{ $t('context_menu.move') }}
</div>
</li>
<li class="menu-option" @click="shareItem" v-if="multiSelectContextMenu">
<div class="icon">
<link-icon size="17"></link-icon>
</div>
<div class="text-label">
{{
item.shared
? $t('context_menu.share_edit')
: $t('context_menu.share')
}}
</div>
</li>
<li class="menu-option" @click="deleteItem">
<div class="icon">
<trash-2-icon size="17"></trash-2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.delete') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item ">
<li class="menu-option" @click="ItemDetail" v-if="multiSelectContextMenu">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="!isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
<div v-if="$isThisLocation(['base', 'participant_uploads', 'latest']) &&$checkPermission('master') && !showFromPreview" id="menu-list" class="menu-options">
<!-- Single options -->
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && multiSelectContextMenu">
<Option @click.native="addToFavourites" v-if="item && isFolder " :title=" isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')"
icon="favourites"/>
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder" />
</OptionGroup>
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="renameItem" :title="$t('context_menu.rename')" icon="rename" />
<Option @click.native="moveItem" v-if="!$isThisLocation(['latest'])" :title="$t('context_menu.move')" icon="move-item"/>
<Option @click.native="shareItem" :title=" item.shared
? $t('context_menu.share_edit')
: $t('context_menu.share')"
icon="share"/>
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash"/>
</OptionGroup>
<OptionGroup v-if="item && multiSelectContextMenu ">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail"/>
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download"/>
</OptionGroup>
<!-- Multi options -->
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && !multiSelectContextMenu">
<Option @click.native="addToFavourites" v-if="item && !hasFile" :title=" isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')"
icon="favourites"/>
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder" />
</OptionGroup>
<OptionGroup v-if="item && !multiSelectContextMenu">
<Option @click.native="moveItem" v-if="!$isThisLocation(['latest'])" :title="$t('context_menu.move')" icon="move-item"/>
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash"/>
</OptionGroup>
<OptionGroup v-if="item && !multiSelectContextMenu && !hasFolder">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download"/>
</OptionGroup>
</div>
<!--ContextMenu for Base location with EDITOR permission-->
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('editor') && !showFromPreview " id="menu-list" class="menu-options">
<ul class="menu-option-group">
<li class="menu-option" @click="createFolder">
<div class="icon">
<folder-plus-icon size="17"></folder-plus-icon>
</div>
<div class="text-label">
{{ $t('context_menu.create_folder') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="renameItem" v-if="multiSelectContextMenu">
<div class="icon">
<edit2-icon size="17"></edit2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.rename') }}
</div>
</li>
<li class="menu-option" @click="moveItem">
<div class="icon">
<corner-down-right-icon size="17"></corner-down-right-icon>
</div>
<div class="text-label">
{{ $t('context_menu.move') }}
</div>
</li>
<li class="menu-option" @click="deleteItem">
<div class="icon">
<trash-2-icon size="17"></trash-2-icon>
</div>
<div class="text-label">
{{ $t('context_menu.delete') }}
</div>
</li>
</ul>
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="ItemDetail" v-if="multiSelectContextMenu">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="!isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
<!-- Single options -->
<OptionGroup v-if="multiSelectContextMenu">
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
</OptionGroup>
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="renameItem" :title=" $t('context_menu.rename')" icon="rename"/>
<Option @click.native="moveItem" :title="$t('context_menu.move')" icon="move-item"/>
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash"/>
</OptionGroup>
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail"/>
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
<!-- Multi options -->
<OptionGroup v-if="!multiSelectContextMenu">
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
</OptionGroup>
<OptionGroup v-if="item && !multiSelectContextMenu">
<Option @click.native="moveItem" :title="$t('context_menu.move')" icon="move-item"/>
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash"/>
</OptionGroup>
<OptionGroup v-if="item && !multiSelectContextMenu && !hasFolder">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</div>
<!--ContextMenu for Base location with VISITOR permission-->
<div v-if="
$isThisLocation(['base', 'public']) && $checkPermission('visitor') && !showFromPreview
" id="menu-list" class="menu-options">
<ul class="menu-option-group" v-if="item">
<li class="menu-option" @click="ItemDetail" v-if="multiSelectContextMenu">
<div class="icon">
<eye-icon size="17"></eye-icon>
</div>
<div class="text-label">
{{ $t('context_menu.detail') }}
</div>
</li>
<li class="menu-option" @click="downloadItem" v-if="!isFolder">
<div class="icon">
<download-cloud-icon size="17"></download-cloud-icon>
</div>
<div class="text-label">
{{ $t('context_menu.download') }}
</div>
</li>
</ul>
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('visitor') && !showFromPreview" id="menu-list" class="menu-options">
<!-- Single options -->
<OptionGroup v-if="item && multiSelectContextMenu">
<Option @click.native="ItemDetail" :title="$t('context_menu.detail')" icon="detail"/>
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download"/>
</OptionGroup>
<!-- Multi options -->
<OptionGroup v-if="!multiSelectContextMenu && item ">
<Option @click.native="downloadItem" v-if="!hasFolder" :title="$t('context_menu.download')" icon="download"/>
<Option v-if="hasFolder" :title="$t('context_menu.no_options')" icon="no-options" class="no-options"/>
</OptionGroup>
</div>
</div>
</template>
<script>
import {
CornerDownRightIcon,
DownloadCloudIcon,
FolderPlusIcon,
LifeBuoyIcon,
Trash2Icon,
Edit2Icon,
TrashIcon,
StarIcon,
LinkIcon,
EyeIcon
} from 'vue-feather-icons'
import OptionGroup from '@/components/FilesView/OptionGroup'
import Option from '@/components/FilesView/Option'
import { mapGetters } from 'vuex'
import { events } from '@/bus'
export default {
name: 'ContextMenu',
components: {
CornerDownRightIcon,
DownloadCloudIcon,
FolderPlusIcon,
LifeBuoyIcon,
Trash2Icon,
Edit2Icon,
TrashIcon,
LinkIcon,
StarIcon,
EyeIcon
OptionGroup,
Option,
},
computed: {
...mapGetters(['user', 'fileInfoDetail']),
hasFolder(){
// Check if selected items includes some folder
if(this.fileInfoDetail.find(item => item.type === 'folder'))
return true
},
hasFile(){
// Check if selected items includes some files
if(this.fileInfoDetail.find(item => item.type !== 'folder'))
return true
},
multiSelectContextMenu() {
// If is context Menu open on multi selected items open just options for the multi selected items
if (this.fileInfoDetail.length > 1 && this.fileInfoDetail.includes(this.item)) {
if (this.fileInfoDetail.length > 1 && this.fileInfoDetail.includes(this.item))
return false
}
// If is context Menu open for the non selected item open options for the single item
if (this.fileInfoDetail.length < 2 || !this.fileInfoDetail.includes(this.item)) {
if (this.fileInfoDetail.length < 2 || !this.fileInfoDetail.includes(this.item))
return true
}
},
favourites() {
return this.user.relationships.favourites.data.attributes.folders
@@ -420,6 +270,12 @@ export default {
},
methods: {
emptyTrash(){
this.$store.dispatch('emptyTrash')
},
restoreItem(){
this.$store.dispatch('restoreItem', this.item)
},
shareCancel() {
this.$store.dispatch('shareCancel')
},
@@ -598,25 +454,25 @@ export default {
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
.no-options {
/deep/ .text-label {
color: $text-muted !important;
}
/deep/ &:hover {
background: transparent;
}
/deep/ path,
/deep/line,
/deep/circle {
stroke: $text-muted !important;
}
}
.filePreviewFixed {
position: fixed !important;
display: flex;
}
.menu-option {
display: flex;
align-items: center;
.icon {
margin-right: 20px;
line-height: 0;
}
.text-label {
@include font-size(16);
}
}
.contextmenu {
min-width: 250px;
position: absolute;
@@ -636,66 +492,24 @@ export default {
width: 100%;
margin: 0;
padding: 0;
.menu-option-group {
padding: 5px 0;
border-bottom: 1px solid $light_mode_border;
&:first-child {
padding-top: 0;
}
&:last-child {
padding-bottom: 0;
border-bottom: none;
}
}
.menu-option {
white-space: nowrap;
font-weight: 700;
@include font-size(14);
padding: 15px 20px;
cursor: pointer;
width: 100%;
color: $text;
&:hover {
background: $light_background;
.text-label {
color: $theme;
}
path,
line,
polyline,
rect,
circle,
polygon {
stroke: $theme;
}
}
}
}
@media (prefers-color-scheme: dark) {
.contextmenu {
background: $dark_mode_foreground;
.menu-options {
.menu-option-group {
border-color: $dark_mode_border_color;
}
.menu-option {
color: $dark_mode_text_primary;
&:hover {
background: rgba($theme, 0.1);
}
}
}
}
.no-options {
/deep/ .text-label {
color: $dark_mode_text_secondary !important;
}
/deep/ &:hover {
background: transparent;
}
/deep/ path,
/deep/line,
/deep/circle {
stroke: $dark_mode_text_secondary !important;
}
}
}
</style>