mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-18 08:12:15 +00:00
Merge remote-tracking branch 'origin/version-v1.8.1'
# Conflicts: # config/vuefilemanager.php # public/chunks/admin-account.js # public/chunks/admin.js # public/chunks/app-appearance.js # public/chunks/app-billings.js # public/chunks/app-email.js # public/chunks/app-index.js # public/chunks/app-others.js # public/chunks/app-payments.js # public/chunks/app-settings.js # public/chunks/app-setup.js # public/chunks/billings-detail.js # public/chunks/contact-us.js # public/chunks/dashboard.js # public/chunks/database.js # public/chunks/environment-setup.js # public/chunks/files.js # public/chunks/files~chunks/shared-files~chunks/shared-page.js # public/chunks/installation-disclaimer.js # public/chunks/invoices.js # public/chunks/landing-page.js # public/chunks/pages.js # public/chunks/plan-create.js # public/chunks/plan-delete.js # public/chunks/plan-settings.js # public/chunks/plan-subscribers.js # public/chunks/plan.js # public/chunks/plans.js # public/chunks/profile.js # public/chunks/purchase-code.js # public/chunks/settings-create-payment-methods.js # public/chunks/settings-invoices.js # public/chunks/settings-payment-methods.js # public/chunks/settings-storage.js # public/chunks/settings-subscription.js # public/chunks/settings.js # public/chunks/shared-files.js # public/chunks/shared-page.js # public/chunks/sign-up.js # public/chunks/stripe-credentials.js # public/chunks/subscription-plans.js # public/chunks/subscription-service.js # public/chunks/upgrade-billing.js # public/chunks/upgrade.js # public/chunks/user-create.js # public/chunks/user-delete.js # public/chunks/user-detail.js # public/chunks/user-invoices.js # public/chunks/user-password.js # public/chunks/user-storage.js # public/chunks/user-subscription.js # public/chunks/user.js # public/chunks/users.js # public/js/main.js # public/mix-manifest.json # resources/js/views/FilePages/Files.vue
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
<!--Mobile Navigation-->
|
||||
<MobileNavigation/>
|
||||
|
||||
<!-- Processing popup for zip -->
|
||||
<ProcessingPopup/>
|
||||
|
||||
<!--Confirm Popup-->
|
||||
@@ -58,7 +59,6 @@
|
||||
|
||||
<CookieDisclaimer/>
|
||||
|
||||
<!--Background vignette-->
|
||||
<Vignette/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<!-- Single options -->
|
||||
<OptionGroup v-if="multiSelectContextMenu">
|
||||
<Option @click.native="restoreItem" v-if="item" :title="$t('context_menu.restore')" icon="restore"/>
|
||||
<Option @click.native="deleteItem" :title="$t('context_menu.delete')" icon="trash"/>
|
||||
<Option @click.native="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>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
<!-- 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>
|
||||
@@ -62,6 +63,7 @@
|
||||
<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>
|
||||
|
||||
<!-- Multi options -->
|
||||
@@ -83,13 +85,15 @@
|
||||
|
||||
<!-- Base location with MASTER permission-->
|
||||
<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>
|
||||
|
||||
<!-- Single options -->
|
||||
<OptionGroup v-if="!$isThisLocation(['participant_uploads', 'latest']) && multiSelectContextMenu">
|
||||
<Option @click.native="addToFavourites" v-if="item && isFolder " :title="isInFavourites
|
||||
? $t('context_menu.remove_from_favourites')
|
||||
: $t('context_menu.add_to_favourites')" icon="favourites"/>
|
||||
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
|
||||
<OptionGroup 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>
|
||||
|
||||
|
||||
@@ -106,6 +110,7 @@
|
||||
<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>
|
||||
|
||||
<!-- Multi options -->
|
||||
@@ -113,7 +118,6 @@
|
||||
<Option @click.native="addToFavourites" v-if="item && !hasFile" :title=" isInFavourites
|
||||
? $t('context_menu.remove_from_favourites')
|
||||
: $t('context_menu.add_to_favourites')" icon="favourites"/>
|
||||
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
|
||||
</OptionGroup>
|
||||
|
||||
<OptionGroup v-if="item && !multiSelectContextMenu">
|
||||
@@ -129,11 +133,13 @@
|
||||
<!-- Base & Public location with EDITOR permission-->
|
||||
<div v-if="$isThisLocation(['base', 'public']) && $checkPermission('editor') && !showFromPreview " id="menu-list" class="menu-options">
|
||||
|
||||
<!-- Single options -->
|
||||
<OptionGroup v-if="multiSelectContextMenu">
|
||||
<!-- No Files options -->
|
||||
<OptionGroup v-if="multiSelectContextMenu && !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"/>
|
||||
@@ -143,12 +149,10 @@
|
||||
<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>
|
||||
|
||||
<!-- Multi options -->
|
||||
<OptionGroup v-if="!multiSelectContextMenu">
|
||||
<Option @click.native="createFolder" :title="$t('context_menu.create_folder')" icon="create-folder"/>
|
||||
</OptionGroup>
|
||||
|
||||
<OptionGroup v-if="item && !multiSelectContextMenu">
|
||||
<Option @click.native="moveItem" :title="$t('context_menu.move')" icon="move-item"/>
|
||||
@@ -167,6 +171,7 @@
|
||||
<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>
|
||||
|
||||
<!-- Multi options -->
|
||||
@@ -250,11 +255,21 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
downloadFolder(){
|
||||
this.$store.dispatch('downloadFolder' , this.item)
|
||||
},
|
||||
emptyTrash() {
|
||||
this.$store.dispatch('emptyTrash')
|
||||
},
|
||||
restoreItem() {
|
||||
this.$store.dispatch('restoreItem', this.item)
|
||||
|
||||
// If is item not in selected items restore just this single 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))
|
||||
this.$store.dispatch('restoreItem', null)
|
||||
},
|
||||
shareCancel() {
|
||||
this.$store.dispatch('shareCancel')
|
||||
|
||||
@@ -25,22 +25,22 @@
|
||||
<SearchBar/>
|
||||
</div>
|
||||
|
||||
<!--Files controlls-->
|
||||
<!--Creating controls-->
|
||||
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor'])">
|
||||
<ToolbarButtonUpload :class="{ 'is-inactive': canUploadInView || !hasCapacity }" :action="$t('actions.upload')"/>
|
||||
<ToolbarButton :class="{ 'is-inactive': canCreateFolderInView }" @click.native="createFolder" source="folder-plus" :action="$t('actions.create_folder')"/>
|
||||
</div>
|
||||
|
||||
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor'])">
|
||||
<!--File Controls-->
|
||||
<div class="toolbar-button-wrapper" v-if="$checkPermission(['master', 'editor']) && ! $isMobile()">
|
||||
<ToolbarButton source="move" :class="{ 'is-inactive': canMoveInView }" :action="$t('actions.move')" @click.native="moveItem"/>
|
||||
<ToolbarButton v-if="!$isThisLocation(['public'])" source="share" :class="{ 'is-inactive': canShareInView }" :action="$t('actions.share')" @click.native="shareItem"/>
|
||||
<ToolbarButton source="trash" :class="{ 'is-inactive': canDeleteInView }" :action="$t('actions.delete')" @click.native="deleteItem"/>
|
||||
</div>
|
||||
|
||||
<!--View options-->
|
||||
<!--View Controls-->
|
||||
<div class="toolbar-button-wrapper">
|
||||
<ToolbarButton source="preview-sorting" class="preview-sorting" :action="$t('actions.sorting_view')" :class="{ active: sortingAndPreview }" @click.stop.native="sortingAndPreview = !sortingAndPreview"/>
|
||||
|
||||
<ToolbarButton :action="$t('actions.info_panel')" :class="{ active: fileInfoVisible }" @click.native="$store.dispatch('fileInfoToggle')" source="info"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -103,7 +103,7 @@ export default {
|
||||
return !this.$isThisLocation(['base', 'public'])
|
||||
},
|
||||
canDeleteInView() {
|
||||
return !this.$isThisLocation([
|
||||
let locations = [
|
||||
'trash',
|
||||
'trash-root',
|
||||
'base',
|
||||
@@ -111,19 +111,22 @@ export default {
|
||||
'latest',
|
||||
'shared',
|
||||
'public'
|
||||
])
|
||||
]
|
||||
return !this.$isThisLocation(locations) || this.fileInfoDetail.length === 0
|
||||
},
|
||||
canUploadInView() {
|
||||
return !this.$isThisLocation(['base', 'public'])
|
||||
},
|
||||
canMoveInView() {
|
||||
return !this.$isThisLocation([
|
||||
let locations = [
|
||||
'base',
|
||||
'participant_uploads',
|
||||
'latest',
|
||||
'shared',
|
||||
'public'
|
||||
])
|
||||
]
|
||||
return !this.$isThisLocation(locations) || this.fileInfoDetail.length === 0
|
||||
|
||||
},
|
||||
canShareInView() {
|
||||
let locations = [
|
||||
@@ -134,7 +137,7 @@ export default {
|
||||
'public'
|
||||
]
|
||||
|
||||
return !this.$isThisLocation(locations) || this.fileInfoDetail.length > 1
|
||||
return !this.$isThisLocation(locations) || this.fileInfoDetail.length > 1 || this.fileInfoDetail.length === 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
||||
@@ -1,72 +1,77 @@
|
||||
<template>
|
||||
<MultiSelected :title="title" :subtitle="subtitle" id="multi-select-ui" v-show="dragged" />
|
||||
<MultiSelected :title="title" :subtitle="subtitle" id="multi-select-ui" v-show="isVisible"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MultiSelected from '@/components/FilesView/MultiSelected'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { events } from '@/bus'
|
||||
|
||||
export default {
|
||||
name:"DragUI",
|
||||
components: {MultiSelected},
|
||||
computed: {
|
||||
...mapGetters(['fileInfoDetail']),
|
||||
title(){
|
||||
export default {
|
||||
name: 'DragUI',
|
||||
components: { MultiSelected },
|
||||
computed: {
|
||||
...mapGetters(['fileInfoDetail']),
|
||||
title() {
|
||||
let filesLength = this.fileInfoDetail.length,
|
||||
hasDraggedItem = this.fileInfoDetail.includes(this.draggedItem)
|
||||
|
||||
// Title for multiple selected items
|
||||
if(this.fileInfoDetail.length > 1 && this.fileInfoDetail.includes(this.draggedItem)) {
|
||||
return this.$t('file_detail.selected_multiple')
|
||||
}
|
||||
// Title for multiple selected items
|
||||
if (filesLength > 1 && hasDraggedItem) {
|
||||
return this.$t('file_detail.selected_multiple')
|
||||
}
|
||||
|
||||
// Title for single item
|
||||
if((this.fileInfoDetail.length < 2 || !this.fileInfoDetail.includes(this.draggedItem)) && this.draggedItem ) {
|
||||
return this.draggedItem.name
|
||||
}
|
||||
},
|
||||
subtitle(){
|
||||
// Subtitle for multiple selected items
|
||||
if(this.fileInfoDetail.length > 1 && this.fileInfoDetail.includes(this.draggedItem) ) {
|
||||
return this.fileInfoDetail.length + ' ' + this.$tc('file_detail.items', this.fileInfoDetail.length)
|
||||
}
|
||||
|
||||
if((this.fileInfoDetail.length < 2 || !this.fileInfoDetail.includes(this.draggedItem)) && this.draggedItem) {
|
||||
|
||||
// Subtitle for single folder
|
||||
if(this.draggedItem.type === 'folder') {
|
||||
return this.draggedItem.items == 0 ? this.$t('folder.empty') : this.$tc('folder.item_counts', this.draggedItem.items)
|
||||
}
|
||||
|
||||
// Subtitle for single file
|
||||
if(this.draggedItem !== 'folder' && this.draggedItem.mimetype){
|
||||
return '.'+this.draggedItem.mimetype
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dragged: false,
|
||||
draggedItem: undefined
|
||||
// Title for single item
|
||||
if ((filesLength < 2 || !hasDraggedItem) && this.draggedItem) {
|
||||
return this.draggedItem.name
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
subtitle() {
|
||||
let filesLength = this.fileInfoDetail.length,
|
||||
hasDraggedItem = this.fileInfoDetail.includes(this.draggedItem)
|
||||
|
||||
// Hnadle Drag & Drop Ghost show
|
||||
|
||||
events.$on('dragstart', (data) => {
|
||||
setTimeout(() => {
|
||||
this.dragged = true
|
||||
}, 50);
|
||||
this.draggedItem = data
|
||||
})
|
||||
events.$on('drop', () => {
|
||||
this.dragged = false
|
||||
})
|
||||
|
||||
// Subtitle for multiple selected items
|
||||
if (filesLength > 1 && hasDraggedItem) {
|
||||
return filesLength + ' ' + this.$tc('file_detail.items', filesLength)
|
||||
}
|
||||
|
||||
if ((filesLength < 2 || !hasDraggedItem) && this.draggedItem) {
|
||||
|
||||
// Subtitle for single folder
|
||||
if (this.draggedItem.type === 'folder') {
|
||||
return this.draggedItem.items == 0 ? this.$t('folder.empty') : this.$tc('folder.item_counts', this.draggedItem.items)
|
||||
}
|
||||
|
||||
// Subtitle for single file
|
||||
if (this.draggedItem !== 'folder' && this.draggedItem.mimetype) {
|
||||
return '.' + this.draggedItem.mimetype
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isVisible: false,
|
||||
draggedItem: undefined
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// Handle Drag & Drop Ghost show
|
||||
events.$on('dragstart', data => {
|
||||
this.draggedItem = data
|
||||
|
||||
setTimeout(() => {
|
||||
this.isVisible = true
|
||||
}, 100)
|
||||
})
|
||||
|
||||
events.$on('drop', () => {
|
||||
this.isVisible = false
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -82,38 +87,44 @@ import {events} from '@/bus'
|
||||
padding: 10px;
|
||||
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;
|
||||
}
|
||||
background: white;
|
||||
|
||||
/deep/ .text {
|
||||
.title {
|
||||
color: $text;
|
||||
}
|
||||
/deep/.icon-wrapper {
|
||||
.icon {
|
||||
stroke: $theme;
|
||||
}
|
||||
|
||||
.count {
|
||||
color: $text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .icon-wrapper {
|
||||
.icon {
|
||||
stroke: $theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
#multi-select-ui {
|
||||
background: $dark_mode_foreground;
|
||||
/deep/.text {
|
||||
|
||||
/deep/ .text {
|
||||
.title {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
|
||||
.count {
|
||||
color: $dark_mode_text_secondary;
|
||||
}
|
||||
}
|
||||
/deep/.icon-wrapper {
|
||||
.icon {
|
||||
}
|
||||
|
||||
/deep/ .icon-wrapper {
|
||||
.icon {
|
||||
stroke: $theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
<div class="sharelink">
|
||||
<lock-icon v-if="isLocked" @click="shareItemOptions" class="lock-icon" size="17"></lock-icon>
|
||||
<unlock-icon v-if="! isLocked" @click="shareItemOptions" class="lock-icon" size="17"></unlock-icon>
|
||||
<CopyInput class="copy-sharelink" size="small" :value="fileInfoDetail[0].shared.link"/>
|
||||
<CopyInput class="copy-sharelink" size="small" :item="fileInfoDetail[0]"/>
|
||||
</div>
|
||||
</ListInfoItem>
|
||||
|
||||
|
||||
@@ -25,14 +25,18 @@
|
||||
<!--Image thumbnail-->
|
||||
<img loading="lazy" v-if="isImage && data.thumbnail" class="image" :src="data.thumbnail" :alt="data.name"/>
|
||||
|
||||
<!-- If folder have set emoji -->
|
||||
<Emoji class="emoji" v-if="isFolder && folderIconHandle" :emoji="folderIconHandle" size="80" />
|
||||
|
||||
<!--Else show only folder icon-->
|
||||
<FontAwesomeIcon v-if="isFolder" :class="{'is-deleted': isDeleted}" class="folder-icon" icon="folder"/>
|
||||
<FontAwesomeIcon v-if="isFolder && !folderIconHandle" :ref="`folder${this.data.unique_id}`" :class="{'is-deleted': isDeleted}" class="folder-icon" icon="folder"/>
|
||||
|
||||
</div>
|
||||
|
||||
<!--Name-->
|
||||
<div class="item-name">
|
||||
<!--Name-->
|
||||
<b ref="name" @input="renameItem" @keydown.delete.stop :contenteditable="canEditName" class="name">
|
||||
<b :ref="this.data.unique_id" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName" class="name">
|
||||
{{ itemName }}
|
||||
</b>
|
||||
|
||||
@@ -67,6 +71,7 @@
|
||||
|
||||
<script>
|
||||
import { LinkIcon, UserPlusIcon, CheckIcon } from 'vue-feather-icons'
|
||||
import Emoji from '@/components/Others/Emoji'
|
||||
import { debounce } from 'lodash'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { events } from '@/bus'
|
||||
@@ -77,12 +82,28 @@ export default {
|
||||
components: {
|
||||
UserPlusIcon,
|
||||
CheckIcon,
|
||||
LinkIcon
|
||||
LinkIcon,
|
||||
Emoji
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'FilePreviewType', 'sharedDetail', 'fileInfoDetail'
|
||||
]),
|
||||
folderIconHandle(){
|
||||
|
||||
// If folder have set some color
|
||||
if(this.data.icon_color) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs[`folder${this.data.unique_id}`].firstElementChild.style.fill = `${this.data.icon_color}`
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
// If folder have set some emoji
|
||||
if(this.data.icon_emoji)
|
||||
return this.data.icon_emoji
|
||||
|
||||
},
|
||||
...mapGetters({ allData: 'data' }),
|
||||
isClicked() {
|
||||
return this.fileInfoDetail.some(element => element.unique_id == this.data.unique_id)
|
||||
@@ -158,6 +179,10 @@ export default {
|
||||
events.$emit('unClick')
|
||||
|
||||
if (!this.$isMobile()) {
|
||||
|
||||
// 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.data.unique_id)) {
|
||||
@@ -267,6 +292,14 @@ export default {
|
||||
created() {
|
||||
this.itemName = this.data.name
|
||||
|
||||
events.$on('newFolder:focus', (unique_id) => {
|
||||
|
||||
if(this.data.unique_id == unique_id) {
|
||||
this.$refs[unique_id].focus()
|
||||
document.execCommand('selectAll')
|
||||
}
|
||||
})
|
||||
|
||||
events.$on('mobileSelecting:start', () => {
|
||||
this.multiSelectMode = true
|
||||
this.$store.commit('CLEAR_FILEINFO_DETAIL')
|
||||
@@ -318,7 +351,7 @@ export default {
|
||||
}
|
||||
|
||||
.select-box-active {
|
||||
background-color: $text;
|
||||
background-color: $theme;
|
||||
|
||||
.icon {
|
||||
stroke: white;
|
||||
@@ -452,6 +485,10 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.emoji {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.file-link {
|
||||
display: block;
|
||||
}
|
||||
@@ -568,10 +605,10 @@ export default {
|
||||
}
|
||||
|
||||
.select-box-active {
|
||||
background-color: #f4f5f6;
|
||||
background-color: lighten($theme, 5%);
|
||||
|
||||
.icon {
|
||||
stroke: $text;
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
<template>
|
||||
<div class="file-wrapper" @click.stop="clickedItem" @dblclick="goToItem" spellcheck="false">
|
||||
<!--List preview-->
|
||||
<div :draggable="canDrag" @dragstart="$emit('dragstart')" @drop="
|
||||
drop()
|
||||
area = false" @dragleave="dragLeave" @dragover.prevent="dragEnter" class="file-item" :class="{'is-clicked' : isClicked , 'no-clicked' : !isClicked && this.$isMobile(), 'is-dragenter': area }">
|
||||
<div
|
||||
:draggable="canDrag"
|
||||
@dragstart="$emit('dragstart')"
|
||||
@drop="drop()"
|
||||
@dragleave="dragLeave"
|
||||
@dragover.prevent="dragEnter"
|
||||
class="file-item" :class="{'is-clicked' : isClicked , 'no-clicked' : !isClicked && this.$isMobile(), 'is-dragenter': area }"
|
||||
>
|
||||
<!-- MultiSelecting for the mobile version -->
|
||||
<transition name="slide-from-left">
|
||||
<div class="check-select" v-if="mobileMultiSelect">
|
||||
@@ -26,13 +31,17 @@
|
||||
<!--Image thumbnail-->
|
||||
<img loading="lazy" v-if="isImage && data.thumbnail" class="image" :src="data.thumbnail" :alt="data.name"/>
|
||||
|
||||
<!-- If folder have set emoji -->
|
||||
<Emoji v-if="isFolder && folderIconHandle" :emoji="folderIconHandle" size="52" />
|
||||
|
||||
<!--Else show only folder icon-->
|
||||
<FontAwesomeIcon v-if="isFolder" :class="{ 'is-deleted': isDeleted }" class="folder-icon" icon="folder"/>
|
||||
<FontAwesomeIcon v-if="isFolder && !folderIconHandle" :ref="`folder${this.data.unique_id}`" :class="{ 'is-deleted': isDeleted }" class="folder-icon" icon="folder"/>
|
||||
|
||||
</div>
|
||||
|
||||
<!--Name-->
|
||||
<div class="item-name">
|
||||
<b ref="name" @input="renameItem" @keydown.delete.stop :contenteditable="canEditName" class="name">
|
||||
<b :ref="this.data.unique_id" @input="renameItem" @keydown.delete.stop @click.stop :contenteditable="canEditName" class="name">
|
||||
{{ itemName }}
|
||||
</b>
|
||||
|
||||
@@ -69,6 +78,7 @@
|
||||
|
||||
<script>
|
||||
import { LinkIcon, UserPlusIcon, CheckIcon } from 'vue-feather-icons'
|
||||
import Emoji from '@/components/Others/Emoji'
|
||||
import { debounce } from 'lodash'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { events } from '@/bus'
|
||||
@@ -79,11 +89,27 @@ export default {
|
||||
components: {
|
||||
UserPlusIcon,
|
||||
LinkIcon,
|
||||
CheckIcon
|
||||
CheckIcon,
|
||||
Emoji
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['FilePreviewType', 'fileInfoDetail']),
|
||||
...mapGetters({ allData: 'data' }),
|
||||
folderIconHandle(){
|
||||
|
||||
// If folder have set some icon color
|
||||
if(this.data.icon_color) {
|
||||
this.$nextTick(() => {
|
||||
this.$refs[`folder${this.data.unique_id}`].firstElementChild.style.fill = `${this.data.icon_color}`
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
// If folder have set some emoji
|
||||
if(this.data.icon_emoji)
|
||||
return this.data.icon_emoji
|
||||
|
||||
},
|
||||
isClicked() {
|
||||
return this.fileInfoDetail.some(element => element.unique_id == this.data.unique_id)
|
||||
},
|
||||
@@ -140,6 +166,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
drop() {
|
||||
this.area = false
|
||||
events.$emit('drop')
|
||||
},
|
||||
showItemActions() {
|
||||
@@ -162,6 +189,9 @@ export default {
|
||||
|
||||
if (!this.$isMobile()) {
|
||||
|
||||
// After click deselect new folder rename input
|
||||
document.getSelection().removeAllRanges();
|
||||
|
||||
if ((e.ctrlKey || e.metaKey) && !e.shiftKey) {
|
||||
// Click + Ctrl
|
||||
|
||||
@@ -265,8 +295,17 @@ export default {
|
||||
}, 300)
|
||||
},
|
||||
created() {
|
||||
|
||||
this.itemName = this.data.name
|
||||
|
||||
events.$on('newFolder:focus', (unique_id) => {
|
||||
|
||||
if(this.data.unique_id == unique_id) {
|
||||
this.$refs[unique_id].focus()
|
||||
document.execCommand('selectAll')
|
||||
}
|
||||
})
|
||||
|
||||
events.$on('mobileSelecting:start', () => {
|
||||
this.mobileMultiSelect = true
|
||||
this.$store.commit('CLEAR_FILEINFO_DETAIL')
|
||||
@@ -289,6 +328,7 @@ export default {
|
||||
@import '@assets/vue-file-manager/_variables';
|
||||
@import '@assets/vue-file-manager/_mixins';
|
||||
|
||||
|
||||
.slide-from-left-move {
|
||||
transition: transform 300s ease;
|
||||
}
|
||||
@@ -328,10 +368,10 @@ export default {
|
||||
}
|
||||
|
||||
.select-box-active {
|
||||
background-color: #f4f5f6;
|
||||
background-color: $theme;
|
||||
|
||||
.icon {
|
||||
stroke: $text;
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -533,10 +573,10 @@ export default {
|
||||
}
|
||||
|
||||
.select-box-active {
|
||||
background-color: lighten($dark_mode_foreground, 10%);
|
||||
background-color: $theme;
|
||||
|
||||
.icon {
|
||||
stroke: $theme;
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<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'])">
|
||||
<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>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<audio class="file audio" :class="{ 'file-shadow': !isMobileDevice }" v-if="fileInfoDetail[0].type == 'audio'" :src="currentFile.file_url" controlsList="nodownload" controls></audio>
|
||||
<img v-if="fileInfoDetail[0].type === 'image' && currentFile.thumbnail" class="file" :class="{ 'file-shadow': !isMobileDevice }" id="image" :src="currentFile.file_url" />
|
||||
<div class="video-wrapper" v-if="fileInfoDetail[0].type === 'video' && currentFile.file_url">
|
||||
<video :src="currentFile.file_url" class="video" :class="{ 'file-shadow': !isMobileDevice }" controlsList="nodownload" disablePictureInPicture playsinline controls />
|
||||
<video :src="currentFile.file_url" class="video" :class="{ 'file-shadow': !isMobileDevice }" controlsList="nodownload" disablePictureInPicture playsinline controls autoplay />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,7 +42,7 @@ import { events } from '@/bus'
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.options {
|
||||
background: $dark_mode_background;
|
||||
background: $dark_mode_foreground;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<li class="menu-option">
|
||||
<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>
|
||||
@@ -12,6 +12,7 @@
|
||||
<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>
|
||||
</div>
|
||||
<div class="text-label">
|
||||
{{ title }}
|
||||
@@ -24,6 +25,7 @@ import {
|
||||
CornerDownRightIcon,
|
||||
DownloadCloudIcon,
|
||||
FolderPlusIcon,
|
||||
PaperclipIcon,
|
||||
LifeBuoyIcon,
|
||||
Trash2Icon,
|
||||
Edit2Icon,
|
||||
@@ -41,6 +43,7 @@ import {
|
||||
CornerDownRightIcon,
|
||||
DownloadCloudIcon,
|
||||
FolderPlusIcon,
|
||||
PaperclipIcon,
|
||||
LifeBuoyIcon,
|
||||
Trash2Icon,
|
||||
SmileIcon,
|
||||
@@ -57,6 +60,22 @@ import {
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-option {
|
||||
white-space: nowrap;
|
||||
font-weight: 700;
|
||||
@@ -95,6 +114,11 @@ import {
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.danger {
|
||||
&:hover {
|
||||
background: rgba($danger, 0.1) !important;
|
||||
}
|
||||
}
|
||||
.menu-option {
|
||||
color: $dark_mode_text_primary;
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<transition name="popup">
|
||||
<div class="popup" v-if="isZippingFiles">
|
||||
<div class="popup" v-if="processingPopup">
|
||||
<div class="popup-wrapper">
|
||||
<div class="popup-content">
|
||||
<div class="spinner-wrapper">
|
||||
<Spinner/>
|
||||
</div>
|
||||
<h1 class="title">{{ $t('popup_zipping.title') }}</h1>
|
||||
<p class="message">{{ $t('popup_zipping.message') }}</p>
|
||||
<h1 class="title">{{ processingPopup.title }}</h1>
|
||||
<p class="message">{{ processingPopup.message }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -25,7 +25,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isZippingFiles'
|
||||
'processingPopup'
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +84,6 @@ export default {
|
||||
|
||||
this.filter.field = field
|
||||
|
||||
console.log(this.filter);
|
||||
|
||||
// Set sorting direction
|
||||
if (this.filter.sort === 'DESC')
|
||||
this.filter.sort = 'ASC'
|
||||
|
||||
@@ -5,11 +5,17 @@
|
||||
:description="index.header_description"
|
||||
></PageTitle>
|
||||
|
||||
<router-link class="sign-up-button" :to="{name: 'SignUp'}">
|
||||
<!--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">
|
||||
<!--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>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="cookie-wrapper" v-if="isVisibleDisclaimer && config.isSaaS">
|
||||
<span class="close-icon">
|
||||
<x-icon @click="closeDisclaimer" size="12"></x-icon>
|
||||
<span @click="closeDisclaimer" class="close-icon">
|
||||
<x-icon size="12"></x-icon>
|
||||
</span>
|
||||
<i18n path="cookie_disclaimer.description" tag="p">
|
||||
<router-link :to="{name: 'DynamicPage', params: {slug: 'cookie-policy'}}">{{ $t('cookie_disclaimer.button') }}</router-link>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<!--Set password-->
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper password" name="Title" rules="required" v-slot="{ errors }">
|
||||
<label class="input-label">{{ $t('popup_create_folder.label') }}:</label>
|
||||
<input v-model="name" :class="{'is-error': errors[0]}" type="text" :placeholder="$t('popup_create_folder.placeholder')">
|
||||
<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>
|
||||
</ValidationObserver>
|
||||
@@ -82,6 +82,15 @@
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
events.$on('popup:open', ({name}) => {
|
||||
|
||||
if (name === 'create-folder')
|
||||
this.$nextTick(() => {
|
||||
this.$refs.input.focus()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
25
resources/js/components/Others/Emoji.vue
Normal file
25
resources/js/components/Others/Emoji.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div v-show="transferEmoji" :style="{width: `${size}px`, height: `${size}px`}" v-html="transferEmoji"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import twemoji from 'twemoji'
|
||||
export default {
|
||||
name: 'Emoji',
|
||||
props: ['emoji', 'size'],
|
||||
computed: {
|
||||
transferEmoji () {
|
||||
|
||||
// Transfer single emoji to twemoji
|
||||
return twemoji.parse(this.emoji.char, {
|
||||
folder: 'svg',
|
||||
ext: '.svg',
|
||||
attributes: () => ({
|
||||
loading: 'lazy',
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,95 +1,190 @@
|
||||
<template>
|
||||
<div class="inline-wrapper icon-append copy-input" :class="size" @click="copyUrl">
|
||||
<input ref="sel" :value="value" id="link-input" type="text" class="input-text" readonly>
|
||||
<div class="icon">
|
||||
<link-icon v-if="! isCopiedLink" size="14"></link-icon>
|
||||
<check-icon v-if="isCopiedLink" size="14"></check-icon>
|
||||
<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>
|
||||
<div class="icon-item" @click.stop.prevent="menuForEmail">
|
||||
<send-icon size="14"></send-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { LinkIcon, CheckIcon } from 'vue-feather-icons'
|
||||
import { LinkIcon, CheckIcon, SendIcon } from 'vue-feather-icons'
|
||||
import { events } from '@/bus'
|
||||
|
||||
export default {
|
||||
name: 'CopyInput',
|
||||
props: ['size', 'value'],
|
||||
components: {
|
||||
CheckIcon,
|
||||
LinkIcon,
|
||||
export default {
|
||||
name: 'CopyInput',
|
||||
props: ['size', 'item'],
|
||||
components: {
|
||||
CheckIcon,
|
||||
LinkIcon,
|
||||
SendIcon
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isCopiedLink: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
menuForEmail() {
|
||||
events.$emit('popup:open', {
|
||||
name: 'share-edit',
|
||||
item: this.item,
|
||||
sentToEmail: true,
|
||||
})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isCopiedLink: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
copyUrl() {
|
||||
copyUrl() {
|
||||
|
||||
// Get input value
|
||||
var copyText = document.getElementById("link-input");
|
||||
// Get input value
|
||||
var copyText = document.getElementById('link-input')
|
||||
|
||||
// select link
|
||||
copyText.select();
|
||||
copyText.setSelectionRange(0, 99999);
|
||||
// select link
|
||||
copyText.select()
|
||||
copyText.setSelectionRange(0, 99999)
|
||||
|
||||
// Copy
|
||||
document.execCommand("copy");
|
||||
// Copy
|
||||
document.execCommand('copy')
|
||||
|
||||
// Mark button as copied
|
||||
this.isCopiedLink = true
|
||||
// Mark button as copied
|
||||
this.isCopiedLink = true
|
||||
|
||||
// Reset copy button
|
||||
setTimeout(() => {this.isCopiedLink = false}, 1000)
|
||||
},
|
||||
// Reset copy button
|
||||
setTimeout(() => {
|
||||
this.isCopiedLink = false
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
</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/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";
|
||||
|
||||
// Single page
|
||||
.copy-input {
|
||||
.multi-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: $light_background;
|
||||
border-bottom-right-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
|
||||
&.small {
|
||||
line,
|
||||
path,
|
||||
polygon {
|
||||
stroke: $text !important;
|
||||
}
|
||||
|
||||
&.icon-append {
|
||||
.icon-item {
|
||||
padding: 9px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-left: 1px solid $light_mode_border_darken;
|
||||
cursor: pointer;
|
||||
|
||||
.icon {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: $text;
|
||||
|
||||
input {
|
||||
padding: 6px 10px;
|
||||
@include font-size(13);
|
||||
line,
|
||||
polyline,
|
||||
path,
|
||||
polygon {
|
||||
stroke: white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
&:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom-right-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Single page
|
||||
.copy-input {
|
||||
border: 1px solid $light_mode_border_darken;
|
||||
border-radius: 8px;
|
||||
|
||||
&.small {
|
||||
|
||||
&.icon-append {
|
||||
|
||||
.icon {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:disabled {
|
||||
color: $text;
|
||||
cursor: pointer;
|
||||
}
|
||||
padding: 6px 10px;
|
||||
@include font-size(13);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.copy-input {
|
||||
input {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
input {
|
||||
text-overflow: ellipsis;
|
||||
box-shadow: none;
|
||||
|
||||
&:disabled {
|
||||
color: $text;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.copy-input {
|
||||
border-color: #333333;
|
||||
}
|
||||
|
||||
.multi-icon {
|
||||
background: $dark_mode_foreground;
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
|
||||
|
||||
line,
|
||||
path,
|
||||
polygon {
|
||||
stroke: $dark_mode_text_primary !important;
|
||||
}
|
||||
|
||||
.icon-item {
|
||||
border-color: #333333;
|
||||
|
||||
&:hover {
|
||||
background: rgba($theme, 0.1);
|
||||
|
||||
line,
|
||||
polyline,
|
||||
path,
|
||||
polygon {
|
||||
stroke: $theme !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
.copy-input {
|
||||
input {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -35,12 +35,19 @@
|
||||
}
|
||||
|
||||
p {
|
||||
@include font-size(15);
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
word-break: break-word;
|
||||
font-weight: 600;
|
||||
|
||||
/deep/ a {
|
||||
font-size: 15px;
|
||||
color: $theme;
|
||||
}
|
||||
|
||||
/deep/ b {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: $theme;
|
||||
}
|
||||
}
|
||||
@@ -71,10 +78,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 960px) {
|
||||
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 690px) {
|
||||
|
||||
.info-box {
|
||||
|
||||
197
resources/js/components/Others/Forms/MultiEmailInput.vue
Normal file
197
resources/js/components/Others/Forms/MultiEmailInput.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<label class="input-label">{{ label }}:</label>
|
||||
<div class="input-wrapper" :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>
|
||||
<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"/>
|
||||
</div>
|
||||
</div>
|
||||
<span class="error-message" v-if="isError">{{ isError }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { XIcon } from 'vue-feather-icons'
|
||||
import { events } from '@/bus'
|
||||
|
||||
export default {
|
||||
name: 'MultiEmailInput',
|
||||
components: { XIcon },
|
||||
props: ['isError', 'label'],
|
||||
computed: {
|
||||
getCharactersLength() {
|
||||
return this.emails.join( '' ).length
|
||||
},
|
||||
placeHolder() {
|
||||
return !this.emails.length ? this.$t( 'shared_form.email_placeholder' ) : ''
|
||||
},
|
||||
inputSize() {
|
||||
return this.email && this.email.length > 14 ? this.email.length : 14
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
emails: [],
|
||||
email: undefined
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
removeEmail( email ) {
|
||||
this.emails = this.emails.filter( item => item !== email )
|
||||
|
||||
// After romove email send new emails list to parent
|
||||
events.$emit( 'emailsInputValues', this.emails )
|
||||
},
|
||||
removeLastEmail( event ) {
|
||||
|
||||
// If is input empty and presse backspace remove last email from array
|
||||
if ( event.code === 'Backspace' && this.email === '' )
|
||||
this.emails.pop()
|
||||
},
|
||||
handleEmail() {
|
||||
|
||||
if ( this.email.length > 0 ) {
|
||||
// Get index of @ and last dot
|
||||
let lastDot = this.email.lastIndexOf( '.' )
|
||||
let at = this.email.indexOf( '@' )
|
||||
|
||||
// Check if is after @ some dot, if email have @ anf if dont have more like one
|
||||
if ( lastDot < at || at === -1 || this.email.match(/@/g).length > 1 ) return
|
||||
|
||||
// First email dont need to be separated by comma or space to be sended
|
||||
if( this.emails.length === 0 )
|
||||
events.$emit('emailsInputValues', [this.email])
|
||||
|
||||
|
||||
// After come or backspace push the single email to array or emails
|
||||
if ( this.email.includes(',') || this.email.includes(' ') ) {
|
||||
|
||||
let email = this.email.replace( /[","," "]/, '' )
|
||||
|
||||
this.email = ''
|
||||
|
||||
// Push single email to aray of emails
|
||||
this.emails.push( email )
|
||||
|
||||
events.$emit( 'emailsInputValues', this.emails )
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.input.focus()
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
@import '@assets/vue-file-manager/_forms';
|
||||
|
||||
.wrapper {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.input-label {
|
||||
@include font-size(14);
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
margin-bottom: 0;
|
||||
background: white;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
min-height: 50px;
|
||||
border-radius: 8px;
|
||||
padding: 6px 10px;
|
||||
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.12);
|
||||
cursor: text;
|
||||
border: 1px solid transparent;
|
||||
@include transition(150ms);
|
||||
|
||||
&.is-error {
|
||||
border: 1px solid $danger;
|
||||
box-shadow: 0 0 7px rgba($danger, 0.3);
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
border: 1px solid $theme;
|
||||
box-shadow: 0 1px 5px rgba($theme, 0.3);
|
||||
}
|
||||
|
||||
.email-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.email-input {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.email-tag {
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
padding: 5px 10px;
|
||||
background: rgba($theme, .1);
|
||||
border-radius: 8px;
|
||||
margin-right: 5px;
|
||||
align-items: center;
|
||||
|
||||
&.mb-offset {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: $theme;
|
||||
font-weight: 700;
|
||||
@include font-size(14);
|
||||
}
|
||||
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.email-input {
|
||||
width: auto;
|
||||
border: none ;
|
||||
font-weight: 700;
|
||||
@include font-size(16);
|
||||
padding-left: 11px;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba($text-muted, .5)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.input-wrapper {
|
||||
background: $dark_mode_foreground;
|
||||
|
||||
.email-list {
|
||||
|
||||
.email-input {
|
||||
background: $dark_mode_foreground;
|
||||
color: $dark_mode_text_primary;
|
||||
|
||||
&::placeholder {
|
||||
color: $dark_mode_text_secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -2,7 +2,8 @@
|
||||
<div class="popup-header">
|
||||
<div class="icon">
|
||||
<corner-down-right-icon v-if="icon === 'move'" size="15" class="title-icon"></corner-down-right-icon>
|
||||
<link-icon v-if="icon === 'share'" size="17" class="title-icon"></link-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>
|
||||
</div>
|
||||
<div class="label">
|
||||
@@ -13,7 +14,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {CornerDownRightIcon, LinkIcon, XIcon, Edit2Icon} from 'vue-feather-icons'
|
||||
import {CornerDownRightIcon, LinkIcon, XIcon, Edit2Icon, ShareIcon} from 'vue-feather-icons'
|
||||
import {events} from '@/bus'
|
||||
|
||||
export default {
|
||||
@@ -23,6 +24,7 @@
|
||||
],
|
||||
components: {
|
||||
CornerDownRightIcon,
|
||||
ShareIcon,
|
||||
Edit2Icon,
|
||||
LinkIcon,
|
||||
XIcon,
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 20;
|
||||
z-index: 19;
|
||||
overflow-y: auto;
|
||||
display: grid;
|
||||
padding: 40px;
|
||||
|
||||
@@ -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"/>
|
||||
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="metadata" :setFolderIcon="setFolderIcon"/>
|
||||
|
||||
<!--Form to set sharing-->
|
||||
<ValidationObserver @submit.prevent="changeName" ref="renameForm" v-slot="{ invalid }" tag="form" class="form-wrapper">
|
||||
@@ -15,106 +15,189 @@
|
||||
<!--Set password-->
|
||||
<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>
|
||||
<input v-model="pickedItem.name" :class="{'is-error': errors[0]}" type="text" :placeholder="$t('popup_rename.placeholder')">
|
||||
<div class="input">
|
||||
<input v-model="pickedItem.name" :class="{'is-error': errors[0]}" ref="input" type="text" :placeholder="$t('popup_rename.placeholder')">
|
||||
<div @click="pickedItem.name = ''" class="close-icon-wrapper">
|
||||
<x-icon class="close-icon" 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> -->
|
||||
|
||||
</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 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 ThumbnailItem from '@/components/Others/ThumbnailItem'
|
||||
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'
|
||||
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 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'
|
||||
|
||||
export default {
|
||||
name: 'RenameItem',
|
||||
components: {
|
||||
ValidationProvider,
|
||||
ValidationObserver,
|
||||
ThumbnailItem,
|
||||
ActionButton,
|
||||
PopupWrapper,
|
||||
PopupActions,
|
||||
PopupContent,
|
||||
PopupHeader,
|
||||
ButtonBase,
|
||||
required,
|
||||
export default {
|
||||
name: 'RenameItem',
|
||||
components: {
|
||||
ValidationProvider,
|
||||
ValidationObserver,
|
||||
SetFolderIcon,
|
||||
ThumbnailItem,
|
||||
ActionButton,
|
||||
PopupWrapper,
|
||||
PopupActions,
|
||||
PopupContent,
|
||||
PopupHeader,
|
||||
ButtonBase,
|
||||
required,
|
||||
XIcon
|
||||
},
|
||||
computed: {
|
||||
itemTypeTitle() {
|
||||
return this.pickedItem && this.pickedItem.type === 'folder' ? this.$t('types.folder') : this.$t('types.file')
|
||||
},
|
||||
computed: {
|
||||
itemTypeTitle() {
|
||||
return this.pickedItem && this.pickedItem.type === 'folder' ? this.$t('types.folder') : this.$t('types.file')
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pickedItem: undefined,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeName() {
|
||||
if (this.pickedItem.name && this.pickedItem.name !== '') {
|
||||
|
||||
let item = {
|
||||
unique_id: this.pickedItem.unique_id,
|
||||
type: this.pickedItem.type,
|
||||
name: this.pickedItem.name
|
||||
}
|
||||
|
||||
// Rename item request
|
||||
this.$store.dispatch('renameItem', item)
|
||||
|
||||
// Rename item in view
|
||||
events.$emit('change:name', item)
|
||||
|
||||
this.$closePopup()
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
// Show popup
|
||||
events.$on('popup:open', args => {
|
||||
|
||||
if (args.name !== 'rename-item') return
|
||||
|
||||
// Store picked item
|
||||
this.pickedItem = args.item
|
||||
})
|
||||
moreOptionsTitle() {
|
||||
return this.isMoreOptions ? this.$t('shared_form.button_close_options') : this.$t('shared_form.button_folder_icon_open')
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pickedItem: undefined,
|
||||
isMoreOptions: false,
|
||||
setFolderIcon: undefined
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
moreOptions() {
|
||||
this.isMoreOptions = !this.isMoreOptions
|
||||
|
||||
this.setFolderIcon = undefined
|
||||
},
|
||||
changeName() {
|
||||
if (this.pickedItem.name && this.pickedItem.name !== '') {
|
||||
|
||||
let item = {
|
||||
unique_id: this.pickedItem.unique_id,
|
||||
type: this.pickedItem.type,
|
||||
name: this.pickedItem.name,
|
||||
folder_icon: this.setFolderIcon ? this.setFolderIcon : null
|
||||
}
|
||||
|
||||
// Rename item request
|
||||
this.$store.dispatch('renameItem', item)
|
||||
|
||||
// Rename item in view
|
||||
events.$emit('change:name', item)
|
||||
|
||||
this.$closePopup()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
// Show popup
|
||||
events.$on('popup:open', args => {
|
||||
|
||||
if (args.name !== 'rename-item') return
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.input.focus()
|
||||
})
|
||||
|
||||
this.isMoreOptions = false
|
||||
|
||||
this.setFolderIcon = undefined
|
||||
|
||||
// Store picked item
|
||||
this.pickedItem = args.item
|
||||
})
|
||||
|
||||
events.$on('setFolderIcon', (icon) => {
|
||||
this.setFolderIcon = !icon ? undefined : icon.value
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
@import '@assets/vue-file-manager/_forms';
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
@import '@assets/vue-file-manager/_forms';
|
||||
|
||||
.item-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
.input {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
.close-icon-wrapper {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
right: 15px;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&:hover {
|
||||
.close-icon {
|
||||
line {
|
||||
stroke: $theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
line {
|
||||
stroke: rgba($text-muted, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.close-icon-wrapper {
|
||||
&:hover {
|
||||
|
||||
.close-icon {
|
||||
line {
|
||||
stroke: $theme !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
line {
|
||||
stroke: rgba($dark_mode_text_primary, 0.3) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
498
resources/js/components/Others/SetFolderIcon.vue
Normal file
498
resources/js/components/Others/SetFolderIcon.vue
Normal file
@@ -0,0 +1,498 @@
|
||||
<template>
|
||||
<div class="set-folder-icon">
|
||||
|
||||
<TabWrapper >
|
||||
|
||||
<!-- 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">Pick Yout Emoji Icon:</label>
|
||||
|
||||
<!-- Selected Emoji input -->
|
||||
<div @click.stop="openMenu" class="select-input-wrapper">
|
||||
|
||||
<div class="select-input" v-if="selectedEmoji">
|
||||
<Emoji class="emoji-preview" :emoji="selectedEmoji" size="25"></Emoji>
|
||||
<span>{{selectedEmoji.name}}</span>
|
||||
</div>
|
||||
|
||||
<div class="not-selected" v-if="! selectedEmoji">
|
||||
<span> {{$t('popup_rename.set_emoji_input_placeholder')}}</span>
|
||||
</div>
|
||||
|
||||
<chevron-down-icon v-if="!selectOpen" size="19"/>
|
||||
|
||||
<div v-if="selectOpen" @click="resetEmoji" class="select-input-icon-wrapper">
|
||||
<x-icon size="14" class="select-input-icon"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Emojis List -->
|
||||
<transition v-if="selectOpen" name="slide-in">
|
||||
<div class="emoji-wrapper">
|
||||
<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 emojiGroups" :key="i" class="group-option" :class="{'active' : group.name === groupInView}">
|
||||
<Emoji :emoji="group.emoji" size="33"/>
|
||||
</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" size="33"/>
|
||||
</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" size="33"/>
|
||||
</li>
|
||||
</ul>
|
||||
<span class="not-found" v-if="filteredEmojis.length === 0"> {{$t('popup_rename.emoji_list_not_found')}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</transition>
|
||||
</div>
|
||||
</TabOption>
|
||||
|
||||
<!-- Colors -->
|
||||
<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, index) in colors"
|
||||
:key="index"
|
||||
@click="setIcon({'color': color})"
|
||||
class="single-color"
|
||||
:class="{'active-color': color === selectedColor }"
|
||||
:style="{background:color}" />
|
||||
</ul>
|
||||
</div>
|
||||
</TabOption>
|
||||
</TabWrapper>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { SmileIcon, FolderIcon, ChevronDownIcon, XIcon } from 'vue-feather-icons'
|
||||
import TabWrapper from '@/components/Others/TabWrapper'
|
||||
import TabOption from '@/components/Others/TabOption'
|
||||
import Emoji from '@/components/Others/Emoji'
|
||||
import lodash from 'lodash'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { events } from '@/bus'
|
||||
|
||||
export default {
|
||||
name: "SetFolderIcon",
|
||||
props: ['folderData', 'unique_id'],
|
||||
components: {
|
||||
ChevronDownIcon ,
|
||||
TabWrapper,
|
||||
TabOption,
|
||||
FolderIcon,
|
||||
SmileIcon,
|
||||
XIcon,
|
||||
Emoji
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['emojis', 'emojiGroups']),
|
||||
allEmoji() {
|
||||
return _.groupBy(this.emojis, 'group')
|
||||
},
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
selectedEmoji: undefined,
|
||||
selectedColor: undefined,
|
||||
searchInput: '',
|
||||
filteredEmojis: [],
|
||||
selectOpen: false,
|
||||
groupInView: 'Smileys & Emotion',
|
||||
colors: [ '#FF6633', '#FFB399', '#FF33FF', '#FFFF99', '#00B3E6',
|
||||
'#E6B333', '#3366E6', '#999966', '#99FF99', '#B34D4D',
|
||||
'#80B300', '#809900', '#E6B3B3', '#6680B3' ]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
checkGroupInView: _.debounce(function() {
|
||||
|
||||
this.emojiGroups.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
|
||||
},
|
||||
filterEmojis: _.debounce(function( emoji ){
|
||||
|
||||
this.filteredEmojis = this.emojis.filter(emoji => emoji.name.includes(this.searchInput))
|
||||
|
||||
}, 800),
|
||||
openMenu() {
|
||||
|
||||
this.selectOpen = ! this.selectOpen
|
||||
|
||||
this.searchInput = ''
|
||||
|
||||
this.groupInView = 'Smileys & Emotion'
|
||||
},
|
||||
setIcon( value ) {
|
||||
|
||||
if(value.emoji){
|
||||
this.selectedEmoji = value.emoji
|
||||
this.selectedColor = undefined
|
||||
}
|
||||
|
||||
if(value.color) {
|
||||
this.selectedColor = value.color
|
||||
this.selectedEmoji = undefined
|
||||
}
|
||||
|
||||
events.$emit('setFolderIcon', { 'value':value, 'unique_id':this.unique_id })
|
||||
|
||||
this.selectOpen = false
|
||||
},
|
||||
resetEmoji(){
|
||||
|
||||
this.selectedEmoji = undefined
|
||||
|
||||
events.$emit('setFolderIcon', undefined)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
|
||||
this.selectOpen = false
|
||||
|
||||
events.$on('unClick', () => {
|
||||
this.selectOpen = false
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
@import '@assets/vue-file-manager/_forms';
|
||||
|
||||
.color-pick-wrapper {
|
||||
.color-wrapper {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
.single-color {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
list-style: none;
|
||||
margin: 8px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
|
||||
&.active-color {
|
||||
border: 2px solid $text;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border: 2px solid $text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-emoji-wrapper{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.main-label {
|
||||
@include font-size(14);
|
||||
font-weight: 700;
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.emoji-wrapper {
|
||||
height: 350px;
|
||||
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;
|
||||
top: 152px;
|
||||
|
||||
.loader {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.groups-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.active {
|
||||
background: $light_background;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.group-option {
|
||||
list-style: none;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
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: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.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;
|
||||
|
||||
.select-input-icon-wrapper {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
&:hover {
|
||||
background: $light_background !important;
|
||||
|
||||
.select-input-icon {
|
||||
line {
|
||||
stroke: $theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-input-icon {
|
||||
line {
|
||||
stroke: $text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select-input {
|
||||
@include font-size(16);
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
.emoji-preview {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.not-selected {
|
||||
span {
|
||||
color: rgba($text, 0.5);
|
||||
@include font-size(15);
|
||||
font-weight: 700
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
.set-folder-icon {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.slide-in-enter-active {
|
||||
transition: all 5s ease;
|
||||
}
|
||||
|
||||
.slide-in-enter
|
||||
{
|
||||
opacity: 0;
|
||||
transform: translateY(-50px);
|
||||
}
|
||||
|
||||
@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 {
|
||||
background: rgba($theme, 0.1) !important;
|
||||
.select-input-icon {
|
||||
line {
|
||||
stroke: $theme !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.select-input-icon {
|
||||
line {
|
||||
stroke:$dark_mode_text_primary !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
<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>
|
||||
@@ -9,8 +9,27 @@
|
||||
<!--Item Thumbnail-->
|
||||
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="metadata"/>
|
||||
|
||||
<!-- Infobox for successfull sended email -->
|
||||
<InfoBox v-if="isGeneratedShared && sharedViaEmail" class="info-box-wrapper">
|
||||
<p v-html="$t('shared_form.email_successfully_send_message')"></p>
|
||||
</InfoBox>
|
||||
|
||||
<!--Form to set sharing-->
|
||||
<ValidationObserver v-if="! isGeneratedShared" ref="shareForm" v-slot="{ invalid }" tag="form" class="form-wrapper">
|
||||
<ValidationObserver @submit.prevent v-if="! isGeneratedShared" ref="shareForm" v-slot="{ invalid }" tag="form" class="form-wrapper">
|
||||
|
||||
<TabWrapper>
|
||||
|
||||
<!-- Share via 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]"/>
|
||||
</ValidationProvider>
|
||||
</TabOption>
|
||||
|
||||
</TabWrapper>
|
||||
|
||||
<!--Permision Select-->
|
||||
<ValidationProvider v-if="isFolder" tag="div" mode="passive" class="input-wrapper" name="Permission" rules="required" v-slot="{ errors }">
|
||||
@@ -49,201 +68,212 @@
|
||||
<!--Copy generated link-->
|
||||
<div v-if="isGeneratedShared" class="form-wrapper">
|
||||
<div class="input-wrapper">
|
||||
<label class="input-label">{{ $t('shared_form.label_shared_url') }}:</label>
|
||||
<CopyInput size="small" :value="shareLink" />
|
||||
<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"/>
|
||||
</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 SelectBoxInput from '@/components/Others/Forms/SelectBoxInput'
|
||||
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 SwitchInput from '@/components/Others/Forms/SwitchInput'
|
||||
import SelectInput from '@/components/Others/Forms/SelectInput'
|
||||
import ThumbnailItem from '@/components/Others/ThumbnailItem'
|
||||
import ActionButton from '@/components/Others/ActionButton'
|
||||
import CopyInput from '@/components/Others/Forms/CopyInput'
|
||||
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||
import {required} from 'vee-validate/dist/rules'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
import axios from 'axios'
|
||||
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'
|
||||
import PopupContent from '@/components/Others/Popup/PopupContent'
|
||||
import PopupHeader from '@/components/Others/Popup/PopupHeader'
|
||||
import MultiEmailInput from '@/components/Others/Forms/MultiEmailInput'
|
||||
import SwitchInput from '@/components/Others/Forms/SwitchInput'
|
||||
import SelectInput from '@/components/Others/Forms/SelectInput'
|
||||
import ThumbnailItem from '@/components/Others/ThumbnailItem'
|
||||
import ActionButton from '@/components/Others/ActionButton'
|
||||
import CopyInput from '@/components/Others/Forms/CopyInput'
|
||||
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 axios from 'axios'
|
||||
|
||||
export default {
|
||||
name: 'ShareCreate',
|
||||
components: {
|
||||
ValidationProvider,
|
||||
ValidationObserver,
|
||||
SelectBoxInput,
|
||||
ThumbnailItem,
|
||||
ActionButton,
|
||||
PopupWrapper,
|
||||
PopupActions,
|
||||
PopupContent,
|
||||
PopupHeader,
|
||||
SelectInput,
|
||||
SwitchInput,
|
||||
ButtonBase,
|
||||
CopyInput,
|
||||
required,
|
||||
export default {
|
||||
name: 'ShareCreate',
|
||||
components: {
|
||||
ValidationProvider,
|
||||
ValidationObserver,
|
||||
SelectBoxInput,
|
||||
ThumbnailItem,
|
||||
ActionButton,
|
||||
PopupWrapper,
|
||||
PopupActions,
|
||||
TabWrapper,
|
||||
TabOption,
|
||||
PopupContent,
|
||||
PopupHeader,
|
||||
MultiEmailInput,
|
||||
SelectInput,
|
||||
SwitchInput,
|
||||
ButtonBase,
|
||||
CopyInput,
|
||||
MailIcon,
|
||||
required,
|
||||
LinkIcon,
|
||||
InfoBox
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'permissionOptions',
|
||||
'expirationList'
|
||||
]),
|
||||
itemTypeTitle() {
|
||||
return this.pickedItem && this.pickedItem.type === 'folder' ? this.$t('types.folder') : this.$t('types.file')
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'permissionOptions',
|
||||
'expirationList',
|
||||
]),
|
||||
itemTypeTitle() {
|
||||
return this.pickedItem && this.pickedItem.type === 'folder' ? this.$t('types.folder') : this.$t('types.file')
|
||||
isFolder() {
|
||||
return this.pickedItem && this.pickedItem.type === 'folder'
|
||||
},
|
||||
submitButtonText() {
|
||||
return this.isGeneratedShared ? this.$t('shared_form.button_done') : this.$t('shared_form.button_generate')
|
||||
},
|
||||
moreOptionsTitle() {
|
||||
return this.isMoreOptions ? this.$t('shared_form.button_close_options') : this.$t('shared_form.button_more_options')
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shareOptions: {
|
||||
isPassword: false,
|
||||
expiration: undefined,
|
||||
password: undefined,
|
||||
permission: undefined,
|
||||
type: undefined,
|
||||
unique_id: undefined,
|
||||
emails: undefined
|
||||
},
|
||||
isFolder() {
|
||||
return this.pickedItem && this.pickedItem.type === 'folder'
|
||||
},
|
||||
submitButtonText() {
|
||||
return this.isGeneratedShared ? this.$t('shared_form.button_done') : this.$t('shared_form.button_generate')
|
||||
},
|
||||
moreOptionsTitle() {
|
||||
return this.isMoreOptions ? this.$t('shared_form.button_close_options') : this.$t('shared_form.button_more_options')
|
||||
pickedItem: undefined,
|
||||
isGeneratedShared: false,
|
||||
isLoading: false,
|
||||
isMoreOptions: false,
|
||||
sharedViaEmail: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
moreOptions() {
|
||||
this.isMoreOptions = !this.isMoreOptions
|
||||
|
||||
if (!this.isMoreOptions)
|
||||
this.shareOptions.expiration = undefined
|
||||
},
|
||||
async submitShareOptions() {
|
||||
|
||||
// If shared was generated, then close popup
|
||||
if (this.isGeneratedShared) {
|
||||
events.$emit('popup:close')
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shareOptions: {
|
||||
|
||||
// Validate fields
|
||||
const isValid = await this.$refs.shareForm.validate()
|
||||
|
||||
if (!isValid) return
|
||||
|
||||
this.isLoading = true
|
||||
|
||||
// Send request to get share link
|
||||
axios
|
||||
.post('/api/share', this.shareOptions)
|
||||
.then(response => {
|
||||
|
||||
// Show infobox and reset emails container
|
||||
if (this.shareOptions.emails)
|
||||
this.sharedViaEmail = true
|
||||
|
||||
// End loading
|
||||
this.isGeneratedShared = true
|
||||
|
||||
this.$store.commit('UPDATE_SHARED_ITEM', response.data.data.attributes)
|
||||
})
|
||||
.catch(() => {
|
||||
events.$emit('alert:open', {
|
||||
title: this.$t('popup_error.title'),
|
||||
message: this.$t('popup_error.message'),
|
||||
})
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
events.$on('emailsInputValues', (emails) => this.shareOptions.emails = emails)
|
||||
|
||||
// Show popup
|
||||
events.$on('popup:open', args => {
|
||||
|
||||
if (args.name !== 'share-create') return
|
||||
|
||||
// Store picked item
|
||||
this.pickedItem = args.item
|
||||
|
||||
this.shareOptions.type = args.item.type
|
||||
this.shareOptions.unique_id = args.item.unique_id
|
||||
})
|
||||
|
||||
// Close popup
|
||||
events.$on('popup:close', () => {
|
||||
|
||||
// Restore data
|
||||
setTimeout(() => {
|
||||
this.shareOptions = {
|
||||
permission: undefined,
|
||||
password: undefined,
|
||||
isPassword: false,
|
||||
expiration: undefined,
|
||||
password: undefined,
|
||||
permission: undefined,
|
||||
type: undefined,
|
||||
unique_id: undefined,
|
||||
},
|
||||
pickedItem: undefined,
|
||||
shareLink: undefined,
|
||||
isGeneratedShared: false,
|
||||
isLoading: false,
|
||||
isMoreOptions: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
moreOptions() {
|
||||
this.isMoreOptions = ! this.isMoreOptions
|
||||
|
||||
if (! this.isMoreOptions)
|
||||
this.shareOptions.expiration = undefined
|
||||
},
|
||||
async submitShareOptions() {
|
||||
|
||||
// If shared was generated, then close popup
|
||||
if (this.isGeneratedShared) {
|
||||
events.$emit('popup:close')
|
||||
|
||||
return;
|
||||
emails: undefined
|
||||
}
|
||||
|
||||
// Validate fields
|
||||
const isValid = await this.$refs.shareForm.validate();
|
||||
|
||||
if (!isValid) return;
|
||||
|
||||
this.isLoading = true
|
||||
|
||||
// Send request to get share link
|
||||
axios
|
||||
.post('/api/share', this.shareOptions)
|
||||
.then(response => {
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
|
||||
this.shareLink = response.data.data.attributes.link
|
||||
this.isGeneratedShared = true
|
||||
|
||||
this.$store.commit('UPDATE_SHARED_ITEM', response.data.data.attributes)
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
// todo: catch errors
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
// Show popup
|
||||
events.$on('popup:open', args => {
|
||||
|
||||
if (args.name !== 'share-create') return
|
||||
|
||||
// Store picked item
|
||||
this.pickedItem = args.item
|
||||
|
||||
this.shareOptions.type = args.item.type
|
||||
this.shareOptions.unique_id = args.item.unique_id
|
||||
})
|
||||
|
||||
// Close popup
|
||||
events.$on('popup:close', () => {
|
||||
|
||||
// Restore data
|
||||
setTimeout(() => {
|
||||
this.shareOptions = {
|
||||
permission: undefined,
|
||||
password: undefined,
|
||||
isPassword: false,
|
||||
expiration: undefined,
|
||||
type: undefined,
|
||||
unique_id: undefined,
|
||||
}
|
||||
this.isGeneratedShared = false
|
||||
this.isMoreOptions = false
|
||||
this.shareLink = undefined
|
||||
}, 150)
|
||||
})
|
||||
}
|
||||
this.isGeneratedShared = false
|
||||
this.isMoreOptions = false
|
||||
this.sharedViaEmail = false
|
||||
}, 150)
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
@import '@assets/vue-file-manager/_forms';
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
@import '@assets/vue-file-manager/_forms';
|
||||
|
||||
.more-options {
|
||||
margin-bottom: 10px;
|
||||
.more-options {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
|
||||
&.password {
|
||||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
.item-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
&.password {
|
||||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,14 +9,26 @@
|
||||
<!--Item Thumbnail-->
|
||||
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="metadata"/>
|
||||
|
||||
<!--Form to set sharing-->
|
||||
<ValidationObserver ref="shareForm" v-slot="{ invalid }" tag="form" class="form-wrapper">
|
||||
<!-- Infobox for successfull sended email -->
|
||||
<InfoBox v-if="sendToRecipientsMenu && isEmailSended" class="info-box-wrapper">
|
||||
<p v-html="$t('shared_form.email_successfully_send_message')"></p>
|
||||
</InfoBox>
|
||||
|
||||
<!--Share link-->
|
||||
<div class="input-wrapper">
|
||||
<label class="input-label">{{ $t('shared_form.label_shared_url') }}:</label>
|
||||
<CopyInput size="small" :value="pickedItem.shared.link" />
|
||||
</div>
|
||||
<div v-if="! sendToRecipientsMenu || (sendToRecipientsMenu && isEmailSended)" class="input-wrapper copy-input">
|
||||
<label class="input-label">{{ $t('shared_form.label_share_vie_email') }}:</label>
|
||||
<CopyInput size="small" :item="pickedItem" />
|
||||
</div>
|
||||
|
||||
<ValidationObserver @submit.prevent v-if="sendToRecipientsMenu && !isEmailSended" v-slot="{ invalid }" ref="shareEmail" tag="form" class="form-wrapper">
|
||||
|
||||
<ValidationProvider tag="div" mode="passive" name="Email" rules="required" v-slot="{ errors }">
|
||||
<MultiEmailInput rules="required" v-model="emails" :label="$t('shared_form.label_send_to_recipients')" :isError="errors[0]" />
|
||||
</ValidationProvider>
|
||||
|
||||
</ValidationObserver>
|
||||
|
||||
<!--Form to set sharing-->
|
||||
<ValidationObserver @submit.prevent v-if="! sendToRecipientsMenu" ref="shareForm" v-slot="{ invalid }" tag="form" class="form-wrapper">
|
||||
|
||||
<!--Permision Select-->
|
||||
<ValidationProvider v-if="isFolder" tag="div" mode="passive" class="input-wrapper" name="Permission" rules="required" v-slot="{ errors }">
|
||||
@@ -58,7 +70,7 @@
|
||||
|
||||
<!--Actions-->
|
||||
<PopupActions>
|
||||
<ButtonBase
|
||||
<ButtonBase v-if="! sendToRecipientsMenu || (sendToRecipientsMenu && !isEmailSended)"
|
||||
class="popup-button"
|
||||
@click.native="destroySharing"
|
||||
:button-style="destroyButtonStyle"
|
||||
@@ -72,7 +84,7 @@
|
||||
button-style="theme"
|
||||
:loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
>{{ $t('popup_share_edit.save') }}
|
||||
>{{ secondButtonText }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
</PopupWrapper>
|
||||
@@ -87,10 +99,12 @@
|
||||
import PopupHeader from '@/components/Others/Popup/PopupHeader'
|
||||
import SwitchInput from '@/components/Others/Forms/SwitchInput'
|
||||
import SelectInput from '@/components/Others/Forms/SelectInput'
|
||||
import MultiEmailInput from '@/components/Others/Forms/MultiEmailInput'
|
||||
import ThumbnailItem from '@/components/Others/ThumbnailItem'
|
||||
import ActionButton from '@/components/Others/ActionButton'
|
||||
import CopyInput from '@/components/Others/Forms/CopyInput'
|
||||
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||
import InfoBox from '@/components/Others/Forms/InfoBox'
|
||||
import {required} from 'vee-validate/dist/rules'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
@@ -109,10 +123,12 @@
|
||||
PopupContent,
|
||||
PopupHeader,
|
||||
SelectInput,
|
||||
MultiEmailInput,
|
||||
SwitchInput,
|
||||
ButtonBase,
|
||||
CopyInput,
|
||||
required,
|
||||
InfoBox,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
@@ -125,10 +141,26 @@
|
||||
return this.pickedItem && this.pickedItem.type === 'folder'
|
||||
},
|
||||
destroyButtonText() {
|
||||
return this.isConfirmedDestroy ? this.$t('popup_share_edit.confirm') : this.$t('popup_share_edit.stop')
|
||||
if(! this.sendToRecipientsMenu)
|
||||
return this.isConfirmedDestroy ? this.$t('popup_share_edit.confirm') : this.$t('popup_share_edit.stop')
|
||||
|
||||
if(this.sendToRecipientsMenu)
|
||||
return this.$t('popup_share_edit.go_back')
|
||||
},
|
||||
destroyButtonStyle() {
|
||||
return this.isConfirmedDestroy ? 'danger-solid' : 'secondary'
|
||||
if(! this.sendToRecipientsMenu)
|
||||
return this.isConfirmedDestroy ? 'danger-solid' : 'secondary'
|
||||
|
||||
if(this.sendToRecipientsMenu)
|
||||
return 'secondary'
|
||||
},
|
||||
secondButtonText(){
|
||||
if(! this.sendToRecipientsMenu)
|
||||
return this.$t('popup_share_edit.save')
|
||||
|
||||
if(this.sendToRecipientsMenu)
|
||||
return this.isEmailSended ? this.$t('shared_form.button_done') : this.$t('popup_share_edit.send_to_recipients')
|
||||
|
||||
},
|
||||
isSharedLocation() {
|
||||
return this.currentFolder && this.currentFolder.location === 'shared'
|
||||
@@ -139,11 +171,14 @@
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sendToRecipientsMenu: false,
|
||||
isConfirmedDestroy: false,
|
||||
canChangePassword: false,
|
||||
shareOptions: undefined,
|
||||
pickedItem: undefined,
|
||||
emails:undefined,
|
||||
isMoreOptions: false,
|
||||
isEmailSended:false,
|
||||
isDeleting: false,
|
||||
isLoading: false,
|
||||
}
|
||||
@@ -158,8 +193,38 @@
|
||||
changePassword() {
|
||||
this.canChangePassword = false
|
||||
},
|
||||
async sendViaEmail() {
|
||||
|
||||
// Validate email field
|
||||
const isValid = await this.$refs.shareEmail.validate();
|
||||
|
||||
if (!isValid) return;
|
||||
|
||||
this.isLoading = true
|
||||
|
||||
axios.
|
||||
post(`/api/share/${this.shareOptions.token}/send-email`, {
|
||||
emails: this.emails
|
||||
})
|
||||
.catch(() => {
|
||||
this.$isSomethingWrong()
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
this.isEmailSended = true
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
})
|
||||
|
||||
},
|
||||
async destroySharing() {
|
||||
|
||||
if(this.sendToRecipientsMenu) {
|
||||
this.sendToRecipientsMenu = false
|
||||
return
|
||||
}
|
||||
|
||||
// Set confirm button
|
||||
if (! this.isConfirmedDestroy) {
|
||||
|
||||
@@ -188,6 +253,18 @@
|
||||
},
|
||||
async updateShareOptions() {
|
||||
|
||||
// If is open send share via email
|
||||
if(this.sendToRecipientsMenu && !this.isEmailSended) {
|
||||
this.sendViaEmail()
|
||||
return
|
||||
}
|
||||
|
||||
// Is is open send share via email and email was already sended
|
||||
if(this.sendToRecipientsMenu && this.isEmailSended){
|
||||
events.$emit('popup:close')
|
||||
return
|
||||
}
|
||||
|
||||
// If shared was generated, then close popup
|
||||
if (this.isGeneratedShared) {
|
||||
|
||||
@@ -219,18 +296,21 @@
|
||||
events.$emit('popup:close')
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
this.$isSomethingWrong()
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
this.sendToRecipientsMenu = false
|
||||
|
||||
events.$on('emailsInputValues', (emails) => {
|
||||
this.emails = emails
|
||||
})
|
||||
|
||||
// Show popup
|
||||
events.$on('popup:open', args => {
|
||||
|
||||
@@ -251,6 +331,9 @@
|
||||
if (args.item.shared.expire_in)
|
||||
this.isMoreOptions = true
|
||||
|
||||
if (args.sentToEmail)
|
||||
this.sendToRecipientsMenu = true
|
||||
|
||||
this.canChangePassword = args.item.shared.protected
|
||||
})
|
||||
|
||||
@@ -259,6 +342,8 @@
|
||||
|
||||
// Restore data
|
||||
setTimeout(() => {
|
||||
this.sendToRecipientsMenu = false
|
||||
this.isEmailSended = false
|
||||
this.isConfirmedDestroy = false
|
||||
this.canChangePassword = false
|
||||
this.pickedItem = undefined
|
||||
@@ -278,6 +363,10 @@
|
||||
&.password {
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
&.copy-input {
|
||||
padding: 0px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.change-password {
|
||||
|
||||
22
resources/js/components/Others/TabOption.vue
Normal file
22
resources/js/components/Others/TabOption.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div v-if="isActive">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "TabOption",
|
||||
props: ['title', 'icon', 'selected'],
|
||||
data () {
|
||||
return {
|
||||
isActive: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.isActive = this.selected
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
117
resources/js/components/Others/TabWrapper.vue
Normal file
117
resources/js/components/Others/TabWrapper.vue
Normal file
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="tab-wrapper">
|
||||
<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"/>
|
||||
|
||||
<!--Title-->
|
||||
<b class="tab-title">{{tab.title}}</b>
|
||||
</div>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
LinkIcon,
|
||||
MailIcon,
|
||||
SmileIcon,
|
||||
FolderIcon } from 'vue-feather-icons'
|
||||
|
||||
export default {
|
||||
name: "TabWrapper",
|
||||
components: {
|
||||
LinkIcon,
|
||||
MailIcon,
|
||||
SmileIcon,
|
||||
FolderIcon
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
tabs: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectTab(selectedTab) {
|
||||
this.tabs.forEach(tab => {
|
||||
tab.isActive = tab.title == selectedTab.title
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.tabs = this.$children
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
@import '@assets/vue-file-manager/_forms';
|
||||
|
||||
.tab-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
background: white;
|
||||
color: $text;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #E8E9EB;
|
||||
|
||||
.tab-title {
|
||||
@include font-size(14);
|
||||
}
|
||||
|
||||
.tab {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 8px;
|
||||
|
||||
&.active {
|
||||
background: $light_background;
|
||||
|
||||
.tab-title {
|
||||
color: $text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-icon {
|
||||
margin-right: 10px;
|
||||
path,
|
||||
circle,
|
||||
line,
|
||||
polyline {
|
||||
color: $theme !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.tab-wrapper {
|
||||
background: $dark_mode_foreground;
|
||||
border-color: transparent;
|
||||
|
||||
.tab.active {
|
||||
background: rgba($theme, 0.1);
|
||||
|
||||
.tab-title {
|
||||
color: $theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -13,8 +13,12 @@
|
||||
<!--Image thumbnail-->
|
||||
<img v-if="isImage && item.thumbnail" class="image" :src="item.thumbnail" :alt="item.name"/>
|
||||
|
||||
<!-- If folder have set emoji -->
|
||||
<Emoji v-if="isFolder && folderIconHandle" :emoji="folderIconHandle" size="36"/>
|
||||
|
||||
<!--Else show only folder icon-->
|
||||
<FontAwesomeIcon v-if="isFolder" class="folder-icon" icon="folder"/>
|
||||
<FontAwesomeIcon ref="folderIcon" v-if="isFolder && !folderIconHandle" class="folder-icon" icon="folder"/>
|
||||
|
||||
</div>
|
||||
|
||||
<!--Name-->
|
||||
@@ -41,12 +45,37 @@
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex'
|
||||
import Emoji from '@/components/Others/Emoji'
|
||||
|
||||
export default {
|
||||
name: 'ThumbnailItem',
|
||||
props: ['item', 'info'],
|
||||
props: ['item', 'info', 'setFolderIcon'],
|
||||
components: {Emoji},
|
||||
computed: {
|
||||
...mapGetters(['currentFolder']),
|
||||
|
||||
folderIconHandle(){
|
||||
|
||||
// Set icon folder if set folder from rename popup
|
||||
if(this.setFolderIcon){
|
||||
|
||||
return this.setFolderIcon.emoji
|
||||
? this.setFolderIcon.emoji
|
||||
: this.$nextTick(() => {
|
||||
this.$refs.folderIcon.firstElementChild.style.fill = `${this.setFolderIcon.color}`
|
||||
})
|
||||
}
|
||||
|
||||
// If folder have already set some icon
|
||||
if(!this.setFolderIcon && (this.item.icon_emoji || this.item.icon_color)){
|
||||
|
||||
return this.item.icon_emoji
|
||||
? this.item.icon_emoji
|
||||
: this.$nextTick(() => {
|
||||
this.$refs.folderIcon.firstElementChild.style.fill = `${this.item.icon_color}`
|
||||
})
|
||||
}
|
||||
},
|
||||
isFolder() {
|
||||
return this.item.type === 'folder'
|
||||
},
|
||||
@@ -103,9 +132,12 @@
|
||||
.icon-item {
|
||||
position: relative;
|
||||
min-width: 52px;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
line-height: 0;
|
||||
|
||||
|
||||
.file-icon {
|
||||
@include font-size(35);
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
name: 'Vignette',
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isZippingFiles'
|
||||
'processingPopup'
|
||||
]),
|
||||
isVisible() {
|
||||
return this.isZippingFiles || this.isVisibleVignette
|
||||
return this.processingPopup || this.isVisibleVignette
|
||||
},
|
||||
},
|
||||
data() {
|
||||
@@ -56,7 +56,7 @@
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 19;
|
||||
z-index: 18;
|
||||
background: $light_mode_vignette;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<section class="content-sidebar">
|
||||
<section class="content-sidebar" id="content-sidebar">
|
||||
<slot></slot>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
4
resources/js/helpers.js
vendored
4
resources/js/helpers.js
vendored
@@ -177,7 +177,7 @@ const Helpers = {
|
||||
|
||||
if (files.length == 0) return
|
||||
|
||||
if (!this.$checkFileMimetype(files)) return
|
||||
if (!this.$checkFileMimetype(files) || !this.$checkUploadLimit(files)) return
|
||||
|
||||
this.$handleUploading(files, undefined)
|
||||
}
|
||||
@@ -351,7 +351,7 @@ const Helpers = {
|
||||
let body = document.body
|
||||
body.classList.add('windows')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"users": "Users"
|
||||
},
|
||||
"admin_page_dashboard": {
|
||||
"backer_button": "成为支持者",
|
||||
"backer_button": "Help Us Improve",
|
||||
"license": "执照",
|
||||
"version": "版",
|
||||
"w_latest_users": {
|
||||
@@ -283,7 +283,8 @@
|
||||
"share_edit": "编辑分享设定",
|
||||
"upload": "上传",
|
||||
"select": "Select",
|
||||
"no_options": "No Options Available"
|
||||
"no_options": "No Options Available",
|
||||
"zip_folder": "Zip and Download"
|
||||
},
|
||||
"mobile_selecting": {
|
||||
"select_all": "Select All",
|
||||
@@ -597,7 +598,9 @@
|
||||
"confirm": "确认",
|
||||
"save": "保存更改",
|
||||
"stop": "停止风险",
|
||||
"title": "更新分享设定"
|
||||
"title": "更新分享设定",
|
||||
"go_back": "Go Back",
|
||||
"send_to_recipients": "Send to Recipients"
|
||||
},
|
||||
"popup_signup_error": {
|
||||
"message": "Please check your database connection if everything works correctly.",
|
||||
@@ -689,10 +692,17 @@
|
||||
"label_password_protection": "密码保护",
|
||||
"label_permission": "权限",
|
||||
"label_shared_url": "分享链接",
|
||||
"label_share_vie_email": "Get your link",
|
||||
"label_send_to_recipients": "Send to Recipients",
|
||||
"label_expiration": "Link Expiration",
|
||||
"expiration_hour": "{value}h.",
|
||||
"expiration_day": "{value}d.",
|
||||
"placeholder_permission": "请设置权限"
|
||||
"placeholder_permission": "请设置权限",
|
||||
"email_successfully_send_message": "Your item was <b>successfully sended</b> to recipients emails.",
|
||||
"share_by_link": "Share by Link",
|
||||
"share_by_email": "Share by Email",
|
||||
"recipients_label": "Recipients",
|
||||
"email_placeholder": "Type your emails"
|
||||
},
|
||||
"sidebar": {
|
||||
"favourites": "收藏",
|
||||
@@ -802,7 +812,9 @@
|
||||
"state": "州",
|
||||
"state_plac": "输入您的帐单状态",
|
||||
"title_account": "帐户信息",
|
||||
"title_billing": "账单信息"
|
||||
"title_billing": "账单信息",
|
||||
"timezone": "Timezone",
|
||||
"timezone_plac" : "Select your timezone"
|
||||
},
|
||||
"user_subscription": {
|
||||
"billed": "开票",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"users": "Users"
|
||||
},
|
||||
"admin_page_dashboard": {
|
||||
"backer_button": "Become a Backer",
|
||||
"backer_button": "Help Us Improve",
|
||||
"license": "License",
|
||||
"version": "Version",
|
||||
"w_latest_users": {
|
||||
@@ -285,7 +285,8 @@
|
||||
"share_edit": "Edit Sharing",
|
||||
"upload": "Upload",
|
||||
"select": "Select",
|
||||
"no_options": "No Options Available"
|
||||
"no_options": "No Options Available",
|
||||
"zip_folder": "Zip and Download"
|
||||
},
|
||||
"mobile_selecting": {
|
||||
"select_all": "Select All",
|
||||
@@ -307,9 +308,9 @@
|
||||
"paginate_info": "Showing 1 - {visible} from {total} records"
|
||||
},
|
||||
"empty_page": {
|
||||
"call_to_action": "Upload File",
|
||||
"description": "Upload some files here easily via upload button",
|
||||
"title": "There is Nothing"
|
||||
"call_to_action": "Upload Files",
|
||||
"description": "Upload some files here easily via upload button.",
|
||||
"title": "Upload Your First File"
|
||||
},
|
||||
"errors": {
|
||||
"capacity_digit": "The storage capacity must be lower than 10 digit number."
|
||||
@@ -579,7 +580,14 @@
|
||||
"popup_rename": {
|
||||
"title": "Rename Your {item}",
|
||||
"label": "Edit Name",
|
||||
"placeholder": "Type your title"
|
||||
"placeholder": "Type your title",
|
||||
"tab_emoji_title": "Emoji as an Icon",
|
||||
"tab_color_title": "Folder Color",
|
||||
"set_emoji_input_placeholder": "Emojis List...",
|
||||
"search_emoji_input_placeholder": "Search your emoji...",
|
||||
"emoji_list_not_found": "Not Found",
|
||||
"color_pick_label": "Pick Your Color:"
|
||||
|
||||
},
|
||||
"popup_create_folder": {
|
||||
"folder_default_name": "New Folder",
|
||||
@@ -598,8 +606,10 @@
|
||||
"change_pass": "Change Password",
|
||||
"confirm": "Confirm",
|
||||
"save": "Save Changes",
|
||||
"stop": "Stop Sharing",
|
||||
"title": "Update sharing options"
|
||||
"stop": "Cancel Sharing",
|
||||
"title": "Update sharing options",
|
||||
"go_back": "Go Back",
|
||||
"send_to_recipients": "Send to Recipients"
|
||||
},
|
||||
"popup_signup_error": {
|
||||
"message": "Please check your database connection if everything works correctly.",
|
||||
@@ -686,15 +696,23 @@
|
||||
"shared_form": {
|
||||
"button_more_options": "Set Expiration",
|
||||
"button_close_options": "Close Options",
|
||||
"button_folder_icon_open": "Customize Folder Icon",
|
||||
"button_done": "Awesome, I’m done!",
|
||||
"button_generate": "Generate Link",
|
||||
"label_password_protection": "Password Protected",
|
||||
"label_permission": "Permission",
|
||||
"label_shared_url": "Share url",
|
||||
"label_share_vie_email": "Get your link",
|
||||
"label_send_to_recipients": "Send to Recipients",
|
||||
"label_expiration": "Link Expiration",
|
||||
"expiration_hour": "{value}h.",
|
||||
"expiration_day": "{value}d.",
|
||||
"placeholder_permission": "Select your permission"
|
||||
"placeholder_permission": "Select your permission",
|
||||
"email_successfully_send_message": "Your item was <b>successfully sended</b> to recipients emails.",
|
||||
"share_by_link": "Share by Link",
|
||||
"share_by_email": "Share by Email",
|
||||
"recipients_label": "Recipients",
|
||||
"email_placeholder": "Type your emails"
|
||||
},
|
||||
"sidebar": {
|
||||
"favourites": "Favourites",
|
||||
@@ -804,7 +822,9 @@
|
||||
"state": "State",
|
||||
"state_plac": "Type your billing state",
|
||||
"title_account": "Account Information",
|
||||
"title_billing": "Billing Information"
|
||||
"title_billing": "Billing Information",
|
||||
"timezone": "Timezone",
|
||||
"timezone_plac" : "Select your timezone"
|
||||
},
|
||||
"user_subscription": {
|
||||
"billed": "Billed",
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"users": "Uživatelia"
|
||||
},
|
||||
"admin_page_dashboard": {
|
||||
"backer_button": "Staňte sa podporovateľom",
|
||||
"backer_button": "Pomôžte nám zlepšiť sa",
|
||||
"license": "Licencia",
|
||||
"version": "Verzia",
|
||||
"w_latest_users": {
|
||||
@@ -285,7 +285,8 @@
|
||||
"share_edit": "Upraviť zdieľanie",
|
||||
"upload": "Nahrať",
|
||||
"select": "Výber",
|
||||
"no_options": "Nie sú k dispozícii žiadne možnosti"
|
||||
"no_options": "Nie sú k dispozícii žiadne možnosti",
|
||||
"zip_folder": "Zazipovať priečinok"
|
||||
},
|
||||
"mobile_selecting": {
|
||||
"select_all": "Vybrať všetko",
|
||||
@@ -599,7 +600,9 @@
|
||||
"confirm": "Potvrdiť",
|
||||
"save": "Uložiť zmeny",
|
||||
"stop": "Zastaviť zdieľanie",
|
||||
"title": "Upraviť nastavenia zdieľania"
|
||||
"title": "Upraviť nastavenia zdieľania",
|
||||
"go_back": "Spať",
|
||||
"send_to_recipients": "Odoslať príjemcom"
|
||||
},
|
||||
"popup_signup_error": {
|
||||
"message": "Prosím skontrolujte databázove spojenie, či všetko funguje správne.",
|
||||
@@ -691,10 +694,17 @@
|
||||
"label_password_protection": "Chrániť heslom",
|
||||
"label_permission": "Oprávnenie",
|
||||
"label_shared_url": "Zdieľací odkaz",
|
||||
"label_share_vie_email": "Získajte odkaz",
|
||||
"label_send_to_recipients": "Odoslať príjemcom",
|
||||
"label_expiration": "Expirácia Linku",
|
||||
"expiration_hour": "{value}h.",
|
||||
"expiration_day": "{value}d.",
|
||||
"placeholder_permission": "Zvoľte oprávnenia"
|
||||
"placeholder_permission": "Zvoľte oprávnenia",
|
||||
"email_successfully_send_message": "Vaša položka bola <b>úspešne odoslaná</b> na e-maily príjemcov.",
|
||||
"share_by_link": "Zdieľať odkazom",
|
||||
"share_by_email": "Zdieľať e-mailom",
|
||||
"recipients_label": "Príjemcovia",
|
||||
"email_placeholder": "Zadajte e-mailové adresy"
|
||||
},
|
||||
"sidebar": {
|
||||
"favourites": "Obľúbené",
|
||||
@@ -804,7 +814,9 @@
|
||||
"state": "Štát",
|
||||
"state_plac": "Zadajte Štát",
|
||||
"title_account": "informácie o účte",
|
||||
"title_billing": "Fakturačné údaje"
|
||||
"title_billing": "Fakturačné údaje",
|
||||
"timezone": "Časové pásmo",
|
||||
"timezone_plac" : "Vyberte svoje časové pásmo"
|
||||
},
|
||||
"user_subscription": {
|
||||
"billed": "Ůčtované",
|
||||
|
||||
3
resources/js/main.js
vendored
3
resources/js/main.js
vendored
@@ -90,8 +90,9 @@ Vue.use(Helpers);
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
// Handle position of Drag & Drop Ghost
|
||||
document.addEventListener('drag', (event) => {
|
||||
document.addEventListener('drag', event => {
|
||||
let multiSelect = document.getElementById('multi-select-ui')
|
||||
|
||||
multiSelect.style.top = event.clientY + 20 + 'px'
|
||||
multiSelect.style.left = event.clientX + 'px'
|
||||
|
||||
|
||||
2
resources/js/store/index.js
vendored
2
resources/js/store/index.js
vendored
@@ -3,6 +3,7 @@ import Vue from 'vue'
|
||||
|
||||
import fileFunctions from './modules/fileFunctions'
|
||||
import fileBrowser from './modules/fileBrowser'
|
||||
import emojisList from './modules/emojisList'
|
||||
import userAuth from './modules/userAuth'
|
||||
import sharing from './modules/sharing'
|
||||
import app from './modules/app'
|
||||
@@ -13,6 +14,7 @@ export default new Vuex.Store({
|
||||
modules: {
|
||||
fileFunctions,
|
||||
fileBrowser,
|
||||
emojisList,
|
||||
userAuth,
|
||||
sharing,
|
||||
app,
|
||||
|
||||
129
resources/js/store/modules/app.js
vendored
129
resources/js/store/modules/app.js
vendored
@@ -1,7 +1,7 @@
|
||||
import i18n from '@/i18n/index'
|
||||
|
||||
const defaultState = {
|
||||
fileInfoPanelVisible: localStorage.getItem('file_info_visibility') == 'true' || false,
|
||||
fileInfoPanelVisible: localStorage.getItem('file_info_visibility') == 'true' || true,
|
||||
FilePreviewType: localStorage.getItem('preview_type') || 'list',
|
||||
config: undefined,
|
||||
index: undefined,
|
||||
@@ -839,6 +839,132 @@ const defaultState = {
|
||||
value: 'ZMW',
|
||||
},
|
||||
],
|
||||
timezones : [
|
||||
{
|
||||
value: "-12.0",
|
||||
label: "(GMT -12:00) Eniwetok, Kwajalein"
|
||||
},
|
||||
{
|
||||
value: "-11.0",
|
||||
label: "(GMT -11:00) Midway Island, Samoa"
|
||||
},
|
||||
{
|
||||
value: "-10.0",
|
||||
label: "(GMT -10:00) Hawaii"
|
||||
},
|
||||
{
|
||||
value: "-9.0",
|
||||
label: "(GMT -9:00) Alaska"
|
||||
},
|
||||
{
|
||||
value: "-8.0",
|
||||
label: "(GMT -8:00) Pacific Time (US & Canada)"
|
||||
},
|
||||
{
|
||||
value: "-7.0",
|
||||
label: "(GMT -7:00) Mountain Time (US & Canada)"
|
||||
},
|
||||
{
|
||||
value: "-6.0",
|
||||
label: "(GMT -6:00) Central Time (US & Canada), Mexico City"
|
||||
},
|
||||
{
|
||||
value: "-5.0",
|
||||
label: "(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima"
|
||||
},
|
||||
{
|
||||
value: "-4.0",
|
||||
label: "(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz"
|
||||
},
|
||||
{
|
||||
value: "-3.5",
|
||||
label: "(GMT -3:30) Newfoundland"
|
||||
},
|
||||
{
|
||||
value: "-3.0",
|
||||
label: "(GMT -3:00) Brazil, Buenos Aires, Georgetown"
|
||||
},
|
||||
{
|
||||
value: "-2.0",
|
||||
label: "(GMT -2:00) Mid-Atlantic"
|
||||
},
|
||||
{
|
||||
value: "-1.0",
|
||||
label: "(GMT -1:00) Azores, Cape Verde Islands"
|
||||
},
|
||||
{
|
||||
value: "0.0",
|
||||
label: "(GMT) Western Europe Time, London, Lisbon, Casablanca"
|
||||
},
|
||||
{
|
||||
value: "1.0",
|
||||
label: "(GMT +1:00) Brussels, Copenhagen, Madrid, Paris"
|
||||
},
|
||||
{
|
||||
value: "2.0",
|
||||
label: "(GMT +2:00) Kaliningrad, South Africa"
|
||||
},
|
||||
{
|
||||
value: "3.0",
|
||||
label: "(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg"
|
||||
},
|
||||
{
|
||||
value: "3.5",
|
||||
label: "(GMT +3:30) Tehran"
|
||||
},
|
||||
{
|
||||
value: "4.0",
|
||||
label: "(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi"
|
||||
},
|
||||
{
|
||||
value: "4.5",
|
||||
label: "(GMT +4:30) Kabul"
|
||||
},
|
||||
{
|
||||
value: "5.0",
|
||||
label: "(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent"
|
||||
},
|
||||
{
|
||||
value: "5.5",
|
||||
label: "(GMT +5:30) Bombay, Calcutta, Madras, New Delhi"
|
||||
},
|
||||
{
|
||||
value: "5.75",
|
||||
label: "(GMT +5:45) Kathmandu"
|
||||
},
|
||||
{
|
||||
value: "6.0",
|
||||
label: "(GMT +6:00) Almaty, Dhaka, Colombo"
|
||||
},
|
||||
{
|
||||
value: "7.0",
|
||||
label: "(GMT +7:00) Bangkok, Hanoi, Jakarta"
|
||||
},
|
||||
{
|
||||
value: "8.0",
|
||||
label: "(GMT +8:00) Beijing, Perth, Singapore, Hong Kong"
|
||||
},
|
||||
{
|
||||
value: "9.0",
|
||||
label: "(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk"
|
||||
},
|
||||
{
|
||||
value: "9.5",
|
||||
label: "(GMT +9:30) Adelaide, Darwin"
|
||||
},
|
||||
{
|
||||
value: "10.0",
|
||||
label: "(GMT +10:00) Eastern Australia, Guam, Vladivostok"
|
||||
},
|
||||
{
|
||||
value: "11.0",
|
||||
label: "(GMT +11:00) Magadan, Solomon Islands, New Caledonia"
|
||||
},
|
||||
{
|
||||
value: "12.0",
|
||||
label: "(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka"
|
||||
}
|
||||
]
|
||||
}
|
||||
const actions = {
|
||||
changePreviewType: ({commit, state}, preview) => {
|
||||
@@ -906,6 +1032,7 @@ const getters = {
|
||||
requestedPlan: state => state.requestedPlan,
|
||||
currencyList: state => state.currencyList,
|
||||
countries: state => state.countries,
|
||||
timezones: state=> state.timezones,
|
||||
api: state => state.config.api,
|
||||
config: state => state.config,
|
||||
index: state => state.index,
|
||||
|
||||
14038
resources/js/store/modules/emojisList.js
vendored
Normal file
14038
resources/js/store/modules/emojisList.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10
resources/js/store/modules/fileBrowser.js
vendored
10
resources/js/store/modules/fileBrowser.js
vendored
@@ -80,7 +80,7 @@ const actions = {
|
||||
})
|
||||
|
||||
axios
|
||||
.get(getters.api + '/latest' + getters.sorting.URI)
|
||||
.get(getters.api + '/latest' )
|
||||
.then(response => {
|
||||
commit('LOADING_STATE', {loading: false, data: response.data})
|
||||
events.$emit('scrollTop')
|
||||
@@ -209,6 +209,7 @@ const mutations = {
|
||||
state.navigation = tree
|
||||
},
|
||||
LOADING_STATE(state, payload) {
|
||||
state.fileInfoDetail= []
|
||||
state.data = payload.data
|
||||
state.isLoading = payload.loading
|
||||
},
|
||||
@@ -227,7 +228,6 @@ const mutations = {
|
||||
state.browseHistory.pop()
|
||||
},
|
||||
CHANGE_ITEM_NAME(state, updatedFile) {
|
||||
|
||||
// Rename filename in file info detail
|
||||
if (state.fileInfoDetail && state.fileInfoDetail.unique_id == updatedFile.unique_id) {
|
||||
state.fileInfoDetail = updatedFile
|
||||
@@ -235,7 +235,11 @@ const mutations = {
|
||||
|
||||
// Rename item name in data view
|
||||
state.data.find(item => {
|
||||
if (item.unique_id == updatedFile.unique_id) item.name = updatedFile.name
|
||||
if (item.unique_id == updatedFile.unique_id) {
|
||||
item.name = updatedFile.name
|
||||
item.icon_color = updatedFile.icon_color ? updatedFile.icon_color : null
|
||||
item.icon_emoji = updatedFile.icon_emoji ? updatedFile.icon_emoji : null
|
||||
}
|
||||
})
|
||||
},
|
||||
REMOVE_ITEM_FILEINFO_DETAIL(state,item) {
|
||||
|
||||
60
resources/js/store/modules/fileFunctions.js
vendored
60
resources/js/store/modules/fileFunctions.js
vendored
@@ -6,10 +6,34 @@ import axios from 'axios'
|
||||
import Vue from 'vue'
|
||||
|
||||
const defaultState = {
|
||||
isZippingFiles: false,
|
||||
processingPopup: undefined,
|
||||
}
|
||||
|
||||
const actions = {
|
||||
downloadFolder: ({commit, getters}, folder) => {
|
||||
|
||||
commit('PROCESSING_POPUP', {
|
||||
title: i18n.t('popup_zipping.title'),
|
||||
message: i18n.t('popup_zipping.message'),
|
||||
})
|
||||
|
||||
// Get route
|
||||
let route = getters.sharedDetail && !getters.sharedDetail.protected
|
||||
? '/api/zip-folder/' + folder.unique_id + '/public/' + router.currentRoute.params.token
|
||||
: '/api/zip-folder/' + folder.unique_id
|
||||
|
||||
axios.get(route)
|
||||
.then(response => {
|
||||
Vue.prototype.$downloadFile(response.data.url, response.data.name)
|
||||
})
|
||||
.catch(() => {
|
||||
Vue.prototype.$isSomethingWrong()
|
||||
})
|
||||
.finally(() => {
|
||||
commit('PROCESSING_POPUP', undefined)
|
||||
})
|
||||
|
||||
},
|
||||
downloadFiles: ({ commit, getters }) => {
|
||||
let files = []
|
||||
|
||||
@@ -96,6 +120,11 @@ const actions = {
|
||||
|
||||
events.$emit('scrollTop')
|
||||
|
||||
//Set focus on new folder name
|
||||
setTimeout(() => {
|
||||
events.$emit('newFolder:focus', response.data.unique_id)
|
||||
}, 10);
|
||||
|
||||
if (getters.currentFolder.location !== 'public')
|
||||
dispatch('getAppData')
|
||||
if (getters.currentFolder.location === 'public')
|
||||
@@ -119,6 +148,7 @@ const actions = {
|
||||
.post(route, {
|
||||
name: data.name,
|
||||
type: data.type,
|
||||
folder_icon: data.folder_icon,
|
||||
_method: 'patch'
|
||||
})
|
||||
.then(response => {
|
||||
@@ -220,24 +250,36 @@ const actions = {
|
||||
},
|
||||
restoreItem: ({ commit, getters }, item) => {
|
||||
|
||||
let itemToRestore = []
|
||||
let items = [item]
|
||||
let restoreToHome = false
|
||||
|
||||
// If coming no selected item dont get items to restore from fileInfoDetail
|
||||
if (!item)
|
||||
items = getters.fileInfoDetail
|
||||
|
||||
// Check if file can be restored to home directory
|
||||
if (getters.currentFolder.location === 'trash')
|
||||
restoreToHome = true
|
||||
|
||||
// Remove file
|
||||
commit('REMOVE_ITEM', item.unique_id)
|
||||
items.forEach(data => itemToRestore.push({
|
||||
'type': data.type,
|
||||
'unique_id': data.unique_id,
|
||||
}))
|
||||
|
||||
// Remove file preview
|
||||
commit('CLEAR_FILEINFO_DETAIL')
|
||||
|
||||
axios
|
||||
.post(getters.api + '/restore-item/' + item.unique_id, {
|
||||
type: item.type,
|
||||
.post(getters.api + '/restore-items' ,{
|
||||
to_home: restoreToHome,
|
||||
_method: 'patch'
|
||||
data: itemToRestore,
|
||||
})
|
||||
.then(
|
||||
|
||||
// Remove file
|
||||
items.forEach( data => commit('REMOVE_ITEM', data.unique_id) )
|
||||
)
|
||||
.catch(() => Vue.prototype.$isSomethingWrong())
|
||||
},
|
||||
deleteItem: ({ commit, getters, dispatch }, noSelectedItem) => {
|
||||
@@ -340,13 +382,13 @@ const actions = {
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
ZIPPING_FILE_STATUS(state, status) {
|
||||
state.isZippingFiles = status
|
||||
PROCESSING_POPUP(state, status) {
|
||||
state.processingPopup = status
|
||||
}
|
||||
}
|
||||
|
||||
const getters = {
|
||||
isZippingFiles: state => state.isZippingFiles
|
||||
processingPopup: state => state.processingPopup
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
11
resources/js/store/modules/userAuth.js
vendored
11
resources/js/store/modules/userAuth.js
vendored
@@ -39,11 +39,18 @@ const actions = {
|
||||
})
|
||||
},
|
||||
logOut: ({getters, commit}) => {
|
||||
|
||||
let popup = setTimeout(() => {
|
||||
commit('PROCESSING_POPUP', {
|
||||
title: 'Logging Out',
|
||||
message: 'Wait a second...',
|
||||
})
|
||||
}, 300)
|
||||
|
||||
axios
|
||||
.get(getters.api + '/logout')
|
||||
.then(() => {
|
||||
|
||||
// Commit Remove Access Token from vuex storage
|
||||
clearTimeout(popup)
|
||||
commit('DESTROY_DATA')
|
||||
|
||||
router.push({name: 'SignIn'})
|
||||
|
||||
@@ -30,6 +30,14 @@
|
||||
{{ $t('admin_menu.settings') }}
|
||||
</div>
|
||||
</router-link>
|
||||
<router-link :to="{name: 'Pages'}" class="menu-list-item link">
|
||||
<div class="icon">
|
||||
<monitor-icon size="17"></monitor-icon>
|
||||
</div>
|
||||
<div class="label">
|
||||
{{ $t('admin_menu.pages') }}
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</ContentGroup>
|
||||
|
||||
@@ -52,14 +60,6 @@
|
||||
{{ $t('admin_menu.invoices') }}
|
||||
</div>
|
||||
</router-link>
|
||||
<router-link :to="{name: 'Pages'}" class="menu-list-item link">
|
||||
<div class="icon">
|
||||
<monitor-icon size="17"></monitor-icon>
|
||||
</div>
|
||||
<div class="label">
|
||||
{{ $t('admin_menu.pages') }}
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</ContentGroup>
|
||||
</ContentSidebar>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
</div>
|
||||
</router-link>
|
||||
|
||||
<router-link v-if="config.isSaaS" replace :to="{name: 'AppIndex'}" class="menu-list-item link">
|
||||
<router-link replace :to="{name: 'AppIndex'}" class="menu-list-item link">
|
||||
<div class="icon">
|
||||
<home-icon size="17"></home-icon>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,27 @@
|
||||
<template>
|
||||
<PageTab :is-loading="isLoading" class="form-fixed-width">
|
||||
|
||||
<PageTabGroup>
|
||||
<PageTabGroup v-if="app">
|
||||
<div class="form block-form">
|
||||
|
||||
<FormLabel>Home Page</FormLabel>
|
||||
|
||||
<div class="block-wrapper">
|
||||
<div class="input-wrapper">
|
||||
<div class="inline-wrapper">
|
||||
<div class="switch-label">
|
||||
<label class="input-label">
|
||||
Allow Homepage
|
||||
</label>
|
||||
<small class="input-help">
|
||||
When this is turned on, your visitors can visit your default homepage.
|
||||
</small>
|
||||
</div>
|
||||
<SwitchInput @input="$updateText('/settings', 'allow_homepage', app.allow_homepage)" v-model="app.allow_homepage" class="switch" :state="app.allow_homepage"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Header-->
|
||||
<div>
|
||||
<FormLabel>Header Title</FormLabel>
|
||||
@@ -15,9 +33,7 @@
|
||||
<div class="block-wrapper">
|
||||
<label>Title:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }">
|
||||
<input @input="$updateText('/settings', 'header_title', header_title)" v-model="header_title"
|
||||
type="text"
|
||||
:class="{'is-error': errors[0]}"/>
|
||||
<input @input="$updateText('/settings', 'header_title', app.header_title)" v-model="app.header_title" type="text" :class="{'is-error': errors[0]}"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -25,8 +41,7 @@
|
||||
<div class="block-wrapper">
|
||||
<label>Description:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }">
|
||||
<textarea @input="$updateText('/settings', 'header_description', header_description)" rows="2" v-model="header_description"
|
||||
:class="{'is-error': errors[0]}"></textarea>
|
||||
<textarea @input="$updateText('/settings', 'header_description', app.header_description)" rows="2" v-model="app.header_description" :class="{'is-error': errors[0]}"></textarea>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -44,18 +59,13 @@
|
||||
Show section:
|
||||
</label>
|
||||
</div>
|
||||
<SwitchInput
|
||||
@input="$updateText('/settings', 'section_features', section_features)"
|
||||
v-model="section_features"
|
||||
class="switch"
|
||||
:state="section_features"
|
||||
/>
|
||||
<SwitchInput @input="$updateText('/settings', 'section_features', app.section_features)" v-model="app.section_features" class="switch" :state="app.section_features"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="section_features">
|
||||
<div v-if="app.section_features">
|
||||
<div class="block-wrapper">
|
||||
<img src="/assets/images/admin/main-features.jpg" alt="Main Features" class="page-image">
|
||||
</div>
|
||||
@@ -63,9 +73,7 @@
|
||||
<div class="block-wrapper">
|
||||
<label>Title:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }">
|
||||
<input @input="$updateText('/settings', 'features_title', features_title)" v-model="features_title"
|
||||
type="text"
|
||||
:class="{'is-error': errors[0]}"/>
|
||||
<input @input="$updateText('/settings', 'features_title', app.features_title)" v-model="app.features_title" type="text" :class="{'is-error': errors[0]}"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -73,8 +81,7 @@
|
||||
<div class="block-wrapper">
|
||||
<label>Description:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }">
|
||||
<textarea @input="$updateText('/settings', 'features_description', features_description)" rows="2" v-model="features_description"
|
||||
:class="{'is-error': errors[0]}"></textarea>
|
||||
<textarea @input="$updateText('/settings', 'features_description', app.features_description)" rows="2" v-model="app.features_description" :class="{'is-error': errors[0]}"></textarea>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -93,68 +100,54 @@
|
||||
Show section:
|
||||
</label>
|
||||
</div>
|
||||
<SwitchInput
|
||||
@input="$updateText('/settings', 'section_feature_boxes', section_feature_boxes)"
|
||||
v-model="section_feature_boxes"
|
||||
class="switch"
|
||||
:state="section_feature_boxes"
|
||||
/>
|
||||
<SwitchInput @input="$updateText('/settings', 'section_feature_boxes', app.section_feature_boxes)" v-model="app.section_feature_boxes" class="switch" :state="app.section_feature_boxes"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="section_feature_boxes">
|
||||
<div v-if="app.section_feature_boxes">
|
||||
<div class="block-wrapper">
|
||||
<img src="/assets/images/admin/feature-boxes.jpg" alt="Main Features" class="page-image">
|
||||
</div>
|
||||
<div class="block-wrapper">
|
||||
<label>First Box Title:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Title 1" rules="required" v-slot="{ errors }">
|
||||
<input @input="$updateText('/settings', 'feature_title_1', feature_title_1)" v-model="feature_title_1"
|
||||
type="text"
|
||||
:class="{'is-error': errors[0]}"/>
|
||||
<input @input="$updateText('/settings', 'feature_title_1', app.feature_title_1)" v-model="app.feature_title_1" type="text" :class="{'is-error': errors[0]}"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
<div class="block-wrapper">
|
||||
<label>First Box Description:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Description 1" rules="required" v-slot="{ errors }">
|
||||
<textarea @input="$updateText('/settings', 'feature_description_1', feature_description_1)" rows="2" v-model="feature_description_1"
|
||||
:class="{'is-error': errors[0]}"></textarea>
|
||||
<textarea @input="$updateText('/settings', 'feature_description_1', app.feature_description_1)" rows="2" v-model="app.feature_description_1" :class="{'is-error': errors[0]}"></textarea>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
<div class="block-wrapper">
|
||||
<label>Second Box Title:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Title 2" rules="required" v-slot="{ errors }">
|
||||
<input @input="$updateText('/settings', 'feature_title_2', feature_title_2)" v-model="feature_title_2"
|
||||
type="text"
|
||||
:class="{'is-error': errors[0]}"/>
|
||||
<input @input="$updateText('/settings', 'feature_title_2', app.feature_title_2)" v-model="app.feature_title_2" type="text" :class="{'is-error': errors[0]}"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
<div class="block-wrapper">
|
||||
<label>Second Box Description:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Description 2" rules="required" v-slot="{ errors }">
|
||||
<textarea @input="$updateText('/settings', 'feature_description_2', feature_description_2)" rows="2" v-model="feature_description_2"
|
||||
:class="{'is-error': errors[0]}"></textarea>
|
||||
<textarea @input="$updateText('/settings', 'feature_description_2', app.feature_description_2)" rows="2" v-model="app.feature_description_2" :class="{'is-error': errors[0]}"></textarea>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
<div class="block-wrapper">
|
||||
<label>Third Box Title:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Title 3" rules="required" v-slot="{ errors }">
|
||||
<input @input="$updateText('/settings', 'feature_title_3', feature_title_3)" v-model="feature_title_3"
|
||||
type="text"
|
||||
:class="{'is-error': errors[0]}"/>
|
||||
<input @input="$updateText('/settings', 'feature_title_3', app.feature_title_3)" v-model="app.feature_title_3" type="text" :class="{'is-error': errors[0]}"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
<div class="block-wrapper">
|
||||
<label>Third Box Description:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="Feature Description 3" rules="required" v-slot="{ errors }">
|
||||
<textarea @input="$updateText('/settings', 'feature_description_3', feature_description_3)" rows="2" v-model="feature_description_3"
|
||||
:class="{'is-error': errors[0]}"></textarea>
|
||||
<textarea @input="$updateText('/settings', 'feature_description_3', app.feature_description_3)" rows="2" v-model="app.feature_description_3" :class="{'is-error': errors[0]}"></textarea>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -162,7 +155,7 @@
|
||||
</div>
|
||||
|
||||
<!--Pricing Content-->
|
||||
<div>
|
||||
<div v-if="config.isSaaS">
|
||||
<FormLabel class="mt-70">Pricing Content</FormLabel>
|
||||
|
||||
<div class="block-wrapper">
|
||||
@@ -173,27 +166,19 @@
|
||||
Show section:
|
||||
</label>
|
||||
</div>
|
||||
<SwitchInput
|
||||
@input="$updateText('/settings', 'section_pricing_content', section_pricing_content)"
|
||||
v-model="section_pricing_content"
|
||||
class="switch"
|
||||
:state="section_pricing_content"
|
||||
/>
|
||||
<SwitchInput @input="$updateText('/settings', 'section_pricing_content', app.section_pricing_content)" v-model="app.section_pricing_content" class="switch" :state="app.section_pricing_content"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="section_pricing_content">
|
||||
<div v-if="app.section_pricing_content">
|
||||
<div class="block-wrapper">
|
||||
<img src="/assets/images/admin/pricing-content.jpg" alt="Main Features" class="page-image">
|
||||
</div>
|
||||
<div class="block-wrapper">
|
||||
<label>Title:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }">
|
||||
<input @input="$updateText('/settings', 'pricing_title', pricing_title)" v-model="pricing_title"
|
||||
type="text"
|
||||
:class="{'is-error': errors[0]}"/>
|
||||
<input @input="$updateText('/settings', 'pricing_title', app.pricing_title)" v-model="app.pricing_title" type="text" :class="{'is-error': errors[0]}"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -201,8 +186,7 @@
|
||||
<div class="block-wrapper">
|
||||
<label>Description:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }">
|
||||
<textarea @input="$updateText('/settings', 'pricing_description', pricing_description)" rows="2" v-model="pricing_description"
|
||||
:class="{'is-error': errors[0]}"></textarea>
|
||||
<textarea @input="$updateText('/settings', 'pricing_description', app.pricing_description)" rows="2" v-model="app.pricing_description" :class="{'is-error': errors[0]}"></textarea>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -221,27 +205,20 @@
|
||||
Show section:
|
||||
</label>
|
||||
</div>
|
||||
<SwitchInput
|
||||
@input="$updateText('/settings', 'section_get_started', section_get_started)"
|
||||
v-model="section_get_started"
|
||||
class="switch"
|
||||
:state="section_get_started"
|
||||
/>
|
||||
<SwitchInput @input="$updateText('/settings', 'section_get_started', app.section_get_started)" v-model="app.section_get_started" class="switch" :state="app.section_get_started"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="section_get_started">
|
||||
<div v-if="app.section_get_started">
|
||||
<div class="block-wrapper">
|
||||
<img src="/assets/images/admin/get-started-content.jpg" alt="Main Features" class="page-image">
|
||||
</div>
|
||||
<div class="block-wrapper">
|
||||
<label>Title:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }">
|
||||
<input @input="$updateText('/settings', 'get_started_title', get_started_title)" v-model="get_started_title"
|
||||
type="text"
|
||||
:class="{'is-error': errors[0]}"/>
|
||||
<input @input="$updateText('/settings', 'get_started_title', app.get_started_title)" v-model="app.get_started_title" type="text" :class="{'is-error': errors[0]}"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -249,8 +226,7 @@
|
||||
<div class="block-wrapper">
|
||||
<label>Description:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Description" rules="required" v-slot="{ errors }">
|
||||
<textarea @input="$updateText('/settings', 'get_started_description', get_started_description)" rows="2" v-model="get_started_description"
|
||||
:class="{'is-error': errors[0]}"></textarea>
|
||||
<textarea @input="$updateText('/settings', 'get_started_description', app.get_started_description)" rows="2" v-model="app.get_started_description" :class="{'is-error': errors[0]}"></textarea>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -264,9 +240,7 @@
|
||||
<div class="block-wrapper">
|
||||
<label>Footer content:</label>
|
||||
<ValidationProvider tag="div" mode="passive" class="input-wrapper" name="App Title" rules="required" v-slot="{ errors }">
|
||||
<input @input="$updateText('/settings', 'footer_content', footer_content)" v-model="footer_content"
|
||||
type="text"
|
||||
:class="{'is-error': errors[0]}"/>
|
||||
<input @input="$updateText('/settings', 'footer_content', app.footer_content)" v-model="app.footer_content" type="text" :class="{'is-error': errors[0]}"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
@@ -277,125 +251,100 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
|
||||
import StorageItemDetail from '@/components/Others/StorageItemDetail'
|
||||
import PageTabGroup from '@/components/Others/Layout/PageTabGroup'
|
||||
import SelectInput from '@/components/Others/Forms/SelectInput'
|
||||
import SwitchInput from '@/components/Others/Forms/SwitchInput'
|
||||
import ImageInput from '@/components/Others/Forms/ImageInput'
|
||||
import FormLabel from '@/components/Others/Forms/FormLabel'
|
||||
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||
import SetupBox from '@/components/Others/Forms/SetupBox'
|
||||
import PageTab from '@/components/Others/Layout/PageTab'
|
||||
import InfoBox from '@/components/Others/Forms/InfoBox'
|
||||
import {required} from 'vee-validate/dist/rules'
|
||||
import axios from 'axios'
|
||||
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
|
||||
import StorageItemDetail from '@/components/Others/StorageItemDetail'
|
||||
import PageTabGroup from '@/components/Others/Layout/PageTabGroup'
|
||||
import SelectInput from '@/components/Others/Forms/SelectInput'
|
||||
import SwitchInput from '@/components/Others/Forms/SwitchInput'
|
||||
import ImageInput from '@/components/Others/Forms/ImageInput'
|
||||
import FormLabel from '@/components/Others/Forms/FormLabel'
|
||||
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||
import SetupBox from '@/components/Others/Forms/SetupBox'
|
||||
import PageTab from '@/components/Others/Layout/PageTab'
|
||||
import InfoBox from '@/components/Others/Forms/InfoBox'
|
||||
import { required } from 'vee-validate/dist/rules'
|
||||
import axios from 'axios'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'AppIndex',
|
||||
components: {
|
||||
ValidationObserver,
|
||||
ValidationProvider,
|
||||
StorageItemDetail,
|
||||
PageTabGroup,
|
||||
SwitchInput,
|
||||
SelectInput,
|
||||
ImageInput,
|
||||
ButtonBase,
|
||||
FormLabel,
|
||||
SetupBox,
|
||||
required,
|
||||
PageTab,
|
||||
InfoBox,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: true,
|
||||
section_features: 1,
|
||||
section_feature_boxes: 1,
|
||||
section_pricing_content: 1,
|
||||
section_get_started: 1,
|
||||
|
||||
header_title: '',
|
||||
header_description: '',
|
||||
|
||||
features_title: '',
|
||||
features_description: '',
|
||||
|
||||
feature_title_1: '',
|
||||
feature_description_1: '',
|
||||
|
||||
feature_title_2: '',
|
||||
feature_description_2: '',
|
||||
|
||||
feature_title_3: '',
|
||||
feature_description_3: '',
|
||||
|
||||
pricing_title: '',
|
||||
pricing_description: '',
|
||||
|
||||
get_started_title: '',
|
||||
get_started_description: '',
|
||||
|
||||
footer_content: '',
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
axios.get('/api/settings', {
|
||||
params: {
|
||||
column: 'footer_content|get_started_description|get_started_title|pricing_description|pricing_title|feature_description_3|feature_title_3|feature_description_2|feature_title_2|feature_description_1|feature_title_1|features_description|features_title|header_description|header_title|section_get_started|section_pricing_content|section_feature_boxes|section_features'
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
this.section_features = parseInt(response.data.section_features)
|
||||
this.section_feature_boxes = parseInt(response.data.section_feature_boxes)
|
||||
this.section_pricing_content = parseInt(response.data.section_pricing_content)
|
||||
this.section_get_started = parseInt(response.data.section_get_started)
|
||||
|
||||
this.header_title = response.data.header_title
|
||||
this.header_description = response.data.header_description
|
||||
|
||||
this.features_title = response.data.features_title
|
||||
this.features_description = response.data.features_description
|
||||
|
||||
this.feature_title_1 = response.data.feature_title_1
|
||||
this.feature_description_1 = response.data.feature_description_1
|
||||
|
||||
this.feature_title_2 = response.data.feature_title_2
|
||||
this.feature_description_2 = response.data.feature_description_2
|
||||
|
||||
this.feature_title_3 = response.data.feature_title_3
|
||||
this.feature_description_3 = response.data.feature_description_3
|
||||
|
||||
this.pricing_title = response.data.pricing_title
|
||||
this.pricing_description = response.data.pricing_description
|
||||
|
||||
this.get_started_title = response.data.get_started_title
|
||||
this.get_started_description = response.data.get_started_description
|
||||
|
||||
this.footer_content = response.data.footer_content
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
export default {
|
||||
name: 'AppIndex',
|
||||
components: {
|
||||
ValidationObserver,
|
||||
ValidationProvider,
|
||||
StorageItemDetail,
|
||||
PageTabGroup,
|
||||
SwitchInput,
|
||||
SelectInput,
|
||||
ImageInput,
|
||||
ButtonBase,
|
||||
FormLabel,
|
||||
SetupBox,
|
||||
required,
|
||||
PageTab,
|
||||
InfoBox
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['config'])
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoading: true,
|
||||
app: undefined
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
axios.get('/api/settings', {
|
||||
params: {
|
||||
column: 'allow_homepage|footer_content|get_started_description|get_started_title|pricing_description|pricing_title|feature_description_3|feature_title_3|feature_description_2|feature_title_2|feature_description_1|feature_title_1|features_description|features_title|header_description|header_title|section_get_started|section_pricing_content|section_feature_boxes|section_features'
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
this.app = {
|
||||
allow_homepage: parseInt(response.data.allow_homepage),
|
||||
section_features: parseInt(response.data.section_features),
|
||||
section_feature_boxes: parseInt(response.data.section_feature_boxes),
|
||||
section_pricing_content: parseInt(response.data.section_pricing_content),
|
||||
section_get_started: parseInt(response.data.section_get_started),
|
||||
header_title: response.data.header_title,
|
||||
header_description: response.data.header_description,
|
||||
features_title: response.data.features_title,
|
||||
features_description: response.data.features_description,
|
||||
feature_title_1: response.data.feature_title_1,
|
||||
feature_description_1: response.data.feature_description_1,
|
||||
feature_title_2: response.data.feature_title_2,
|
||||
feature_description_2: response.data.feature_description_2,
|
||||
feature_title_3: response.data.feature_title_3,
|
||||
feature_description_3: response.data.feature_description_3,
|
||||
pricing_title: response.data.pricing_title,
|
||||
pricing_description: response.data.pricing_description,
|
||||
get_started_title: response.data.get_started_title,
|
||||
get_started_description: response.data.get_started_description,
|
||||
footer_content: response.data.footer_content
|
||||
}
|
||||
|
||||
console.log(this.app);
|
||||
})
|
||||
.finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@assets/vue-file-manager/_variables';
|
||||
@import '@assets/vue-file-manager/_mixins';
|
||||
@import '@assets/vue-file-manager/_forms';
|
||||
@import '@assets/vue-file-manager/_variables';
|
||||
@import '@assets/vue-file-manager/_mixins';
|
||||
@import '@assets/vue-file-manager/_forms';
|
||||
|
||||
.block-form {
|
||||
max-width: 100%;
|
||||
}
|
||||
.block-form {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.page-image {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #ececec;
|
||||
}
|
||||
.page-image {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #ececec;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
{{ data.license }}
|
||||
</ColorLabel>
|
||||
</a>
|
||||
<a v-if="! config.isDemo" href="https://vuefilemanager.com/become-a-backer" target="_blank" class="became-backer">
|
||||
<a href="https://bit.ly/VueFileManager-survey" target="_blank" class="became-backer">
|
||||
<div class="icon">
|
||||
<credit-card-icon size="15"></credit-card-icon>
|
||||
</div>
|
||||
@@ -177,7 +177,7 @@
|
||||
}
|
||||
|
||||
.became-backer {
|
||||
background: rgba($yellow, 0.1);
|
||||
background: rgba($theme, 0.1);
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
border-radius: 6px;
|
||||
@@ -194,12 +194,12 @@
|
||||
line-height: 0;
|
||||
|
||||
rect, line {
|
||||
stroke: $yellow;
|
||||
stroke: $theme;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
color: $yellow;
|
||||
color: $theme;
|
||||
font-weight: 700;
|
||||
@include font-size(14);
|
||||
}
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
},
|
||||
created() {
|
||||
this.$scrollTop()
|
||||
this.$store.commit('PROCESSING_POPUP', undefined)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<i18n v-if="config.isSaaS" path="page_registration.agreement" tag="p" class="legal-agreement">
|
||||
<i18n path="page_registration.agreement" tag="p" class="legal-agreement">
|
||||
<router-link :to="{name: 'DynamicPage', params: {slug: 'terms-of-service'}}" target="_blank">{{ termsOfService.title }}</router-link>
|
||||
<router-link :to="{name: 'DynamicPage', params: {slug: 'privacy-policy'}}" target="_blank">{{ privacyPolicy.title }}</router-link>
|
||||
</i18n>
|
||||
|
||||
@@ -188,7 +188,7 @@ export default {
|
||||
events.$on('drop', () => {
|
||||
this.dragInProgress = false
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<MainFeatures />
|
||||
|
||||
<!--Pricing Tables-->
|
||||
<PricingTables />
|
||||
<PricingTables v-if="config.isSaaS" />
|
||||
|
||||
<!--Get Started Call To Action-->
|
||||
<GetStarted />
|
||||
@@ -60,18 +60,15 @@
|
||||
isLoading: true,
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
if (! this.config.isSaaS) {
|
||||
this.$router.push({name: 'SignIn'})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (! this.config.isSaaS) return
|
||||
|
||||
if (! this.config.allowHomepage)
|
||||
this.$router.push({name: 'SignIn'})
|
||||
|
||||
// Get page content
|
||||
axios.get('/api/content', {
|
||||
params: {
|
||||
column: 'footer_content|get_started_description|get_started_title|pricing_description|pricing_title|feature_description_3|feature_title_3|feature_description_2|feature_title_2|feature_description_1|feature_title_1|features_description|features_title|header_description|header_title|section_get_started|section_pricing_content|section_feature_boxes|section_features'
|
||||
column: 'allow_homepage|footer_content|get_started_description|get_started_title|pricing_description|pricing_title|feature_description_3|feature_title_3|feature_description_2|feature_title_2|feature_description_1|feature_title_1|features_description|features_title|header_description|header_title|section_get_started|section_pricing_content|section_feature_boxes|section_features'
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
|
||||
@@ -9,12 +9,18 @@
|
||||
<!--Move item setup-->
|
||||
<MoveItem />
|
||||
|
||||
<!-- Processing popup for zip -->
|
||||
<ProcessingPopup/>
|
||||
|
||||
<!-- Mobile Menu for Multi selected items -->
|
||||
<MobileMultiSelectMenu/>
|
||||
|
||||
<!--Rename folder or file item-->
|
||||
<RenameItem/>
|
||||
|
||||
<!--Create folder in mobile version-->
|
||||
<CreateFolder/>
|
||||
|
||||
<!-- Drag & Drop UI -->
|
||||
<DragUI/>
|
||||
|
||||
@@ -116,15 +122,16 @@
|
||||
import MobileSortingAndPreview from '@/components/FilesView/MobileSortingAndPreview'
|
||||
import MobileMultiSelectMenu from '@/components/FilesView/MobileMultiSelectMenu'
|
||||
import DesktopSortingAndPreview from '@/components/FilesView/DesktopSortingAndPreview'
|
||||
import ProcessingPopup from '@/components/FilesView/ProcessingPopup'
|
||||
import TreeMenuNavigator from '@/components/Others/TreeMenuNavigator'
|
||||
import FileFullPreview from '@/components/FilesView/FileFullPreview'
|
||||
import DesktopToolbar from '@/components/FilesView/DesktopToolbar'
|
||||
import ContentSidebar from '@/components/Sidebar/ContentSidebar'
|
||||
import DragUI from '@/components/FilesView/DragUI'
|
||||
import FileItemGrid from '@/components/FilesView/FileItemGrid'
|
||||
import ContentGroup from '@/components/Sidebar/ContentGroup'
|
||||
import FileBrowser from '@/components/FilesView/FileBrowser'
|
||||
import ContextMenu from '@/components/FilesView/ContextMenu'
|
||||
import CreateFolder from '@/components/Others/CreateFolder'
|
||||
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||
import MobileMenu from '@/components/FilesView/MobileMenu'
|
||||
import AuthContent from '@/components/Auth/AuthContent'
|
||||
@@ -133,6 +140,7 @@
|
||||
import Spinner from '@/components/FilesView/Spinner'
|
||||
import MoveItem from '@/components/Others/MoveItem'
|
||||
import Vignette from '@/components/Others/Vignette'
|
||||
import DragUI from '@/components/FilesView/DragUI'
|
||||
import Alert from '@/components/FilesView/Alert'
|
||||
import {required} from 'vee-validate/dist/rules'
|
||||
import {mapGetters} from 'vuex'
|
||||
@@ -152,9 +160,10 @@
|
||||
ValidationObserver,
|
||||
TreeMenuNavigator,
|
||||
FileFullPreview,
|
||||
ProcessingPopup,
|
||||
DesktopToolbar,
|
||||
ContentSidebar,
|
||||
DragUI,
|
||||
CreateFolder,
|
||||
FileItemGrid,
|
||||
ContentGroup,
|
||||
AuthContent,
|
||||
@@ -169,6 +178,7 @@
|
||||
required,
|
||||
Vignette,
|
||||
Spinner,
|
||||
DragUI,
|
||||
Alert,
|
||||
},
|
||||
computed: {
|
||||
|
||||
@@ -25,6 +25,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</PageTabGroup>
|
||||
|
||||
<PageTabGroup v-if="userInfo">
|
||||
<div class="form block-form">
|
||||
<FormLabel>{{$t('user_settings.timezone')}}</FormLabel>
|
||||
<div class="block-wrapper">
|
||||
<label>GMT:</label>
|
||||
<div class="input-wrapper">
|
||||
<SelectInput @input="$updateText('/user/relationships/settings', 'timezone', userTimezone)"
|
||||
v-model="userTimezone"
|
||||
:default="userTimezone"
|
||||
:options="timezones"
|
||||
:placeholder="$t('user_settings.timezone_plac')"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageTabGroup>
|
||||
|
||||
<PageTabGroup v-if="config.isSaaS && billingInfo">
|
||||
<div class="form block-form">
|
||||
<FormLabel>{{ $t('user_settings.title_billing') }}</FormLabel>
|
||||
@@ -141,12 +158,13 @@
|
||||
PageTab,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['config', 'countries']),
|
||||
...mapGetters(['config', 'countries', 'timezones']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
userInfo: undefined,
|
||||
billingInfo: undefined,
|
||||
userTimezone: undefined,
|
||||
isLoading: false,
|
||||
}
|
||||
},
|
||||
@@ -158,6 +176,8 @@
|
||||
},
|
||||
created() {
|
||||
|
||||
this.userTimezone = this.user.relationships.timezone.data.attributes.timezone
|
||||
|
||||
this.userInfo = {
|
||||
name: this.user.data.attributes.name,
|
||||
email: this.user.data.attributes.email
|
||||
|
||||
@@ -7,6 +7,12 @@ return [
|
||||
'time' => '%d. %B. %Y 于 %H:%M',
|
||||
'home' => '首页',
|
||||
|
||||
//Shared link email message
|
||||
'shared_link_email_subject' => '🙋 :user share some files with you. Look at it!',
|
||||
'shared_link_email_greeting' => 'Hello!',
|
||||
'shared_link_email_user' => ':user (:email) send you a link to shared files.',
|
||||
'shared_link_email_link' => 'Open your files',
|
||||
|
||||
// Reset password email
|
||||
'reset_password_greeting' => 'Hello!',
|
||||
'reset_password_subject' => 'Reset password for your account on ',
|
||||
|
||||
@@ -7,6 +7,12 @@ return [
|
||||
'time' => '%d. %B. %Y at %H:%M',
|
||||
'home' => 'Home',
|
||||
|
||||
//Shared link email message
|
||||
'shared_link_email_subject' => '🙋 :user share some files with you. Look at it!',
|
||||
'shared_link_email_greeting' => 'Hello!',
|
||||
'shared_link_email_user' => ':user (:email) send you a link to shared files.',
|
||||
'shared_link_email_link' => 'Open your files',
|
||||
|
||||
// Reset password email
|
||||
'reset_password_greeting' => 'Hello!',
|
||||
'reset_password_subject' => 'Reset password for your account on ',
|
||||
|
||||
@@ -7,6 +7,12 @@ return [
|
||||
'time' => '%d. %B. %Y o %H:%M',
|
||||
'home' => 'Domov',
|
||||
|
||||
//Shared link email message
|
||||
'shared_link_email_subject' => '🙋 :user vám posiela zdieľané súbory.',
|
||||
'shared_link_email_greeting' => 'Ahoj!',
|
||||
'shared_link_email_user' => ':user (:email) vám posiela odkaz pre zdieľané súbory.',
|
||||
'shared_link_email_link' => 'Vaše súbory',
|
||||
|
||||
// Reset password email
|
||||
'reset_password_greeting' => 'Ahoj!',
|
||||
'reset_password_subject' => 'Resetujte svoje heslo v aplikácií ',
|
||||
|
||||
12
resources/sass/app.scss
vendored
12
resources/sass/app.scss
vendored
@@ -442,7 +442,19 @@
|
||||
|
||||
}
|
||||
|
||||
.info-box-wrapper {
|
||||
margin: 0px 20px;
|
||||
}
|
||||
|
||||
.windows {
|
||||
|
||||
#content-sidebar {
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar {
|
||||
width: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
|
||||
@@ -11,6 +11,8 @@ $red: #FE6057;
|
||||
$purple: #9D66FE;
|
||||
|
||||
$light_mode_border: #F8F8F8;
|
||||
$light_mode_border_darken: #E8E9EB;
|
||||
|
||||
$danger: #fd397a;
|
||||
$light_text: #A4ADB6;
|
||||
$light_background: #f4f5f6;
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
stripe_public_key: '{{ config('cashier.key') ? config('cashier.key') : null }}',
|
||||
|
||||
userRegistration: {{ isset($settings->registration) ? $settings->registration : 1 }},
|
||||
allowHomepage: {{ isset($settings->allow_homepage) ? $settings->allow_homepage : 1 }},
|
||||
storageLimit: {{ isset($settings->storage_limitation) ? $settings->storage_limitation : 1 }},
|
||||
storageDefaultSpace: {{ isset($settings->storage_default) ? $settings->storage_default : 5 }},
|
||||
storageDefaultSpaceFormatted: '{{ isset($settings->storage_default) ? format_gigabytes($settings->storage_default) : format_gigabytes(5) }}',
|
||||
|
||||
Reference in New Issue
Block a user