Merge remote-tracking branch 'origin/v2'

# Conflicts:
#	config/content.php
#	config/vuefilemanager.php
#	public/mix-manifest.json
#	resources/js/views/Mobile/AdminMobileMenu.vue
#	resources/js/views/Shared/SharedPage.vue
This commit is contained in:
Peter Papp
2021-04-03 07:40:32 +02:00
483 changed files with 40246 additions and 44513 deletions
+28 -145
View File
@@ -1,147 +1,33 @@
<template>
<div id="vue-file-manager" v-cloak @click="unClick">
<div id="vuefilemanager" @click="unClick" v-cloak>
<Alert />
<ToastrWrapper />
<!--System alerts-->
<Alert/>
<router-view v-if="isLoadedTranslations" />
<div id="application-wrapper" v-if="! isGuestLayout">
<!-- Full File Preview -->
<FileFullPreview/>
<!--Mobile Navigation-->
<MobileNavigation/>
<!-- Processing popup for zip -->
<ProcessingPopup/>
<!--Confirm Popup-->
<Confirm/>
<!--Share Item setup-->
<ShareCreate/>
<ShareEdit/>
<!--Rename folder or file item-->
<RenameItem/>
<!--Create folder in mobile version-->
<CreateFolder/>
<!--Move item setup-->
<MoveItem/>
<!-- Mobile Menu for Multiselected items -->
<MobileMultiSelectMenu/>
<!-- Drag & Drop UI -->
<DragUI/>
<!-- Mobile menu for selecting view and sorting -->
<MobileSortingAndPreview/>
<!--Mobile Menu-->
<MobileMenu/>
<!--Navigation Sidebar-->
<MenuBar/>
<!--Toastr-->
<ToastrWrapper/>
<!--File page-->
<keep-alive :include="['Admin', 'Users']">
<router-view :class="{'is-scaled-down': isScaledDown}"/>
</keep-alive>
</div>
<router-view v-if="isGuestLayout"/>
<CookieDisclaimer/>
<Vignette/>
<CookieDisclaimer />
<Vignette />
</div>
</template>
<script>
import MobileSortingAndPreview from '@/components/FilesView/MobileSortingAndPreview'
import MobileMultiSelectMenu from '@/components/FilesView/MobileMultiSelectMenu'
import ToastrWrapper from '@/components/Others/Notifications/ToastrWrapper'
import ProcessingPopup from '@/components/FilesView/ProcessingPopup'
import FileFullPreview from '@/components/FilesView/FileFullPreview'
import MobileNavigation from '@/components/Others/MobileNavigation'
import CookieDisclaimer from '@/components/Others/CookieDisclaimer'
import CreateFolder from '@/components/Others/CreateFolder'
import MobileMenu from '@/components/FilesView/MobileMenu'
import ShareCreate from '@/components/Others/ShareCreate'
import Confirm from '@/components/Others/Popup/Confirm'
import RenameItem from '@/components/Others/RenameItem'
import ShareEdit from '@/components/Others/ShareEdit'
import MoveItem from '@/components/Others/MoveItem'
import Vignette from '@/components/Others/Vignette'
import DragUI from '@/components/FilesView/DragUI'
import MenuBar from '@/components/Sidebar/MenuBar'
import Alert from '@/components/FilesView/Alert'
import { includes } from 'lodash'
import { mapGetters } from 'vuex'
import { events } from './bus'
import {events} from './bus'
export default {
name: 'app',
components: {
MobileSortingAndPreview,
MobileMultiSelectMenu,
MobileNavigation,
CookieDisclaimer,
FileFullPreview,
ProcessingPopup,
ToastrWrapper,
CreateFolder,
ShareCreate,
MobileMenu,
RenameItem,
ShareEdit,
MoveItem,
Vignette,
Confirm,
MenuBar,
DragUI,
Alert
},
computed: {
...mapGetters([
'isLogged', 'isGuest', 'config', 'fileQueue'
]),
isGuestLayout() {
return (includes([
'InstallationDisclaimer',
'SubscriptionService',
'StripeCredentials',
'SubscriptionPlans',
'ForgottenPassword',
'CreateNewPassword',
'EnvironmentSetup',
'VerifyByPassword',
'SaaSLandingPage',
'BillingsDetail',
'NotFoundShared',
'AdminAccount',
'PurchaseCode',
'DynamicPage',
'SharedPage',
'ContactUs',
'AppSetup',
'Database',
'Upgrade',
'SignIn',
'SignUp'
], this.$route.name)
)
}
},
data() {
return {
isScaledDown: false
isLoadedTranslations: false
}
},
methods: {
@@ -151,46 +37,43 @@ export default {
},
beforeMount() {
// Store config to vuex
this.$store.commit('INIT', {
authCookie: this.$root.$data.config.hasAuthCookie,
config: this.$root.$data.config,
rootDirectory: {
name: this.$t('locations.home'),
location: 'base',
unique_id: 0
}
})
// Get language translations
this.$store.dispatch('getLanguageTranslations', this.$root.$data.config.language)
.then(response => {
this.isLoadedTranslations = true
// Store config to vuex
this.$store.commit('INIT', {
config: this.$root.$data.config,
rootDirectory: {
name: this.$t('locations.home'),
location: 'base',
id: undefined
}
})
})
// Get installation state
let installation = this.$root.$data.config.installation
// Redirect to database verify code
if (installation === 'setup-database')
this.$router.push({ name: 'PurchaseCode' })
this.$router.push({name: 'PurchaseCode'})
// Redirect to starting installation process
if (installation === 'setup-disclaimer')
this.$router.push({ name: 'InstallationDisclaimer' })
this.$router.push({name: 'InstallationDisclaimer'})
},
mounted() {
this.$checkOS()
// Handle mobile navigation scale animation
events.$on('show:mobile-navigation', () => this.isScaledDown = true)
events.$on('hide:mobile-navigation', () => this.isScaledDown = false)
events.$on('mobileMenu:show', () => this.isScaledDown = true)
events.$on('fileItem:deselect', () => this.isScaledDown = false)
events.$on('mobileSortingAndPreview', state => this.isScaledDown = state)
}
}
</script>
<style lang="scss">
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;400;600;700;800;900&display=swap');
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
[v-cloak],
[v-cloak] > * {
@@ -216,7 +99,7 @@ export default {
height: 100%;
}
#vue-file-manager {
#vuefilemanager {
position: absolute;
width: 100%;
height: 100%;
@@ -1,13 +1,13 @@
<template>
<WidgetWrapper :icon="icon" :title="title">
<DatatableWrapper @init="isLoading = false" api="/api/dashboard/new-users" :paginator="false" :columns="columns" class="table table-users">
<DatatableWrapper @init="isLoading = false" api="/api/admin/dashboard/newbies" :paginator="false" :columns="columns" class="table table-users">
<template slot-scope="{ row }">
<tr>
<td style="width: 300px">
<router-link :to="{name: 'UserDetail', params: {id: row.data.id}}">
<DatatableCellImage
:image="row.data.attributes.avatar"
:title="row.data.attributes.name"
:image="row.data.relationships.settings.data.attributes.avatar"
:title="row.data.relationships.settings.data.attributes.name"
:description="row.data.attributes.email"
/>
</router-link>
@@ -19,7 +19,7 @@
</td>
<td>
<span class="cell-item">
{{ row.relationships.storage.data.attributes.used_formatted }}
{{ row.data.attributes.storage.used_formatted }}
</span>
</td>
<td>
@@ -30,10 +30,10 @@
<td>
<div class="action-icons">
<router-link :to="{name: 'UserDetail', params: {id: row.data.id}}">
<edit-2-icon size="15" class="icon icon-edit"></edit-2-icon>
<Edit2Icon size="15" class="icon icon-edit" />
</router-link>
<router-link :to="{name: 'UserDelete', params: {id: row.data.id}}">
<trash2-icon size="15" class="icon icon-trash"></trash2-icon>
<Trash2Icon size="15" class="icon icon-trash" />
</router-link>
</div>
</td>
@@ -110,8 +110,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
@media (prefers-color-scheme: dark) {
@@ -5,7 +5,7 @@
</div>
<router-link :to="{name: linkRoute}" class="footer-link">
<span class="content">{{ linkName }}</span>
<chevron-right-icon size="16"></chevron-right-icon>
<chevron-right-icon size="16" class="text-theme"></chevron-right-icon>
</router-link>
</WidgetWrapper>
</template>
@@ -28,8 +28,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.widget-value {
margin-top: 10px;
@@ -46,7 +46,7 @@
align-items: center;
polyline {
stroke: $theme;
color: inherit;
}
.content {
@@ -3,9 +3,9 @@
<div class="widget-content">
<div class="headline">
<div class="icon">
<users-icon v-if="icon === 'users'" size="19"></users-icon>
<star-icon v-if="icon === 'star'" size="19"></star-icon>
<hard-drive-icon v-if="icon === 'hard-drive'" size="19"></hard-drive-icon>
<users-icon v-if="icon === 'users'" size="19" class="text-theme"></users-icon>
<star-icon v-if="icon === 'star'" size="19" class="text-theme"></star-icon>
<hard-drive-icon v-if="icon === 'hard-drive'" size="19" class="text-theme"></hard-drive-icon>
</div>
<b class="title">{{ title }}</b>
</div>
@@ -30,8 +30,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.widget-content {
@include widget-card;
@@ -44,7 +44,7 @@
margin-right: 10px;
path, circle, line, polygon {
stroke: $theme;
color: inherit;
}
}
}
+8 -8
View File
@@ -1,12 +1,12 @@
<template>
<button class="button outline">
<button class="button outline hover-text-theme hover-border-theme">
<span class="text-label">{{ text }}</span>
<span v-if="loading" class="icon">
<FontAwesomeIcon icon="sync-alt" class="sync-alt"/>
<FontAwesomeIcon icon="sync-alt" class="sync-alt svg-color-theme"/>
</span>
<span v-if="! loading && icon" class="icon">
<FontAwesomeIcon :icon="icon"/>
<FontAwesomeIcon :icon="icon" class="svg-color-theme"/>
</span>
</button>
</template>
@@ -28,8 +28,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.button {
cursor: pointer;
@@ -74,15 +74,15 @@
.icon {
path {
fill: $theme;
fill: inherit;
}
}
&:hover {
border-color: $theme;
border-color: inherit;
.text-label {
color: $theme;
color: inherit;
}
}
}
+3 -3
View File
@@ -96,8 +96,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.popup {
position: absolute;
@@ -169,7 +169,7 @@
@media (prefers-color-scheme: dark) {
.popup-wrapper {
background: $dark_mode_background;
background: $dark_mode_foreground;
}
.popup-content {
.title {
@@ -1,7 +1,7 @@
<template>
<button class="button-base" :class="buttonStyle" type="button">
<div v-if="loading" class="icon">
<refresh-cw-icon size="16" class="sync-alt"></refresh-cw-icon>
<refresh-cw-icon size="16" class="sync-alt" />
</div>
<div class="content">
<slot v-if="! loading"></slot>
@@ -22,8 +22,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.button-base {
@include font-size(15);
@@ -47,28 +47,11 @@
transform: scale(0.95);
}
&.theme {
background: rgba($theme, .1);
.content {
color: $theme;
}
polyline, path {
stroke: $theme;
}
}
&.theme-solid {
background: $theme;
.content {
color: white;
}
polyline, path {
stroke: white;
}
}
&.danger {
@@ -133,9 +116,15 @@
}
polyline, path {
stroke: $theme;
color: inherit;
}
}
}
.popup-wrapper {
.button-base.secondary {
background: lighten($dark_mode_foreground, 3%);
}
}
}
</style>
@@ -31,8 +31,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.button-base {
@include font-size(15);
@@ -48,11 +48,6 @@
transform: scale(0.95);
}
&.theme {
color: $theme;
background: rgba($theme, .1);
}
&.secondary {
color: $text;
background: $light_background;
+98 -110
View File
@@ -4,16 +4,16 @@
<!-- File Preview -->
<div class="menu-options" id="menu-list" v-if="showFromPreview">
<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="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"/>
: $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"/>
<Option @click.native="downloadItem" v-if="!isFolder" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</div>
@@ -21,26 +21,26 @@
<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" v-if="item" :title="$t('context_menu.delete')" icon="trash"/>
<Option @click.native="emptyTrash" :title="$t('context_menu.empty_trash')" icon="empty-trash"/>
<OptionGroup v-if="isMultiSelectContextMenu">
<Option @click.native="restoreItem" v-if="item" :title="$t('context_menu.restore')" icon="restore" />
<Option @click.native="deleteItem" v-if="item" :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 v-if="item && isMultiSelectContextMenu">
<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="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 v-if="!isMultiSelectContextMenu">
<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 && !hasFolder">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download"/>
<OptionGroup v-if="item && !isMultiSelectContextMenu && !hasFolder">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</div>
@@ -48,38 +48,38 @@
<div v-if="$isThisLocation(['shared']) && $checkPermission('master') && !showFromPreview" id="menu-list" class="menu-options">
<!-- Single options -->
<OptionGroup class="menu-option-group" v-if="item && isFolder && multiSelectContextMenu">
<Option @click.native="addToFavourites" :title=" isInFavourites
<OptionGroup class="menu-option-group" v-if="item && isFolder && isMultiSelectContextMenu">
<Option @click.native="addToFavourites" :title="isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')" icon="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 v-if="item && isMultiSelectContextMenu">
<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"/>
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder"/>
<OptionGroup v-if="item && isMultiSelectContextMenu">
<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" />
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
</OptionGroup>
<!-- Multi options -->
<OptionGroup class="menu-option-group" v-if="item && !hasFile && !multiSelectContextMenu">
<Option @click.native="addToFavourites" :title=" isInFavourites
<OptionGroup class="menu-option-group" v-if="item && !hasFile && !isMultiSelectContextMenu">
<Option @click.native="addToFavourites" :title="isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')" icon="favourites"/>
: $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 v-if="item && !isMultiSelectContextMenu">
<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 v-if="item && !isMultiSelectContextMenu && !hasFolder">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</div>
@@ -87,46 +87,46 @@
<div v-if="$isThisLocation(['base', 'participant_uploads', 'latest']) && $checkPermission('master') && !showFromPreview" id="menu-list" class="menu-options">
<!-- No Files options -->
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && multiSelectContextMenu && !item">
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && isMultiSelectContextMenu && !item">
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder" />
</OptionGroup>
<!-- Single options -->
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && item && multiSelectContextMenu && isFolder">
<Option @click.native="addToFavourites" :title="isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites')" icon="favourites"/>
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && item && isMultiSelectContextMenu && isFolder">
<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="moveItem" v-if="!$isThisLocation(['latest'])" :title="$t('context_menu.move')" icon="move-item"/>
<OptionGroup v-if="item && isMultiSelectContextMenu">
<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"/>
: $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"/>
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder"/>
<OptionGroup v-if="item && isMultiSelectContextMenu ">
<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" />
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
</OptionGroup>
<!-- Multi options -->
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && !multiSelectContextMenu">
<Option @click.native="addToFavourites" v-if="item && !hasFile" :title=" isInFavourites
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && !isMultiSelectContextMenu && item && !hasFile">
<Option @click.native="addToFavourites" :title=" isInFavourites
? $t('context_menu.remove_from_favourites')
: $t('context_menu.add_to_favourites')" icon="favourites"/>
: $t('context_menu.add_to_favourites')" icon="favourites" />
</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 v-if="item && !isMultiSelectContextMenu">
<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 v-if="item && !isMultiSelectContextMenu && !hasFolder">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</div>
@@ -134,33 +134,33 @@
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('editor') && !showFromPreview " id="menu-list" class="menu-options">
<!-- No Files options -->
<OptionGroup v-if="multiSelectContextMenu && !item">
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
<OptionGroup v-if="isMultiSelectContextMenu && !item">
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder" />
</OptionGroup>
<!-- Single options -->
<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 v-if="item && isMultiSelectContextMenu">
<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"/>
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder"/>
<OptionGroup v-if="item && isMultiSelectContextMenu">
<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" />
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
</OptionGroup>
<!-- Multi options -->
<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 v-if="item && !isMultiSelectContextMenu">
<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 v-if="item && !isMultiSelectContextMenu && !hasFolder">
<Option @click.native="downloadItem" :title="$t('context_menu.download')" icon="download" />
</OptionGroup>
</div>
@@ -168,16 +168,16 @@
<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"/>
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder"/>
<OptionGroup v-if="item && isMultiSelectContextMenu">
<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" />
<Option @click.native="downloadFolder" v-if="isFolder" :title="$t('context_menu.zip_folder')" icon="zip-folder" />
</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 v-if="!isMultiSelectContextMenu && 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>
@@ -187,8 +187,8 @@
<script>
import OptionGroup from '@/components/FilesView/OptionGroup'
import Option from '@/components/FilesView/Option'
import { mapGetters } from 'vuex'
import { events } from '@/bus'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
export default {
name: 'ContextMenu',
@@ -199,20 +199,12 @@ export default {
computed: {
...mapGetters(['user', 'fileInfoDetail']),
hasFolder() {
// Check if selected items includes some folder
if (this.fileInfoDetail.find(item => item.type === 'folder'))
return true
return this.fileInfoDetail.find(item => item.type === 'folder')
},
hasFile() {
// Check if selected items includes some files
if (this.fileInfoDetail.find(item => item.type !== 'folder'))
return true
return this.fileInfoDetail.find(item => item.type !== 'folder')
},
multiSelectContextMenu() {
isMultiSelectContextMenu() {
// 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))
@@ -221,10 +213,9 @@ export default {
// 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))
return true
},
favourites() {
return this.user.relationships.favourites.data.attributes.folders
return this.user.data.relationships.favourites.data.attributes.folders
},
isFolder() {
return this.item && this.item.type === 'folder'
@@ -241,7 +232,7 @@ export default {
return this.item && this.item.type === 'image'
},
isInFavourites() {
return this.favourites.find((el) => el.unique_id == this.item.unique_id)
return this.favourites.find((el) => el.id === this.item.id)
}
},
data() {
@@ -253,10 +244,9 @@ export default {
positionY: 0
}
},
methods: {
downloadFolder(){
this.$store.dispatch('downloadFolder' , this.item)
downloadFolder() {
this.$store.dispatch('downloadFolder', this.item)
},
emptyTrash() {
this.$store.dispatch('emptyTrash')
@@ -264,36 +254,36 @@ export default {
restoreItem() {
// If is item not in selected items restore just this single item
if(!this.fileInfoDetail.includes(this.item))
if (!this.fileInfoDetail.includes(this.item))
this.$store.dispatch('restoreItem', this.item)
// If is item in selected items restore all items from fileInfoDetail
if(this.fileInfoDetail.includes(this.item))
if (this.fileInfoDetail.includes(this.item))
this.$store.dispatch('restoreItem', null)
},
shareCancel() {
this.$store.dispatch('shareCancel')
},
renameItem() {
events.$emit('popup:open', { name: 'rename-item', item: this.item })
events.$emit('popup:open', {name: 'rename-item', item: this.item})
},
moveItem() {
events.$emit('popup:open', { name: 'move', item: [this.item] })
events.$emit('popup:open', {name: 'move', item: [this.item]})
},
shareItem() {
if (this.item.shared) {
// Open edit share popup
events.$emit('popup:open', { name: 'share-edit', item: this.item })
events.$emit('popup:open', {name: 'share-edit', item: this.item})
} else {
// Open create share popup
events.$emit('popup:open', { name: 'share-create', item: this.item })
events.$emit('popup:open', {name: 'share-create', item: this.item})
}
},
addToFavourites() {
// Check if folder is in favourites and then add/remove from favourites
if (
this.favourites &&
!this.favourites.find(el => el.unique_id == this.item.unique_id)
!this.favourites.find(el => el.id === this.item.id)
) {
// Add to favourite folder that is not selected
if (!this.fileInfoDetail.includes(this.item)) {
@@ -419,10 +409,8 @@ export default {
this.isVisible = false
this.showFromPreview = false
this.item = undefined
})
events.$on('contextMenu:show', (event, item) => {
// Store item
this.item = item
@@ -445,8 +433,8 @@ export default {
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.no-options {
/deep/ .text-label {
@@ -29,8 +29,8 @@ import { events } from '@/bus'
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.sorting-preview {
min-width: 250px;
@@ -46,38 +46,12 @@ import { events } from '@/bus'
&.showed {
display: block;
}
/deep/.menu-option {
&:hover {
background: $light_background;
.text-label {
color: $theme;
}
path,
/deep/ line,
/deep/ polyline,
rect,
circle,
polygon {
stroke: $theme !important;
}
}
}
}
@media (prefers-color-scheme: dark) {
.sorting-preview {
background: $dark_mode_foreground;
/deep/ .menu-option {
&:hover {
background: rgba($theme, 0.1);
}
}
}
}
@@ -7,14 +7,12 @@
<chevron-left-icon size="17" :class="{ 'is-active': browseHistory.length > 1 }" class="icon-back"></chevron-left-icon>
<span class="back-directory-title">
{{ directoryName }}
</span>
{{ directoryName }}
</span>
<span @click.stop="folderActions" v-if="
browseHistory.length > 1 && $isThisLocation(['base', 'public'])
" class="folder-options" id="folder-actions">
<more-horizontal-icon size="14" class="icon-more"></more-horizontal-icon>
</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>
@@ -86,10 +84,7 @@ export default {
if (!this.$store.getters.user) return true
// Check if user has storage
return (
this.$store.getters.user.relationships.storage.data.attributes.used <=
100
)
return this.$store.getters.user.data.attributes.storage.used <= 100
},
directoryName() {
return this.currentFolder
@@ -187,7 +182,7 @@ export default {
this.$store.dispatch('deleteItem')
},
createFolder() {
this.$store.dispatch('createFolder', this.$t('popup_create_folder.folder_default_name'))
this.$store.dispatch('createFolder', {name: this.$t('popup_create_folder.folder_default_name')})
},
moveItem() {
if (this.fileInfoDetail.length > 0)
@@ -223,27 +218,13 @@ export default {
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.preview-sorting {
/deep/ .label {
color: $text !important;
}
/deep/ .preview-sorting {
path, line, polyline, rect, circle {
stroke: $text !important;
}
}
&:hover {
/deep/ .preview-sorting {
path, line, polyline, rect, circle {
stroke: $theme !important;
}
}
}
}
.toolbar-wrapper {
@@ -304,7 +285,7 @@ export default {
background: $light_background;
svg circle {
stroke: $theme;
color: inherit;
}
}
@@ -351,22 +332,9 @@ export default {
margin-left: 5px;
&.active {
/deep/ svg {
line,
circle,
rect {
stroke: $theme;
}
}
&.preview-sorting {
background: $light_background;
/deep/ .preview-sorting {
path, line, polyline, rect, circle {
stroke: $theme !important;
}
}
}
}
@@ -427,16 +395,5 @@ export default {
background: $dark_mode_foreground !important;
}
}
.preview-sorting {
/deep/ .label {
color: $text !important;
}
/deep/ .preview-sorting {
path, line, polyline, rect, circle {
stroke: $dark_mode_text_primary !important;
}
}
}
}
</style>
+2 -36
View File
@@ -68,15 +68,13 @@ export default {
events.$on('drop', () => {
this.isVisible = false
})
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
#multi-select-ui {
max-width: 300px;
@@ -88,43 +86,11 @@ export default {
border-radius: 8px;
box-shadow: 0 7px 25px 1px rgba(0, 0, 0, 0.12);
background: white;
/deep/ .text {
.title {
color: $text;
}
.count {
color: $text-muted;
}
}
/deep/ .icon-wrapper {
.icon {
stroke: $theme;
}
}
}
@media (prefers-color-scheme: dark) {
#multi-select-ui {
background: $dark_mode_foreground;
/deep/ .text {
.title {
color: $dark_mode_text_primary;
}
.count {
color: $dark_mode_text_secondary;
}
}
/deep/ .icon-wrapper {
.icon {
stroke: $theme;
}
}
}
}
@@ -20,8 +20,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.empty-message {
text-align: center;
@@ -59,8 +59,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.empty-page {
position: absolute;
@@ -8,10 +8,10 @@
tabindex="-1"
>
<div
class="files-container"
ref="fileContainer"
:class="{'is-fileinfo-visible': fileInfoVisible && !$isMinimalScale() , 'mobile-multi-select' : mobileMultiSelect}"
@click.self="filesContainerClick"
class="files-container"
ref="fileContainer"
:class="{'is-fileinfo-visible': fileInfoVisible && !$isMinimalScale() , 'mobile-multi-select' : mobileMultiSelect}"
@click.self="filesContainerClick"
>
<!--MobileToolbar-->
<MobileToolbar />
@@ -25,20 +25,20 @@
<!--Item previews list-->
<div v-if="isList" class="file-list-wrapper">
<transition-group
name="file"
tag="section"
class="file-list"
:class="FilePreviewType"
name="file"
tag="section"
class="file-list"
:class="FilePreviewType"
>
<FileItemList
@dragstart="dragStart(item)"
@drop.stop.native.prevent="dragFinish(item, $event)"
@contextmenu.native.prevent="contextMenu($event, item)"
:item="item"
v-for="item in data"
:key="item.unique_id"
class="file-item"
:class="draggedItems.includes(item) ? 'dragged' : '' "
@dragstart="dragStart(item)"
@drop.stop.native.prevent="dragFinish(item, $event)"
@contextmenu.native.prevent="contextMenu($event, item)"
:item="item"
v-for="item in data"
:key="item.id"
class="file-item"
:class="draggedItems.includes(item) ? 'dragged' : '' "
/>
</transition-group>
</div>
@@ -46,47 +46,47 @@
<!--Item previews grid-->
<div v-if="isGrid" class="file-grid-wrapper">
<transition-group
name="file"
tag="section"
class="file-list"
:class="FilePreviewType"
name="file"
tag="section"
class="file-list"
:class="FilePreviewType"
>
<FileItemGrid
@dragstart="dragStart(item)"
@drop.native.prevent="dragFinish(item, $event)"
@contextmenu.native.prevent="contextMenu($event, item)"
:item="item"
v-for="item in data"
:key="item.unique_id"
class="file-item"
:class="draggedItems.includes(item) ? 'dragged' : '' "
@dragstart="dragStart(item)"
@drop.native.prevent="dragFinish(item, $event)"
@contextmenu.native.prevent="contextMenu($event, item)"
:item="item"
v-for="item in data"
:key="item.id"
class="file-item"
:class="draggedItems.includes(item) ? 'dragged' : '' "
/>
</transition-group>
</div>
<!--Show empty page if folder is empty-->
<EmptyPage v-if="! isSearching"/>
<EmptyPage v-if="! isSearching" />
<!--Show empty page if no search results-->
<EmptyMessage
v-if="isSearching && isEmpty"
:message="$t('messages.nothing_was_found')"
icon="eye-slash"
v-if="isSearching && isEmpty"
:message="$t('messages.nothing_was_found')"
icon="eye-slash"
/>
</div>
<!--File Info Panel-->
<div v-if="! $isMinimalScale()" class="file-info-container" :class="{ 'is-fileinfo-visible': fileInfoVisible }">
<!--File info panel-->
<FileInfoPanel v-if="fileInfoDetail.length === 1"/>
<FileInfoPanel v-if="fileInfoDetail.length === 1" />
<MultiSelected v-if="fileInfoDetail.length > 1"
:title="$t('file_detail.selected_multiple')"
:subtitle="this.fileInfoDetail.length + ' ' + $tc('file_detail.items', this.fileInfoDetail.length)"
<MultiSelected v-if="fileInfoDetail.length > 1"
:title="$t('file_detail.selected_multiple')"
:subtitle="this.fileInfoDetail.length + ' ' + $tc('file_detail.items', this.fileInfoDetail.length)"
/>
<!--If file info panel empty show message-->
<EmptyMessage v-if="fileInfoDetail.length === 0" :message="$t('messages.nothing_to_preview')" icon="eye-off"/>
<EmptyMessage v-if="fileInfoDetail.length === 0" :message="$t('messages.nothing_to_preview')" icon="eye-off" />
</div>
</div>
</template>
@@ -140,11 +140,11 @@
draggedItems() {
//Set opacity for dragged items
if(!this.fileInfoDetail.includes(this.draggingId)){
if (!this.fileInfoDetail.includes(this.draggingId)) {
return [this.draggingId]
}
if(this.fileInfoDetail.includes(this.draggingId)) {
if (this.fileInfoDetail.includes(this.draggingId)) {
return this.fileInfoDetail
}
}
@@ -158,13 +158,13 @@
},
methods: {
deleteItems() {
if(this.fileInfoDetail.length > 0 && this.$checkPermission('master') || this.$checkPermission('editor')) {
if (this.fileInfoDetail.length > 0 && this.$checkPermission('master') || this.$checkPermission('editor')) {
this.$store.dispatch('deleteItem')
}
},
dropUpload(event) {
// Upload external file
this.$uploadExternalFiles(event, this.currentFolder.unique_id)
this.$uploadExternalFiles(event, this.currentFolder.id)
this.isDragging = false
},
@@ -191,29 +191,27 @@
if (data.type !== 'folder' || this.draggingId === data) return
//Prevent move selected folder to folder if in beteewn selected folders
if(this.fileInfoDetail.find(item => item === data && this.fileInfoDetail.length > 1)) return
if (this.fileInfoDetail.find(item => item === data && this.fileInfoDetail.length > 1)) return
// Move folder to new parent
//Move item if is not included in selected items
if(!this.fileInfoDetail.includes(this.draggingId)){
this.$store.dispatch('moveItem', {to_item:data ,noSelectedItem:this.draggingId})
//Move item if is not included in selected items
if (!this.fileInfoDetail.includes(this.draggingId)) {
this.$store.dispatch('moveItem', {to_item: data, noSelectedItem: this.draggingId})
}
//Move selected items to folder
if(this.fileInfoDetail.length > 0 && this.fileInfoDetail.includes(this.draggingId)){
this.$store.dispatch('moveItem', {to_item:data ,noSelectedItem: null})
if (this.fileInfoDetail.length > 0 && this.fileInfoDetail.includes(this.draggingId)) {
this.$store.dispatch('moveItem', {to_item: data, noSelectedItem: null})
}
} else {
// Get unique_id of current folder
const unique_id = data.type !== 'folder' ? this.currentFolder.unique_id : data.unique_id
// Get id of current folder
const id = data.type !== 'folder' ? this.currentFolder.id : data.id
// Upload external file
this.$uploadExternalFiles(event, unique_id)
this.$uploadExternalFiles(event, id)
}
this.isDragging = false
@@ -222,52 +220,55 @@
events.$emit('contextMenu:show', event, item)
},
filesContainerClick() {
// Deselect itms clicked by outside
// Deselect items clicked by outside
this.$store.commit('CLEAR_FILEINFO_DETAIL')
}
},
created() {
events.$on('mobileSelecting:start' , () => {
this.mobileMultiSelect =true
events.$on('mobileSelecting:start', () => {
this.mobileMultiSelect = true
})
events.$on('mobileSelecting:stop' , () => {
this.mobileMultiSelect = false
events.$on('mobileSelecting:stop', () => {
this.mobileMultiSelect = false
})
events.$on('drop', () => {
this.isDragging = false
setTimeout(() => {
this.draggingId = undefined
}, 10);
}, 10)
})
events.$on('fileItem:deselect', () =>
events.$on('fileItem:deselect', () => {
this.$store.commit('CLEAR_FILEINFO_DETAIL')
)
})
events.$on('scrollTop', () => {
// Scroll top
var container = document.getElementsByClassName(
'files-container'
)[0]
if (container) container.scrollTop = 0
if (container)
container.scrollTop = 0
})
}
}
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.file-list {
.dragged {
/deep/.is-dragenter {
border: 2px solid transparent;
}
/deep/ .is-dragenter {
border: 2px solid transparent;
}
}
}
@@ -279,7 +280,7 @@
position: fixed;
pointer-events: none;
z-index: 100;
}
.mobile-multi-select {
@@ -433,7 +434,7 @@
.mobile-search {
margin-bottom: 0;
}
.file-info-container {
display: none;
}
@@ -78,7 +78,7 @@ export default {
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vuefilemanager/_variables';
.file-full-preview-wrapper {
width: 100%;
@@ -15,7 +15,7 @@
</div>
<div class="file-info">
<span ref="name" class="name">{{ fileInfoDetail[0].name }}</span>
<span class="mimetype" v-if="fileInfoDetail[0].mimetype">.{{ fileInfoDetail[0].mimetype }}</span>
<span class="mimetype text-theme" v-if="fileInfoDetail[0].mimetype">.{{ fileInfoDetail[0].mimetype }}</span>
</div>
</div>
</div>
@@ -27,7 +27,7 @@
:content="fileInfoDetail[0].filesize">
</ListInfoItem>
<ListInfoItem v-if="$checkPermission(['master']) && fileInfoDetail[0].user_scope !== 'master'"
<ListInfoItem v-if="$checkPermission(['master']) && fileInfoDetail[0].author !== 'user'"
:title="$t('file_detail.author')"
:content="$t('file_detail.author_participant')">
</ListInfoItem>
@@ -104,7 +104,7 @@
return option.value === this.fileInfoDetail[0].shared.permission
})
return title ? title.label : this.$t('shared.can_download')
return title ? this.$t(title.label) : this.$t('shared.can_download')
},
sharedIcon() {
switch (this.fileInfoDetail[0].shared.permission) {
@@ -119,7 +119,7 @@
}
},
isLocked() {
return this.fileInfoDetail[0].shared.protected
return this.fileInfoDetail[0].shared.is_protected
}
},
methods: {
@@ -136,8 +136,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.file-info-content {
padding-bottom: 20px;
@@ -180,7 +180,6 @@
.mimetype {
@include font-size(12);
font-weight: 600;
color: $theme;
display: block;
}
}
@@ -215,18 +214,5 @@
}
}
}
.sharelink {
.lock-icon {
&:hover {
path, rect {
stroke: $theme;
}
}
}
}
}
</style>
@@ -10,29 +10,29 @@
<!-- MultiSelecting for the mobile version -->
<div :class="{'check-select-folder' : this.item.type === 'folder', 'check-select' : this.item.type !== 'folder'}" v-if="multiSelectMode">
<div class="select-box" :class="{'select-box-active' : isClicked } ">
<CheckIcon v-if="isClicked" class="icon" size="17"/>
<CheckIcon v-if="isClicked" class="icon" size="17" />
</div>
</div>
<!--If is file or image, then link item-->
<span v-if="isFile || (isImage && !item.thumbnail)" class="file-icon-text">
<span v-if="isFile || (isImage && !item.thumbnail)" class="file-icon-text text-theme">
{{ item.mimetype }}
</span>
<!--Folder thumbnail-->
<FontAwesomeIcon v-if="isFile || (isImage && !item.thumbnail)" class="file-icon" icon="file"/>
<FontAwesomeIcon v-if="isFile || (isImage && !item.thumbnail)" class="file-icon" icon="file" />
<!--Image thumbnail-->
<img loading="lazy" v-if="isImage && item.thumbnail" class="image" :src="item.thumbnail" :alt="item.name"/>
<img loading="lazy" v-if="isImage && item.thumbnail" class="image" :src="item.thumbnail" :alt="item.name" />
<!--Else show only folder icon-->
<FolderIcon v-if="isFolder" :item="item" location="file-item-grid" class="folder"/>
<!--Else show only folder icon-->
<FolderIcon v-if="isFolder" :item="item" location="file-item-grid" class="folder svg-color-theme" />
</div>
<!--Name-->
<div class="item-name">
<!--Name-->
<b :ref="this.item.unique_id" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName" class="name">
<b :ref="this.item.id" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName" class="name">
{{ itemName }}
</b>
@@ -40,12 +40,12 @@
<!--Shared Icon-->
<div v-if="$checkPermission('master') && item.shared" class="item-shared">
<link-icon size="12" class="shared-icon"></link-icon>
<link-icon size="12" class="shared-icon text-theme" />
</div>
<!--Participant owner Icon-->
<div v-if="$checkPermission('master') && item.user_scope !== 'master'" class="item-shared">
<user-plus-icon size="12" class="shared-icon"></user-plus-icon>
<div v-if="$checkPermission('master') && item.author !== 'user'" class="item-shared">
<user-plus-icon size="12" class="shared-icon text-theme" />
</div>
<!--Filesize-->
@@ -59,23 +59,24 @@
</div>
<span @click.stop="showItemActions" class="show-actions" v-if="$isMobile() && ! multiSelectMode && canShowMobileOptions">
<FontAwesomeIcon icon="ellipsis-h" class="icon-action"></FontAwesomeIcon>
<MoreHorizontalIcon icon="ellipsis-h" size="16" class="icon-action text-theme"/>
</span>
</div>
</div>
</template>
<script>
import { LinkIcon, UserPlusIcon, CheckIcon } from 'vue-feather-icons'
import {LinkIcon, UserPlusIcon, CheckIcon, MoreHorizontalIcon} from 'vue-feather-icons'
import FolderIcon from '@/components/FilesView/FolderIcon'
import { debounce } from 'lodash'
import { mapGetters } from 'vuex'
import { events } from '@/bus'
import {debounce} from 'lodash'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
export default {
name: 'FileItemGrid',
props: ['item'],
components: {
MoreHorizontalIcon,
UserPlusIcon,
CheckIcon,
LinkIcon,
@@ -85,23 +86,23 @@ export default {
...mapGetters([
'FilePreviewType', 'sharedDetail', 'fileInfoDetail', 'data'
]),
folderEmojiOrColor(){
folderEmojiOrColor() {
// If folder have set some color
if(this.item.icon_color) {
this.$nextTick(() => {
this.$refs[`folder${this.item.unique_id}`].firstElementChild.style.fill = `${this.item.icon_color}`
// If folder have set some color
if (this.item.color) {
this.$nextTick(() => {
this.$refs[`folder${this.item.id}`].firstElementChild.style.fill = this.item.color
})
return false
}
// If folder have set some emoji
if(this.item.icon_emoji)
return this.item.icon_emoji
if (this.item.emoji)
return this.item.emoji
},
isClicked() {
return this.fileInfoDetail.some(element => element.unique_id == this.item.unique_id)
return this.fileInfoDetail.some(element => element.id === this.item.id)
},
isFolder() {
return this.item.type === 'folder'
@@ -177,10 +178,10 @@ export default {
// After click deselect new folder rename input
document.getSelection().removeAllRanges();
if (e.ctrlKey || e.metaKey && !e.shiftKey) {
// Click + Ctrl
if (this.fileInfoDetail.some(item => item.unique_id === this.item.unique_id)) {
if (this.fileInfoDetail.some(item => item.id === this.item.id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.item)
} else {
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
@@ -218,9 +219,9 @@ export default {
if (this.$isMobile() && this.isFolder) {
// Go to folder
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [{ folder: this.item, back: false, init: false }])
this.$store.dispatch('browseShared', [{folder: this.item, back: false, init: false}])
} else {
this.$store.dispatch('getFolder', [{ folder: this.item, back: false, init: false }])
this.$store.dispatch('getFolder', [{folder: this.item, back: false, init: false}])
}
}
@@ -233,21 +234,12 @@ export default {
}
if (this.multiSelectMode && this.$isMobile()) {
if (this.fileInfoDetail.some(item => item.unique_id === this.item.unique_id)) {
if (this.fileInfoDetail.some(item => item.id === this.item.id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.item)
} else {
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
}
}
// Get target classname
let itemClass = e.target.className
if (
['name', 'icon', 'file-link', 'file-icon-text'].includes(
itemClass
)
)
return
},
goToItem() {
if (this.isImage || this.isVideo || this.isAudio) {
@@ -262,19 +254,19 @@ export default {
this.$store.commit('CLEAR_FILEINFO_DETAIL')
if (this.$isThisLocation('public')) {
this.$store.dispatch('browseShared', [{ folder: this.item, back: false, init: false }])
this.$store.dispatch('browseShared', [{folder: this.item, back: false, init: false}])
} else {
this.$store.dispatch('getFolder', [{ folder: this.item, back: false, init: false }])
this.$store.dispatch('getFolder', [{folder: this.item, back: false, init: false}])
}
}
},
renameItem: debounce(function(e) {
renameItem: debounce(function (e) {
// Prevent submit empty string
if (e.target.innerText.trim() === '') return
this.$store.dispatch('renameItem', {
unique_id: this.item.unique_id,
id: this.item.id,
type: this.item.type,
name: e.target.innerText
})
@@ -283,10 +275,10 @@ export default {
created() {
this.itemName = this.item.name
events.$on('newFolder:focus', (unique_id) => {
events.$on('newFolder:focus', (id) => {
if(this.item.unique_id == unique_id && !this.$isMobile()) {
this.$refs[unique_id].focus()
if (this.item.id === id && !this.$isMobile()) {
this.$refs[id].focus()
document.execCommand('selectAll')
}
})
@@ -302,15 +294,15 @@ export default {
})
// Change item name
events.$on('change:name', (item) => {
if (this.item.unique_id == item.unique_id) this.itemName = item.name
if (this.item.id === item.id) this.itemName = item.name
})
}
}
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.check-select {
margin-right: 10px;
@@ -358,8 +350,8 @@ export default {
@include font-size(12);
}
path {
fill: $theme;
circle {
color: inherit;
}
}
@@ -403,7 +395,7 @@ export default {
vertical-align: middle;
path, circle, line {
stroke: $theme;
color: inherit;
}
}
}
@@ -447,7 +439,6 @@ export default {
padding: 15px 0;
&.is-dragenter {
border: 2px dashed $theme;
border-radius: 8px;
}
@@ -498,7 +489,6 @@ export default {
text-align: center;
left: 0;
right: 0;
color: $theme;
@include font-size(12);
font-weight: 600;
user-select: none;
@@ -559,7 +549,7 @@ export default {
.file-icon-text {
@include font-size(12);
}
.folder {
width: 75px;
@@ -569,7 +559,7 @@ export default {
/deep/ .folder-icon {
@include font-size(75)
}
}
}
.image {
@@ -21,7 +21,7 @@
<!--Thumbnail for item-->
<div class="icon-item">
<!--If is file or image, then link item-->
<span v-if="isFile || (isImage && !item.thumbnail)" class="file-icon-text">
<span v-if="isFile || (isImage && !item.thumbnail)" class="file-icon-text text-theme">
{{ item.mimetype | limitCharacters }}
</span>
@@ -32,24 +32,24 @@
<img loading="lazy" v-if="isImage && item.thumbnail" class="image" :src="item.thumbnail" :alt="item.name"/>
<!--Else show only folder icon-->
<FolderIcon v-if="isFolder" :item="item" location="file-item-list" class="folder" />
<FolderIcon v-if="isFolder" :item="item" location="file-item-list" class="folder svg-color-theme" />
</div>
<!--Name-->
<div class="item-name">
<b :ref="this.item.unique_id" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName" class="name">
<b :ref="this.item.id" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName" class="name">
{{ itemName }}
</b>
<div class="item-info">
<!--Shared Icon-->
<div v-if="$checkPermission('master') && item.shared" class="item-shared">
<link-icon size="12" class="shared-icon"></link-icon>
<link-icon size="12" class="shared-icon text-theme"></link-icon>
</div>
<!--Participant owner Icon-->
<div v-if="$checkPermission('master') && item.user_scope !== 'master'" class="item-shared">
<user-plus-icon size="12" class="shared-icon"></user-plus-icon>
<div v-if="$checkPermission('master') && item.author !== 'user'" class="item-shared">
<user-plus-icon size="12" class="shared-icon text-theme"></user-plus-icon>
</div>
<!--Filesize and timestamp-->
@@ -64,7 +64,7 @@
<transition name="slide-from-right">
<div class="actions" v-if="$isMobile() && ! mobileMultiSelect">
<span @click.stop="showItemActions" class="show-actions">
<FontAwesomeIcon icon="ellipsis-v" class="icon-action"></FontAwesomeIcon>
<MoreVerticalIcon size="16" class="icon-action text-theme" />
</span>
</div>
</transition>
@@ -73,7 +73,7 @@
</template>
<script>
import { LinkIcon, UserPlusIcon, CheckIcon } from 'vue-feather-icons'
import { LinkIcon, UserPlusIcon, CheckIcon, MoreVerticalIcon } from 'vue-feather-icons'
import FolderIcon from '@/components/FilesView/FolderIcon'
import { debounce } from 'lodash'
import { mapGetters } from 'vuex'
@@ -83,6 +83,7 @@ export default {
name: 'FileItemList',
props: ['item'],
components: {
MoreVerticalIcon,
UserPlusIcon,
LinkIcon,
FolderIcon,
@@ -91,7 +92,7 @@ export default {
computed: {
...mapGetters(['FilePreviewType', 'fileInfoDetail', 'data']),
isClicked() {
return this.fileInfoDetail.some(element => element.unique_id == this.item.unique_id)
return this.fileInfoDetail.some(element => element.id === this.item.id)
},
isFolder() {
return this.item.type === 'folder'
@@ -175,7 +176,7 @@ export default {
if ((e.ctrlKey || e.metaKey) && !e.shiftKey) {
// Click + Ctrl
if (this.fileInfoDetail.some(item => item.unique_id === this.item.unique_id)) {
if (this.fileInfoDetail.some(item => item.id === this.item.id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.item)
} else {
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
@@ -209,6 +210,7 @@ export default {
}
if (!this.mobileMultiSelect && this.$isMobile()) {
// Open in mobile version on first click
if (this.$isMobile() && this.isFolder) {
// Go to folder
@@ -228,17 +230,12 @@ export default {
}
if (this.mobileMultiSelect && this.$isMobile()) {
if (this.fileInfoDetail.some(item => item.unique_id === this.item.unique_id)) {
if (this.fileInfoDetail.some(item => item.id === this.item.id)) {
this.$store.commit('REMOVE_ITEM_FILEINFO_DETAIL', this.item)
} else {
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
}
}
// Get target classname
let itemClass = e.target.className
if (['name', 'icon', 'file-link', 'file-icon-text'].includes(itemClass)) return
},
goToItem() {
if (this.isImage || this.isVideo || this.isAudio) {
@@ -249,7 +246,7 @@ export default {
} else if (this.isFolder) {
//Clear selected items after open another folder
// Clear selected items after open another folder
this.$store.commit('CLEAR_FILEINFO_DETAIL')
if (this.$isThisLocation('public')) {
@@ -264,7 +261,7 @@ export default {
if (e.target.innerText.trim() === '') return
this.$store.dispatch('renameItem', {
unique_id: this.item.unique_id,
id: this.item.id,
type: this.item.type,
name: e.target.innerText
})
@@ -274,10 +271,10 @@ export default {
this.itemName = this.item.name
events.$on('newFolder:focus', (unique_id) => {
events.$on('newFolder:focus', (id) => {
if(this.item.unique_id == unique_id && !this.$isMobile()) {
this.$refs[unique_id].focus()
if(this.item.id === id && !this.$isMobile()) {
this.$refs[id].focus()
document.execCommand('selectAll')
}
})
@@ -293,16 +290,16 @@ export default {
})
// Change item name
events.$on('change:name', (item) => {
if (this.item.unique_id == item.unique_id) this.itemName = item.name
events.$on('change:name', item => {
if (this.item.id === item.id) this.itemName = item.name
})
}
}
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.slide-from-left-move {
@@ -366,13 +363,14 @@ export default {
.show-actions {
cursor: pointer;
padding: 12px 6px 12px;
padding: 12px 0 12px 6px;
.icon-action {
margin-top: 9px;
@include font-size(14);
path {
fill: $theme;
circle {
color: inherit;
}
}
}
@@ -405,7 +403,7 @@ export default {
path,
circle,
line {
stroke: $theme;
color: inherit;
}
}
}
@@ -485,7 +483,6 @@ export default {
text-align: center;
left: 0;
right: 0;
color: $theme;
font-weight: 600;
user-select: none;
max-width: 50px;
@@ -514,7 +511,6 @@ export default {
padding: 7px;
&.is-dragenter {
border: 2px dashed $theme;
border-radius: 8px;
}
@@ -586,10 +582,6 @@ export default {
&.is-clicked {
background: $dark_mode_foreground;
.item-name .name {
color: $theme;
}
.file-icon {
path {
fill: $dark_mode_background;
@@ -26,8 +26,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.preview {
width: 100%;
@@ -46,7 +46,7 @@ export default {
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vuefilemanager/_variables';
.prev,
.next {
cursor: pointer;
@@ -1,13 +1,13 @@
<template>
<div class="navigation-panel" v-if="fileInfoDetail[0]">
<div class="name-wrapper">
<x-icon @click="closeFullPreview" size="22" class="icon-close"></x-icon>
<x-icon @click="closeFullPreview" size="22" class="icon-close hover-text-theme" />
<div class="name-count-wrapper">
<p class="title">{{ fileInfoDetail[0].name }}</p>
<span class="file-count"> ({{ showingImageIndex + ' ' + $t('pronouns.of') + ' ' + filteredFiles.length }}) </span>
</div>
<span id="fast-preview-menu" class="fast-menu-icon" @click.stop="menuOpen" v-if="$checkPermission(['master', 'editor', 'visitor'])">
<more-horizontal-icon class="more-icon" size="14"> </more-horizontal-icon>
<span id="fast-preview-menu" class="fast-menu-icon group" @click.stop="menuOpen" v-if="$checkPermission(['master', 'editor', 'visitor'])">
<more-horizontal-icon class="more-icon group-hover-text-theme" size="14" />
</span>
</div>
@@ -48,7 +48,7 @@ export default {
showingImageIndex() {
let activeIndex = ''
this.filteredFiles.filter((element, index) => {
if (element.unique_id == this.fileInfoDetail[0].unique_id) {
if (element.id === this.fileInfoDetail[0].id) {
activeIndex = index + 1
}
})
@@ -107,8 +107,8 @@ export default {
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.name-wrapper {
width: 33%;
@@ -162,14 +162,13 @@ export default {
border-radius: 6px;
vertical-align: middle;
cursor: pointer;
color: $text;
@include transition(150ms);
&:hover {
background: $light_background;
line {
stroke: $theme;
color: inherit;
}
}
}
@@ -191,7 +190,7 @@ export default {
background: $light_background;
svg circle {
stroke: $theme;
color: inherit;
}
}
.more-icon {
@@ -20,9 +20,9 @@
export default {
name: 'FolderIcon',
props: [
'item',
'folderIcon',
'location'
'location',
'item',
],
components: {
Emoji
@@ -37,7 +37,7 @@
return this.folderIcon.emoji ? this.folderIcon.emoji : false
// Return emoji if is already set
return this.item.icon_emoji ? this.item.icon_emoji : false
return this.item.emoji ? this.item.emoji : false
},
color() {
// Return color if is changed from rename popup
@@ -45,15 +45,15 @@
return this.folderIcon.color ? this.folderIcon.color : false
// Return color if is already set
return this.item.icon_color ? this.item.icon_color : false
return this.item.color ? this.item.color : false
}
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
// Locations
.file-item-list {
@@ -84,12 +84,6 @@
}
}
.default-color {
path {
fill: $theme !important;
}
}
.folder-icon {
path {
@@ -1,14 +1,16 @@
<template>
<svg width="13px" height="15px" viewBox="0 0 13 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="VueFileManager" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="Storage-Alert-Copy" transform="translate(-888.000000, -238.000000)" stroke="#000000" stroke-width="1.6">
<g id="Sorting-Menu" transform="translate(865.000000, 67.000000)">
<g id="alphabet-icon" transform="translate(24.000000, 172.000000)">
<polyline id="Path" points="11.1999993 13.1999991 5.59999967 0.199999094 0 13.1999991 5.59999967 0.199999094"></polyline>
<line x1="2.25" y1="8" x2="8.75" y2="8" id="Line-2"></line>
</g>
</g>
</g>
</g>
<svg class="alphabet-icon" fill="none" stroke="currentColor" stroke-width="2" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" width="15px" height="15px" viewBox="0 0 15 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<polyline id="Path" points="11.1999993 13.1999991 5.59999967 0.199999094 0 13.1999991 5.59999967 0.199999094"></polyline>
<line x1="2.25" y1="8" x2="8.75" y2="8" id="Line-2"></line>
</svg>
</template>
</template>
<style lang="scss">
.alphabet-icon {
polyline, line, g {
color: inherit;
}
}
</style>
@@ -1,20 +1,19 @@
<template>
<svg
width="15px" height="15px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="VueFileManager" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="Storage-Alert-Copy" transform="translate(-1092.000000, -28.000000)" stroke="#000000" stroke-width="1.4">
<g id="Toolbar" transform="translate(331.000000, 19.000000)">
<g id="Tools" transform="translate(581.000000, 9.000000)">
<g id="sort-icon" transform="translate(181.000000, 1.000000)">
<rect id="Rectangle" x="9.77777778" y="0" width="6.22222222" height="6.22222222"></rect>
<rect id="Rectangle" x="9.77777778" y="9.77777778" width="6.22222222" height="6.22222222"></rect>
<line x1="0" y1="2" x2="6" y2="2" id="Path"></line>
<line x1="0" y1="8" x2="6" y2="8" id="Path"></line>
<line x1="0" y1="14" x2="6" y2="14" id="Path"></line>
</g>
</g>
</g>
</g>
</g>
<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">
<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>
<line x1="0" y1="8" x2="6" y2="8"></line>
<line x1="0" y1="14" x2="6" y2="14"></line>
</svg>
</template>
</template>
<style lang="scss">
.preview-list-icon {
rect, line {
color: inherit;
}
}
</style>
@@ -107,8 +107,8 @@ export default {
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.meta-data-list {
list-style: none;
@@ -91,7 +91,7 @@ export default {
},
choseActiveFile() {
this.sliderFile.forEach((element, index) => {
if (element.unique_id == this.fileInfoDetail[0].unique_id) {
if (element.id == this.fileInfoDetail[0].id) {
this.currentIndex = index
}
})
@@ -122,8 +122,8 @@ export default {
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.media-full-preview {
height: calc(100% - 72px);
@@ -1,17 +1,18 @@
<template>
<button class="mobile-action-button">
<div class="flex">
<credit-card-icon v-if="icon === 'credit-card'" size="15" class="icon"></credit-card-icon>
<folder-plus-icon v-if="icon === 'folder-plus'" size="15" class="icon"></folder-plus-icon>
<list-icon v-if="icon === 'th-list'" size="15" class="icon"></list-icon>
<trash-icon v-if="icon === 'trash'" size="15" class="icon"></trash-icon>
<grid-icon v-if="icon === 'th'" size="15" class="icon"></grid-icon>
<user-plus-icon v-if="icon === 'user-plus'" size="15" class="icon"></user-plus-icon>
<plus-icon v-if="icon === 'plus'" size="15" class="icon"></plus-icon>
<check-square-icon v-if="icon === 'check-square'" size="15" class="icon"></check-square-icon>
<x-square-icon v-if="icon === 'x-square'" size="15" class="icon"></x-square-icon>
<check-icon v-if="icon === 'check'" size="15" class="icon"></check-icon>
<sorting-and-preview-icon v-if="icon === 'preview-sorting'" size="15" class="icon preview-sorting"></sorting-and-preview-icon>
<credit-card-icon v-if="icon === 'credit-card'" size="15" class="icon dark-text-theme" />
<folder-plus-icon v-if="icon === 'folder-plus'" size="15" class="icon dark-text-theme" />
<list-icon v-if="icon === 'th-list'" size="15" class="icon dark-text-theme" />
<trash-icon v-if="icon === 'trash'" size="15" class="icon dark-text-theme" />
<grid-icon v-if="icon === 'th'" size="15" class="icon dark-text-theme" />
<user-plus-icon v-if="icon === 'user-plus'" size="15" class="icon dark-text-theme" />
<plus-icon v-if="icon === 'plus'" size="15" class="icon dark-text-theme" />
<check-square-icon v-if="icon === 'check-square'" size="15" class="icon dark-text-theme" />
<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" />
<span class="label">
<slot></slot>
</span>
@@ -20,7 +21,7 @@
</template>
<script>
import { CheckIcon, XSquareIcon, CheckSquareIcon, FolderPlusIcon, ListIcon, GridIcon, TrashIcon, UserPlusIcon, PlusIcon, CreditCardIcon } from 'vue-feather-icons'
import { DollarSignIcon, CheckIcon, XSquareIcon, CheckSquareIcon, FolderPlusIcon, ListIcon, GridIcon, TrashIcon, UserPlusIcon, PlusIcon, CreditCardIcon } from 'vue-feather-icons'
import SortingAndPreviewIcon from '@/components/FilesView/Icons/SortingAndPreviewIcon'
export default {
@@ -31,6 +32,7 @@
components: {
SortingAndPreviewIcon,
CheckSquareIcon,
DollarSignIcon,
CreditCardIcon,
FolderPlusIcon,
UserPlusIcon,
@@ -45,8 +47,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.mobile-action-button {
background: $light_background;
@@ -81,20 +83,6 @@
&:active {
@include transform(scale(0.95));
}
/*&:hover {
background: rgba($theme, 0.1);
.icon {
path, line, polyline, rect, circle {
stroke: $theme;
}
}
.label {
color: $theme;
}
}*/
}
@media (prefers-color-scheme: dark) {
@@ -102,7 +90,7 @@
background: $dark_mode_foreground;
path, line, polyline, rect, circle {
stroke: $theme;
color: inherit;
}
.label {
@@ -1,7 +1,7 @@
<template>
<button class="mobile-action-button">
<div class="flex">
<upload-cloud-icon class="icon" size="15"></upload-cloud-icon>
<upload-cloud-icon class="icon dark-text-theme" size="15" />
<label label="file" class="label button file-input button-base">
<slot></slot>
<input
@@ -34,8 +34,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.mobile-action-button {
background: $light_background;
@@ -69,7 +69,7 @@
background: $dark_mode_foreground;
path, line, polyline, rect, circle {
stroke: $theme;
color: inherit;
}
.label {
@@ -6,9 +6,9 @@
<MobileActionButton @click.native="$store.dispatch('emptyTrash')" icon="trash">
{{ $t('context_menu.empty_trash') }}
</MobileActionButton>
<MobileMultiSelectButton @click.native="enableMultiSelectMode">
<MobileActionButton @click.native="enableMultiSelectMode" icon="check-square">
{{ $t('context_menu.select') }}
</MobileMultiSelectButton>
</MobileActionButton>
<MobileActionButton class="preview-sorting" @click.native="showViewOptions" icon="preview-sorting">
{{$t('preview_sorting.preview_sorting_button')}}
</MobileActionButton>
@@ -23,9 +23,9 @@
<MobileActionButtonUpload :class="{'is-inactive' : multiSelectMode}">
{{ $t('context_menu.upload') }}
</MobileActionButtonUpload>
<MobileMultiSelectButton @click.native="enableMultiSelectMode">
<MobileActionButton @click.native="enableMultiSelectMode" icon="check-square">
{{ $t('context_menu.select') }}
</MobileMultiSelectButton>
</MobileActionButton>
<MobileActionButton class="preview-sorting" @click.native="showViewOptions" icon="preview-sorting">
{{$t('preview_sorting.preview_sorting_button')}}
</MobileActionButton>
@@ -49,9 +49,9 @@
<!--ContextMenu for Base location with VISITOR permission-->
<div v-if="baseLocationVisitorMenu && ! multiSelectMode" class="mobile-actions">
<MobileMultiSelectButton @click.native="enableMultiSelectMode">
<MobileActionButton @click.native="enableMultiSelectMode" icon="check-square">
{{ $t('context_menu.select') }}
</MobileMultiSelectButton>
</MobileActionButton>
<MobileActionButton class="preview-sorting" @click.native="showViewOptions" icon="preview-sorting">
{{$t('preview_sorting.preview_sorting_button')}}
</MobileActionButton>
@@ -64,7 +64,6 @@
<script>
import MobileActionButtonUpload from '@/components/FilesView/MobileActionButtonUpload'
import MobileMultiSelectButton from '@/components/FilesView/MobileMultiSelectButton'
import MobileActionButton from '@/components/FilesView/MobileActionButton'
import UploadProgress from '@/components/FilesView/UploadProgress'
import {mapGetters} from 'vuex'
@@ -74,7 +73,6 @@
name: 'MobileActions',
components: {
MobileActionButtonUpload,
MobileMultiSelectButton,
MobileActionButton,
UploadProgress,
},
@@ -135,8 +133,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.button-enter-active,
.button-leave-active {
@@ -157,18 +155,6 @@
position: absolute;
}
.preview-sorting {
background: $light_background !important;
/deep/ .label {
color: $text !important;
}
/deep/ .preview-sorting {
path, line, polyline, rect, circle {
stroke: $text !important;
}
}
}
#mobile-actions-wrapper {
display: none;
background: white;
@@ -202,16 +188,5 @@
#mobile-actions-wrapper {
background: $dark_mode_background;
}
.preview-sorting {
background: $dark_mode_foreground !important;
/deep/ .label {
color: $dark_mode_text_primary !important;
}
/deep/ .preview-sorting {
path, line, polyline, rect, circle {
stroke: $theme !important;
}
}
}
}
</style>
@@ -315,11 +315,11 @@ export default {
computed: {
...mapGetters(['fileInfoDetail', 'user']),
favourites() {
return this.user.relationships.favourites.data.attributes.folders
return this.user.data.relationships.favourites.data.attributes.folders
},
isInFavourites() {
return this.favourites.find(
(el) => el.unique_id == this.fileInfoDetail[0].unique_id
(el) => el.id == this.fileInfoDetail[0].id
)
},
isFile() {
@@ -369,7 +369,7 @@ export default {
if (
this.favourites &&
!this.favourites.find(
(el) => el.unique_id == this.fileInfoDetail[0].unique_id
(el) => el.id == this.fileInfoDetail[0].id
)
) {
this.$store.dispatch('addToFavourites', this.fileInfoDetail[0])
@@ -416,8 +416,8 @@ export default {
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.mobile-selected-menu {
display: flex;
@@ -1,100 +0,0 @@
<template>
<button class="mobile-action-button" :class="{'active' : mobileSelectingActive}">
<div class="flex" >
<CheckSquareIcon size="15" class="icon"></CheckSquareIcon>
<span class="label">
<slot></slot>
</span>
</div>
</button>
</template>
<script>
import {CheckSquareIcon} from "vue-feather-icons";
import {events} from '@/bus'
export default {
name: 'MobileActionButton',
props: [
'icon'
],
components: {
CheckSquareIcon
},
data () {
return {
mobileSelectingActive: false
}
},
mounted() {
events.$on('mobileSelecting:start' , () => {
this.mobileSelectingActive = true
})
events.$on('mobileSelecting:stop' , () => {
this.mobileSelectingActive = false
})
}
}
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
.mobile-action-button {
background: $light_background;
margin-right: 15px;
border-radius: 8px;
padding: 7px 10px;
cursor: pointer;
border: none;
@include transition(150ms);
.flex {
display: flex;
align-items: center;
}
.icon {
margin-right: 10px;
@include font-size(14);
path, line, polyline, rect, circle {
@include transition(150ms);
}
}
.label {
@include transition(150ms);
@include font-size(14);
font-weight: 700;
color: $text;
}
}
.active {
.icon {
path, line, polyline, rect, circle {
stroke: $theme !important;
}
}
.label {
color: $theme !important;
}
}
@media (prefers-color-scheme: dark) {
.mobile-action-button {
background: $dark_mode_foreground;
path, line, polyline, rect, circle {
stroke: $theme;
}
.label {
color: $dark_mode_text_primary;
}
}
}
</style>
@@ -75,8 +75,8 @@ export default {
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.multiselect-actions {
display: flex;
@@ -25,8 +25,8 @@ import { events } from '@/bus'
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.options {
position: absolute;
@@ -84,8 +84,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.mobile-toolbar {
background: white;
@@ -1,55 +1,59 @@
<template>
<div class="wrapper">
<div class="icon-wrapper">
<CheckSquareIcon class="icon" size="21"/>
<CheckSquareIcon class="icon text-theme" size="21" />
</div>
<div class="text" >
<span class="title">{{title }}</span>
<span class="count">{{subtitle }}</span>
<div class="text">
<span class="title">{{ title }}</span>
<span class="count">{{ subtitle }}</span>
</div>
</div>
</template>
<script>
import {CheckSquareIcon} from "vue-feather-icons";
import {mapGetters} from 'vuex'
import {events} from '@/bus'
import {CheckSquareIcon} from "vue-feather-icons"
export default {
name:'MultiSelected',
props: [ 'title' , 'subtitle' ],
components: {CheckSquareIcon},
}
export default {
name: 'MultiSelected',
props: [
'title',
'subtitle'
],
components: {
CheckSquareIcon
},
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.wrapper {
display: flex;
justify-content: center;
.text{
.text {
padding-left: 10px;
width: 100%;
word-break: break-all;
.title {
@include font-size(14);
@include font-size(14);
font-weight: 700;
line-height: 1.4;
display: block;
color: $text;
}
.count {
@include font-size(12);
@include font-size(12);
font-weight: 600;
color: $theme;
color: $text-muted;
display: block;
}
}
.icon-wrapper {
display: inline-flex;
align-items: center;
@@ -60,8 +64,9 @@ import {events} from '@/bus'
white-space: nowrap;
outline: none;
border: none;
.icon {
stroke: $text;
polyline, path {
color: inherit;
}
}
}
@@ -72,15 +77,11 @@ import {events} from '@/bus'
.title {
color: $dark_mode_text_primary;
}
.count {
color: $dark_mode_text_secondary;
}
}
.icon-wrapper {
.icon {
stroke: $theme;
}
}
}
}
}
</style>
+41 -53
View File
@@ -1,26 +1,31 @@
<template>
<li class="menu-option" :class="[icon === 'trash' ? 'danger' : '']">
<div class="icon">
<trash-2-icon v-if="icon === 'trash'" size="17"></trash-2-icon>
<life-buoy-icon v-if="icon === 'restore'" size="17"></life-buoy-icon>
<trash-icon v-if="icon === 'empty-trash'" size="17"></trash-icon>
<eye-icon v-if="icon ==='detail'" size="17"></eye-icon>
<download-cloud-icon v-if="icon === 'download'" size="17"></download-cloud-icon>
<edit2-icon v-if="icon === 'rename'" size="17"></edit2-icon>
<corner-down-right-icon v-if="icon === 'move-item'" size="17"></corner-down-right-icon>
<link-icon v-if="icon === 'share'" size="17"></link-icon>
<star-icon v-if="icon === 'favourites'" size="17"></star-icon>
<folder-plus-icon v-if="icon === 'create-folder'" size="17"></folder-plus-icon>
<smile-icon v-if="icon === 'no-options'" size="17"></smile-icon>
<paperclip-icon v-if="icon === 'zip-folder'" size="17"></paperclip-icon>
<li class="menu-option group">
<div class="icon group-hover-text-theme">
<calendar-icon v-if="icon === 'calendar'" size="17" class="group-hover-text-theme"/>
<grid-icon v-if="icon === 'grid'" size="17" class="group-hover-text-theme"/>
<list-icon v-if="icon === 'list'" size="17" class="group-hover-text-theme"/>
<trash-2-icon v-if="icon === 'trash'" size="17" class="group-hover-text-theme"/>
<life-buoy-icon v-if="icon === 'restore'" size="17" class="group-hover-text-theme"/>
<trash-icon v-if="icon === 'empty-trash'" size="17" class="group-hover-text-theme"/>
<eye-icon v-if="icon ==='detail'" size="17" class="group-hover-text-theme"/>
<download-cloud-icon v-if="icon === 'download'" size="17" class="group-hover-text-theme"/>
<edit2-icon v-if="icon === 'rename'" size="17" class="group-hover-text-theme"/>
<corner-down-right-icon v-if="icon === 'move-item'" size="17" class="group-hover-text-theme"/>
<link-icon v-if="icon === 'share'" size="17" class="group-hover-text-theme"/>
<star-icon v-if="icon === 'favourites'" size="17" class="group-hover-text-theme"/>
<folder-plus-icon v-if="icon === 'create-folder'" size="17" class="group-hover-text-theme"/>
<smile-icon v-if="icon === 'no-options'" size="17" class="group-hover-text-theme"/>
<paperclip-icon v-if="icon === 'zip-folder'" size="17" class="group-hover-text-theme"/>
<alphabet-icon v-if="icon === 'alphabet'" size="17" class="group-hover-text-theme"/>
</div>
<div class="text-label">
<div class="text-label group-hover-text-theme">
{{ title }}
</div>
</li>
</template>
<script>
import AlphabetIcon from '@/components/FilesView/Icons/AlphabetIcon'
import {
CornerDownRightIcon,
DownloadCloudIcon,
@@ -33,7 +38,10 @@ import {
StarIcon,
LinkIcon,
EyeIcon,
SmileIcon
SmileIcon,
GridIcon,
ListIcon,
CalendarIcon,
} from 'vue-feather-icons'
export default {
@@ -45,6 +53,7 @@ import {
FolderPlusIcon,
PaperclipIcon,
LifeBuoyIcon,
AlphabetIcon,
Trash2Icon,
SmileIcon,
Edit2Icon,
@@ -52,29 +61,16 @@ import {
LinkIcon,
StarIcon,
EyeIcon,
GridIcon,
ListIcon,
CalendarIcon,
}
}
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
.danger {
.text-label {
color: $danger !important;
}
.icon {
path,
line,
polyline,
rect,
circle,
polygon {
stroke: $danger !important;
}
}
}
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.menu-option {
white-space: nowrap;
@@ -90,6 +86,15 @@ import {
.icon {
margin-right: 20px;
line-height: 0;
path,
line,
polyline,
rect,
circle,
polygon {
color: inherit;
}
}
.text-label {
@@ -98,32 +103,15 @@ import {
&:hover {
background: $light_background;
.text-label {
color: $theme;
}
path,
line,
polyline,
rect,
circle,
polygon {
stroke: $theme;
}
}
}
@media (prefers-color-scheme: dark) {
.danger {
&:hover {
background: rgba($danger, 0.1) !important;
}
}
.menu-option {
color: $dark_mode_text_primary;
&:hover {
background: rgba($theme, 0.1);
background: lighten($dark_mode_foreground, 2%);
}
}
}
@@ -11,23 +11,23 @@
</script>
<style scoped lang="scss" scoped>
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.menu-option-group {
padding: 5px 0;
border-bottom: 1px solid $light_mode_border;
padding: 5px 0;
border-bottom: 1px solid $light_mode_border;
&:first-child {
padding-top: 0;
}
&:last-child {
padding-bottom: 0;
border-bottom: none;
}
&:first-child {
padding-top: 0;
}
&:last-child {
padding-bottom: 0;
border-bottom: none;
}
}
@media (prefers-color-scheme: dark) {
.menu-option-group {
border-color: $dark_mode_border_color;
@@ -32,8 +32,8 @@ export default {
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.spinner-wrapper {
padding-bottom: 90px;
@@ -103,7 +103,7 @@ export default {
@media (prefers-color-scheme: dark) {
.popup-wrapper {
background: $dark_mode_background;
background: $dark_mode_foreground;
}
.popup-content {
.title {
@@ -1,6 +1,6 @@
<template>
<div class="progress-bar">
<span :style="{ width: progress + '%' }"></span>
<span class="bg-theme" :style="{ width: progress + '%' }"></span>
</div>
</template>
@@ -12,8 +12,8 @@ export default {
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.progress-bar {
width: 100%;
@@ -23,7 +23,6 @@ export default {
border-radius: 10px;
span {
background: $theme;
display: block;
height: 100%;
border-radius: 10px;
@@ -1,14 +1,14 @@
<template>
<div class="search-bar">
<div class="icon" v-if="!isQuery">
<search-icon size="19"></search-icon>
<search-icon size="19" />
</div>
<div class="icon" v-if="isQuery" @click="resetQuery">
<x-icon class="pointer" size="19"></x-icon>
<x-icon class="pointer" size="19" />
</div>
<input
v-model="query"
class="query"
class="query focus-border-theme"
type="text"
name="query"
:placeholder="$t('inputs.placeholder_search_files')"
@@ -74,8 +74,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.search-bar {
position: relative;
@@ -99,8 +99,7 @@
}
&:focus {
border: 1px solid $theme;
box-shadow: 0 0 7px rgba($theme, 0.3);
//box-shadow: 0 0 7px rgba($theme, 0.3);
}
&:focus + .icon {
@@ -1,52 +1,24 @@
<template>
<div class="menu-options" id="menu-list">
<ul class="menu-option-group">
<li v-if="isList" class="menu-option" @click="changePreview('grid')">
<div class="icon">
<grid-icon size="17"/>
</div>
<div class="text-label">
{{ $t('preview_sorting.grid_view') }}
</div>
</li>
<li v-if="isGrid" class="menu-option" @click="changePreview('list')">
<div class="icon">
<list-icon size="17"/>
</div>
<div class="text-label">
{{ $t('preview_sorting.list_view') }}
</div>
</li>
</ul>
<ul class="menu-option-group">
<li class="menu-option" @click.stop="sort('created_at')">
<div class="icon">
<calendar-icon size="17"/>
</div>
<div class="text-label">
{{ $t('preview_sorting.sort_date') }}
</div>
<div class="show-icon">
<arrow-up-icon size="17" v-if="filter.field === 'created_at'" :class="{ 'arrow-down': filter.sort === 'ASC' }"/>
</div>
</li>
<li class="menu-option" @click.stop="sort('name')">
<div class="icon">
<alphabet-icon size="17" class="alphabet-icon"/>
</div>
<div class="text-label">
{{ $t('preview_sorting.sort_alphabet') }}
</div>
<div class="show-icon">
<arrow-up-icon size="17" v-if="filter.field === 'name'" :class="{ 'arrow-down': filter.sort === 'ASC' }"/>
</div>
</li>
</ul>
<OptionGroup class="menu-option-group">
<Option v-if="isList" @click.native="changePreview('grid')" :title="$t('preview_sorting.grid_view')" icon="grid" />
<Option v-if="isGrid" @click.native="changePreview('list')" :title="$t('preview_sorting.list_view')" icon="list" />
</OptionGroup>
<OptionGroup class="menu-option-group">
<Option @click.native.stop="sort('created_at')" :title="$t('preview_sorting.sort_date')" icon="calendar" />
<Option @click.native.stop="sort('name')" :title="$t('preview_sorting.sort_alphabet')" icon="alphabet" />
</OptionGroup>
<!-- TODO: implementovat sipky
<arrow-up-icon size="17" v-if="filter.field === 'created_at'" :class="{ 'arrow-down': filter.sort === 'ASC' }"/>
<arrow-up-icon size="17" v-if="filter.field === 'name'" :class="{ 'arrow-down': filter.sort === 'ASC' }"/>-->
</div>
</template>
<script>
import OptionGroup from '@/components/FilesView/OptionGroup'
import Option from '@/components/FilesView/Option'
import { CalendarIcon, ListIcon, GridIcon, ArrowUpIcon, CheckIcon } from 'vue-feather-icons'
import AlphabetIcon from '@/components/FilesView/Icons/AlphabetIcon'
import { mapGetters } from 'vuex'
@@ -55,6 +27,8 @@ import { events } from '@/bus'
export default {
name: 'SortingAndPreviewMenu',
components: {
OptionGroup,
Option,
CalendarIcon,
AlphabetIcon,
ArrowUpIcon,
@@ -116,13 +90,12 @@ export default {
this.filter.sort = sorting ? sorting.sort : 'DESC'
this.filter.field = sorting ? sorting.field : 'created_at'
}
}
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.show-icon {
margin-left: auto;
@@ -139,14 +112,6 @@ export default {
.icon {
margin-right: 20px;
line-height: 0;
.alphabet-icon {
/deep/ line,
/deep/ polyline {
stroke: $text;
}
}
}
.text-label {
@@ -209,15 +174,6 @@ export default {
.menu-option {
color: $dark_mode_text_primary;
.icon {
.alphabet-icon {
/deep/ line,
/deep/ polyline {
stroke: $dark_mode_text_primary;
}
}
}
}
}
}
@@ -1,6 +1,6 @@
<template>
<div id="loading-bar-spinner" class="spinner">
<div class="spinner-icon"></div>
<div class="spinner-icon border-top-theme border-left-theme"></div>
</div>
</template>
@@ -11,8 +11,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
#loading-bar-spinner.spinner {
left: 50%;
@@ -28,8 +28,8 @@
width: 40px;
height: 40px;
border: solid 4px transparent;
border-top-color: $theme !important;
border-left-color: $theme !important;
//border-top-color: $theme !important;
//border-left-color: $theme !important;
border-radius: 50%;
}
@@ -1,132 +1,140 @@
<template>
<button class="button" :title="action">
<button class="button hover-text-theme hover-svg-stroke-theme" :title="action">
<corner-down-right-icon
v-if="source === 'move'"
size="19"
></corner-down-right-icon>
v-if="source === 'move'"
size="19"
class="hover-text-theme"
/>
<download-cloud-icon
v-if="source === 'download'"
size="19"
></download-cloud-icon>
v-if="source === 'download'"
size="19"
class="hover-text-theme"
/>
<folder-plus-icon
v-if="source === 'folder-plus'"
size="19"
></folder-plus-icon>
<edit-2-icon v-if="source === 'rename'" size="19"></edit-2-icon>
<printer-icon v-if="source === 'print'" size="19"></printer-icon>
<trash-2-icon v-if="source === 'trash'" size="19"></trash-2-icon>
<list-icon v-if="source === 'th-list'" size="19"></list-icon>
<info-icon v-if="source === 'info'" size="19"></info-icon>
<grid-icon v-if="source === 'th'" size="19"></grid-icon>
<link-icon v-if="source === 'share'" size="19"></link-icon>
<x-icon v-if="source === 'close'" size="19"></x-icon>
<cloud-off-icon v-if="source === 'shared-off'" size="19"></cloud-off-icon>
<sorting-and-preview-icon v-if="source === 'preview-sorting'" size="19" class="preview-sorting"></sorting-and-preview-icon>
v-if="source === 'folder-plus'"
size="19"
class="hover-text-theme"
/>
<edit-2-icon v-if="source === 'rename'" size="19" />
<printer-icon v-if="source === 'print'" size="19" />
<trash-2-icon v-if="source === 'trash'" size="19" />
<list-icon v-if="source === 'th-list'" size="19" />
<info-icon v-if="source === 'info'" size="19" />
<grid-icon v-if="source === 'th'" size="19" />
<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"/>
</button>
</template>
<script>
import {
FolderPlusIcon,
Trash2Icon,
GridIcon,
ListIcon,
Edit2Icon,
InfoIcon,
CornerDownRightIcon,
LinkIcon,
DownloadCloudIcon,
XIcon,
PrinterIcon,
CloudOffIcon,
FolderPlusIcon,
Trash2Icon,
GridIcon,
ListIcon,
Edit2Icon,
InfoIcon,
CornerDownRightIcon,
LinkIcon,
DownloadCloudIcon,
XIcon,
PrinterIcon,
CloudOffIcon,
} from "vue-feather-icons";
import SortingAndPreviewIcon from '@/components/FilesView/Icons/SortingAndPreviewIcon'
export default {
name: "ToolbarButton",
props: ["source", "action"],
components: {
SortingAndPreviewIcon,
CornerDownRightIcon,
DownloadCloudIcon,
FolderPlusIcon,
CloudOffIcon,
PrinterIcon,
Trash2Icon,
Edit2Icon,
ListIcon,
XIcon,
GridIcon,
InfoIcon,
LinkIcon,
},
name: "ToolbarButton",
props: ["source", "action"],
components: {
SortingAndPreviewIcon,
CornerDownRightIcon,
DownloadCloudIcon,
FolderPlusIcon,
CloudOffIcon,
PrinterIcon,
Trash2Icon,
Edit2Icon,
ListIcon,
XIcon,
GridIcon,
InfoIcon,
LinkIcon,
},
};
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_variables";
@import "@assets/vue-file-manager/_mixins";
@import "@assets/vuefilemanager/_variables";
@import "@assets/vuefilemanager/_mixins";
.preview-sorting {
svg {
width: 19px;
height: 19px;
}
svg {
width: 19px;
height: 19px;
}
rect, line {
@include transition(150ms);
}
}
.button {
height: 42px;
width: 42px;
border-radius: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
text-align: center;
cursor: pointer;
white-space: nowrap;
outline: none;
border: none;
@include transition(150ms);
background: transparent;
height: 42px;
width: 42px;
border-radius: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
text-align: center;
cursor: pointer;
white-space: nowrap;
outline: none;
border: none;
@include transition(150ms);
background: transparent;
svg {
color: inherit;
&:hover {
.preview-sorting {
path, line, polyline, rect, circle {
stroke: $theme !important;
}
color: inherit;
}
}
}
&:hover {
background: $light_background;
&:hover {
background: $light_background;
path,
line,
polyline,
rect,
circle {
@include transition(150ms);
stroke: $theme;
path,
line,
polyline,
rect,
circle {
@include transition(150ms);
color: inherit;
}
}
}
}
@media (prefers-color-scheme: dark) {
.button {
background: transparent;
.button {
background: transparent;
&:hover {
background: $dark_mode_foreground;
}
&:hover {
background: $dark_mode_foreground;
}
path,
line,
polyline,
rect,
circle {
stroke: $dark_mode_text_primary;
path,
line,
polyline,
rect,
circle {
stroke: $dark_mode_text_primary;
}
}
}
}
</style>
@@ -1,6 +1,6 @@
<template>
<label label="file" class="button file-input">
<upload-cloud-icon size="17"></upload-cloud-icon>
<label label="file" class="button hover-text-theme file-input">
<upload-cloud-icon size="17" />
<input
@change="emmitFiles"
v-show="false"
@@ -30,8 +30,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.button {
height: 42px;
@@ -47,12 +47,24 @@
outline: none;
border: none;
svg {
color: inherit;
path, line, polyline, rect, circle {
color: inherit;
}
}
&:hover {
background: $light_background;
path, line, polyline, rect, circle {
path,
line,
polyline,
rect,
circle {
@include transition(150ms);
stroke: $theme;
color: inherit;
}
}
}
@@ -5,7 +5,7 @@
<!--Is processing-->
<span v-if="isProcessingFile">
<refresh-cw-icon size="12" class="sync-alt"></refresh-cw-icon>
<refresh-cw-icon size="12" class="sync-alt text-theme" />
{{ $t('uploading.processing_file') }}
</span>
@@ -17,7 +17,7 @@
<div class="progress-wrapper">
<ProgressBar :progress="uploadingProgress" />
<span @click="cancelUpload" :title="$t('uploading.cancel')" class="cancel-icon">
<x-icon size="16" @click="cancelUpload"></x-icon>
<x-icon size="16" @click="cancelUpload" class="hover-text-theme"></x-icon>
</span>
</div>
</div>
@@ -55,15 +55,15 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.sync-alt {
animation: spin 1s linear infinite;
margin-right: 5px;
polyline, path {
stroke: $theme;
color: inherit;
}
}
@@ -103,7 +103,7 @@
&:hover {
line {
stroke: $theme;
color: inherit;
}
}
}
@@ -15,9 +15,9 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_landing-page';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.page-title {
position: relative;
@@ -4,7 +4,7 @@
<div class="plan-wrapper">
<header class="plan-header">
<div class="icon">
<hard-drive-icon size="26"></hard-drive-icon>
<hard-drive-icon class="text-theme" size="26" />
</div>
<h1 class="title">{{ plan.data.attributes.name }}</h1>
<h2 class="description">{{ plan.data.attributes.description }}</h2>
@@ -14,7 +14,7 @@
<span class="storage-description">{{ $t('page_pricing_tables.storage_capacity') }}</span>
</section>
<footer class="plan-footer">
<b class="price">
<b class="price text-theme">
{{ plan.data.attributes.price }}/{{ $t('global.monthly_ac') }}
<small v-if="plan.data.attributes.tax_rates.length > 0" class="vat-disclaimer">{{ $t('page_pricing_tables.vat_excluded') }}</small>
</b>
@@ -39,7 +39,7 @@
}
},
created() {
axios.get('/api/public/pricing')
axios.get('/api/pricing')
.then(response => {
this.plans = response.data
this.$emit('load', response.data)
@@ -49,8 +49,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.plans-wrapper {
box-shadow: 0 7px 20px 5px hsla(220, 36%, 16%, 0.05);
@@ -73,7 +73,7 @@
.icon {
path, line, polyline, rect, circle {
color: $theme;
color: inherit;
}
}
@@ -113,7 +113,6 @@
}
.price {
color: $theme;
@include font-size(18);
display: block;
padding-top: 5px;
@@ -8,12 +8,12 @@
:description="index.get_started_description"
></PageTitle>
<router-link tag="button" class="get-started-button" :to="{name: 'SignUp'}">
<router-link tag="button" class="get-started-button bg-theme-800 hover-bg-theme shadow-theme" :to="{name: 'SignUp'}">
<span class="content">{{ $t('page_index.get_started_button') }}</span>
<chevron-right-icon size="22"></chevron-right-icon>
</router-link>
<cloud-icon size="790" class="cloud-bg"></cloud-icon>
<cloud-icon size="790" class="cloud-bg svg-color-theme" />
<div class="icons">
<hard-drive-icon size="42" class="icon"></hard-drive-icon>
@@ -88,9 +88,9 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_landing-page';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.icons {
@@ -274,10 +274,10 @@
top: 70px;
right: 60px;
transform: scale(-1, 1) rotate(13deg);
opacity: 0.1;
path {
stroke: none;
fill: rgba($theme, 0.05);
}
}
@@ -288,26 +288,19 @@
.get-started-button {
display: flex;
align-items: center;
background: none;
outline: none;
border: none;
margin-left: auto;
margin-right: auto;
cursor: pointer;
background: rgba($theme, 0.8);
padding: 20px 36px;
border-radius: 6px;
box-shadow: 0 5px 10px 2px rgba($theme, 0.34);
//box-shadow: 0 5px 10px 2px rgba($theme, 0.34);
margin-bottom: 395px;
@include transition(150ms);
position: relative;
z-index: 1;
&:hover {
box-shadow: 0 7px 16px 2px rgba($theme, 0.4);
background: rgba($theme, 1);
}
.content {
@include font-size(19);
font-weight: 700;
@@ -57,9 +57,9 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_landing-page';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.icons {
@@ -69,9 +69,9 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_landing-page';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.features {
padding-left: 75px;
@@ -1,6 +1,6 @@
<template>
<nav class="main-navigation">
<router-link :to="{name: 'SaaSLandingPage'}" tag="div" class="logo">
<router-link :to="{name: 'Homepage'}" tag="div" class="logo">
<img v-if="config.app_logo_horizontal" :src="$getImage(config.app_logo_horizontal)" :alt="config.app_name">
<b v-if="! config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
</router-link>
@@ -12,25 +12,32 @@
</a>
</li>-->
<li>
<router-link :to="{name: 'ContactUs'}">
<router-link :to="{name: 'ContactUs'}" class="hover-text-theme">
{{ $t('page_index.menu.contact_us') }}
</router-link>
</li>
</ul>
<ul class="navigation-links">
<ul v-if="! config.isAuthenticated" class="navigation-links">
<li>
<router-link :to="{name: 'SignIn'}">
<router-link :to="{name: 'SignIn'}" class="hover-text-theme">
{{ $t('page_index.menu.log_in') }}
</router-link>
</li>
<li v-if="config.userRegistration">
<router-link class="cta-button" :to="{name: 'SignUp'}">
<router-link class="cta-button text-theme bg-theme-100" :to="{name: 'SignUp'}">
{{ $t('page_index.menu.sign_in') }}
</router-link>
</li>
</ul>
<ul v-if="config.isAuthenticated" class="navigation-links">
<li v-if="config.userRegistration">
<router-link class="cta-button text-theme bg-theme-100" :to="{name: 'Files'}">
{{ $t('go_to_files') }}
</router-link>
</li>
</ul>
</div>
<router-link class="cta-button log-in" :to="{name: 'SignIn'}">
<router-link class="cta-button log-in text-theme bg-theme-100" :to="{name: 'SignIn'}">
{{ $t('page_index.menu.log_in') }}
</router-link>
</nav>
@@ -48,9 +55,9 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_landing-page';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.main-navigation {
justify-content: space-between;
@@ -77,7 +84,7 @@
.navigation-links {
display: inline-block;
margin-left: 50px;
margin-left: 25px;
&:first-child {
margin-left: 0;
@@ -91,19 +98,13 @@
font-weight: 700;
@include font-size(17);
@include transition(150ms);
&:hover {
color: $theme;
}
}
}
}
.cta-button {
background: rgba($theme, 0.1);
border-radius: 6px;
padding: 8px 23px;
color: $theme;
@include font-size(17);
font-weight: 700;
@@ -1,6 +1,6 @@
<template>
<footer class="page-wrapper medium">
<router-link :to="{name: 'SaaSLandingPage'}" tag="div" class="logo">
<router-link :to="{name: 'Homepage'}" tag="div" class="logo">
<img v-if="config.app_logo_horizontal" :src="$getImage(config.app_logo_horizontal)" :alt="config.app_name">
<b v-if="! config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
</router-link>
@@ -11,14 +11,14 @@
</a>
</li>-->
<li>
<router-link :to="{name: 'ContactUs'}">
<router-link :to="{name: 'ContactUs'}" class="hover-text-theme">
{{ $t('page_index.menu.contact_us') }}
</router-link>
</li>
</ul>
<ul class="navigation-links">
<li v-if="legal.visibility" v-for="(legal, index) in config.legal" :key="index">
<router-link :to="{name: 'DynamicPage', params: {slug: legal.slug }}">
<router-link :to="{name: 'DynamicPage', params: {slug: legal.slug }}" class="hover-text-theme">
{{ legal.title }}
</router-link>
</li>
@@ -39,9 +39,9 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_landing-page';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
footer {
text-align: center;
@@ -75,10 +75,6 @@
font-weight: 700;
@include font-size(17);
@include transition(150ms);
&:hover {
color: $theme;
}
}
}
}
@@ -90,7 +86,6 @@
padding-bottom: 20px;
/deep/ a {
color: $theme;
font-weight: 700;
}
}
@@ -3,26 +3,29 @@
<PageTitle
:title="index.header_title"
:description="index.header_description"
></PageTitle>
/>
<!--User registration button-->
<router-link v-if="config.userRegistration" class="sign-up-button" :to="{name: 'SignUp'}">
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.sign_up_button')" />
</router-link>
<div v-if="! config.isAuthenticated">
<!--User login button-->
<router-link v-if="! config.userRegistration" class="sign-up-button" :to="{name: 'SignIn'}">
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.menu.log_in')" />
</router-link>
<!--User registration button-->
<router-link v-if="config.userRegistration" class="sign-up-button" :to="{name: 'SignUp'}">
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.sign_up_button')" />
</router-link>
<div class="features" v-if="config.isSaaS">
<div class="feature">
<credit-card-icon size="19" class="feature-icon"></credit-card-icon>
<b class="feature-title">{{ $t('page_index.sign_feature_1') }}</b>
</div>
<div class="feature">
<hard-drive-icon size="19" class="feature-icon"></hard-drive-icon>
<b class="feature-title">{{ $t('page_index.sign_feature_2', {defaultSpace: config.storageDefaultSpaceFormatted}) }}</b>
<!--User login button-->
<router-link v-if="! config.userRegistration" class="sign-up-button" :to="{name: 'SignIn'}">
<AuthButton class="button" icon="chevron-right" :text="$t('page_index.menu.log_in')" />
</router-link>
<div class="features" v-if="config.isSaaS">
<div class="feature">
<credit-card-icon size="19" class="feature-icon"></credit-card-icon>
<b class="feature-title">{{ $t('page_index.sign_feature_1') }}</b>
</div>
<div class="feature">
<hard-drive-icon size="19" class="feature-icon"></hard-drive-icon>
<b class="feature-title">{{ $t('page_index.sign_feature_2', {defaultSpace: config.storageDefaultSpaceFormatted}) }}</b>
</div>
</div>
</div>
</header>
@@ -50,9 +53,9 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_landing-page';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.features {
display: flex;
@@ -51,9 +51,9 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_landing-page';
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_landing-page';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.pricing {
.cloud-bg {
@@ -17,6 +17,7 @@
<cloud-icon v-if="link.icon === 'cloud'" size="17"></cloud-icon>
<monitor-icon v-if="link.icon === 'monitor'" size="17"></monitor-icon>
<box-icon v-if="link.icon === 'box'" size="17"></box-icon>
<globe-icon v-if="link.icon === 'language'" size="17"></globe-icon>
</div>
<b class="menu-link">
<span>{{ link.title }}</span>
@@ -39,6 +40,7 @@
Trash2Icon,
CloudIcon,
PowerIcon,
GlobeIcon,
ShareIcon,
UsersIcon,
UserIcon,
@@ -61,6 +63,7 @@
Trash2Icon,
CloudIcon,
PowerIcon,
GlobeIcon,
UsersIcon,
ShareIcon,
LockIcon,
@@ -73,8 +76,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.link-item {
display: flex;
@@ -11,7 +11,7 @@
<!--More Actions-->
<div @click="showMobileNavigation" class="mobile-menu">
<menu-icon size="17" class="icon"></menu-icon>
<menu-icon size="17" class="icon" />
</div>
</header>
</template>
@@ -45,8 +45,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.mobile-header {
padding: 10px 0;
@@ -1,7 +1,7 @@
<template>
<div class="action-button">
<x-icon size="12" class="icon" v-if="icon === 'x'"></x-icon>
<edit-2-icon size="12" class="icon" v-if="icon === 'pencil-alt'"></edit-2-icon>
<x-icon size="12" class="icon text-theme" v-if="icon === 'x'" />
<edit-2-icon size="12" class="icon text-theme" v-if="icon === 'pencil-alt'" />
<span class="label">
<slot></slot>
</span>
@@ -22,8 +22,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.action-button {
cursor: pointer;
@@ -40,7 +40,7 @@
margin-right: 2px;
path, circle, line {
stroke: $theme;
color: inherit;
}
}
}
@@ -12,8 +12,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.color-label {
text-transform: capitalize;
@@ -0,0 +1,136 @@
<template>
<div class="color-pick-wrapper">
<label class="main-label">{{ $t('popup_rename.color_pick_label') }}:</label>
<ul class="color-wrapper">
<li v-for="(color, i) in colors" :key="i" @click="setColor( color )" class="single-color">
<check-icon v-if="color === selectedColor" class="color-icon" size="22"/>
<span :style="{background:color}" class="color-box"></span>
</li>
</ul>
</div>
</template>
<script>
import { CheckIcon } from 'vue-feather-icons'
import { mapGetters } from 'vuex'
export default {
name: 'ColorPicker',
props: [ 'pickedColor' ],
components: { CheckIcon },
computed: {
...mapGetters([
'config'
])
},
data () {
return {
selectedColor: this.pickedColor,
colors: [
'#FE6F6F',
'#FE6F91',
'#FE6FC0',
'#FE6FF0',
'#DD6FFE',
'#AD6FFE',
'#7D6FFE',
'#6F90FE',
'#6FC0FE',
'#6FF0FE',
'#6FFEDD',
'#6FFEAD',
'#6FFE7D',
'#90FE6F',
'#C0FE6F',
'#F0FE6F',
'#FEDD6F',
'#FEAD6F',
'#FE7D6F',
'#4c4c4c',
'#06070B',
]
}
},
methods: {
setColor (value) {
this.selectedColor = value
this.$emit('input', value)
}
},
created() {
this.colors.push(this.config.app_color)
}
}
</script>
<style lang="scss" scoped>
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.color-pick-wrapper {
.color-wrapper {
margin-bottom: 20px;
display: grid;
grid-template-columns: repeat(auto-fill, 32px);
justify-content: space-between;
gap: 7px;
.single-color {
height: 31px;
list-style: none;
border-radius: 8px;
cursor: pointer;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
.color-icon {
z-index: 2;
polyline {
stroke: white;
}
}
.color-box {
width: 100%;
height: 100%;
position: absolute;
display: block;
}
}
}
}
.main-label {
@include font-size(14);
font-weight: 700;
margin-bottom: 8px;
display: block;
}
.set-folder-icon {
position: relative;
}
@media (prefers-color-scheme: dark) {
.color-pick-wrapper {
.color-wrapper {
.single-color {
&.active-color {
border: 2px solid;
}
&:hover {
border: 2px solid $dark_mode_text_primary;
}
}
}
}
}
</style>
@@ -36,8 +36,8 @@
</script>
<style lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
#files-view {
font-family: 'Nunito', sans-serif;
@@ -40,11 +40,12 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.cookie-wrapper {
@include widget-card;
background: white;
position: fixed;
bottom: 0;
left: 115px;
@@ -71,7 +72,7 @@
a {
font-size: 12px;
color: $theme;
text-decoration: underline;
}
}
}
@@ -16,6 +16,10 @@
<input v-model="name" :class="{'is-error': errors[0]}" type="text" ref="input" :placeholder="$t('popup_create_folder.placeholder')">
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
<SetFolderIcon v-if="isMoreOptions"/>
<ActionButton @click.native.stop="moreOptions" :icon="isMoreOptions ? 'x' : 'pencil-alt'">{{ moreOptionsTitle }}</ActionButton>
</ValidationObserver>
</PopupContent>
@@ -44,11 +48,11 @@
import PopupContent from '@/components/Others/Popup/PopupContent'
import PopupHeader from '@/components/Others/Popup/PopupHeader'
import ThumbnailItem from '@/components/Others/ThumbnailItem'
import SetFolderIcon from '@/components/Others/SetFolderIcon'
import ActionButton from '@/components/Others/ActionButton'
import ButtonBase from '@/components/FilesView/ButtonBase'
import {required} from 'vee-validate/dist/rules'
import {events} from '@/bus'
import axios from 'axios'
export default {
name: 'CreateFolder',
@@ -56,6 +60,7 @@
ValidationProvider,
ValidationObserver,
ThumbnailItem,
SetFolderIcon,
ActionButton,
PopupWrapper,
PopupActions,
@@ -64,19 +69,29 @@
ButtonBase,
required,
},
computed: {
moreOptionsTitle() {
return this.isMoreOptions ? this.$t('shared_form.button_close_options') : this.$t('shared_form.button_folder_icon_open')
}
},
data() {
return {
name: undefined,
isMoreOptions: false,
folderIcon: undefined
}
},
methods: {
moreOptions() {
this.isMoreOptions = !this.isMoreOptions
},
async createFolder() {
// Validate fields
const isValid = await this.$refs.createForm.validate();
if (isValid) {
this.$store.dispatch('createFolder', this.name)
this.$store.dispatch('createFolder', {'name':this.name, 'icon': this.folderIcon})
this.$closePopup()
@@ -85,18 +100,26 @@
},
},
mounted() {
events.$on('setFolderIcon', (icon) => {
this.folderIcon = icon
})
events.$on('popup:open', ({name}) => {
if (name === 'create-folder' && ! this.$isMobile())
this.$nextTick(() => this.$refs.input.focus())
})
events.$on('setFolderIcon', (icon) => {
this.setFolderIcon = icon
})
}
}
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.item-thumbnail {
margin-bottom: 20px;
@@ -0,0 +1,864 @@
<template>
<PopupWrapper name="create-language">
<!--Title-->
<PopupHeader :title="$t('create_language')" icon="edit" />
<!--Content-->
<PopupContent>
<!--Form to set sharing-->
<ValidationObserver @submit.prevent="createLanguage" ref="createForm" v-slot="{ invalid }" tag="form" class="form-wrapper">
<ValidationProvider tag="div" mode="passive" class="input-wrapper password" name="Language Locale" rules="required" v-slot="{ errors }">
<label class="input-label">{{ $t('select_locale') }}:</label>
<SelectInput v-model="form.locale" :options="locales" :placeholder="$t('select_language_locale')" :isError="errors[0]" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" class="input-wrapper password" name="Language Name" rules="required" v-slot="{ errors }">
<label class="input-label">{{ $t('locale_name') }}:</label>
<input v-model="form.name" :class="{'is-error': errors[0]}" type="text" ref="input" class="focus-border-theme" :placeholder="$t('type_language_name')">
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
</ValidationObserver>
</PopupContent>
<!--Actions-->
<PopupActions>
<ButtonBase
class="popup-button"
@click.native="$closePopup()"
button-style="secondary"
>
{{ $t('global.cancel') }}
</ButtonBase>
<ButtonBase
class="popup-button"
@click.native="createLanguage"
button-style="theme"
:loading="isLoading"
:disabled="isLoading"
>
{{ $t('create_language') }}
</ButtonBase>
</PopupActions>
</PopupWrapper>
</template>
<script>
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import PopupWrapper from '@/components/Others/Popup/PopupWrapper'
import PopupActions from '@/components/Others/Popup/PopupActions'
import PopupContent from '@/components/Others/Popup/PopupContent'
import PopupHeader from '@/components/Others/Popup/PopupHeader'
import SelectInput from '@/components/Others/Forms/SelectInput'
import ButtonBase from '@/components/FilesView/ButtonBase'
import {required} from 'vee-validate/dist/rules'
import {events} from '@/bus'
import axios from 'axios'
export default {
name: 'CreateLanguage',
components: {
ValidationProvider,
ValidationObserver,
PopupWrapper,
PopupActions,
PopupContent,
PopupHeader,
SelectInput,
ButtonBase,
required,
},
data() {
return {
form: {
name: undefined,
locale: undefined,
},
isLoading: false,
locales: [
{
value: "ab",
label: "Abkhaz"
},
{
value: "aa",
label: "Afar"
},
{
value: "af",
label: "Afrikaans"
},
{
value: "ak",
label: "Akan"
},
{
value: "sq",
label: "Albanian"
},
{
value: "am",
label: "Amharic"
},
{
value: "ar",
label: "Arabic"
},
{
value: "an",
label: "Aragonese"
},
{
value: "hy",
label: "Armenian"
},
{
value: "as",
label: "Assamese"
},
{
value: "av",
label: "Avaric"
},
{
value: "ae",
label: "Avestan"
},
{
value: "ay",
label: "Aymara"
},
{
value: "az",
label: "Azerbaijani"
},
{
value: "bm",
label: "Bambara"
},
{
value: "ba",
label: "Bashkir"
},
{
value: "eu",
label: "Basque"
},
{
value: "be",
label: "Belarusian"
},
{
value: "bn",
label: "Bengali; Bangla"
},
{
value: "bh",
label: "Bihari"
},
{
value: "bi",
label: "Bislama"
},
{
value: "bs",
label: "Bosnian"
},
{
value: "br",
label: "Breton"
},
{
value: "bg",
label: "Bulgarian"
},
{
value: "my",
label: "Burmese"
},
{
value: "ca",
label: "Catalan; Valencian"
},
{
value: "ch",
label: "Chamorro"
},
{
value: "ce",
label: "Chechen"
},
{
value: "ny",
label: "Chichewa; Chewa; Nyanja"
},
{
value: "zh",
label: "Chinese"
},
{
value: "cv",
label: "Chuvash"
},
{
value: "kw",
label: "Cornish"
},
{
value: "co",
label: "Corsican"
},
{
value: "cr",
label: "Cree"
},
{
value: "hr",
label: "Croatian"
},
{
value: "cs",
label: "Czech"
},
{
value: "da",
label: "Danish"
},
{
value: "dv",
label: "Divehi; Dhivehi; Maldivian;"
},
{
value: "nl",
label: "Dutch"
},
{
value: "dz",
label: "Dzongkha"
},
{
value: "en",
label: "English"
},
{
value: "eo",
label: "Esperanto"
},
{
value: "et",
label: "Estonian"
},
{
value: "ee",
label: "Ewe"
},
{
value: "fo",
label: "Faroese"
},
{
value: "fj",
label: "Fijian"
},
{
value: "fi",
label: "Finnish"
},
{
value: "fr",
label: "French"
},
{
value: "ff",
label: "Fula; Fulah; Pulaar; Pular"
},
{
value: "gl",
label: "Galician"
},
{
value: "lg",
label: "Ganda"
},
{
value: "ka",
label: "Georgian"
},
{
value: "de",
label: "German"
},
{
value: "el",
label: "Greek, Modern"
},
{
value: "gn",
label: "Guaraní"
},
{
value: "gu",
label: "Gujarati"
},
{
value: "ht",
label: "Haitian; Haitian Creole"
},
{
value: "ha",
label: "Hausa"
},
{
value: "he",
label: "Hebrew (modern)"
},
{
value: "hz",
label: "Herero"
},
{
value: "hi",
label: "Hindi"
},
{
value: "ho",
label: "Hiri Motu"
},
{
value: "hu",
label: "Hungarian"
},
{
value: "ia",
label: "Interlingua"
},
{
value: "id",
label: "Indonesian"
},
{
value: "ie",
label: "Interlingue"
},
{
value: "ga",
label: "Irish"
},
{
value: "ig",
label: "Igbo"
},
{
value: "ik",
label: "Inupiaq"
},
{
value: "io",
label: "Ido"
},
{
value: "is",
label: "Icelandic"
},
{
value: "it",
label: "Italian"
},
{
value: "iu",
label: "Inuktitut"
},
{
value: "ja",
label: "Japanese"
},
{
value: "jv",
label: "Javanese"
},
{
value: "kl",
label: "Kalaallisut, Greenlandic"
},
{
value: "kn",
label: "Kannada"
},
{
value: "kr",
label: "Kanuri"
},
{
value: "ks",
label: "Kashmiri"
},
{
value: "kk",
label: "Kazakh"
},
{
value: "km",
label: "Khmer"
},
{
value: "ki",
label: "Kikuyu, Gikuyu"
},
{
value: "rw",
label: "Kinyarwanda"
},
{
value: "rn",
label: "Kirundi"
},
{
value: "ky",
label: "Kyrgyz"
},
{
value: "kv",
label: "Komi"
},
{
value: "kg",
label: "Kongo"
},
{
value: "ko",
label: "Korean"
},
{
value: "ku",
label: "Kurdish"
},
{
value: "kj",
label: "Kwanyama, Kuanyama"
},
{
value: "la",
label: "Latin"
},
{
value: "lb",
label: "Luxembourgish, Letzeburgesch"
},
{
value: "li",
label: "Limburgish, Limburgan, Limburger"
},
{
value: "ln",
label: "Lingala"
},
{
value: "lo",
label: "Lao"
},
{
value: "lt",
label: "Lithuanian"
},
{
value: "lu",
label: "Luba-Katanga"
},
{
value: "lv",
label: "Latvian"
},
{
value: "gv",
label: "Manx"
},
{
value: "mk",
label: "Macedonian"
},
{
value: "mg",
label: "Malagasy"
},
{
value: "ms",
label: "Malay"
},
{
value: "ml",
label: "Malayalam"
},
{
value: "mt",
label: "Maltese"
},
{
value: "mi",
label: "MÄori"
},
{
value: "mr",
label: "Marathi"
},
{
value: "mh",
label: "Marshallese"
},
{
value: "mn",
label: "Mongolian"
},
{
value: "na",
label: "Nauru"
},
{
value: "nv",
label: "Navajo, Navaho"
},
{
value: "nb",
label: "Norwegian"
},
{
value: "nd",
label: "North Ndebele"
},
{
value: "ne",
label: "Nepali"
},
{
value: "ng",
label: "Ndonga"
},
{
value: "nn",
label: "Norwegian Nynorsk"
},
{
value: "no",
label: "Norwegian"
},
{
value: "ii",
label: "Nuosu"
},
{
value: "oc",
label: "Occitan"
},
{
value: "oj",
label: "Ojibwe, Ojibwa"
},
{
value: "cu",
label: "Old Church Slavonic, Church Slavic, Church Slavonic, Old Bulgarian, Old Slavonic"
},
{
value: "om",
label: "Oromo"
},
{
value: "or",
label: "Oriya"
},
{
value: "os",
label: "Ossetian, Ossetic"
},
{
value: "pa",
label: "Panjabi, Punjabi"
},
{
value: "pi",
label: "Pali"
},
{
value: "fa",
label: "Persian (Farsi)"
},
{
value: "pl",
label: "Polish"
},
{
value: "ps",
label: "Pashto, Pushto"
},
{
value: "pt",
label: "Portuguese"
},
{
value: "qu",
label: "Quechua"
},
{
value: "rm",
label: "Romansh"
},
{
value: "ro",
label: "Romanian"
},
{
value: "ru",
label: "Russian"
},
{
value: "sa",
label: "Sanskrit"
},
{
value: "sc",
label: "Sardinian"
},
{
value: "sd",
label: "Sindhi"
},
{
value: "se",
label: "Northern Sami"
},
{
value: "sm",
label: "Samoan"
},
{
value: "sg",
label: "Sango"
},
{
value: "sr",
label: "Serbian"
},
{
value: "gd",
label: "Scottish Gaelic"
},
{
value: "sn",
label: "Shona"
},
{
value: "si",
label: "Sinhala, Sinhalese"
},
{
value: "sk",
label: "Slovak"
},
{
value: "sl",
label: "Slovene"
},
{
value: "so",
label: "Somali"
},
{
value: "st",
label: "Southern Sotho"
},
{
value: "az",
label: "South Azerbaijani"
},
{
value: "nr",
label: "South Ndebele"
},
{
value: "es",
label: "Spanish; Castilian"
},
{
value: "su",
label: "Sundanese"
},
{
value: "sw",
label: "Swahili"
},
{
value: "ss",
label: "Swati"
},
{
value: "sv",
label: "Swedish"
},
{
value: "ta",
label: "Tamil"
},
{
value: "te",
label: "Telugu"
},
{
value: "tg",
label: "Tajik"
},
{
value: "th",
label: "Thai"
},
{
value: "ti",
label: "Tigrinya"
},
{
value: "bo",
label: "Tibetan Standard, Tibetan, Central"
},
{
value: "tk",
label: "Turkmen"
},
{
value: "tl",
label: "Tagalog"
},
{
value: "tn",
label: "Tswana"
},
{
value: "to",
label: "Tonga (Tonga Islands)"
},
{
value: "tr",
label: "Turkish"
},
{
value: "ts",
label: "Tsonga"
},
{
value: "tt",
label: "Tatar"
},
{
value: "tw",
label: "Twi"
},
{
value: "ty",
label: "Tahitian"
},
{
value: "ug",
label: "Uyghur, Uighur"
},
{
value: "uk",
label: "Ukrainian"
},
{
value: "ur",
label: "Urdu"
},
{
value: "uz",
label: "Uzbek"
},
{
value: "ve",
label: "Venda"
},
{
value: "vi",
label: "Vielabele"
},
{
value: "vo",
label: "Volapük"
},
{
value: "wa",
label: "Walloon"
},
{
value: "cy",
label: "Welsh"
},
{
value: "wo",
label: "Wolof"
},
{
value: "fy",
label: "Western Frisian"
},
{
value: "xh",
label: "Xhosa"
},
{
value: "yi",
label: "Yiddish"
},
{
value: "yo",
label: "Yoruba"
},
{
value: "za",
label: "Zhuang, Chuang"
},
{
value: "zu",
label: "Zulu"
}
]
}
},
methods: {
async createLanguage() {
// Validate fields
const isValid = await this.$refs.createForm.validate();
if (isValid) {
this.isLoading = true
axios.post('/api/admin/languages', this.form)
.then(response => {
events.$emit('reload:languages', response.data)
})
.catch(() => {
this.$isSomethingWrong()
})
.finally(() => {
this.form = {
name: undefined,
locale: undefined,
}
this.isLoading = false
this.$closePopup()
})
}
},
}
}
</script>
<style scoped lang="scss">
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.item-thumbnail {
margin-bottom: 20px;
}
</style>
+2 -2
View File
@@ -29,8 +29,8 @@ export default {
</script>
<style lang="scss" scoped>
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.emoji-container {
font-size: inherit;
@@ -0,0 +1,498 @@
<template>
<div class="select-emoji-wrapper">
<label class="main-label">{{ $t('popup_rename.select_emoji_label') }}:</label>
<!-- Selected Emoji input -->
<div @click.stop="openList" class="select-input-wrapper focus-border-theme" :class="{'active-menu' : selectOpen}">
<!-- If is emoji selected -->
<div class="select-input" v-if="selectedEmoji && selectedEmoji !== 'default'">
<div @click.stop="resetEmoji" class="select-input-icon-wrapper">
<x-icon size="14" class="select-input-icon" />
</div>
<Emoji class="emoji-preview" :emoji="selectedEmoji" location="emoji-picker-preview" />
<span>{{ selectedEmoji.name }}</span>
</div>
<!-- If is emoji not selected -->
<div class="not-selected" v-if="! selectedEmoji || selectedEmoji === 'default'">
<span> {{ $t('popup_rename.set_emoji_input_placeholder') }}</span>
</div>
<chevron-down-icon class="row-icon" size="19" />
</div>
<!-- Emojis List -->
<transition name="slide-in">
<div v-if="selectOpen">
<!-- Spinner -->
<div v-if="!isLoadedEmojis" class="emoji-wrapper">
<Spinner />
</div>
<!-- List -->
<div v-if="isLoadedEmojis && emojis" class="emoji-wrapper">
<!-- Search input -->
<input @click.stop @input="searchEmojis" v-model="searchInput" class="emoji-input" :placeholder="$t('popup_rename.search_emoji_input_placeholder')">
<!-- Navigation of Emojis Groups -->
<ul v-show="searchInput.length < 1" class="groups-list">
<li @click.stop="scrollToGroup(group.name)" v-for="(group,i) in emojis.emojisGroups" :key="i" class="group-option" :class="{'active' : group.name === groupInView}">
<Emoji :emoji="group.emoji" location="emoji-picker" />
</li>
</ul>
<!-- All Emojis -->
<div v-show="searchInput.length < 1" @scroll="checkGroupInView" id="group-box" class="group-wrapper">
<div v-for="(group, name) in allEmoji()" :key="name" class="options-wrapper" :id="`group-${name}`">
<label class="group-name-label">{{ name }}</label>
<ul class="options-list">
<li @click="setEmoji( emoji )" v-for="(emoji,i) in group" :key="i" class="option">
<Emoji :emoji="emoji" location="emoji-picker" />
</li>
</ul>
</div>
</div>
<!-- Searched emojis -->
<div v-if="searchInput.length > 0" class="group-wrapper">
<div class="options-wrapper">
<ul class="options-list">
<li @click="setEmoji( emoji )" v-for="(emoji,i) in filteredEmojis" :key="i" class="option">
<Emoji :emoji="emoji" location="emoji-picker" />
</li>
</ul>
<span class="not-found" v-if="filteredEmojis.length === 0 && filteredEmojisLoaded"> {{ $t('popup_rename.emoji_list_not_found') }}</span>
<Spinner v-if=" ! filteredEmojisLoaded " />
</div>
</div>
</div>
</div>
</transition>
</div>
</template>
<script>
import {ChevronDownIcon, XIcon} from 'vue-feather-icons'
import Spinner from '@/components/FilesView/Spinner'
import Emoji from '@/components/Others/Emoji'
import {mapGetters} from 'vuex'
import {groupBy} from 'lodash'
import {events} from '@/bus'
export default {
name: 'EmojiPicker',
props: ['pickedEmoji'],
components: {
ChevronDownIcon,
Spinner,
Emoji,
XIcon,
},
computed: {
...mapGetters(['emojis']),
},
data() {
return {
selectedEmoji: this.pickedEmoji,
searchInput: '',
filteredEmojis: [],
selectOpen: false,
isLoadedEmojis: false,
filteredEmojisLoaded: true,
groupInView: 'Smileys & Emotion',
}
},
methods: {
allEmoji() {
return groupBy(this.emojis.emojisList, 'group')
},
checkGroupInView: _.debounce(function () {
this.emojis.emojisGroups.forEach(group => {
let element = document.getElementById(`group-${group.name}`).getBoundingClientRect()
let groupBox = document.getElementById('group-box').getBoundingClientRect()
// Check if the group is in the viewport of group-box
if (element.top < groupBox.top && element.bottom > groupBox.top) {
this.groupInView = group.name
}
})
}, 200),
scrollToGroup(name) {
let group = document.getElementById(`group-${name}`)
group.scrollIntoView({behavior: 'smooth'})
this.groupInView = name
},
searchEmojis() {
// Turn on spinner until filteredEmojis will loaded
this.filteredEmojisLoaded = false
this.filteredEmojis = [],
this.filterEmojis()
},
filterEmojis: _.debounce(function () {
this.filteredEmojis = this.emojis.emojisList.filter(emoji => emoji.name.includes(this.searchInput.toLowerCase()))
this.filteredEmojisLoaded = true
}, 800),
openList() {
this.isLoadedEmojis = false
this.selectOpen = !this.selectOpen
// Load emojis from server just if not loaded already
if (this.selectOpen && !this.emojis) {
axios.get('/assets/emojis.json')
.then(response => {
this.$store.commit('LOAD_EMOJIS_LIST', response.data)
})
.finally(() => this.isLoadedEmojis = true)
}
// Simulate loading for the emojisList processing
if (this.emojis) {
setTimeout(() => {
this.isLoadedEmojis = true
}, 20);
}
this.searchInput = ''
this.groupInView = 'Smileys & Emotion'
},
setEmoji(value) {
// Set emoji
this.selectedEmoji = value
this.$emit('input', value)
this.selectOpen = false
},
resetEmoji() {
this.selectedEmoji = undefined
this.$emit('input', 'default')
}
},
mounted() {
this.selectOpen = false
events.$on('unClick', () => {
this.selectOpen = false
this.isLoadedEmojis = false
})
}
}
</script>
<style lang="scss" scoped>
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.select-emoji-wrapper {
margin-bottom: 20px;
}
.main-label {
@include font-size(14);
font-weight: 700;
margin-bottom: 8px;
display: block;
}
.emoji-wrapper {
height: 400px;
width: 100%;
position: absolute;
border: 1px solid transparent;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
border-radius: 8px;
background: white;
display: flex;
flex-direction: column;
padding: 10px;
z-index: 10;
top: 152px;
.groups-list {
display: grid;
grid-template-columns: repeat(9, auto);
justify-content: space-between;
overflow-x: auto;
overflow-y: hidden;
height: 90px;
.active {
background: $light_background;
border-radius: 8px;
}
.group-option {
width: 45px;
height: 45px;
list-style: none;
padding: 6px;
cursor: pointer;
&:hover {
background: $light_background;
border-radius: 8px;
}
}
}
.emoji-input {
width: 100%;
border-radius: 8px;
margin-bottom: 20px;
background: $light_background;
border: none;
padding: 13px 20px;
font-weight: 700;
&::placeholder {
font-weight: 700;
color: $light_text;
}
}
.group-wrapper {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
overflow-y: scroll;
padding: 0px;
.options-wrapper {
display: flex;
flex-wrap: wrap;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0px;
}
.options-list {
display: grid;
grid-template-columns: repeat(auto-fill, 45px);
justify-content: space-between;
width: 100%;
}
.group-name-label {
width: 100%;
@include font-size(14);
font-weight: 700;
margin-bottom: 10px;
}
.option {
list-style: none;
width: 45px;
height: 45px;
padding: 6px;
cursor: pointer;
&:hover {
background: $light_background;
border-radius: 8px;
}
}
.not-found {
align-self: center;
margin: auto;
font-weight: 700;
padding: 10px;
border-radius: 8px;
background: $light_background;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
}
}
}
}
.select-input-wrapper {
height: 50px;
padding: 13px 20px;
border: 1px solid transparent;
border-radius: 8px;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid transparent;
@include transition(150ms);
.row-icon {
@include transition(150ms);
}
&.active-menu {
//box-shadow: 0 0 7px rgba($theme, 0.3);
.row-icon {
transform: rotate(180deg);
}
}
.select-input {
@include font-size(16);
font-weight: 700;
display: flex;
flex-direction: row;
align-items: center;
.emoji-preview {
margin-left: 5px;
margin-right: 10px;
width: 22px;
height: 22px;
}
.select-input-icon-wrapper {
width: 22px;
height: 22px;
border-radius: 6px;
display: flex;
justify-content: center;
align-items: center;
margin-left: -7px;
&:hover {
.select-input-icon {
line {
stroke: $theme;
}
}
}
.select-input-icon {
line {
stroke: $text;
}
}
}
}
.not-selected {
span {
color: rgba($text, 0.5);
@include font-size(15);
font-weight: 700
}
}
}
.slide-in-enter-active {
transition: all 150ms ease;
}
.slide-in-enter {
opacity: 0;
transform: translateY(-210px);
}
.slide-in-enter-to {
transform: translateY(-134px);
}
@media (max-width: 690px) {
.emoji-wrapper {
height: 300px;
}
}
@media (max-width: 336px) {
.emoji-wrapper {
top: 173px;
}
}
@media (prefers-color-scheme: dark) {
.emoji-wrapper {
background: lighten($dark_mode_foreground, 2%);
.emoji-input {
background: $dark_mode_foreground;
}
.groups-list {
.active {
background: $dark_mode_foreground !important;
}
.group-option {
&:hover {
background: $dark_mode_foreground !important;
}
}
}
.options-wrapper {
.option {
&:hover {
background: $dark_mode_foreground !important;
}
}
.not-found {
background: $dark_mode_foreground !important;
}
}
}
.select-input-wrapper {
background: lighten($dark_mode_foreground, 3%);
.not-selected {
span {
color: $dark_mode_text_secondary;
}
}
.select-input-icon-wrapper {
&:hover {
.select-input-icon {
line {
stroke: $theme !important;
}
}
}
.select-input-icon {
line {
stroke: $dark_mode_text_primary !important;
}
}
}
}
}
</style>
@@ -30,8 +30,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.empty-page-content {
width: 100%;
@@ -2,12 +2,12 @@
<div class="inline-wrapper icon-append copy-input" :class="size" @click="copyUrl">
<input ref="sel" :value="item.shared.link" id="link-input" type="text" class="input-text" readonly>
<div class="multi-icon">
<div class="icon-item">
<link-icon v-if="! isCopiedLink" size="14"></link-icon>
<check-icon v-if="isCopiedLink" size="14"></check-icon>
<div class="icon-item group hover-bg-theme-100">
<link-icon v-if="! isCopiedLink" size="14" class="group-hover-text-theme hover-text-theme"/>
<check-icon v-if="isCopiedLink" size="14" class="group-hover-text-theme hover-text-theme"/>
</div>
<div class="icon-item" @click.stop.prevent="menuForEmail">
<send-icon size="14"></send-icon>
<div class="icon-item group hover-bg-theme-100" @click.stop.prevent="menuForEmail">
<send-icon size="14" class="group-hover-text-theme hover-text-theme" />
</div>
</div>
</div>
@@ -63,10 +63,10 @@ export default {
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import "@assets/vue-file-manager/_forms.scss";
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import "@assets/vuefilemanager/_forms.scss";
.multi-icon {
display: flex;
@@ -78,7 +78,7 @@ export default {
line,
path,
polygon {
stroke: $text !important;
color: $text;
}
.icon-item {
@@ -89,13 +89,12 @@ export default {
cursor: pointer;
&:hover {
background: $text;
line,
polyline,
path,
polygon {
stroke: white !important;
color: inherit;
}
}
@@ -160,22 +159,11 @@ export default {
line,
path,
polygon {
stroke: $dark_mode_text_primary !important;
color: inherit !important;
}
.icon-item {
border-color: #333333;
&:hover {
background: rgba($theme, 0.1);
line,
polyline,
path,
polygon {
stroke: $theme !important;
}
}
}
@@ -1,6 +1,7 @@
<template>
<div class="form-label">
<edit-2-icon size="22" class="icon"></edit-2-icon>
<edit-2-icon v-if="!icon" size="22" class="icon text-theme" />
<settings-icon v-if="icon === 'settings'" size="22" class="icon text-theme" />
<b class="label">
<slot></slot>
</b>
@@ -8,19 +9,21 @@
</template>
<script>
import { Edit2Icon } from 'vue-feather-icons'
import { Edit2Icon, SettingsIcon } from 'vue-feather-icons'
export default {
name: 'FormLabel',
props: ['icon'],
components: {
Edit2Icon
Edit2Icon,
SettingsIcon
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.form-label {
display: flex;
@@ -30,8 +33,8 @@
.icon {
margin-right: 10px;
path {
stroke: $theme;
path, circle {
color: inherit;
}
}
@@ -1,7 +1,7 @@
<template>
<div class="dropzone" :class="{ 'is-error': error }">
<div v-if="imagePreview" @click="resetImage" class="reset-image">
<x-icon size="14" class="close-icon"></x-icon>
<x-icon size="14" class="close-icon text-theme" />
</div>
<input
@@ -18,7 +18,7 @@
/>
<div class="dropzone-message" v-show="! isData">
<image-icon size="28" class="icon-upload"></image-icon>
<image-icon size="28" class="icon-upload text-theme"></image-icon>
<span class="dropzone-title">
{{ $t('input_image.title') }}
</span>
@@ -85,8 +85,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.dropzone {
border: 1px dashed #a1abc2;
@@ -146,7 +146,7 @@
.icon-upload {
rect, circle, polyline {
stroke: $theme
color: inherit
}
}
@@ -195,7 +195,7 @@
.icon-upload {
path, polyline, line {
stroke: $theme;
color: inherit;
}
}
@@ -12,8 +12,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.info-box {
padding: 20px;
@@ -42,23 +42,19 @@
/deep/ a {
font-size: 15px;
color: $theme;
}
/deep/ b {
font-size: 15px;
font-weight: 700;
color: $theme;
}
}
b {
font-weight: 700;
color: $theme;
}
a {
color: $theme;
font-weight: 700;
@include font-size(15);
line-height: 1.6;
@@ -1,10 +1,10 @@
<template>
<div class="wrapper">
<label class="input-label">{{ label }}:</label>
<div class="input-wrapper" :class="{'is-error' : isError}" @click="$refs.input.focus()">
<div class="input-wrapper focus-within-border-theme" :class="{'is-error' : isError}" @click="$refs.input.focus()">
<div class="email-list">
<div class="email-tag" :class="{'mb-offset': getCharactersLength > 45}" v-for="(email, i) in emails" :key="i">
<span>{{ email }}</span>
<div class="email-tag bg-theme-100" :class="{'mb-offset': getCharactersLength > 45}" v-for="(email, i) in emails" :key="i">
<span class="text-theme">{{ email }}</span>
<x-icon @click="removeEmail(email)" class="icon" size="14"/>
</div>
<input @keydown.delete=removeLastEmail($event) @keyup="handleEmail()" v-model="email" :size="inputSize" class="email-input" :placeholder="placeHolder" autocomplete="new-password" ref="input"/>
@@ -91,8 +91,8 @@ export default {
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.wrapper {
margin-bottom: 20px;
@@ -123,8 +123,8 @@ export default {
}
&:focus-within {
border: 1px solid $theme;
box-shadow: 0 1px 5px rgba($theme, 0.3);
//border: 1px solid $theme;
//box-shadow: 0 1px 5px rgba($theme, 0.3);
}
.email-list {
@@ -140,7 +140,6 @@ export default {
white-space: nowrap;
display: flex;
padding: 5px 10px;
background: rgba($theme, .1);
border-radius: 8px;
margin-right: 5px;
align-items: center;
@@ -151,7 +150,6 @@ export default {
}
span {
color: $theme;
font-weight: 700;
@include font-size(14);
}
@@ -0,0 +1,115 @@
<template>
<div class="search-bar">
<div v-if="!query" class="icon">
<search-icon size="19" />
</div>
<div @click="clearInput" v-if="query" class="icon">
<x-icon class="pointer" size="19"></x-icon>
</div>
<input
v-model="query"
@input="$emit('input', query)"
class="query focus-border-theme"
type="text"
name="searchInput"
:placeholder="$t('search_translations')"
/>
</div>
</template>
<script>
import {SearchIcon, XIcon} from 'vue-feather-icons'
export default {
name: 'SearchInput',
components: {
SearchIcon,
XIcon,
},
data() {
return {
query: undefined,
}
},
methods: {
clearInput() {
this.query = undefined
this.$emit('reset-query')
},
},
}
</script>
<style lang="scss" scoped>
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
@import '@assets/vuefilemanager/_forms';
.search-bar {
padding: 7px 0px;
position: relative;
width: 100%;
border-radius: 8px;
input {
background: $light_background;
border-radius: 8px;
outline: 0;
padding: 9px 20px 9px 43px;
font-weight: 700;
@include font-size(16);
width: 100%;
height: 50px;
min-width: 175px;
transition: 0.15s all ease;
border: 1px solid transparent;
-webkit-appearance: none;
box-shadow: none;
&::placeholder {
color: $light_text;
@include font-size(14);
font-weight: 700;
}
&:focus {
border-width: 1px;
border-style: solid;
}
&:focus + .icon {
path {
color: inherit;
}
}
}
.icon {
height: 100%;
position: absolute;
top: 0;
left: 0;
padding: 11px 15px;
display: flex;
align-items: center;
circle,
line {
color: $light_text;
}
.pointer {
cursor: pointer;
}
}
}
@media (prefers-color-scheme: dark) {
.search-bar {
input {
background: $dark_mode_foreground;
}
}
}
</style>
@@ -1,11 +1,11 @@
<template>
<div class="select-box">
<div class="box-item"
:class="{'selected': item.value === input}"
<div class="box-item active-bg-theme-100 active-border-theme"
:class="{'active': item.value === input}"
@click="getSelectedValue(item)"
v-for="(item, i) in data" :key="i"
>
<span class="box-value">{{ item.label }}</span>
<span class="box-value active-text-theme">{{ item.label }}</span>
</div>
</div>
</template>
@@ -40,10 +40,10 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import "@assets/vue-file-manager/_forms.scss";
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import "@assets/vuefilemanager/_forms.scss";
.select-box {
display: flex;
@@ -67,15 +67,6 @@
.box-value {
@include font-size(15);
}
&.selected {
background: rgba($theme, .1);
border-color: $theme;
.box-value {
color: $theme;
}
}
}
}
@@ -18,7 +18,7 @@
<span class="option-value placehoder">{{ placeholder }}</span>
</div>
<chevron-down-icon size="19" class="chevron"></chevron-down-icon>
<chevron-down-icon size="19" class="chevron" />
</div>
<!--Options-->
@@ -78,8 +78,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.select {
position: relative;
@@ -117,7 +117,9 @@
}
.input-area {
border: 1px solid transparent;
border-width: 1px;
border-style: solid;
border-color: transparent;
justify-content: space-between;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
//background: $light_mode_input_background;
@@ -135,8 +137,7 @@
}
&.is-active {
border-color: $theme;
box-shadow: 0 0 7px rgba($theme, 0.3);
//box-shadow: 0 0 7px rgba($theme, 0.3);
.chevron {
@include transform(rotate(180deg));
@@ -186,11 +187,11 @@
.input-area {
background: $dark_mode_foreground;
border-color: $dark_mode_foreground;
}
.option-icon {
path {
fill: $theme
}
.popup-wrapper {
.input-area {
background: lighten($dark_mode_foreground, 3%);
}
}
@@ -201,16 +202,12 @@
border-bottom: none;
&:hover {
background: rgba($theme, .1);
.option-value {
color: $theme;
}
background: lighten($dark_mode_foreground, 5%);
.option-icon {
path, circle {
stroke: $theme;
color: inherit;
}
}
}
@@ -14,8 +14,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.setup-box {
padding: 20px;
@@ -39,8 +39,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.input-wrapper {
display: flex;
@@ -83,7 +83,6 @@
}
&.active {
background: $theme;
.switch-button {
left: 25px;
@@ -95,5 +94,11 @@
.switch {
background: $dark_mode_foreground;
}
.popup-wrapper {
.switch {
background: lighten($dark_mode_foreground, 3%);
}
}
}
</style>
@@ -20,6 +20,6 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
</style>
@@ -11,8 +11,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.page-tab-group {
margin-bottom: 65px;
+2 -2
View File
@@ -11,6 +11,6 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
</style>
@@ -1,6 +1,6 @@
<template>
<li class="list-info-item">
<b>{{ title }}</b>
<b class="text-theme">{{ title }}</b>
<span v-if="content">{{ content }}</span>
<slot></slot>
</li>
@@ -14,8 +14,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.list-info-item {
display: block;
@@ -33,7 +33,6 @@
b {
display: block;
@include font-size(13);
color: $theme;
margin-bottom: 2px;
}
@@ -123,8 +123,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.mobile-navigation {
padding: 20px;
+61 -51
View File
@@ -7,33 +7,33 @@
<PopupContent type="height-limited" v-if="pickedItem">
<!--Show Spinner when loading folders-->
<Spinner v-if="isLoadingTree"/>
<Spinner v-if="isLoadingTree" />
<!--Folder tree-->
<div v-if="! isLoadingTree && navigation">
<ThumbnailItem v-if="fileInfoDetail.length < 2 || noSelectedItem" class="item-thumbnail" :item="pickedItem" info="location"/>
<ThumbnailItem v-if="fileInfoDetail.length < 2 || isSelectedItem" class="item-thumbnail" :item="pickedItem" info="location" />
<MultiSelected class="multiple-selected"
:title="$t('file_detail.selected_multiple')"
:subtitle="this.fileInfoDetail.length + ' ' + $tc('file_detail.items', this.fileInfoDetail.length)"
v-if="fileInfoDetail.length > 1 && !noSelectedItem"/>
<MultiSelected class="multiple-selected"
:title="$t('file_detail.selected_multiple')"
:subtitle="this.fileInfoDetail.length + ' ' + $tc('file_detail.items', this.fileInfoDetail.length)"
v-if="fileInfoDetail.length > 1 && !isSelectedItem" />
<TreeMenu :disabled-by-id="pickedItem" :depth="1" :nodes="items" v-for="items in navigation" :key="items.unique_id"/>
<TreeMenu :disabled-by-id="pickedItem" :depth="1" :nodes="items" v-for="items in navigation" :key="items.id" />
</div>
</PopupContent>
<!--Actions-->
<PopupActions>
<ButtonBase
class="popup-button"
@click.native="$closePopup()"
button-style="secondary"
class="popup-button"
@click.native="$closePopup()"
button-style="secondary"
>{{ $t('popup_move_item.cancel') }}
</ButtonBase>
<ButtonBase
class="popup-button"
@click.native="moveItem"
:button-style="selectedFolder ? 'theme' : 'secondary'"
class="popup-button"
@click.native="moveItem"
:button-style="selectedFolder ? 'theme' : 'secondary'"
>{{ $t('popup_move_item.submit') }}
</ButtonBase>
</PopupActions>
@@ -74,31 +74,34 @@
selectedFolder: undefined,
pickedItem: undefined,
isLoadingTree: true,
noSelectedItem: false
isSelectedItem: false
}
},
methods: {
moveItem() {
// Prevent empty submit
if (! this.selectedFolder) return
if (!this.selectedFolder) return
//Prevent to move items to the same parent
if(this.fileInfoDetail.find(item => item.parent_id === this.selectedFolder.unique_id)) return
// Prevent to move items to the same parent
if (this.fileInfoDetail.find(item => item.parent_id === this.selectedFolder.id)) return
// Move item
if(!this.noSelectedItem){
this.$store.dispatch('moveItem', {to_item:this.selectedFolder ,noSelectedItem: null})
// Move item
if (!this.isSelectedItem) {
this.$store.dispatch('moveItem', {to_item: this.selectedFolder, isSelectedItem: null})
}
if(this.noSelectedItem){
this.$store.dispatch('moveItem', {to_item:this.selectedFolder ,noSelectedItem:this.pickedItem})
if (this.isSelectedItem) {
this.$store.dispatch('moveItem', {to_item: this.selectedFolder, isSelectedItem: this.pickedItem})
}
console.log('to item:', this.selectedFolder);
console.log('isSelectedItem:', this.pickedItem);
// Close popup
events.$emit('popup:close')
// If is mobile, close the selecting mod after done the move action
if(this.$isMobile())
if (this.$isMobile())
events.$emit('mobileSelecting:stop')
},
},
@@ -107,7 +110,7 @@
// Select folder in tree
events.$on('pick-folder', folder => {
if (folder.unique_id === this.pickedItem.unique_id) {
if (folder.id === this.pickedItem.id) {
this.selectedFolder = undefined
} else {
this.selectedFolder = folder
@@ -118,6 +121,7 @@
events.$on('popup:open', args => {
if (args.name !== 'move') return
// Show tree spinner
this.isLoadingTree = true
@@ -127,13 +131,14 @@
})
// Store picked item
if(!this.fileInfoDetail.includes(args.item[0])){
if (!this.fileInfoDetail.includes(args.item[0])) {
this.pickedItem = args.item[0]
this.noSelectedItem = true
this.isSelectedItem = true
}
if(this.fileInfoDetail.includes(args.item[0])){
if (this.fileInfoDetail.includes(args.item[0])) {
this.pickedItem = this.fileInfoDetail[0]
this.noSelectedItem = false
this.isSelectedItem = false
}
})
@@ -150,40 +155,45 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.item-thumbnail {
margin-bottom: 20px;
}
.multiple-selected {
padding: 0 20px;;
margin-bottom: 20px;
/deep/.text{
.title {
color: $text;
}
.count {
color: $text-muted;
}
.item-thumbnail {
margin-bottom: 20px;
}
.multiple-selected {
padding: 0 20px;;
margin-bottom: 20px;
/deep/ .text {
.title {
color: $text;
}
/deep/.icon-wrapper {
.icon {
stroke: $theme;
}
.count {
color: $text-muted;
}
}
@media (prefers-color-scheme: dark) {
/deep/ .icon-wrapper {
.icon {
stroke: $theme;
}
}
}
@media (prefers-color-scheme: dark) {
.multiple-selected {
/deep/.text {
/deep/ .text {
.title {
color: $dark_mode_text_primary;
}
.count {
color: $dark_mode_text_secondary;
}
}
}
}
}
</style>
@@ -40,8 +40,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.fade-enter-active,
.fade-leave-active {
@@ -24,8 +24,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.toastr-list {
transition: all 5s ease;
@@ -24,8 +24,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.page-header {
display: flex;
@@ -4,7 +4,7 @@
<div class="plan-wrapper">
<header class="plan-header">
<div class="icon">
<hard-drive-icon size="26"></hard-drive-icon>
<hard-drive-icon class="text-theme" size="26" />
</div>
<h1 class="title">{{ plan.data.attributes.name }}</h1>
<h2 class="description">{{ plan.data.attributes.description }}</h2>
@@ -14,7 +14,7 @@
<span class="storage-description">{{ $t('page_pricing_tables.storage_capacity') }}</span>
</section>
<footer class="plan-footer">
<b class="price">
<b class="price text-theme">
{{ plan.data.attributes.price }}/{{ $t('global.monthly_ac') }}
<small v-if="plan.data.attributes.tax_rates.length > 0" class="vat-disclaimer">{{ $t('page_pricing_tables.vat_excluded') }}</small>
</b>
@@ -39,6 +39,9 @@
HardDriveIcon,
ButtonBase,
},
props: [
'customRoute'
],
data() {
return {
plans: undefined,
@@ -50,11 +53,14 @@
methods: {
selectPlan(plan) {
this.$emit('selected-plan', plan)
this.$router.push({name: 'UpgradeBilling'})
let route = this.customRoute ? this.customRoute : 'UpgradeBilling'
this.$router.push({name: route})
}
},
created() {
axios.get('/api/public/pricing')
axios.get('/api/pricing')
.then(response => {
this.plans = response.data.filter(plan => {
return plan.data.attributes.capacity > this.user.data.attributes.storage_capacity
@@ -66,8 +72,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.plan {
text-align: center;
@@ -91,7 +97,7 @@
.icon {
path, line, polyline, rect, circle {
color: $theme;
color: inherit;
}
}
@@ -130,7 +136,6 @@
}
.price {
color: $theme;
@include font-size(18);
display: block;
margin-bottom: 20px;
@@ -84,8 +84,8 @@
</script>
<style scoped lang="scss">
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.popup-image {
padding-top: 20px;
@@ -11,8 +11,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.actions {
padding: 20px;
@@ -14,8 +14,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.popup-content {
&.height-limited {
@@ -1,14 +1,13 @@
<template>
<div class="popup-header">
<div class="icon">
<corner-down-right-icon v-if="icon === 'move'" size="15" class="title-icon"></corner-down-right-icon>
<share-icon v-if="icon === 'share'" size="17" class="title-icon"></share-icon>
<!-- <link-icon v-if="icon === 'share'" size="17" class="title-icon"></link-icon> -->
<edit2-icon v-if="icon === 'edit'" size="17" class="title-icon"></edit2-icon>
<corner-down-right-icon v-if="icon === 'move'" size="15" class="title-icon text-theme" />
<share-icon v-if="icon === 'share'" size="17" class="title-icon text-theme" />
<edit2-icon v-if="icon === 'edit'" size="17" class="title-icon text-theme" />
</div>
<div class="label">
<h1 class="title">{{ title }}</h1>
<x-icon @click="closePopup" size="22" class="close-icon"></x-icon>
<x-icon @click="closePopup" size="22" class="close-icon hover-text-theme" />
</div>
</div>
</template>
@@ -38,8 +37,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.popup-header {
padding: 20px;
@@ -51,7 +50,7 @@
line-height: 0;
path, line, polyline, rect, circle {
stroke: $theme;
color: inherit;
}
}
@@ -81,7 +80,7 @@
background: $light_background;
line {
stroke: $theme;
color: inherit;
}
}
@@ -33,6 +33,9 @@
if (this.name === name)
this.isVisibleWrapper = true
if( (this.name !== name))
this.isVisibleWrapper = false
})
// Open called popup
@@ -49,8 +52,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.popup {
position: absolute;
@@ -138,7 +141,7 @@
@media (prefers-color-scheme: dark) {
.popup-wrapper {
background: $dark_mode_background;
background: $dark_mode_foreground;
box-shadow: $dark_mode_popup_shadow;
}
}
+33 -28
View File
@@ -1,13 +1,13 @@
<template>
<PopupWrapper name="rename-item">
<!--Title-->
<PopupHeader :title="$t('popup_rename.title', {item: itemTypeTitle})" icon="edit"/>
<PopupHeader :title="$t('popup_rename.title', {item: itemTypeTitle})" icon="edit" />
<!--Content-->
<PopupContent>
<!--Item Thumbnail-->
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="metadata" :setFolderIcon="setFolderIcon"/>
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="metadata" :setFolderIcon="folderIcon" />
<!--Form to set sharing-->
<ValidationObserver @submit.prevent="changeName" ref="renameForm" v-slot="{ invalid }" tag="form" class="form-wrapper">
@@ -16,35 +16,36 @@
<ValidationProvider tag="div" mode="passive" class="input-wrapper password" name="Name" rules="required" v-slot="{ errors }">
<label class="input-label">{{ $t('popup_rename.label') }}:</label>
<div class="input">
<input v-model="pickedItem.name" :class="{'is-error': errors[0]}" ref="input" type="text" :placeholder="$t('popup_rename.placeholder')">
<input v-model="pickedItem.name" :class="{'is-error': errors[0]}" ref="input" type="text" class="focus-border-theme" :placeholder="$t('popup_rename.placeholder')">
<div @click="pickedItem.name = ''" class="close-icon-wrapper">
<x-icon class="close-icon" size="14"/>
<x-icon class="close-icon hover-text-theme" size="14" />
</div>
</div>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
<SetFolderIcon v-if="isMoreOptions" :folderData="pickedItem" :unique_id="pickedItem.unique_id" />
<ActionButton v-if="pickedItem.type === 'folder'" @click.native.stop="moreOptions" :icon="isMoreOptions ? 'x' : 'pencil-alt'">{{ moreOptionsTitle }}</ActionButton>
<SetFolderIcon v-if="isMoreOptions" :folderData="pickedItem" />
<ActionButton v-if="pickedItem.type === 'folder'" @click.native.stop="moreOptions" :icon="isMoreOptions ? 'x' : 'pencil-alt'">
{{ moreOptionsTitle }}
</ActionButton>
</ValidationObserver>
</PopupContent>
<!--Actions-->
<PopupActions>
<ButtonBase class="popup-button" @click.native="$closePopup()" button-style="secondary">{{ $t('popup_move_item.cancel') }}
<ButtonBase class="popup-button" @click.native="$closePopup()" button-style="secondary">
{{ $t('popup_move_item.cancel') }}
</ButtonBase>
<ButtonBase class="popup-button" @click.native="changeName" button-style="theme">{{ $t('popup_share_edit.save') }}
<ButtonBase class="popup-button" @click.native="changeName" button-style="theme">
{{ $t('popup_share_edit.save') }}
</ButtonBase>
</PopupActions>
</PopupWrapper>
</template>
<script>
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import PopupWrapper from '@/components/Others/Popup/PopupWrapper'
import PopupActions from '@/components/Others/Popup/PopupActions'
import PopupContent from '@/components/Others/Popup/PopupContent'
@@ -53,10 +54,9 @@ import SetFolderIcon from '@/components/Others/SetFolderIcon'
import ThumbnailItem from '@/components/Others/ThumbnailItem'
import ActionButton from '@/components/Others/ActionButton'
import ButtonBase from '@/components/FilesView/ButtonBase'
import { XIcon } from 'vue-feather-icons'
import { required } from 'vee-validate/dist/rules'
import { events } from '@/bus'
import axios from 'axios'
import {XIcon} from 'vue-feather-icons'
import {required} from 'vee-validate/dist/rules'
import {events} from '@/bus'
export default {
name: 'RenameItem',
@@ -86,7 +86,7 @@ export default {
return {
pickedItem: undefined,
isMoreOptions: false,
setFolderIcon: undefined
folderIcon: undefined
}
},
methods: {
@@ -97,12 +97,17 @@ export default {
if (this.pickedItem.name && this.pickedItem.name !== '') {
let item = {
unique_id: this.pickedItem.unique_id,
id: this.pickedItem.id,
type: this.pickedItem.type,
name: this.pickedItem.name,
folder_icon: this.setFolderIcon ? this.setFolderIcon : null
}
if (this.folderIcon && this.folderIcon.emoji)
item['emoji'] = this.folderIcon.emoji
if (this.folderIcon && this.folderIcon.color)
item['color'] = this.folderIcon.color
// Rename item request
this.$store.dispatch('renameItem', item)
@@ -120,28 +125,28 @@ export default {
if (args.name !== 'rename-item') return
if (! this.$isMobile()) {
if (!this.$isMobile()) {
this.$nextTick(() => this.$refs.input.focus())
}
this.isMoreOptions = false
this.setFolderIcon = undefined
this.folderIcon = undefined
// Store picked item
this.pickedItem = args.item
})
events.$on('setFolderIcon', (icon) => {
this.setFolderIcon = icon.value
this.folderIcon = icon
})
}
}
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.input {
position: relative;
@@ -163,14 +168,14 @@ export default {
&:hover {
.close-icon {
line {
stroke: $theme;
color: inherit;
}
}
}
.close-icon {
line {
stroke: rgba($text-muted, 0.3);
color: rgba($text-muted, 0.3);
}
}
}
@@ -186,14 +191,14 @@ export default {
.close-icon {
line {
stroke: $theme !important;
color: inherit !important;
}
}
}
.close-icon {
line {
stroke: rgba($dark_mode_text_primary, 0.3) !important;
color: rgba($dark_mode_text_primary, 0.3) !important;
}
}
}
@@ -11,8 +11,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.text-label {
@include font-size(12);
+51 -547
View File
@@ -1,595 +1,99 @@
<template>
<TabWrapper class="set-folder-icon">
<!-- Emojis -->
<TabOption :selected="true" id="emoji-list" :title="$t('popup_rename.tab_emoji_title')" icon="emoji">
<div class="select-emoji-wrapper">
<label class="main-label">{{ $t('popup_rename.select_emoji_label') }}:</label>
<!-- Selected Emoji input -->
<div @click.stop="openMenu" class="select-input-wrapper" :class="{'active-menu' : selectOpen}">
<!-- If is emoji selected -->
<div class="select-input" v-if="selectedEmoji">
<div @click.stop="resetEmoji" class="select-input-icon-wrapper">
<x-icon size="14" class="select-input-icon"/>
</div>
<Emoji class="emoji-preview" :emoji="selectedEmoji" location="emoji-picker-preview" />
<span>{{ selectedEmoji.name }}</span>
</div>
<!-- If is emoji not selected -->
<div class="not-selected" v-if="! selectedEmoji">
<span> {{ $t('popup_rename.set_emoji_input_placeholder') }}</span>
</div>
<chevron-down-icon class="row-icon" size="19"/>
</div>
<!-- Emojis List -->
<transition name="slide-in">
<div v-if="selectOpen">
<!-- Spinner -->
<div v-if="!loadedList" class="emoji-wrapper">
<Spinner/>
</div>
<!-- List -->
<div v-if="loadedList && emojis" class="emoji-wrapper">
<!-- Search input -->
<input @click.stop @input="filterEmojis" v-model="searchInput" class="emoji-input" :placeholder="$t('popup_rename.search_emoji_input_placeholder')">
<!-- Navigation of Emojis Groups -->
<ul v-show="searchInput.length < 1" class="groups-list">
<li @click.stop="scrollToGroup(group.name)" v-for="(group,i) in emojis.emojisGroups" :key="i" class="group-option" :class="{'active' : group.name === groupInView}">
<Emoji :emoji="group.emoji" location="emoji-picker" />
</li>
</ul>
<!-- All Emojis -->
<div v-show="searchInput.length < 1" @scroll="checkGroupInView" id="group-box" class="group-wrapper">
<div v-for="(group, name) in allEmoji" :key="name" class="options-wrapper" :id="`group-${name}`">
<label class="group-name-label">{{ name }}</label>
<ul class="options-list">
<li @click="setIcon({'emoji':emoji})" v-for="(emoji,i) in group" :key="i" class="option">
<Emoji :emoji="emoji" location="emoji-picker" />
</li>
</ul>
</div>
</div>
<!-- Searched emojis -->
<div v-if="searchInput.length > 0" class="group-wrapper">
<div class="options-wrapper">
<ul class="options-list">
<li @click="setIcon({'emoji':emoji})" v-for="(emoji,i) in filteredEmojis" :key="i" class="option">
<Emoji :emoji="emoji" location="emoji-picker" />
</li>
</ul>
<span class="not-found" v-if="filteredEmojis.length === 0"> {{ $t('popup_rename.emoji_list_not_found') }}</span>
</div>
</div>
</div>
</div>
</transition>
</div>
<!-- Emojis Picker -->
<TabOption :selected="true" :title="$t('popup_rename.tab_emoji_title')" icon="emoji">
<EmojiPicker :picked-emoji="pickedEmoji" v-model="selectedEmoji" />
</TabOption>
<!-- Colors -->
<!-- Colors Picker-->
<TabOption :title="$t('popup_rename.tab_color_title')" icon="folder">
<div class="color-pick-wrapper">
<label class="main-label">{{ $t('popup_rename.color_pick_label') }}:</label>
<ul class="color-wrapper">
<li v-for="(color, i) in colors" :key="i" @click="setIcon({'color': color})" class="single-color">
<check-icon v-if="color === selectedColor" class="color-icon" size="22"/>
<span :style="{background:color}" class="color-box"></span>
</li>
</ul>
</div>
<ColorPicker :picked-color="pickedColor" v-model="selectedColor" />
</TabOption>
</TabWrapper>
</template>
<script>
import { SmileIcon, FolderIcon, ChevronDownIcon, XIcon, CheckIcon } from 'vue-feather-icons'
import EmojiPicker from '@/components/Others/EmojiPicker'
import ColorPicker from '@/components/Others/ColorPicker'
import TabWrapper from '@/components/Others/TabWrapper'
import TabOption from '@/components/Others/TabOption'
import Spinner from '@/components/FilesView/Spinner'
import Emoji from '@/components/Others/Emoji'
import { groupBy } from 'lodash'
import { mapGetters } from 'vuex'
import { events } from '@/bus'
import {events} from '@/bus'
export default {
name: 'SetFolderIcon',
props: ['folderData', 'unique_id'],
props: ['folderData'],
components: {
ChevronDownIcon,
EmojiPicker,
ColorPicker,
TabWrapper,
FolderIcon,
SmileIcon,
CheckIcon,
TabOption,
Spinner,
XIcon,
Emoji
},
computed: {
...mapGetters(['emojis']),
allEmoji() {
return groupBy(this.emojis.emojisList, 'group')
pickedEmoji() {
// If is color not selected and emoji is selected, push picked emoji to EmojiPicker for the EmojiSelected input
return !this.selectedColor && this.selectedEmoji ? this.selectedEmoji : undefined
},
pickedColor() {
// If is emoji not selected and color is selected, push picked color to ColorPicker
return !this.selectedEmoji && this.selectedColor ? this.selectedColor : undefined
}
},
data() {
return {
selectedEmoji: undefined,
selectedColor: undefined,
searchInput: '',
filteredEmojis: [],
selectOpen: false,
loadedList: false,
groupInView: 'Smileys & Emotion',
colors: [
'#41B883',
'#FE6F6F',
'#FE6F91',
'#FE6FC0',
'#FE6FF0',
'#DD6FFE',
'#AD6FFE',
'#7D6FFE',
'#6F90FE',
'#6FC0FE',
'#6FF0FE',
'#6FFEDD',
'#6FFEAD',
'#6FFE7D',
'#90FE6F',
'#C0FE6F',
'#F0FE6F',
'#FEDD6F',
'#FEAD6F',
'#FE7D6F',
'#4c4c4c',
'#06070B',
]
selectedEmoji: undefined,
}
},
methods: {
checkGroupInView: _.debounce(function() {
watch: {
selectedColor() {
let color = {'color': this.selectedColor}
this.emojis.emojisGroups.forEach(group => {
if (this.selectedColor) {
let element = document.getElementById(`group-${group.name}`).getBoundingClientRect()
let groupBox = document.getElementById('group-box').getBoundingClientRect()
// Check if the group is in the viewport of group-box
if (element.top < groupBox.top && element.bottom > groupBox.top) {
this.groupInView = group.name
}
})
}, 200),
scrollToGroup(name) {
let group = document.getElementById(`group-${name}`)
group.scrollIntoView({ behavior: 'smooth' })
this.groupInView = name
},
filterEmojis: _.debounce(function(emoji) {
this.filteredEmojis = this.emojis.emojisList.filter(emoji => emoji.name.includes(this.searchInput))
}, 800),
openMenu() {
this.selectOpen = !this.selectOpen
//Load emojis
if (this.selectOpen) {
this.$store.dispatch('getEmojisList').then((loaded) => {
this.loadedList = loaded
})
}
if (!this.selectOpen)
this.loadedList = false
this.searchInput = ''
this.groupInView = 'Smileys & Emotion'
},
setIcon(value) {
// Set emoji
if (value.emoji) {
this.selectedEmoji = value.emoji
this.selectedColor = undefined
}
// Set color
if (value.color) {
this.selectedColor = value.color
this.selectedEmoji = undefined
events.$emit('setFolderIcon', color)
}
events.$emit('setFolderIcon', { 'value': value })
this.selectOpen = false
},
resetEmoji() {
selectedEmoji() {
this.selectedEmoji = undefined
let emoji = {'emoji': this.selectedEmoji}
events.$emit('setFolderIcon', { 'value': 'default' })
if (this.selectedEmoji) {
this.selectedColor = undefined
events.$emit('setFolderIcon', this.selectedEmoji === 'default' ? 'default' : emoji)
}
},
},
created() {
if (this.folderData) {
// If folder have already set some color set this color to selected color
this.folderData.color ? this.selectedColor = this.folderData.color : ''
// If folder have already set some emojit set this emoji to selected emoji
this.folderData.emoji ? this.selectedEmoji = this.folderData.emoji : ''
}
},
mounted() {
destroyed() {
if (this.folderData) {
this.selectOpen = false
// After close SetFolderIcon set the saved folder icon for thumbnail
let color = {'color': this.folderData.color}
let emoji = {'emoji': this.folderData.emoji}
// If folder have already set some emoji set this emoji to selected emoji
this.folderData.icon_emoji ? this.selectedEmoji = this.folderData.icon_emoji : ''
// If folder have already set some color set this color to selected color
this.folderData.icon_color ? this.selectedColor = this.folderData.icon_color : ''
events.$on('unClick', () => {
this.selectOpen = false
this.loadedList = false
})
events.$emit('setFolderIcon', this.folderData.emoji ? emoji : color)
}
}
}
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
.color-pick-wrapper {
.color-wrapper {
margin-bottom: 20px;
display: grid;
grid-template-columns: repeat(auto-fill, 32px);
justify-content: space-between;
gap: 7px;
.single-color {
height: 31px;
list-style: none;
border-radius: 8px;
cursor: pointer;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
.color-icon {
z-index: 2;
polyline {
stroke: white;
}
}
.color-box {
width: 100%;
height: 100%;
position: absolute;
display: block;
}
}
}
}
.select-emoji-wrapper {
margin-bottom: 20px;
}
.main-label {
@include font-size(14);
font-weight: 700;
margin-bottom: 8px;
display: block;
}
.emoji-wrapper {
height: 400px;
width: 100%;
position: absolute;
border: 1px solid transparent;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
border-radius: 8px;
background: white;
display: flex;
flex-direction: column;
padding: 10px;
z-index: 10;
top: 152px;
.groups-list {
display: grid;
grid-template-columns: repeat(9, auto);
justify-content: space-between;
overflow-x: auto;
overflow-y: hidden;
height: 90px;
.active {
background: $light_background;
border-radius: 8px;
}
.group-option {
width: 45px;
height: 45px;
list-style: none;
padding: 6px;
cursor: pointer;
&:hover {
background: $light_background;
border-radius: 8px;
}
}
}
.emoji-input {
width: 100%;
border-radius: 8px;
padding: 4px;
margin-bottom: 20px;
background: $light_background;
border: none;
padding: 13px 20px;
font-weight: 700;
&::placeholder {
font-weight: 700;
color: $light_text;
}
}
.group-wrapper {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
overflow-y: scroll;
padding: 0px;
.options-wrapper {
display: flex;
flex-wrap: wrap;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0px;
}
.options-list {
display: grid;
grid-template-columns: repeat(auto-fill, 45px);
justify-content: space-between;
width: 100%;
}
.group-name-label {
width: 100%;
@include font-size(14);
font-weight: 700;
margin-bottom: 10px;
}
.option {
list-style: none;
width: 45px;
height: 45px;
padding: 6px;
cursor: pointer;
&:hover {
background: $light_background;
border-radius: 8px;
}
}
.not-found {
align-self: center;
margin: auto;
font-weight: 700;
padding: 10px;
border-radius: 8px;
background: $light_background;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
}
}
}
}
.select-input-wrapper {
height: 50px;
padding: 13px 20px;
border: 1px solid transparent;
border-radius: 8px;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid transparent;
@include transition(150ms);
.row-icon {
@include transition(150ms);
}
&.active-menu {
border-color: $theme;
box-shadow: 0 0 7px rgba($theme, 0.3);
.row-icon {
transform: rotate(180deg);
}
}
.select-input {
@include font-size(16);
font-weight: 700;
display: flex;
flex-direction: row;
align-items: center;
.emoji-preview {
margin-left: 5px;
margin-right: 10px;
width: 22px;
height: 22px;
}
.select-input-icon-wrapper {
width: 22px;
height: 22px;
border-radius: 6px;
display: flex;
justify-content: center;
align-items: center;
margin-left: -7px;
&:hover {
.select-input-icon {
line {
stroke: $theme;
}
}
}
.select-input-icon {
line {
stroke: $text;
}
}
}
}
.not-selected {
span {
color: rgba($text, 0.5);
@include font-size(15);
font-weight: 700
}
}
}
<style lang="scss" scoped>
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.set-folder-icon {
position: relative;
}
.slide-in-enter-active {
transition: all 150ms ease;
}
.slide-in-enter {
opacity: 0;
transform: translateY(-210px);
}
.slide-in-enter-to {
transform: translateY(-134px);
}
@media (max-width: 690px) {
.emoji-wrapper {
height: 300px;
}
}
@media (max-width: 336px) {
.emoji-wrapper {
top: 173px;
}
}
@media (prefers-color-scheme: dark) {
.color-pick-wrapper {
.color-wrapper {
.single-color {
&.active-color {
border: 2px solid;
}
&:hover {
border: 2px solid $dark_mode_text_primary;
}
}
}
}
.emoji-wrapper {
background: $dark_mode_background;
.emoji-input {
background: $dark_mode_foreground;
}
.groups-list {
.active {
background: $dark_mode_foreground !important;
}
.group-option {
&:hover {
background: $dark_mode_foreground !important;
}
}
}
.options-wrapper {
.option {
&:hover {
background: $dark_mode_foreground !important;
}
}
.not-found {
background: $dark_mode_foreground !important;
}
}
}
.select-input-wrapper {
background: $dark_mode_foreground;
.not-selected {
span {
color: $dark_mode_text_secondary;
}
}
.select-input-icon-wrapper {
&:hover {
.select-input-icon {
line {
stroke: $theme !important;
}
}
}
.select-input-icon {
line {
stroke: $dark_mode_text_primary !important;
}
}
}
}
}
</style>
+31 -25
View File
@@ -1,15 +1,15 @@
<template>
<PopupWrapper name="share-create">
<!--Title-->
<PopupHeader :title="$t('popup_share_create.title', {item: itemTypeTitle})" icon="share"/>
<PopupHeader :title="$t('popup_share_create.title', {item: itemTypeTitle})" icon="share" />
<!--Content-->
<PopupContent>
<!--Item Thumbnail-->
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="metadata"/>
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="metadata" />
<!-- Infobox for successfull sended email -->
<!-- Infobox for successful send email -->
<InfoBox v-if="isGeneratedShared && sharedViaEmail" class="info-box-wrapper">
<p v-html="$t('shared_form.email_successfully_send_message')"></p>
</InfoBox>
@@ -20,21 +20,21 @@
<TabWrapper>
<!-- Share via link -->
<TabOption :selected="true" :title="$t('shared_form.share_by_link')" icon="link"/>
<TabOption :selected="true" :title="$t('shared_form.share_by_link')" icon="link" />
<!-- Share via Email -->
<TabOption :title="$t('shared_form.share_by_email')" icon="email">
<ValidationProvider tag="div" mode="passive" name="Email" rules="required" v-slot="{ errors }">
<MultiEmailInput rules="required" v-model="shareOptions.emails" :label="$t('shared_form.recipients_label')" :isError="errors[0]"/>
<MultiEmailInput rules="required" v-model="shareOptions.emails" :label="$t('shared_form.recipients_label')" :isError="errors[0]" />
</ValidationProvider>
</TabOption>
</TabWrapper>
<!--Permision Select-->
<!--Permission Select-->
<ValidationProvider v-if="isFolder" tag="div" mode="passive" class="input-wrapper" name="Permission" rules="required" v-slot="{ errors }">
<label class="input-label">{{ $t('shared_form.label_permission') }}:</label>
<SelectInput v-model="shareOptions.permission" :options="permissionOptions" :placeholder="$t('shared_form.placeholder_permission')" :isError="errors[0]"/>
<SelectInput v-model="shareOptions.permission" :options="$translateSelectOptions(permissionOptions)" :placeholder="$t('shared_form.placeholder_permission')" :isError="errors[0]" />
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
@@ -42,13 +42,13 @@
<div class="input-wrapper">
<div class="inline-wrapper">
<label class="input-label">{{ $t('shared_form.label_password_protection') }}:</label>
<SwitchInput v-model="shareOptions.isPassword" class="switch" :state="0"/>
<SwitchInput v-model="shareOptions.isPassword" class="switch" :state="0" />
</div>
</div>
<!--Set password-->
<ValidationProvider v-if="shareOptions.isPassword" tag="div" mode="passive" class="input-wrapper password" name="Password" rules="required" v-slot="{ errors }">
<input v-model="shareOptions.password" :class="{'is-error': errors[0]}" type="text" :placeholder="$t('page_sign_in.placeholder_password')">
<input v-model="shareOptions.password" :class="{'is-error': errors[0]}" type="text" class="focus-border-theme" :placeholder="$t('page_sign_in.placeholder_password')">
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
@@ -58,34 +58,38 @@
<!--Set expiration-->
<div class="input-wrapper">
<label class="input-label">{{ $t('shared_form.label_expiration') }}:</label>
<SelectBoxInput v-model="shareOptions.expiration" :data="expirationList" class="box"/>
<SelectBoxInput v-model="shareOptions.expiration" :data="$translateSelectOptions(expirationList)" class="box" />
</div>
</div>
<ActionButton @click.native="moreOptions" :icon="isMoreOptions ? 'x' : 'pencil-alt'">{{ moreOptionsTitle }}</ActionButton>
<ActionButton @click.native="moreOptions" :icon="isMoreOptions ? 'x' : 'pencil-alt'">
{{ moreOptionsTitle }}
</ActionButton>
</ValidationObserver>
<!--Copy generated link-->
<div v-if="isGeneratedShared" class="form-wrapper">
<div class="input-wrapper">
<label class="input-label">{{ this.sharedViaEmail ? $t('shared_form.label_share_vie_email') : $t('shared_form.label_shared_url') }}:</label>
<CopyInput size="small" :item="pickedItem"/>
<CopyInput size="small" :item="pickedItem" />
</div>
</div>
</PopupContent>
<!--Actions-->
<PopupActions>
<ButtonBase v-if="! isGeneratedShared" class="popup-button" @click.native="$closePopup()" button-style="secondary">{{ $t('popup_move_item.cancel') }}
<ButtonBase v-if="! isGeneratedShared" class="popup-button" @click.native="$closePopup()" button-style="secondary">
{{ $t('popup_move_item.cancel') }}
</ButtonBase>
<ButtonBase class="popup-button" @click.native="submitShareOptions" button-style="theme" :loading="isLoading" :disabled="isLoading">{{ submitButtonText }}
<ButtonBase class="popup-button" @click.native="submitShareOptions" button-style="theme" :loading="isLoading" :disabled="isLoading">
{{ submitButtonText }}
</ButtonBase>
</PopupActions>
</PopupWrapper>
</template>
<script>
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import SelectBoxInput from '@/components/Others/Forms/SelectBoxInput'
import PopupWrapper from '@/components/Others/Popup/PopupWrapper'
import PopupActions from '@/components/Others/Popup/PopupActions'
@@ -101,10 +105,10 @@ import TabWrapper from '@/components/Others/TabWrapper'
import TabOption from '@/components/Others/TabOption'
import ButtonBase from '@/components/FilesView/ButtonBase'
import InfoBox from '@/components/Others/Forms/InfoBox'
import { LinkIcon, MailIcon } from 'vue-feather-icons'
import { required } from 'vee-validate/dist/rules'
import { mapGetters } from 'vuex'
import { events } from '@/bus'
import {LinkIcon, MailIcon} from 'vue-feather-icons'
import {required} from 'vee-validate/dist/rules'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
import axios from 'axios'
export default {
@@ -157,7 +161,7 @@ export default {
password: undefined,
permission: undefined,
type: undefined,
unique_id: undefined,
id: undefined,
emails: undefined
},
pickedItem: undefined,
@@ -192,7 +196,9 @@ export default {
// Send request to get share link
axios
.post('/api/share', this.shareOptions)
.post(`/api/share/${this.shareOptions.id}`,
this.shareOptions
)
.then(response => {
// Show infobox and reset emails container
@@ -231,7 +237,7 @@ export default {
this.pickedItem = args.item
this.shareOptions.type = args.item.type
this.shareOptions.unique_id = args.item.unique_id
this.shareOptions.id = args.item.id
})
// Close popup
@@ -245,7 +251,7 @@ export default {
isPassword: false,
expiration: undefined,
type: undefined,
unique_id: undefined,
id: undefined,
emails: undefined
}
this.isGeneratedShared = false
@@ -258,8 +264,8 @@ export default {
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.more-options {
margin-bottom: 10px;
+14 -10
View File
@@ -33,7 +33,7 @@
<!--Permision Select-->
<ValidationProvider v-if="isFolder" tag="div" mode="passive" class="input-wrapper" name="Permission" rules="required" v-slot="{ errors }">
<label class="input-label">{{ $t('shared_form.label_permission') }}:</label>
<SelectInput v-model="shareOptions.permission" :options="permissionOptions" :default="shareOptions.permission" :placeholder="$t('shared_form.placeholder_permission')" :isError="errors[0]"/>
<SelectInput v-model="shareOptions.permission" :options="$translateSelectOptions(permissionOptions)" :default="shareOptions.permission" :placeholder="$t('shared_form.placeholder_permission')" :isError="errors[0]"/>
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
@@ -43,12 +43,14 @@
<label class="input-label">{{ $t('shared_form.label_password_protection') }}:</label>
<SwitchInput v-model="shareOptions.isProtected" :state="shareOptions.isProtected" class="switch"/>
</div>
<ActionButton v-if="(pickedItem.shared.protected && canChangePassword) && shareOptions.isProtected" @click.native="changePassword" class="change-password">{{ $t('popup_share_edit.change_pass') }}</ActionButton>
<ActionButton v-if="(pickedItem.shared.is_protected && canChangePassword) && shareOptions.isProtected" @click.native="changePassword" class="change-password">
{{ $t('popup_share_edit.change_pass') }}
</ActionButton>
</div>
<!--Set password-->
<ValidationProvider v-if="shareOptions.isProtected && ! canChangePassword" tag="div" mode="passive" class="input-wrapper password" name="Password" rules="required" v-slot="{ errors }">
<input v-model="shareOptions.password" :class="{'is-error': errors[0]}" type="text" :placeholder="$t('page_sign_in.placeholder_password')">
<input v-model="shareOptions.password" :class="{'is-error': errors[0]}" type="text" class="focus-border-theme" :placeholder="$t('page_sign_in.placeholder_password')">
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
</ValidationProvider>
@@ -58,11 +60,13 @@
<!--Set expiration-->
<div class="input-wrapper">
<label class="input-label">{{ $t('shared_form.label_expiration') }}:</label>
<SelectBoxInput v-model="shareOptions.expiration" :data="expirationList" :value="shareOptions.expiration" class="box"/>
<SelectBoxInput v-model="shareOptions.expiration" :data="$translateSelectOptions(expirationList)" :value="shareOptions.expiration" class="box"/>
</div>
</div>
<ActionButton @click.native="moreOptions" :icon="isMoreOptions || shareOptions.expiration ? 'x' : 'pencil-alt'">{{ moreOptionsTitle }}</ActionButton>
<ActionButton @click.native="moreOptions" :icon="isMoreOptions || shareOptions.expiration ? 'x' : 'pencil-alt'">
{{ moreOptionsTitle }}
</ActionButton>
</ValidationObserver>
@@ -235,7 +239,6 @@
this.isDeleting = true
// Send delete request
await this.$store.dispatch('shareCancel' , this.pickedItem)
.then((response) => {
@@ -323,7 +326,7 @@
this.shareOptions = {
token: args.item.shared.token,
expiration: args.item.shared.expire_in,
isProtected: args.item.shared.protected,
isProtected: args.item.shared.is_protected,
permission: args.item.shared.permission,
password: undefined,
}
@@ -333,8 +336,9 @@
if (args.sentToEmail)
this.sendToRecipientsMenu = true
this.isEmailSended = false
this.canChangePassword = args.item.shared.protected
this.canChangePassword = args.item.shared.is_protected
})
// Close popup
@@ -355,8 +359,8 @@
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.input-wrapper {
@@ -38,8 +38,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.detail-storage-item {
margin-bottom: 35px;
+18 -10
View File
@@ -4,13 +4,15 @@
<div class="tab" :class="{ active: tab.isActive }" @click="selectTab(tab)" v-for="(tab, i) in tabs" :key="i">
<!--Icon-->
<mail-icon v-if="tab.icon === 'email'" class="tab-icon" size="17"/>
<link-icon v-if="tab.icon === 'link'" class="tab-icon" size="17"/>
<smile-icon v-if="tab.icon === 'emoji'" class="tab-icon" size="17"/>
<folder-icon v-if="tab.icon === 'folder'" class="tab-icon" size="17"/>
<mail-icon v-if="tab.icon === 'email'" class="tab-icon text-theme" size="17"/>
<link-icon v-if="tab.icon === 'link'" class="tab-icon text-theme" size="17"/>
<smile-icon v-if="tab.icon === 'emoji'" class="tab-icon text-theme" size="17"/>
<folder-icon v-if="tab.icon === 'folder'" class="tab-icon text-theme" size="17"/>
<!--Title-->
<b class="tab-title">{{tab.title}}</b>
<b class="tab-title">
{{tab.title}}
</b>
</div>
</div>
<slot></slot>
@@ -52,8 +54,8 @@
</script>
<style scoped lang="scss">
@import "@assets/vue-file-manager/_inapp-forms.scss";
@import '@assets/vue-file-manager/_forms';
@import "@assets/vuefilemanager/_inapp-forms.scss";
@import '@assets/vuefilemanager/_forms';
.tab-wrapper {
display: flex;
@@ -94,7 +96,7 @@
circle,
line,
polyline {
stroke: $theme !important;
color: inherit !important;
}
}
}
@@ -106,13 +108,19 @@
border-color: transparent;
.tab.active {
background: rgba($theme, 0.1);
background: lighten($dark_mode_foreground, 7%);
.tab-title {
color: $theme;
color: $dark_mode_text_primary;
}
}
}
.popup-wrapper {
.tab-wrapper {
background: lighten($dark_mode_foreground, 2%);
}
}
}
</style>
@@ -26,8 +26,8 @@
</script>
<style lang="scss" scoped>
@import '@assets/vue-file-manager/_variables';
@import '@assets/vue-file-manager/_mixins';
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.table-row {
border-radius: 8px;

Some files were not shown because too many files have changed in this diff Show More