Popover refactored

This commit is contained in:
Peter Papp
2021-04-19 17:41:41 +02:00
parent 7cd29fce98
commit 7e8511ab3f
15 changed files with 573 additions and 528 deletions

View File

@@ -2,412 +2,351 @@
<div id="desktop-toolbar">
<div class="toolbar-wrapper">
<!-- Go back-->
<div class="toolbar-go-back" v-if="homeDirectory">
<div @click="goBack" class="go-back-button">
<chevron-left-icon size="17" :class="{ 'is-active': browseHistory.length > 1 }" class="icon-back"></chevron-left-icon>
<div v-if="homeDirectory" @click="goBack" class="location">
<chevron-left-icon :class="{'is-active': browseHistory.length > 1 }" class="icon-back" size="17" />
<span class="back-directory-title">
{{ directoryName }}
</span>
<span class="location-title">
{{ directoryName }}
</span>
<span @click.stop="folderActions" v-if="browseHistory.length > 1 && $isThisLocation(['base', 'public'])" class="folder-options group" id="folder-actions">
<more-horizontal-icon size="14" class="icon-more group-hover-text-theme" />
</span>
</div>
</div>
<span @click.stop="folderActions" v-if="browseHistory.length > 1 && $isThisLocation(['base', 'public'])" class="location-more group" id="folder-actions">
<more-horizontal-icon size="14" class="icon-more group-hover-text-theme" />
</span>
</div>
<!-- Tools-->
<div class="toolbar-tools">
<ToolbarWrapper>
<!--Search bar-->
<div class="toolbar-button-wrapper">
<SearchBar v-model="query" @reset-query="query = ''" :placeholder="$t('inputs.placeholder_search_files')" />
</div>
<!--Search bar-->
<ToolbarGroup style="margin-left: 0">
<SearchBar v-model="query" @reset-query="query = ''" :placeholder="$t('inputs.placeholder_search_files')" />
</ToolbarGroup>
<!--Creating controls-->
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor'])">
<ToolbarButtonUpload :class="{ 'is-inactive': canUploadInView || !hasCapacity }" :action="$t('actions.upload')"/>
<ToolbarButton :class="{ 'is-inactive': canCreateFolderInView }" @click.native="createFolder" source="folder-plus" :action="$t('actions.create_folder')"/>
</div>
<!--Creating controls-->
<ToolbarGroup v-if="$checkPermission(['master', 'editor'])">
<ToolbarButtonUpload :class="{'is-inactive': canUploadInView || !hasCapacity }" :action="$t('actions.upload')" />
<ToolbarButton @click.native="createFolder" :class="{'is-inactive': canCreateFolderInView }" source="folder-plus" :action="$t('actions.create_folder')" />
</ToolbarGroup>
<!--File Controls-->
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor']) && ! $isMobile()">
<ToolbarButton source="move" :class="{ 'is-inactive': canMoveInView }" :action="$t('actions.move')" @click.native="moveItem"/>
<ToolbarButton v-if="!$isThisLocation(['public'])" source="share" :class="{ 'is-inactive': canShareInView }" :action="$t('actions.share')" @click.native="shareItem"/>
<ToolbarButton source="trash" :class="{ 'is-inactive': canDeleteInView }" :action="$t('actions.delete')" @click.native="deleteItem"/>
</div>
<!--File Controls-->
<ToolbarGroup v-if="$checkPermission(['master', 'editor']) && ! $isMobile()">
<ToolbarButton @click.native="moveItem" :class="{'is-inactive': canMoveInView }" source="move" :action="$t('actions.move')" />
<ToolbarButton @click.native="shareItem" v-if="!$isThisLocation(['public'])" :class="{'is-inactive': canShareInView }" source="share" :action="$t('actions.share')" />
<ToolbarButton @click.native="deleteItem" :class="{'is-inactive': canDeleteInView }" source="trash" :action="$t('actions.delete')" />
</ToolbarGroup>
<!--View Controls-->
<div class="toolbar-button-wrapper">
<ToolbarButton source="preview-sorting" class="preview-sorting" :action="$t('actions.sorting_view')" :class="{ active: sortingAndPreview }" @click.stop.native="sortingAndPreview = !sortingAndPreview"/>
<ToolbarButton :action="$t('actions.info_panel')" :class="{ active: fileInfoVisible }" @click.native="$store.dispatch('fileInfoToggle')" source="info"/>
</div>
</div>
<!--View Controls-->
<ToolbarGroup>
<PopoverWrapper>
<ToolbarButton @click.stop.native="showSortingMenu" source="preview-sorting" :action="$t('actions.sorting_view')" />
<PopoverItem name="desktop-sorting">
<FileSortingOptions />
</PopoverItem>
</PopoverWrapper>
<ToolbarButton @click.native="$store.dispatch('fileInfoToggle')" :class="{'active': fileInfoVisible }" :action="$t('actions.info_panel')" source="info" />
</ToolbarGroup>
</ToolbarWrapper>
</div>
<UploadProgress/>
<UploadProgress />
</div>
</template>
<script>
import ToolbarButtonUpload from '@/components/FilesView/ToolbarButtonUpload'
import { ChevronLeftIcon, MoreHorizontalIcon } from 'vue-feather-icons'
import SearchBar from '@/components/FilesView/SearchBar'
import UploadProgress from '@/components/FilesView/UploadProgress'
import ToolbarButton from '@/components/FilesView/ToolbarButton'
import {debounce, last} from 'lodash'
import { mapGetters } from 'vuex'
import { events } from '@/bus'
import ToolbarButtonUpload from '@/components/FilesView/ToolbarButtonUpload'
import FileSortingOptions from '@/components/FilesView/FileSortingOptions'
import {ChevronLeftIcon, MoreHorizontalIcon} from 'vue-feather-icons'
import UploadProgress from '@/components/FilesView/UploadProgress'
import PopoverWrapper from '@/components/Desktop/PopoverWrapper'
import ToolbarWrapper from '@/components/Desktop/ToolbarWrapper'
import ToolbarButton from '@/components/FilesView/ToolbarButton'
import ToolbarGroup from '@/components/Desktop/ToolbarGroup'
import PopoverItem from '@/components/Desktop/PopoverItem'
import SearchBar from '@/components/FilesView/SearchBar'
import {debounce, last} from 'lodash'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
export default {
name: 'ToolBar',
components: {
ToolbarButtonUpload,
MoreHorizontalIcon,
ChevronLeftIcon,
UploadProgress,
ToolbarButton,
SearchBar
},
computed: {
...mapGetters([
'FilePreviewType',
'fileInfoVisible',
'clipboard',
'currentFolder',
'browseHistory',
'homeDirectory'
]),
hasCapacity() {
// Check if storage limitation is set
if (!this.$store.getters.config.storageLimit) return true
export default {
name: 'ToolBar',
components: {
ToolbarButtonUpload,
FileSortingOptions,
MoreHorizontalIcon,
ChevronLeftIcon,
ToolbarWrapper,
UploadProgress,
PopoverWrapper,
ToolbarButton,
ToolbarGroup,
PopoverItem,
SearchBar,
},
computed: {
...mapGetters([
'FilePreviewType',
'fileInfoVisible',
'currentFolder',
'browseHistory',
'homeDirectory',
'clipboard',
]),
hasCapacity() {
// Check if storage limitation is set
if (!this.$store.getters.config.storageLimit) return true
// Check if user is loaded
if (!this.$store.getters.user) return true
// Check if user is loaded
if (!this.$store.getters.user) return true
// Check if user has storage
return this.$store.getters.user.data.attributes.storage.used <= 100
},
directoryName() {
return this.currentFolder
? this.currentFolder.name
: this.homeDirectory.name
},
preview() {
return this.FilePreviewType === 'list' ? 'th' : 'th-list'
},
canCreateFolderInView() {
return !this.$isThisLocation(['base', 'public'])
},
canDeleteInView() {
let locations = [
'trash',
'trash-root',
'base',
'participant_uploads',
'latest',
'shared',
'public'
]
return !this.$isThisLocation(locations) || this.clipboard.length === 0
},
canUploadInView() {
return !this.$isThisLocation(['base', 'public'])
},
canMoveInView() {
let locations = [
'base',
'participant_uploads',
'latest',
'shared',
'public'
]
return !this.$isThisLocation(locations) || this.clipboard.length === 0
// Check if user has storage
return this.$store.getters.user.data.attributes.storage.used <= 100
},
directoryName() {
return this.currentFolder
? this.currentFolder.name
: this.homeDirectory.name
},
preview() {
return this.FilePreviewType === 'list'
? 'th'
: 'th-list'
},
canCreateFolderInView() {
return !this.$isThisLocation(['base', 'public'])
},
canDeleteInView() {
let locations = [
'participant_uploads',
'trash-root',
'latest',
'shared',
'public',
'trash',
'base',
]
return !this.$isThisLocation(locations) || this.clipboard.length === 0
},
canUploadInView() {
return !this.$isThisLocation(['base', 'public'])
},
canMoveInView() {
let locations = [
'participant_uploads',
'latest',
'shared',
'public',
'base',
]
return !this.$isThisLocation(locations) || this.clipboard.length === 0
},
canShareInView() {
let locations = [
'participant_uploads',
'latest',
'shared',
'public',
'base',
]
return !this.$isThisLocation(locations) || this.clipboard.length > 1 || this.clipboard.length === 0
}
},
data() {
return {
query: '',
}
},
watch: {
query: debounce(function (value) {
},
canShareInView() {
let locations = [
'base',
'participant_uploads',
'latest',
'shared',
'public'
]
if (this.query !== '' && typeof this.query !== 'undefined') {
return !this.$isThisLocation(locations) || this.clipboard.length > 1 || this.clipboard.length === 0
}
},
data() {
return {
sortingAndPreview: false,
query: '',
}
},
watch: {
sortingAndPreview() {
if (this.sortingAndPreview) {
events.$emit('sortingAndPreview', true)
}
this.$store.dispatch('getSearchResult', value)
if (!this.sortingAndPreview) {
events.$emit('unClick')
}
},
query: debounce(function (value) {
} else if (typeof value !== 'undefined') {
if (this.query !== '' && typeof this.query !== 'undefined') {
if (this.currentFolder) {
this.$store.dispatch('getSearchResult', value)
// Get back after delete query to previously folder
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [{folder: this.currentFolder, back: true, init: false}])
} else {
this.$store.dispatch('getFolder', [{folder: this.currentFolder, back: true, init: false}])
}
}
} else if (typeof value !== 'undefined') {
this.$store.commit('CHANGE_SEARCHING_STATE', false)
}
}, 300),
},
methods: {
showSortingMenu() {
events.$emit('popover:open', 'desktop-sorting')
},
goBack() {
let previousFolder = last(this.browseHistory)
if (this.currentFolder) {
if (!previousFolder) return
// Get back after delete query to previously folder
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [{folder: this.currentFolder, back: true, init: false}])
} else {
this.$store.dispatch('getFolder', [{folder: this.currentFolder, back: true, init: false}])
}
}
if (previousFolder.location === 'trash-root') {
this.$store.dispatch('getTrash')
this.$store.commit('CHANGE_SEARCHING_STATE', false)
}
}, 300),
},
methods: {
goBack() {
// Get previous folder
let previousFolder = last(this.browseHistory)
} else if (previousFolder.location === 'shared') {
this.$store.dispatch('getShared')
if (!previousFolder) return
} else {
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [
{folder: previousFolder, back: true, init: false}
])
} else {
this.$store.dispatch('getFolder', [
{folder: previousFolder, back: true, init: false}
])
}
}
},
folderActions() {
events.$emit('folder:actions', this.currentFolder)
},
deleteItem() {
if (this.clipboard.length > 0)
this.$store.dispatch('deleteItem')
},
createFolder() {
this.$store.dispatch('createFolder', {name: this.$t('popup_create_folder.folder_default_name')})
},
moveItem() {
if (this.clipboard.length > 0)
events.$emit('popup:open', {name: 'move', item: this.clipboard})
},
shareItem() {
let event = this.clipboard[0].shared
? 'share-edit'
: 'share-create'
if (previousFolder.location === 'trash-root') {
this.$store.dispatch('getTrash')
} else if (previousFolder.location === 'shared') {
this.$store.dispatch('getShared')
} else {
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [
{ folder: previousFolder, back: true, init: false }
])
} else {
this.$store.dispatch('getFolder', [
{ folder: previousFolder, back: true, init: false }
])
}
}
},
folderActions() {
events.$emit('folder:actions', this.currentFolder)
},
deleteItem() {
if (this.clipboard.length > 0)
this.$store.dispatch('deleteItem')
},
createFolder() {
this.$store.dispatch('createFolder', {name: this.$t('popup_create_folder.folder_default_name')})
},
moveItem() {
if (this.clipboard.length > 0)
events.$emit('popup:open', { name: 'move', item: this.clipboard })
},
shareItem() {
let event = this.clipboard[0].shared
? 'share-edit'
: 'share-create'
events.$emit('popup:open', {
name: event,
item: this.clipboard[0]
})
}
},
mounted() {
events.$on('unClick', () => {
this.sortingAndPreview = false
})
}
}
events.$emit('popup:open', {
name: event,
item: this.clipboard[0]
})
}
},
}
</script>
<style scoped lang="scss">
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.preview-sorting {
/deep/ .label {
color: $text !important;
}
.is-inactive {
opacity: 0.25;
pointer-events: none;
}
.toolbar-wrapper {
padding-top: 10px;
padding-bottom: 10px;
display: flex;
position: relative;
z-index: 2;
> div {
flex-grow: 1;
align-self: center;
white-space: nowrap;
}
padding-top: 10px;
padding-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
z-index: 2;
}
.directory-name {
vertical-align: middle;
@include font-size(17);
color: $text;
font-weight: 700;
max-width: 220px;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
}
.location {
align-items: center;
cursor: pointer;
display: flex;
.icon-back {
vertical-align: middle;
cursor: pointer;
margin-right: 6px;
opacity: 0.15;
pointer-events: none;
@include transition(150ms);
.icon-back {
@include transition(150ms);
pointer-events: none;
margin-right: 6px;
flex-shrink: 0;
opacity: 0.15;
&.is-active {
opacity: 1;
pointer-events: initial;
}
}
&.is-active {
opacity: 1;
pointer-events: initial;
}
}
.toolbar-go-back {
cursor: pointer;
.location-title {
@include font-size(15);
line-height: 1;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: $text;
}
.folder-options {
vertical-align: middle;
margin-left: 6px;
padding: 1px 4px;
line-height: 0;
border-radius: 3px;
@include transition(150ms);
.location-more {
margin-left: 6px;
padding: 1px 4px;
line-height: 0;
border-radius: 3px;
@include transition(150ms);
svg circle {
@include transition(150ms);
}
svg circle {
@include transition(150ms);
}
&:hover {
background: $light_background;
&:hover {
background: $light_background;
svg circle {
color: inherit;
}
}
.icon-more {
vertical-align: middle;
}
}
.back-directory-title {
@include font-size(15);
line-height: 1;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
color: $text;
}
svg circle {
color: inherit;
}
}
}
}
.toolbar-position {
text-align: center;
text-align: center;
span {
@include font-size(17);
font-weight: 600;
}
}
.toolbar-tools {
text-align: right;
.toolbar-button-wrapper {
margin-left: 28px;
display: inline-block;
vertical-align: middle;
&:first-child {
margin-left: 0 !important;
}
}
.button {
margin-left: 5px;
&.active {
&.preview-sorting {
background: $light_background;
}
}
&.is-inactive {
opacity: 0.25;
pointer-events: none;
}
&:first-child {
margin-left: 0;
}
}
span {
@include font-size(17);
font-weight: 600;
}
}
@media only screen and (max-width: 1024px) {
.toolbar-go-back .back-directory-title {
max-width: 120px;
}
.location {
.toolbar-tools {
.button {
margin-left: 0;
height: 40px;
width: 40px;
}
.location-title {
max-width: 120px;
}
}
.toolbar-button-wrapper {
margin-left: 25px;
}
}
.toolbar-tools {
.button {
margin-left: 0;
height: 40px;
width: 40px;
}
}
}
@media only screen and (max-width: 960px) {
#desktop-toolbar {
display: none;
}
#desktop-toolbar {
display: none;
}
}
@media (prefers-color-scheme: dark) {
.toolbar .directory-name {
color: $dark_mode_text_primary;
}
.toolbar .directory-name {
color: $dark_mode_text_primary;
}
.toolbar-go-back {
.back-directory-title {
color: $dark_mode_text_primary;
}
.toolbar-go-back {
.location-title {
color: $dark_mode_text_primary;
}
.folder-options {
&:hover {
background: $dark_mode_foreground;
}
}
}
.active {
&.preview-sorting {
background: $dark_mode_foreground !important;
}
}
.location-more {
&:hover {
background: $dark_mode_foreground;
}
}
}
}
</style>