mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-18 08:12:15 +00:00
Popover refactored
This commit is contained in:
51
resources/js/components/Desktop/PopoverItem.vue
Normal file
51
resources/js/components/Desktop/PopoverItem.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div v-if="isVisible" class="popover-item">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {events} from '@/bus'
|
||||
|
||||
export default {
|
||||
name: 'PopoverItem',
|
||||
props: [
|
||||
'name'
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
isVisible: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
events.$on('popover:open', name => {
|
||||
if (this.name === name) this.isVisible = !this.isVisible
|
||||
})
|
||||
|
||||
events.$on('unClick', () => this.isVisible = false)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/vuefilemanager/_variables";
|
||||
@import "@assets/vuefilemanager/_mixins";
|
||||
|
||||
.popover-item {
|
||||
min-width: 250px;
|
||||
position: absolute;
|
||||
z-index: 9;
|
||||
box-shadow: $shadow;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
right: 0;
|
||||
top: 50px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.popover-item {
|
||||
background: $dark_mode_foreground;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
18
resources/js/components/Desktop/PopoverWrapper.vue
Normal file
18
resources/js/components/Desktop/PopoverWrapper.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div class="popover-wrapper">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PopoverWrapper',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.popover-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
28
resources/js/components/Desktop/ToolbarGroup.vue
Normal file
28
resources/js/components/Desktop/ToolbarGroup.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div class="toolbar-button-wrapper">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ToolbarWrapper',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.toolbar-button-wrapper {
|
||||
margin-left: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
|
||||
.toolbar-button-wrapper {
|
||||
margin-left: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
21
resources/js/components/Desktop/ToolbarWrapper.vue
Normal file
21
resources/js/components/Desktop/ToolbarWrapper.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<template>
|
||||
<div class="toolbar-tools">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ToolbarWrapper',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/vuefilemanager/_variables";
|
||||
@import "@assets/vuefilemanager/_mixins";
|
||||
|
||||
.toolbar-tools {
|
||||
text-align: right;
|
||||
display: flex;;
|
||||
}
|
||||
</style>
|
||||
@@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div v-if="isVisible" class="sorting-preview">
|
||||
<FileSortingOptions />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FileSortingOptions from '@/components/FilesView/FileSortingOptions'
|
||||
import { events } from '@/bus'
|
||||
|
||||
export default {
|
||||
name: 'DesktopSortingOptions',
|
||||
components: {
|
||||
FileSortingOptions
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
isVisible: false
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
events.$on('sortingAndPreview', (state) => {
|
||||
this.isVisible = state
|
||||
})
|
||||
|
||||
events.$on('unClick', () => {
|
||||
this.isVisible = false
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/vuefilemanager/_variables";
|
||||
@import "@assets/vuefilemanager/_mixins";
|
||||
|
||||
.sorting-preview {
|
||||
min-width: 250px;
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
box-shadow: $shadow;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
right: 66px;
|
||||
top: 63px;
|
||||
|
||||
&.showed {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.sorting-preview {
|
||||
background: $dark_mode_foreground;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -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>
|
||||
|
||||
@@ -7,31 +7,31 @@
|
||||
<h1 class="title">{{ $t('shared.empty_shared') }}</h1>
|
||||
</div>
|
||||
|
||||
<!--Trash empty message-->
|
||||
<!--Trash empty message-->
|
||||
<div class="text-content" v-if="$isThisLocation(['trash', 'trash-root']) && ! isLoading">
|
||||
<h1 class="title">{{ $t('empty_page.title') }}</h1>
|
||||
</div>
|
||||
|
||||
<!--Trash empty message-->
|
||||
<!--Trash empty message-->
|
||||
<div class="text-content" v-if="$isThisLocation(['participant_uploads']) && ! isLoading">
|
||||
<h1 class="title">{{ $t('messages.nothing_from_participants') }}</h1>
|
||||
</div>
|
||||
|
||||
<!--Base file browser empty message-->
|
||||
<!--Base file browser empty message-->
|
||||
<div class="text-content" v-if="$isThisLocation(['base', 'public', 'latest']) && !isLoading">
|
||||
<h1 class="title">{{ $t('empty_page.title') }}</h1>
|
||||
<p v-if="$checkPermission(['master', 'editor'])" class="description">{{ $t('empty_page.description') }}</p>
|
||||
<ButtonUpload
|
||||
v-if="$checkPermission(['master', 'editor'])"
|
||||
button-style="theme"
|
||||
>
|
||||
v-if="$checkPermission(['master', 'editor'])"
|
||||
button-style="theme"
|
||||
>
|
||||
{{ $t('empty_page.call_to_action') }}
|
||||
</ButtonUpload>
|
||||
</div>
|
||||
|
||||
<!--Spinner-->
|
||||
<!--Spinner-->
|
||||
<div class="text-content" v-if="isLoading">
|
||||
<Spinner/>
|
||||
<Spinner />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,75 +39,79 @@
|
||||
|
||||
<script>
|
||||
import ButtonUpload from '@/components/FilesView/ButtonUpload'
|
||||
import Spinner from '@/components/FilesView/Spinner'
|
||||
import {mapGetters} from 'vuex'
|
||||
import Spinner from '@/components/FilesView/Spinner'
|
||||
import {mapGetters} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'EmptyPage',
|
||||
props: ['title', 'description'],
|
||||
components: {
|
||||
ButtonUpload,
|
||||
Spinner
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['entries', 'isLoading', 'currentFolder']),
|
||||
isEmpty() {
|
||||
return this.entries && this.entries.length == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
export default {
|
||||
name: 'EmptyPage',
|
||||
props: ['title', 'description'],
|
||||
components: {
|
||||
ButtonUpload,
|
||||
Spinner
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'entries',
|
||||
'isLoading',
|
||||
'currentFolder'
|
||||
]),
|
||||
isEmpty() {
|
||||
return this.entries && this.entries.length == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@assets/vuefilemanager/_variables';
|
||||
@import '@assets/vuefilemanager/_mixins';
|
||||
@import '@assets/vuefilemanager/_mixins';
|
||||
|
||||
.empty-page {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
margin-top: 85px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.empty-page {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
margin-top: 85px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.empty-state {
|
||||
margin: 0 auto;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
}
|
||||
.empty-state {
|
||||
margin: 0 auto;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.text-content {
|
||||
text-align: center;
|
||||
margin: 30px 0;
|
||||
.text-content {
|
||||
text-align: center;
|
||||
margin: 30px 0;
|
||||
|
||||
.title {
|
||||
@include font-size(20);
|
||||
color: $text;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
}
|
||||
.title {
|
||||
@include font-size(20);
|
||||
color: $text;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.description {
|
||||
@include font-size(13);
|
||||
color: $text-muted;
|
||||
margin-bottom: 20px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.description {
|
||||
@include font-size(13);
|
||||
color: $text-muted;
|
||||
margin-bottom: 20px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.text-content {
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.text-content {
|
||||
|
||||
.title {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
.title {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: $dark_mode_text_secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
.description {
|
||||
color: $dark_mode_text_secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<svg class="preview-list-icon" fill="none" stroke="currentColor" stroke-width="1.5" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" width="15px" height="15px" viewBox="0 0 20 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg class="preview-list-icon" fill="none" stroke="currentColor" stroke-width="1.5" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" width="20px" height="20px" viewBox="0 0 20 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<rect x="9.77777778" y="0" width="6.22222222" height="6.22222222"></rect>
|
||||
<rect x="9.77777778" y="9.77777778" width="6.22222222" height="6.22222222"></rect>
|
||||
<line x1="0" y1="2" x2="6" y2="2"></line>
|
||||
@@ -13,7 +13,7 @@
|
||||
<x-square-icon v-if="icon === 'x-square'" size="15" class="icon dark-text-theme" />
|
||||
<check-icon v-if="icon === 'check'" size="15" class="icon dark-text-theme" />
|
||||
<dollar-sign-icon v-if="icon === 'dollar-sign'" size="15" class="icon dark-text-theme" />
|
||||
<sorting-and-preview-icon v-if="icon === 'preview-sorting'" size="15" class="icon dark-text-theme preview-sorting" />
|
||||
<sorting-icon v-if="icon === 'preview-sorting'" class="icon dark-text-theme preview-sorting" />
|
||||
<span class="label">
|
||||
<slot></slot>
|
||||
</span>
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
<script>
|
||||
import { FilterIcon, DollarSignIcon, CheckIcon, XSquareIcon, CheckSquareIcon, FolderPlusIcon, ListIcon, GridIcon, TrashIcon, UserPlusIcon, PlusIcon, CreditCardIcon } from 'vue-feather-icons'
|
||||
import SortingAndPreviewIcon from '@/components/FilesView/Icons/SortingAndPreviewIcon'
|
||||
import SortingIcon from '@/components/FilesView/Icons/SortingIcon'
|
||||
|
||||
export default {
|
||||
name: 'MobileActionButton',
|
||||
@@ -31,7 +31,7 @@
|
||||
'icon'
|
||||
],
|
||||
components: {
|
||||
SortingAndPreviewIcon,
|
||||
SortingIcon,
|
||||
CheckSquareIcon,
|
||||
DollarSignIcon,
|
||||
CreditCardIcon,
|
||||
@@ -70,7 +70,7 @@
|
||||
margin-right: 10px;
|
||||
@include font-size(14);
|
||||
|
||||
path, line, polyline, rect, circle {
|
||||
path, line, polyline, rect, circle, polygon {
|
||||
@include transition(150ms);
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@
|
||||
.mobile-action-button {
|
||||
background: $dark_mode_foreground;
|
||||
|
||||
path, line, polyline, rect, circle {
|
||||
path, line, polyline, rect, circle, polygon {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ import {
|
||||
.menu-option {
|
||||
color: $dark_mode_text_primary;
|
||||
|
||||
&:hover {
|
||||
&:hover:not(.hover-disabled) {
|
||||
background: lighten($dark_mode_foreground, 2%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,12 @@
|
||||
<link-icon v-if="source === 'share'" size="19" />
|
||||
<x-icon v-if="source === 'close'" size="19" />
|
||||
<cloud-off-icon v-if="source === 'shared-off'" size="19" />
|
||||
<sorting-and-preview-icon v-if="source === 'preview-sorting'" size="19" class="preview-sorting"/>
|
||||
<sorting-icon v-if="source === 'preview-sorting'" class="preview-sorting"/>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SortingIcon from '@/components/FilesView/Icons/SortingIcon'
|
||||
import {
|
||||
CornerDownRightIcon,
|
||||
DownloadCloudIcon,
|
||||
@@ -35,7 +36,6 @@
|
||||
LinkIcon,
|
||||
XIcon,
|
||||
} from "vue-feather-icons";
|
||||
import SortingAndPreviewIcon from '@/components/FilesView/Icons/SortingAndPreviewIcon'
|
||||
|
||||
export default {
|
||||
name: "ToolbarButton",
|
||||
@@ -44,7 +44,7 @@
|
||||
'action'
|
||||
],
|
||||
components: {
|
||||
SortingAndPreviewIcon,
|
||||
SortingIcon,
|
||||
CornerDownRightIcon,
|
||||
DownloadCloudIcon,
|
||||
FolderPlusIcon,
|
||||
|
||||
@@ -1,32 +1,24 @@
|
||||
<template>
|
||||
<div @contextmenu.prevent.capture="contextMenu($event, undefined)"
|
||||
id="files-view">
|
||||
<ContextMenu/>
|
||||
<DesktopSortingAndPreview/>
|
||||
<DesktopToolbar/>
|
||||
<div @contextmenu.prevent.capture="contextMenu($event, undefined)" id="files-view">
|
||||
<DesktopToolbar/>
|
||||
<ContextMenu />
|
||||
<FileBrowser/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DesktopSortingAndPreview from '@/components/FilesView/DesktopSortingAndPreview'
|
||||
import DesktopToolbar from '@/components/FilesView/DesktopToolbar'
|
||||
import FileBrowser from '@/components/FilesView/FileBrowser'
|
||||
import ContextMenu from '@/components/FilesView/ContextMenu'
|
||||
import {mapGetters} from 'vuex'
|
||||
import ContextMenu from '@/components/FilesView/ContextMenu'
|
||||
import {events} from '@/bus'
|
||||
|
||||
export default {
|
||||
name: 'FilesView',
|
||||
components: {
|
||||
DesktopSortingAndPreview,
|
||||
DesktopToolbar,
|
||||
FileBrowser,
|
||||
ContextMenu,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['config']),
|
||||
},
|
||||
methods: {
|
||||
contextMenu(event, item) {
|
||||
events.$emit('contextMenu:show', event, item)
|
||||
@@ -36,8 +28,6 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@assets/vuefilemanager/_variables';
|
||||
@import '@assets/vuefilemanager/_mixins';
|
||||
|
||||
#files-view {
|
||||
font-family: 'Nunito', sans-serif;
|
||||
|
||||
Reference in New Issue
Block a user