mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-05 18:23:48 +00:00
upload request prototype UI
This commit is contained in:
@@ -68,5 +68,7 @@
|
||||
"/js/chunks/shared-with-me.js": "/js/chunks/shared-with-me.js",
|
||||
"/js/chunks/invitation.js": "/js/chunks/invitation.js",
|
||||
"/css/tailwind.css": "/css/tailwind.css",
|
||||
"/css/app.css": "/css/app.css"
|
||||
"/css/app.css": "/css/app.css",
|
||||
"/js/chunks/request-upload.js": "/js/chunks/request-upload.js",
|
||||
"/js/chunks/request.js": "/js/chunks/request.js"
|
||||
}
|
||||
|
||||
8
resources/css/tailwind.css
vendored
8
resources/css/tailwind.css
vendored
@@ -20,4 +20,12 @@
|
||||
|
||||
.is-inactive {
|
||||
@apply pointer-events-none opacity-40
|
||||
}
|
||||
|
||||
.grid-view {
|
||||
@apply grid grid-cols-3 content-start sm:grid-cols-4 lg:gap-2 xl:grid-cols-6 xl:gap-4;
|
||||
}
|
||||
|
||||
.grid-view-sidebar {
|
||||
@apply grid grid-cols-3 content-start md:grid-cols-2 lg:grid-cols-3 lg:gap-2 xl:grid-cols-4 xl:gap-4 2xl:grid-cols-5;
|
||||
}
|
||||
@@ -5,16 +5,16 @@
|
||||
<ToasterWrapper />
|
||||
<CookieDisclaimer />
|
||||
|
||||
<!--Show spinner before translations is loaded-->
|
||||
<!--Show spinner before translations is loaded-->
|
||||
<Spinner v-if="!isLoaded" />
|
||||
|
||||
<!--Show warning bar when user functionality is restricted-->
|
||||
<!--Show warning bar when user functionality is restricted-->
|
||||
<RestrictionWarningBar />
|
||||
|
||||
<!--App view-->
|
||||
<!--App view-->
|
||||
<router-view v-if="isLoaded" />
|
||||
|
||||
<!--Background under popups-->
|
||||
<!--Background under popups-->
|
||||
<Vignette />
|
||||
</div>
|
||||
</template>
|
||||
@@ -26,94 +26,93 @@ import Spinner from './components/FilesView/Spinner'
|
||||
import Vignette from './components/Others/Vignette'
|
||||
import Alert from './components/FilesView/Alert'
|
||||
import RestrictionWarningBar from './components/Subscription/RestrictionWarningBar'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from './bus'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { events } from './bus'
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
RestrictionWarningBar,
|
||||
CookieDisclaimer,
|
||||
ToasterWrapper,
|
||||
Vignette,
|
||||
Spinner,
|
||||
Alert,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoaded: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['config', 'user']),
|
||||
},
|
||||
watch: {
|
||||
'config.defaultThemeMode': function () {
|
||||
this.handleDarkMode()
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
spotlightListener(e) {
|
||||
if (e.key === 'k' && e.metaKey) {
|
||||
events.$emit('spotlight:show')
|
||||
}
|
||||
},
|
||||
handleDarkMode() {
|
||||
const app = document.getElementsByTagName('html')[0]
|
||||
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
name: 'App',
|
||||
components: {
|
||||
RestrictionWarningBar,
|
||||
CookieDisclaimer,
|
||||
ToasterWrapper,
|
||||
Vignette,
|
||||
Spinner,
|
||||
Alert,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isLoaded: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['config', 'user']),
|
||||
},
|
||||
watch: {
|
||||
'config.defaultThemeMode': function () {
|
||||
this.handleDarkMode()
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
spotlightListener(e) {
|
||||
if (e.key === 'k' && e.metaKey) {
|
||||
events.$emit('spotlight:show')
|
||||
}
|
||||
},
|
||||
handleDarkMode() {
|
||||
const app = document.getElementsByTagName('html')[0]
|
||||
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
|
||||
if (this.config.defaultThemeMode === 'dark') {
|
||||
app.classList.add('dark')
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
||||
} else if (this.config.defaultThemeMode === 'light') {
|
||||
app.classList.remove('dark')
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
||||
} else if (this.config.defaultThemeMode === 'system' && prefersDarkScheme.matches) {
|
||||
app.classList.add('dark')
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
||||
} else if (this.config.defaultThemeMode === 'system' && !prefersDarkScheme.matches) {
|
||||
app.classList.remove('dark')
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
||||
}
|
||||
},
|
||||
},
|
||||
beforeMount() {
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
||||
this.handleDarkMode()
|
||||
})
|
||||
if (this.config.defaultThemeMode === 'dark') {
|
||||
app.classList.add('dark')
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
||||
} else if (this.config.defaultThemeMode === 'light') {
|
||||
app.classList.remove('dark')
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
||||
} else if (this.config.defaultThemeMode === 'system' && prefersDarkScheme.matches) {
|
||||
app.classList.add('dark')
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', true)
|
||||
} else if (this.config.defaultThemeMode === 'system' && !prefersDarkScheme.matches) {
|
||||
app.classList.remove('dark')
|
||||
this.$store.commit('UPDATE_DARK_MODE_STATUS', false)
|
||||
}
|
||||
},
|
||||
},
|
||||
beforeMount() {
|
||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
||||
this.handleDarkMode()
|
||||
})
|
||||
|
||||
// Commit config
|
||||
this.$store.commit('INIT', {
|
||||
config: this.$root.$data.config,
|
||||
})
|
||||
// Commit config
|
||||
this.$store.commit('INIT', {
|
||||
config: this.$root.$data.config,
|
||||
})
|
||||
|
||||
// Get installation state
|
||||
let installation = this.$root.$data.config.installation
|
||||
// Get installation state
|
||||
let installation = this.$root.$data.config.installation
|
||||
|
||||
// Redirect to setup wizard
|
||||
if (installation === 'installation-needed') {
|
||||
this.isLoaded = true
|
||||
// Redirect to setup wizard
|
||||
if (installation === 'installation-needed') {
|
||||
this.isLoaded = true
|
||||
|
||||
if (window.location.pathname.split('/')[1] !== 'setup-wizard') {
|
||||
this.$router.push({name: 'StatusCheck'})
|
||||
}
|
||||
} else {
|
||||
this.$store.dispatch('getLanguageTranslations', this.$root.$data.config.locale)
|
||||
.then(() => {
|
||||
this.isLoaded = true
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.$isWindows()) {
|
||||
document.body.classList.add('windows')
|
||||
}
|
||||
if (window.location.pathname.split('/')[1] !== 'setup-wizard') {
|
||||
this.$router.push({ name: 'StatusCheck' })
|
||||
}
|
||||
} else {
|
||||
this.$store.dispatch('getLanguageTranslations', this.$root.$data.config.locale).then(() => {
|
||||
this.isLoaded = true
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.$isWindows()) {
|
||||
document.body.classList.add('windows')
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', this.spotlightListener)
|
||||
},
|
||||
destroyed() {
|
||||
window.removeEventListener('keydown', this.spotlightListener)
|
||||
},
|
||||
window.addEventListener('keydown', this.spotlightListener)
|
||||
},
|
||||
destroyed() {
|
||||
window.removeEventListener('keydown', this.spotlightListener)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -123,54 +122,54 @@ export default {
|
||||
@import '../sass/vuefilemanager/mixins';
|
||||
|
||||
input:-webkit-autofill {
|
||||
transition-delay: 999999999999s;
|
||||
transition-delay: 999999999999s;
|
||||
}
|
||||
|
||||
[v-cloak],
|
||||
[v-cloak] > * {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
* {
|
||||
outline: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
box-sizing: border-box;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: $text;
|
||||
outline: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Nunito', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
box-sizing: border-box;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.vue-feather {
|
||||
path,
|
||||
circle,
|
||||
line,
|
||||
rect,
|
||||
polyline,
|
||||
ellipse,
|
||||
polygon {
|
||||
color: inherit;
|
||||
}
|
||||
path,
|
||||
circle,
|
||||
line,
|
||||
rect,
|
||||
polyline,
|
||||
ellipse,
|
||||
polygon {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
// Dark mode
|
||||
.dark {
|
||||
* {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
* {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
background: $dark_mode_background;
|
||||
color: $dark_mode_text_primary;
|
||||
body,
|
||||
html {
|
||||
background: $dark_mode_background;
|
||||
color: $dark_mode_text_primary;
|
||||
|
||||
img {
|
||||
opacity: 0.95;
|
||||
}
|
||||
}
|
||||
img {
|
||||
opacity: 0.95;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div :class="{ 'sm:mb-7 mb-6': !isLast }" class="w-full justify-between space-y-4 sm:flex sm:space-x-8 sm:space-x-2 sm:space-y-0">
|
||||
<div
|
||||
:class="{ 'mb-6 sm:mb-7': !isLast }"
|
||||
class="w-full justify-between space-y-4 sm:flex sm:space-x-8 sm:space-x-2 sm:space-y-0"
|
||||
>
|
||||
<!--Label for input-->
|
||||
<div class="leading-5">
|
||||
<label class="mb-1.5 block text-sm font-bold text-gray-700 dark:text-gray-200"> {{ title }}: </label>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div :class="{ 'sm:mb-7 mb-6': !isLast }" class="flex w-full items-center justify-between space-x-2 sm:space-x-8">
|
||||
<div :class="{ 'mb-6 sm:mb-7': !isLast }" class="flex w-full items-center justify-between space-x-2 sm:space-x-8">
|
||||
<!--Label for input-->
|
||||
<div class="leading-5">
|
||||
<label class="mb-1.5 block text-sm font-bold text-gray-700 dark:text-gray-200"> {{ title }}: </label>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div :class="{ 'sm:mb-7 mb-6': !isLast }">
|
||||
<div :class="{ 'mb-6 sm:mb-7': !isLast }">
|
||||
<!--Label for input-->
|
||||
<label v-if="title" class="mb-1.5 block text-sm font-bold text-gray-700 dark:text-gray-200"> {{ title }}: </label>
|
||||
<label v-if="title" class="mb-1.5 block text-sm font-bold text-gray-700 dark:text-gray-200">
|
||||
{{ title }}:
|
||||
</label>
|
||||
|
||||
<!--Form element-->
|
||||
<slot />
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
<div id="card-navigation" style="height: 62px" class="mb-7">
|
||||
<div
|
||||
:class="{
|
||||
'fixed top-0 left-0 right-0 z-10 rounded-none bg-white bg-opacity-50 px-6 backdrop-blur-lg backdrop-filter dark:bg-dark-foreground': fixedNav,
|
||||
'fixed top-0 left-0 right-0 z-10 rounded-none bg-white bg-opacity-50 px-6 backdrop-blur-lg backdrop-filter dark:bg-dark-foreground':
|
||||
fixedNav,
|
||||
}"
|
||||
>
|
||||
<div class="overflow-x-auto whitespace-nowrap">
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
v-if="data.length === 1"
|
||||
:class="[
|
||||
{
|
||||
'rounded-tl-lg rounded-bl-lg border-r-2 border-white dark:border-gray-800': chart.progress < 100,
|
||||
'rounded-tl-lg rounded-bl-lg border-r-2 border-white dark:border-gray-800':
|
||||
chart.progress < 100,
|
||||
'rounded-lg border-none': chart.progress >= 100,
|
||||
},
|
||||
chart.color,
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
<template>
|
||||
<DatatableWrapper @init="isLoading = false" api="/api/admin/dashboard/newbies" :paginator="false" :columns="columns" class="mt-6 overflow-x-auto">
|
||||
<DatatableWrapper
|
||||
@init="isLoading = false"
|
||||
api="/api/admin/dashboard/newbies"
|
||||
:paginator="false"
|
||||
:columns="columns"
|
||||
class="mt-6 overflow-x-auto"
|
||||
>
|
||||
<template slot-scope="{ row }">
|
||||
<!--Not a subscription-->
|
||||
<tr v-if="config.subscriptionType === 'none'" class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5">
|
||||
<tr
|
||||
v-if="config.subscriptionType === 'none'"
|
||||
class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5"
|
||||
>
|
||||
<td class="py-3 pr-3 md:pr-1">
|
||||
<router-link
|
||||
:to="{
|
||||
@@ -13,7 +22,10 @@
|
||||
<div class="flex items-center">
|
||||
<MemberAvatar :is-border="false" :size="44" :member="row.data.relationships.settings" />
|
||||
<div class="ml-3 pr-10">
|
||||
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||
<b
|
||||
class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold"
|
||||
style="max-width: 155px"
|
||||
>
|
||||
{{ row.data.relationships.settings.data.attributes.name }}
|
||||
</b>
|
||||
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||
@@ -70,7 +82,10 @@
|
||||
</tr>
|
||||
|
||||
<!--Fixed subscription-->
|
||||
<tr v-if="config.subscriptionType === 'fixed'" class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5">
|
||||
<tr
|
||||
v-if="config.subscriptionType === 'fixed'"
|
||||
class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5"
|
||||
>
|
||||
<td class="py-3 pr-3 md:pr-1">
|
||||
<router-link
|
||||
:to="{
|
||||
@@ -81,7 +96,10 @@
|
||||
<div class="flex items-center">
|
||||
<MemberAvatar :is-border="false" :size="44" :member="row.data.relationships.settings" />
|
||||
<div class="ml-3 pr-10">
|
||||
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||
<b
|
||||
class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold"
|
||||
style="max-width: 155px"
|
||||
>
|
||||
{{ row.data.relationships.settings.data.attributes.name }}
|
||||
</b>
|
||||
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||
@@ -143,7 +161,10 @@
|
||||
</tr>
|
||||
|
||||
<!--Metered subscription-->
|
||||
<tr v-if="config.subscriptionType === 'metered'" class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5">
|
||||
<tr
|
||||
v-if="config.subscriptionType === 'metered'"
|
||||
class="whitespace-nowrap border-b border-dashed border-light dark:border-opacity-5"
|
||||
>
|
||||
<td class="py-3 pr-3 md:pr-1">
|
||||
<router-link
|
||||
:to="{
|
||||
@@ -154,7 +175,10 @@
|
||||
<div class="flex items-center">
|
||||
<MemberAvatar :is-border="false" :size="44" :member="row.data.relationships.settings" />
|
||||
<div class="ml-3 pr-10">
|
||||
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||
<b
|
||||
class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold"
|
||||
style="max-width: 155px"
|
||||
>
|
||||
{{ row.data.relationships.settings.data.attributes.name }}
|
||||
</b>
|
||||
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
<div v-if="row.data.relationships.user" class="flex items-center">
|
||||
<MemberAvatar :is-border="false" :size="36" :member="row.data.relationships.user" />
|
||||
<div class="ml-3 pr-10">
|
||||
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||
<b
|
||||
class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold"
|
||||
style="max-width: 155px"
|
||||
>
|
||||
{{ row.data.relationships.user.data.attributes.name }}
|
||||
</b>
|
||||
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||
@@ -24,10 +27,16 @@
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-3 md:px-1">
|
||||
<ColorLabel v-if="config.subscriptionType === 'fixed'" :color="$getTransactionStatusColor(row.data.attributes.status)">
|
||||
<ColorLabel
|
||||
v-if="config.subscriptionType === 'fixed'"
|
||||
:color="$getTransactionStatusColor(row.data.attributes.status)"
|
||||
>
|
||||
{{ row.data.attributes.status }}
|
||||
</ColorLabel>
|
||||
<ColorLabel v-if="config.subscriptionType === 'metered'" :color="$getTransactionTypeColor(row.data.attributes.type)">
|
||||
<ColorLabel
|
||||
v-if="config.subscriptionType === 'metered'"
|
||||
:color="$getTransactionTypeColor(row.data.attributes.type)"
|
||||
>
|
||||
{{ row.data.attributes.type }}
|
||||
</ColorLabel>
|
||||
</td>
|
||||
@@ -43,7 +52,11 @@
|
||||
</td>
|
||||
<td class="pl-3 md:pl-1">
|
||||
<div class="w-32 text-right md:w-full">
|
||||
<img class="w-32 md:inline-block" :src="$getPaymentLogo(row.data.attributes.driver)" :alt="row.data.attributes.driver" />
|
||||
<img
|
||||
class="w-32 md:inline-block"
|
||||
:src="$getPaymentLogo(row.data.attributes.driver)"
|
||||
:alt="row.data.attributes.driver"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<template>
|
||||
<button class="group mx-auto inline-block flex items-center whitespace-nowrap rounded-lg border-2 border-black px-7 py-2.5 dark:border-gray-300">
|
||||
<button
|
||||
class="group mx-auto inline-block flex items-center whitespace-nowrap rounded-lg border-2 border-black px-7 py-2.5 dark:border-gray-300"
|
||||
>
|
||||
<span class="pr-1 text-lg font-extrabold">
|
||||
{{ text }}
|
||||
</span>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div v-if="config.allowedFacebookLogin || config.allowedGoogleLogin || config.allowedGithubLogin" class="mb-10 flex items-center justify-center">
|
||||
<div
|
||||
v-if="config.allowedFacebookLogin || config.allowedGoogleLogin || config.allowedGithubLogin"
|
||||
class="mb-10 flex items-center justify-center"
|
||||
>
|
||||
<div v-if="config.allowedFacebookLogin" class="mx-5 cursor-pointer">
|
||||
<facebook-icon @click="socialiteRedirect('facebook')" />
|
||||
</div>
|
||||
|
||||
@@ -1,40 +1,52 @@
|
||||
<template>
|
||||
<div v-if="currentFile" class="absolute lg:top-[66px] top-[56px] left-0 right-0 bottom-0 select-none">
|
||||
|
||||
<!--Arrow navigation-->
|
||||
<div v-if="currentFile" class="absolute top-[56px] left-0 right-0 bottom-0 select-none lg:top-[66px]">
|
||||
<!--Arrow navigation-->
|
||||
<div v-if="!$isMobile() && files.length > 1" class="">
|
||||
<div @click.prevent="prev" class="fixed top-1/2 left-0 p-3 cursor-pointer z-20">
|
||||
<div @click.prevent="prev" class="fixed top-1/2 left-0 z-20 cursor-pointer p-3">
|
||||
<chevron-left-icon size="20" />
|
||||
</div>
|
||||
|
||||
<div @click.prevent="next" class="fixed top-1/2 right-0 p-3 cursor-pointer z-20">
|
||||
<div @click.prevent="next" class="fixed top-1/2 right-0 z-20 cursor-pointer p-3">
|
||||
<chevron-right-icon size="20" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Desktop preview-->
|
||||
<div v-if="!$isMobile() && (isAudio || isImage || isVideo || isPDF)" class="w-full h-full flex justify-center items-center">
|
||||
|
||||
<!--Show PDF-->
|
||||
<div
|
||||
v-if="!$isMobile() && (isAudio || isImage || isVideo || isPDF)"
|
||||
class="flex h-full w-full items-center justify-center"
|
||||
>
|
||||
<!--Show PDF-->
|
||||
<PdfFile v-if="isPDF" :file="currentFile" />
|
||||
|
||||
<!--Show Audio, Video and Image-->
|
||||
<div class="w-full h-full flex items-center justify-center">
|
||||
<Audio v-if="isAudio" :file="currentFile"/>
|
||||
<Video v-if="isVideo" :file="currentFile" class="max-w-[1080px] max-h-full self-center mx-auto" />
|
||||
<ImageFile v-if="isImage" :file="currentFile" class="max-w-[100%] max-h-[100%] self-center mx-auto" />
|
||||
<div class="flex h-full w-full items-center justify-center">
|
||||
<Audio v-if="isAudio" :file="currentFile" />
|
||||
<Video v-if="isVideo" :file="currentFile" class="mx-auto max-h-full max-w-[1080px] self-center" />
|
||||
<ImageFile v-if="isImage" :file="currentFile" class="mx-auto max-h-[100%] max-w-[100%] self-center" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Mobile Preview-->
|
||||
<div v-if="$isMobile() && (isAudio || isImage || isVideo || isPDF)" @scroll="checkGroupInView" id="group-box" ref="scrollBox" class="flex gap-6 snap-x snap-mandatory overflow-x-auto h-full">
|
||||
<div v-for="(file, i) in files" :key="i" :id="`group-${file.data.id}`" class="w-screen h-full flex items-center justify-center snap-center shrink-0 relative">
|
||||
<ImageFile v-if="isImage" :file="file" class="max-w-[100%] max-h-[100%] self-center mx-auto"/>
|
||||
<Audio v-if="isAudio" :file="file"/>
|
||||
<!--Mobile Preview-->
|
||||
<div
|
||||
v-if="$isMobile() && (isAudio || isImage || isVideo || isPDF)"
|
||||
@scroll="checkGroupInView"
|
||||
id="group-box"
|
||||
ref="scrollBox"
|
||||
class="flex h-full snap-x snap-mandatory gap-6 overflow-x-auto"
|
||||
>
|
||||
<div
|
||||
v-for="(file, i) in files"
|
||||
:key="i"
|
||||
:id="`group-${file.data.id}`"
|
||||
class="relative flex h-full w-screen shrink-0 snap-center items-center justify-center"
|
||||
>
|
||||
<ImageFile v-if="isImage" :file="file" class="mx-auto max-h-[100%] max-w-[100%] self-center" />
|
||||
<Audio v-if="isAudio" :file="file" />
|
||||
<Video v-if="isVideo" :file="file" />
|
||||
<PdfFile v-if="isPDF" :file="file" />
|
||||
</div>
|
||||
</div>
|
||||
<PdfFile v-if="isPDF" :file="file" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -111,29 +123,29 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
checkGroupInView: _.debounce(function () {
|
||||
this.files.forEach((file, index) => {
|
||||
let element = document.getElementById(`group-${file.data.id}`).getBoundingClientRect()
|
||||
let scrollBox = document.getElementById('group-box').getBoundingClientRect()
|
||||
checkGroupInView: _.debounce(function () {
|
||||
this.files.forEach((file, index) => {
|
||||
let element = document.getElementById(`group-${file.data.id}`).getBoundingClientRect()
|
||||
let scrollBox = document.getElementById('group-box').getBoundingClientRect()
|
||||
|
||||
// Get video
|
||||
const video = document.querySelector(`#group-${file.data.id} video`);
|
||||
// Get video
|
||||
const video = document.querySelector(`#group-${file.data.id} video`)
|
||||
|
||||
// Pause video when playing
|
||||
if (video && !video.paused) {
|
||||
video.pause()
|
||||
}
|
||||
// Pause video when playing
|
||||
if (video && !video.paused) {
|
||||
video.pause()
|
||||
}
|
||||
|
||||
// Check if the group is in the viewport of group-box
|
||||
if (element.left === scrollBox.left) {
|
||||
this.currentIndex = index
|
||||
}
|
||||
})
|
||||
}, 100),
|
||||
// Check if the group is in the viewport of group-box
|
||||
if (element.left === scrollBox.left) {
|
||||
this.currentIndex = index
|
||||
}
|
||||
})
|
||||
}, 100),
|
||||
getFilesForView() {
|
||||
let requestedFile = this.clipboard[0]
|
||||
|
||||
this.entries.map(element => {
|
||||
this.entries.map((element) => {
|
||||
if (requestedFile.data.attributes.mimetype === 'pdf') {
|
||||
if (element.data.attributes.mimetype === 'pdf') this.files.push(element)
|
||||
} else {
|
||||
@@ -143,18 +155,18 @@ export default {
|
||||
|
||||
this.files.forEach((element, index) => {
|
||||
if (element.data.id === this.clipboard[0].data.id) {
|
||||
this.currentIndex = index
|
||||
this.currentIndex = index
|
||||
}
|
||||
})
|
||||
|
||||
// Scroll to the selected item
|
||||
if (this.$isMobile()) {
|
||||
this.$nextTick(() => {
|
||||
let element = document.getElementById(`group-${this.files[this.currentIndex].data.id}`)
|
||||
// Scroll to the selected item
|
||||
if (this.$isMobile()) {
|
||||
this.$nextTick(() => {
|
||||
let element = document.getElementById(`group-${this.files[this.currentIndex].data.id}`)
|
||||
|
||||
this.$refs.scrollBox.scrollLeft = element.getBoundingClientRect().left
|
||||
})
|
||||
}
|
||||
this.$refs.scrollBox.scrollLeft = element.getBoundingClientRect().left
|
||||
})
|
||||
}
|
||||
},
|
||||
next() {
|
||||
if (!this.files.length > 1) return
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-if="currentFile" class="items-center px-3.5 py-4 lg:grid lg:grid-cols-3 lg:py-3 select-none">
|
||||
<div v-if="currentFile" class="select-none items-center px-3.5 py-4 lg:grid lg:grid-cols-3 lg:py-3">
|
||||
<div class="flex items-center justify-between lg:w-auto lg:justify-start">
|
||||
<!--Close icon-->
|
||||
<div @click="closeFullPreview" class="order-last -m-3 cursor-pointer p-3 lg:order-none">
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<audio :class="{ 'file-shadow': !$isMobile() }" class="file audio" :src="file.data.attributes.file_url" controls></audio>
|
||||
<audio
|
||||
:class="{ 'file-shadow': !$isMobile() }"
|
||||
class="file audio"
|
||||
:src="file.data.attributes.file_url"
|
||||
controls
|
||||
></audio>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -31,9 +31,7 @@ export default {
|
||||
components: {
|
||||
pdf,
|
||||
},
|
||||
props: [
|
||||
'file',
|
||||
],
|
||||
props: ['file'],
|
||||
watch: {
|
||||
file() {
|
||||
this.getPdf()
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<video
|
||||
:src="file.data.attributes.file_url"
|
||||
class="video"
|
||||
:class="{ 'file-shadow': !$isMobile() }"
|
||||
controlsList="nodownload"
|
||||
disablePictureInPicture
|
||||
playsinline
|
||||
controls
|
||||
/>
|
||||
<video
|
||||
:src="file.data.attributes.file_url"
|
||||
class="video"
|
||||
:class="{ 'file-shadow': !$isMobile() }"
|
||||
controlsList="nodownload"
|
||||
disablePictureInPicture
|
||||
playsinline
|
||||
controls
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
<p v-if="message" class="message">{{ message }}</p>
|
||||
</div>
|
||||
<div class="popup-actions">
|
||||
<ButtonBase @click.native="closePopup" :button-style="buttonStyle" class="action-confirm">{{ button }} </ButtonBase>
|
||||
<ButtonBase @click.native="closePopup" :button-style="buttonStyle" class="action-confirm"
|
||||
>{{ button }}
|
||||
</ButtonBase>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -31,13 +31,12 @@
|
||||
|
||||
<!--File Controls-->
|
||||
<div class="ml-5 flex items-center xl:ml-8">
|
||||
|
||||
<!--Action buttons-->
|
||||
<div v-if="canEdit && !$isMobile()" class="flex items-center">
|
||||
<ToolbarButton
|
||||
@click.native="$moveFileOrFolder(clipboard[0])"
|
||||
:class="{
|
||||
'is-inactive': ! canManipulate,
|
||||
'is-inactive': !canManipulate,
|
||||
}"
|
||||
source="move"
|
||||
:action="$t('actions.move')"
|
||||
@@ -45,7 +44,7 @@
|
||||
<ToolbarButton
|
||||
@click.native="$deleteFileOrFolder(clipboard[0])"
|
||||
:class="{
|
||||
'is-inactive': ! canManipulate,
|
||||
'is-inactive': !canManipulate,
|
||||
}"
|
||||
source="trash"
|
||||
:action="$t('actions.delete')"
|
||||
@@ -107,19 +106,13 @@ export default {
|
||||
Option,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isVisibleNavigationBars',
|
||||
'currentTeamFolder',
|
||||
'currentFolder',
|
||||
'sharedDetail',
|
||||
'clipboard',
|
||||
]),
|
||||
...mapGetters(['isVisibleNavigationBars', 'currentTeamFolder', 'currentFolder', 'sharedDetail', 'clipboard']),
|
||||
canEdit() {
|
||||
return this.sharedDetail && this.sharedDetail.data.attributes.permission === 'editor'
|
||||
},
|
||||
canManipulate() {
|
||||
return this.clipboard[0]
|
||||
}
|
||||
canManipulate() {
|
||||
return this.clipboard[0]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
showCreateMenu() {
|
||||
|
||||
@@ -12,20 +12,27 @@
|
||||
:action="$t('actions.create')"
|
||||
/>
|
||||
<PopoverItem name="desktop-create" side="left">
|
||||
<OptionGroup :title="$t('Upload')" :class="{'is-inactive': canUploadInView || isTeamFolderHomepage || isSharedWithMeHomepage}">
|
||||
<OptionGroup
|
||||
:title="$t('Upload')"
|
||||
:class="{
|
||||
'is-inactive': canUploadInView || isTeamFolderHomepage || isSharedWithMeHomepage,
|
||||
}"
|
||||
>
|
||||
<OptionUpload :title="$t('actions.upload')" type="file" />
|
||||
<OptionUpload :title="$t('actions.upload_folder')" type="folder" />
|
||||
</OptionGroup>
|
||||
<OptionGroup :title="$t('Create')">
|
||||
<Option
|
||||
@click.stop.native="$createFolder"
|
||||
:class="{ 'is-inactive': canCreateFolder || isTeamFolderHomepage || isSharedWithMeHomepage }"
|
||||
:class="{
|
||||
'is-inactive': canCreateFolder || isTeamFolderHomepage || isSharedWithMeHomepage,
|
||||
}"
|
||||
:title="$t('actions.create_folder')"
|
||||
icon="folder-plus"
|
||||
/>
|
||||
<Option
|
||||
@click.stop.native="$createTeamFolder"
|
||||
:class="{ 'is-inactive': canCreateTeamFolder || isSharedWithMeHomepage }"
|
||||
:class="{ 'is-inactive': canCreateTeamFolder || isSharedWithMeHomepage }"
|
||||
:title="$t('Create Team Folder')"
|
||||
icon="users"
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div class="hidden lg:block">
|
||||
<div class="flex items-center justify-between py-3">
|
||||
<NavigationBar />
|
||||
|
||||
<div class="flex items-center">
|
||||
<div class="bg-theme-200 mr-6 flex cursor-pointer items-center rounded-lg py-1 pr-1 pl-4">
|
||||
<b @click="uploadingDone" class="text-theme mr-3 text-xs">
|
||||
{{ isDone ? $t('Awesome!') : $t('Tell Jane you are done!') }}
|
||||
</b>
|
||||
<img
|
||||
class="w-8 rounded-lg"
|
||||
src="http://192.168.1.112:8000/avatars/md-f45abbe5-962c-4229-aef2-9991e96d54d9.png"
|
||||
alt="Avatar"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!--Create button-->
|
||||
<PopoverWrapper>
|
||||
<ToolbarButton
|
||||
@click.stop.native="showCreateMenu"
|
||||
source="cloud-plus"
|
||||
:action="$t('actions.create')"
|
||||
/>
|
||||
<PopoverItem name="desktop-create" side="left">
|
||||
<OptionGroup :title="$t('Upload')">
|
||||
<OptionUpload :title="$t('actions.upload')" type="file" />
|
||||
<OptionUpload :title="$t('actions.upload_folder')" type="folder" />
|
||||
</OptionGroup>
|
||||
<OptionGroup :title="$t('Create')">
|
||||
<Option
|
||||
@click.stop.native="$createFolder"
|
||||
:title="$t('actions.create_folder')"
|
||||
icon="folder-plus"
|
||||
/>
|
||||
</OptionGroup>
|
||||
</PopoverItem>
|
||||
</PopoverWrapper>
|
||||
|
||||
<!--File Controls-->
|
||||
<div v-if="!$isMobile()" class="ml-5 flex items-center xl:ml-8">
|
||||
<ToolbarButton
|
||||
@click.native="$moveFileOrFolder(clipboard[0])"
|
||||
:class="{
|
||||
'is-inactive': !canManipulate,
|
||||
}"
|
||||
source="move"
|
||||
:action="$t('actions.move')"
|
||||
/>
|
||||
<ToolbarButton
|
||||
@click.native="$deleteFileOrFolder(clipboard[0])"
|
||||
:class="{
|
||||
'is-inactive': !canManipulate,
|
||||
}"
|
||||
source="trash"
|
||||
:action="$t('actions.delete')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!--View Controls-->
|
||||
<div class="ml-5 flex items-center xl:ml-8">
|
||||
<PopoverWrapper>
|
||||
<ToolbarButton
|
||||
@click.stop.native="showSortingMenu"
|
||||
source="preview-sorting"
|
||||
:action="$t('actions.sorting_view')"
|
||||
/>
|
||||
<PopoverItem name="desktop-sorting" side="left">
|
||||
<FileSortingOptions />
|
||||
</PopoverItem>
|
||||
</PopoverWrapper>
|
||||
<ToolbarButton
|
||||
@click.native="$store.dispatch('fileInfoToggle')"
|
||||
:action="$t('actions.info_panel')"
|
||||
source="info"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<UploadProgress />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PopoverWrapper from '../Desktop/PopoverWrapper'
|
||||
import FileSortingOptions from './FileSortingOptions'
|
||||
import PopoverItem from '../Desktop/PopoverItem'
|
||||
import UploadProgress from './UploadProgress'
|
||||
import NavigationBar from './NavigationBar'
|
||||
import ToolbarButton from './ToolbarButton'
|
||||
import OptionUpload from './OptionUpload'
|
||||
import OptionGroup from './OptionGroup'
|
||||
import SearchBar from './SearchBar'
|
||||
import { events } from '../../bus'
|
||||
import { mapGetters } from 'vuex'
|
||||
import Option from './Option'
|
||||
|
||||
export default {
|
||||
name: 'DesktopUploadRequestToolbar',
|
||||
components: {
|
||||
FileSortingOptions,
|
||||
UploadProgress,
|
||||
PopoverWrapper,
|
||||
NavigationBar,
|
||||
ToolbarButton,
|
||||
OptionUpload,
|
||||
OptionGroup,
|
||||
PopoverItem,
|
||||
SearchBar,
|
||||
Option,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['isVisibleNavigationBars', 'currentTeamFolder', 'currentFolder', 'sharedDetail', 'clipboard']),
|
||||
canEdit() {
|
||||
return this.sharedDetail && this.sharedDetail.data.attributes.permission === 'editor'
|
||||
},
|
||||
canManipulate() {
|
||||
return this.clipboard[0]
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDone: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
uploadingDone() {
|
||||
// TODO: add name to the message
|
||||
if (!this.isDone) {
|
||||
events.$emit('toaster', {
|
||||
type: 'success',
|
||||
message: this.$t('We notified Jane about your new uploads successfully.'),
|
||||
})
|
||||
}
|
||||
|
||||
this.isDone = true
|
||||
},
|
||||
showCreateMenu() {
|
||||
events.$emit('popover:open', 'desktop-create')
|
||||
},
|
||||
showSortingMenu() {
|
||||
events.$emit('popover:open', 'desktop-sorting')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<div v-show="isVisible" id="drag-ui" class="w-64 fixed z-20 pointer-events-none p-5 rounded-xl shadow-lg dark:bg-dark-foreground bg-white">
|
||||
<TitlePreview icon="check-square" :title="title" :subtitle="subtitle" />
|
||||
</div>
|
||||
<div
|
||||
v-show="isVisible"
|
||||
id="drag-ui"
|
||||
class="pointer-events-none fixed z-20 w-64 rounded-xl bg-white p-5 shadow-lg dark:bg-dark-foreground"
|
||||
>
|
||||
<TitlePreview icon="check-square" :title="title" :subtitle="subtitle" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -42,7 +46,9 @@ export default {
|
||||
if ((filesLength < 2 || !hasDraggedItem) && this.draggedItem) {
|
||||
// Subtitle for single folder
|
||||
if (this.draggedItem.data.type === 'folder') {
|
||||
return this.draggedItem.items == 0 ? this.$t('folder.empty') : this.$tc('folder.item_counts', this.draggedItem.items)
|
||||
return this.draggedItem.items == 0
|
||||
? this.$t('folder.empty')
|
||||
: this.$tc('folder.item_counts', this.draggedItem.items)
|
||||
}
|
||||
|
||||
// Subtitle for single file
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div class="sticky top-14 z-[19] block overflow-x-auto whitespace-nowrap bg-white px-4 pb-3 dark:bg-dark-background lg:hidden">
|
||||
<div
|
||||
class="sticky top-14 z-[19] block overflow-x-auto whitespace-nowrap bg-white px-4 pb-3 dark:bg-dark-background lg:hidden"
|
||||
>
|
||||
<!--Show Buttons-->
|
||||
<slot v-if="!isMultiSelectMode" />
|
||||
<slot v-if="!isMultiSelectMode" />
|
||||
|
||||
<!-- Multi select mode -->
|
||||
<div v-if="isMultiSelectMode">
|
||||
|
||||
@@ -109,7 +109,7 @@ export default {
|
||||
})
|
||||
}
|
||||
} else {
|
||||
console.log(data.data.type);
|
||||
console.log(data.data.type)
|
||||
// Get id from current folder
|
||||
const id = data.data.type !== 'folder' ? this.currentFolder?.data.id : data.data.id
|
||||
|
||||
@@ -144,13 +144,3 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.grid-view {
|
||||
@apply grid grid-cols-3 content-start sm:grid-cols-4 lg:gap-2 xl:grid-cols-6 xl:gap-4;
|
||||
}
|
||||
|
||||
.grid-view-sidebar {
|
||||
@apply grid grid-cols-3 content-start md:grid-cols-2 lg:grid-cols-3 lg:gap-2 xl:grid-cols-4 xl:gap-4 2xl:grid-cols-5;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,13 +2,43 @@
|
||||
<MenuMobile name="file-filter">
|
||||
<MenuMobileGroup>
|
||||
<OptionGroup :title="$t('Base')">
|
||||
<Option @click.native="goToFiles" :title="$t('sidebar.home')" icon="hard-drive" :is-active="$isThisRoute($route, 'Files')" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToLatest" :title="$t('menu.latest')" icon="upload-cloud" :is-active="$isThisRoute($route, 'RecentUploads')" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToShared" :title="$t('sidebar.my_shared')" icon="share" :is-active="$isThisRoute($route, 'MySharedItems')" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToTrash" :title="$t('menu.trash')" icon="trash" :is-active="$isThisRoute($route, 'Trash')" :is-hover-disabled="true" />
|
||||
<Option
|
||||
@click.native="goToFiles"
|
||||
:title="$t('sidebar.home')"
|
||||
icon="hard-drive"
|
||||
:is-active="$isThisRoute($route, 'Files')"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToLatest"
|
||||
:title="$t('menu.latest')"
|
||||
icon="upload-cloud"
|
||||
:is-active="$isThisRoute($route, 'RecentUploads')"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToShared"
|
||||
:title="$t('sidebar.my_shared')"
|
||||
icon="share"
|
||||
:is-active="$isThisRoute($route, 'MySharedItems')"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToTrash"
|
||||
:title="$t('menu.trash')"
|
||||
icon="trash"
|
||||
:is-active="$isThisRoute($route, 'Trash')"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
</OptionGroup>
|
||||
<OptionGroup :title="$t('Collaboration')">
|
||||
<Option @click.native="goToTeamFolders" :title="$t('Team Folders')" icon="users" :is-active="$isThisRoute($route, 'TeamFolders')" :is-hover-disabled="true" />
|
||||
<Option
|
||||
@click.native="goToTeamFolders"
|
||||
:title="$t('Team Folders')"
|
||||
icon="users"
|
||||
:is-active="$isThisRoute($route, 'TeamFolders')"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToSharedWithMe"
|
||||
:title="$t('Shared with Me')"
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-center">
|
||||
<span class="text-theme absolute z-10 mx-auto mt-1 inline-block w-7 overflow-hidden text-ellipsis text-center font-semibold text-[9px]">
|
||||
<span
|
||||
class="text-theme absolute z-10 mx-auto mt-1 inline-block w-7 overflow-hidden text-ellipsis text-center text-[9px] font-semibold"
|
||||
>
|
||||
{{ entry.data.attributes.mimetype }}
|
||||
</span>
|
||||
|
||||
<svg width="38px" height="51px" viewBox="0 0 38 51" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg
|
||||
width="38px"
|
||||
height="51px"
|
||||
viewBox="0 0 38 51"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<path
|
||||
stroke-width="0"
|
||||
fill="#f4f5f6"
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
<template>
|
||||
<div>
|
||||
<OptionGroup :title="$t('View')">
|
||||
<Option v-if="isList" @click.native="changePreview('grid')" :title="$t('preview_sorting.grid_view')" icon="grid" />
|
||||
<Option v-if="isGrid" @click.native="changePreview('list')" :title="$t('preview_sorting.list_view')" icon="list" />
|
||||
<Option
|
||||
v-if="isList"
|
||||
@click.native="changePreview('grid')"
|
||||
:title="$t('preview_sorting.grid_view')"
|
||||
icon="grid"
|
||||
/>
|
||||
<Option
|
||||
v-if="isGrid"
|
||||
@click.native="changePreview('list')"
|
||||
:title="$t('preview_sorting.list_view')"
|
||||
icon="list"
|
||||
/>
|
||||
</OptionGroup>
|
||||
<OptionGroup :title="$t('Sorting')">
|
||||
<Option @click.native.stop="sort('created_at')" :arrow="arrowForCreatedAtField" :title="$t('preview_sorting.sort_date')" icon="calendar" />
|
||||
<Option @click.native.stop="sort('name')" :arrow="arrowForNameField" :title="$t('preview_sorting.sort_alphabet')" icon="alphabet" />
|
||||
<Option
|
||||
@click.native.stop="sort('created_at')"
|
||||
:arrow="arrowForCreatedAtField"
|
||||
:title="$t('preview_sorting.sort_date')"
|
||||
icon="calendar"
|
||||
/>
|
||||
<Option
|
||||
@click.native.stop="sort('name')"
|
||||
:arrow="arrowForNameField"
|
||||
:title="$t('preview_sorting.sort_alphabet')"
|
||||
icon="alphabet"
|
||||
/>
|
||||
</OptionGroup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -14,7 +14,10 @@
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<polyline id="Path" points="11.1999993 13.1999991 5.59999967 0.199999094 0 13.1999991 5.59999967 0.199999094"></polyline>
|
||||
<polyline
|
||||
id="Path"
|
||||
points="11.1999993 13.1999991 5.59999967 0.199999094 0 13.1999991 5.59999967 0.199999094"
|
||||
></polyline>
|
||||
<line x1="2.25" y1="8" x2="8.75" y2="8" id="Line-2"></line>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
<template>
|
||||
<svg width="53px" height="52px" viewBox="0 0 53 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg
|
||||
width="53px"
|
||||
height="52px"
|
||||
viewBox="0 0 53 39"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<path
|
||||
d="M48.03125,6.5 L29.790833,6.5 C28.7431613,6.5 27.7373076,6.08896217 26.9894703,5.35523504 L22.6980297,1.14476496 C21.9501924,0.41103783 20.9443387,-6.36543387e-16 19.896667,0 L4.96875,0 L4.96875,0 C2.22455078,0 0,2.18257812 0,4.875 L0,34.125 C0,36.8174219 2.22455078,39 4.96875,39 L48.03125,39 C50.7754492,39 53,36.8174219 53,34.125 L53,11.375 C53,8.68257813 50.7754492,6.5 48.03125,6.5 Z"
|
||||
class="svg-color-theme"
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<svg viewBox="0 0 53 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<svg
|
||||
viewBox="0 0 53 39"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<g id="V2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="team-folder">
|
||||
<path
|
||||
@@ -35,7 +40,9 @@
|
||||
d="M9.59999943,10.7999994 L9.59999943,9.59999943 C9.59999943,8.27451611 8.52548289,7.19999957 7.19999957,7.19999957 L2.39999986,7.19999957 C1.07451654,7.19999957 0,8.27451611 0,9.59999943 L0,10.7999994"
|
||||
></path>
|
||||
<circle cx="4.79999971" cy="2.39999986" r="2.39999986"></circle>
|
||||
<path d="M13.1999992,10.7999994 L13.1999992,9.59999943 C13.1991834,8.50627014 12.4589985,7.55143166 11.3999993,7.27799957"></path>
|
||||
<path
|
||||
d="M13.1999992,10.7999994 L13.1999992,9.59999943 C13.1991834,8.50627014 12.4589985,7.55143166 11.3999993,7.27799957"
|
||||
></path>
|
||||
<path
|
||||
d="M8.99999946,0.0779999954 C10.0619483,0.349901852 10.8047053,1.30679461 10.8047053,2.40299986 C10.8047053,3.4992051 10.0619483,4.45609786 8.99999946,4.72799972"
|
||||
></path>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<template>
|
||||
<div class="hidden 2xl:w-[360px] xl:w-[320px] w-[300px] shrink-0 overflow-y-auto overflow-x-hidden px-2.5 pt-2 lg:block">
|
||||
<div
|
||||
class="hidden w-[300px] shrink-0 overflow-y-auto overflow-x-hidden px-2.5 pt-2 lg:block xl:w-[320px] 2xl:w-[360px]"
|
||||
>
|
||||
<!--Is empty clipboard-->
|
||||
<div v-if="isEmpty" class="flex h-full items-center justify-center">
|
||||
<div class="text-center">
|
||||
@@ -23,10 +25,19 @@
|
||||
<div v-if="isSingleFile && !isEmpty">
|
||||
<FilePreviewDetail />
|
||||
|
||||
<TitlePreview class="mb-6" :icon="clipboard[0].data.type" :title="clipboard[0].data.attributes.name" :subtitle="clipboard[0].data.attributes.mimetype" />
|
||||
<TitlePreview
|
||||
class="mb-6"
|
||||
:icon="clipboard[0].data.type"
|
||||
:title="clipboard[0].data.attributes.name"
|
||||
:subtitle="clipboard[0].data.attributes.mimetype"
|
||||
/>
|
||||
|
||||
<!--Filesize-->
|
||||
<ListInfoItem v-if="singleFile.data.attributes.filesize" :title="$t('file_detail.size')" :content="singleFile.data.attributes.filesize" />
|
||||
<ListInfoItem
|
||||
v-if="singleFile.data.attributes.filesize"
|
||||
:title="$t('file_detail.size')"
|
||||
:content="singleFile.data.attributes.filesize"
|
||||
/>
|
||||
|
||||
<!--Created At-->
|
||||
<ListInfoItem :title="$t('file_detail.created_at')" :content="singleFile.data.attributes.created_at" />
|
||||
@@ -35,14 +46,21 @@
|
||||
<ListInfoItem v-if="$checkPermission(['master'])" :title="$t('file_detail.where')">
|
||||
<div @click="$moveFileOrFolder(singleFile)" class="flex cursor-pointer items-center">
|
||||
<b class="inline-block text-sm font-bold">
|
||||
{{ singleFile.data.relationships.parent ? singleFile.data.relationships.parent.data.attributes.name : $getCurrentLocationName() }}
|
||||
{{
|
||||
singleFile.data.relationships.parent
|
||||
? singleFile.data.relationships.parent.data.attributes.name
|
||||
: $getCurrentLocationName()
|
||||
}}
|
||||
</b>
|
||||
<Edit2Icon size="10" class="ml-2" />
|
||||
</div>
|
||||
</ListInfoItem>
|
||||
|
||||
<!--Shared-->
|
||||
<ListInfoItem v-if="$checkPermission('master') && singleFile.data.relationships.shared" :title="$t('file_detail.shared')">
|
||||
<ListInfoItem
|
||||
v-if="$checkPermission('master') && singleFile.data.relationships.shared"
|
||||
:title="$t('file_detail.shared')"
|
||||
>
|
||||
<div @click="$shareFileOrFolder(singleFile)" class="mb-2 flex cursor-pointer items-center">
|
||||
<span class="inline-block text-sm font-bold">
|
||||
{{ sharedInfo }}
|
||||
@@ -50,8 +68,18 @@
|
||||
<Edit2Icon size="10" class="ml-2" />
|
||||
</div>
|
||||
<div class="flex w-full items-center">
|
||||
<lock-icon v-if="isLocked" @click="$shareFileOrFolder(singleFile)" size="17" class="hover-text-theme vue-feather cursor-pointer" />
|
||||
<unlock-icon v-if="!isLocked" @click="$shareFileOrFolder(singleFile)" size="17" class="hover-text-theme vue-feather cursor-pointer" />
|
||||
<lock-icon
|
||||
v-if="isLocked"
|
||||
@click="$shareFileOrFolder(singleFile)"
|
||||
size="17"
|
||||
class="hover-text-theme vue-feather cursor-pointer"
|
||||
/>
|
||||
<unlock-icon
|
||||
v-if="!isLocked"
|
||||
@click="$shareFileOrFolder(singleFile)"
|
||||
size="17"
|
||||
class="hover-text-theme vue-feather cursor-pointer"
|
||||
/>
|
||||
<CopyShareLink :item="singleFile" size="small" class="w-full pl-2.5" />
|
||||
</div>
|
||||
</ListInfoItem>
|
||||
@@ -60,7 +88,7 @@
|
||||
<ListInfoItem v-if="canShowAuthor" :title="$t('Author')">
|
||||
<div class="mt-1.5 flex items-center">
|
||||
<MemberAvatar :size="32" :member="singleFile.data.relationships.owner" />
|
||||
<span class="text-sm ml-3 block font-bold">
|
||||
<span class="ml-3 block text-sm font-bold">
|
||||
{{ singleFile.data.relationships.owner.data.attributes.name }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -112,7 +140,9 @@ export default {
|
||||
return this.clipboard[0]
|
||||
},
|
||||
canShowMetaData() {
|
||||
return this.clipboard[0].data.attributes.metadata && this.clipboard[0].data.attributes.metadata.ExifImageWidth
|
||||
return (
|
||||
this.clipboard[0].data.attributes.metadata && this.clipboard[0].data.attributes.metadata.ExifImageWidth
|
||||
)
|
||||
},
|
||||
isLocked() {
|
||||
return this.clipboard[0].data.relationships.shared.protected
|
||||
|
||||
@@ -96,13 +96,17 @@
|
||||
<!--File & Image sub line-->
|
||||
<small v-if="!isFolder" class="block text-xs text-gray-500 dark:text-gray-500">
|
||||
{{ entry.data.attributes.filesize }}
|
||||
<span class="hidden text-xs text-gray-500 dark:text-gray-500 lg:inline-block">, {{ timeStamp }}</span>
|
||||
<span class="hidden text-xs text-gray-500 dark:text-gray-500 lg:inline-block"
|
||||
>, {{ timeStamp }}</span
|
||||
>
|
||||
</small>
|
||||
|
||||
<!--Folder sub line-->
|
||||
<small v-if="isFolder" class="block text-xs text-gray-500 dark:text-gray-500">
|
||||
{{ folderItems === 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems)
|
||||
}}<span class="hidden text-xs text-gray-500 dark:text-gray-500 lg:inline-block">, {{ timeStamp }}</span>
|
||||
}}<span class="hidden text-xs text-gray-500 dark:text-gray-500 lg:inline-block"
|
||||
>, {{ timeStamp }}</span
|
||||
>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
:entry="item"
|
||||
:highlight="true"
|
||||
:mobile-handler="true"
|
||||
:can-hover="true"
|
||||
:can-hover="true"
|
||||
@mouseup.stop.native="clickFilter"
|
||||
@dragstart.native="$emit('dragstart')"
|
||||
@drop.native="drop()"
|
||||
@@ -184,7 +184,10 @@ export default {
|
||||
|
||||
events.$emit('file-preview:show')
|
||||
} else if (this.isFile || (!this.isFolder && !this.isVideo && !this.isAudio && !this.isImage)) {
|
||||
this.$downloadFile(this.item.data.attributes.file_url, this.item.data.attributes.name + '.' + this.item.data.attributes.mimetype)
|
||||
this.$downloadFile(
|
||||
this.item.data.attributes.file_url,
|
||||
this.item.data.attributes.name + '.' + this.item.data.attributes.mimetype
|
||||
)
|
||||
} else if (this.isFolder) {
|
||||
this.$goToFileView(this.item.data.id)
|
||||
}
|
||||
|
||||
@@ -14,16 +14,30 @@
|
||||
<!--Item thumbnail-->
|
||||
<div class="relative w-16 shrink-0">
|
||||
<!--Member thumbnail for team folders-->
|
||||
<MemberAvatar v-if="user && canShowAuthor" :size="28" :is-border="true" :member="entry.data.relationships.owner" class="absolute right-1.5 -bottom-2 z-10" />
|
||||
<MemberAvatar
|
||||
v-if="user && canShowAuthor"
|
||||
:size="28"
|
||||
:is-border="true"
|
||||
:member="entry.data.relationships.owner"
|
||||
class="absolute right-1.5 -bottom-2 z-10"
|
||||
/>
|
||||
|
||||
<!--Emoji Icon-->
|
||||
<Emoji v-if="entry.data.attributes.emoji" :emoji="entry.data.attributes.emoji" class="ml-1 scale-110 transform text-5xl" />
|
||||
<Emoji
|
||||
v-if="entry.data.attributes.emoji"
|
||||
:emoji="entry.data.attributes.emoji"
|
||||
class="ml-1 scale-110 transform text-5xl"
|
||||
/>
|
||||
|
||||
<!--Folder Icon-->
|
||||
<FolderIcon v-if="isFolder && !entry.data.attributes.emoji" :item="entry" />
|
||||
|
||||
<!--File Icon-->
|
||||
<FileIconThumbnail v-if="isFile || isVideo || isAudio || (isImage && !entry.data.attributes.thumbnail)" :entry="entry" class="pr-2" />
|
||||
<FileIconThumbnail
|
||||
v-if="isFile || isVideo || isAudio || (isImage && !entry.data.attributes.thumbnail)"
|
||||
:entry="entry"
|
||||
class="pr-2"
|
||||
/>
|
||||
|
||||
<!--Image thumbnail-->
|
||||
<img
|
||||
@@ -40,7 +54,7 @@
|
||||
<!--Item Title-->
|
||||
<b
|
||||
class="mb-0.5 block overflow-hidden text-ellipsis whitespace-nowrap text-sm"
|
||||
:class="{'hover:underline': canEditName}"
|
||||
:class="{ 'hover:underline': canEditName }"
|
||||
style="max-width: 240px"
|
||||
ref="name"
|
||||
@input="renameItem"
|
||||
@@ -60,19 +74,23 @@
|
||||
|
||||
<!--File & Image sub line-->
|
||||
<small v-if="!isFolder" class="block text-xs text-gray-500 dark:text-gray-500">
|
||||
{{ entry.data.attributes.filesize }}, {{ timeStamp }}
|
||||
</small>
|
||||
{{ entry.data.attributes.filesize }}, {{ timeStamp }}
|
||||
</small>
|
||||
|
||||
<!--Folder sub line-->
|
||||
<small v-if="isFolder" class="block text-xs text-gray-500 dark:text-gray-500">
|
||||
{{ folderItems === 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ timeStamp }}
|
||||
{{ folderItems === 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }},
|
||||
{{ timeStamp }}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mobile item action button-->
|
||||
<div v-if="mobileHandler && !isMultiSelectMode && $isMobile()" class="relative flex-grow pr-1 text-right">
|
||||
<div @mouseup.stop="$openInDetailPanel(entry)" class="absolute right-10 -mr-4 hidden -translate-y-2/4 transform p-2.5 lg:block">
|
||||
<div
|
||||
@mouseup.stop="$openInDetailPanel(entry)"
|
||||
class="absolute right-10 -mr-4 hidden -translate-y-2/4 transform p-2.5 lg:block"
|
||||
>
|
||||
<eye-icon size="18" class="vue-feather inline-block opacity-30" />
|
||||
</div>
|
||||
<div @mouseup.stop="showItemActions" class="absolute right-0 -mr-4 -translate-y-2/4 transform p-2.5">
|
||||
@@ -149,7 +167,9 @@ export default {
|
||||
)
|
||||
},
|
||||
folderItems() {
|
||||
return this.entry.data.attributes.deleted_at ? this.entry.data.attributes.trashed_items : this.entry.data.attributes.items
|
||||
return this.entry.data.attributes.deleted_at
|
||||
? this.entry.data.attributes.trashed_items
|
||||
: this.entry.data.attributes.items
|
||||
},
|
||||
canShowAuthor() {
|
||||
return !this.isFolder && this.user.data.id !== this.entry.data.relationships.owner.data.id
|
||||
@@ -182,14 +202,14 @@ export default {
|
||||
this.itemName = this.entry.data.attributes.name
|
||||
|
||||
// Change item name
|
||||
events.$on('change:name', item => {
|
||||
events.$on('change:name', (item) => {
|
||||
if (this.entry.data.id === item.id) {
|
||||
this.itemName = item.name
|
||||
}
|
||||
this.itemName = item.name
|
||||
}
|
||||
})
|
||||
|
||||
// Autofocus after newly created folder
|
||||
events.$on('newFolder:focus', id => {
|
||||
events.$on('newFolder:focus', (id) => {
|
||||
if (!this.$isMobile() && this.entry.data.id === id) {
|
||||
this.$refs.name.focus()
|
||||
document.execCommand('selectAll')
|
||||
|
||||
@@ -39,7 +39,9 @@ export default {
|
||||
props: ['isBorder', 'member', 'size'],
|
||||
computed: {
|
||||
letter() {
|
||||
let string = this.member.data.attributes.name ? this.member.data.attributes.name : this.member.data.attributes.email
|
||||
let string = this.member.data.attributes.name
|
||||
? this.member.data.attributes.name
|
||||
: this.member.data.attributes.email
|
||||
|
||||
return string.substr(0, 1)
|
||||
},
|
||||
|
||||
@@ -5,7 +5,12 @@
|
||||
<slot v-if="$slots.editor && $checkPermission('editor')" name="editor" />
|
||||
<slot v-if="$slots.visitor && $checkPermission('visitor')" name="visitor" />
|
||||
|
||||
<ToolbarButton @click.native="closeSelecting" class="action-btn close-icon" source="close" :action="$t('actions.close')" />
|
||||
<ToolbarButton
|
||||
@click.native="closeSelecting"
|
||||
class="action-btn close-icon"
|
||||
source="close"
|
||||
:action="$t('actions.close')"
|
||||
/>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<template>
|
||||
<div @click="goBack" class="flex items-center text-left select-none relative">
|
||||
|
||||
<!--Menu icon-->
|
||||
<div v-if="!isVisibleNavigationBars" @click="toggleNavigationBars" class="-mt-0.5 mr-2 p-2 cursor-pointer lg:block hidden">
|
||||
<div @click="goBack" class="relative flex select-none items-center text-left">
|
||||
<!--Menu icon-->
|
||||
<div
|
||||
v-if="!isVisibleNavigationBars"
|
||||
@click="toggleNavigationBars"
|
||||
class="-mt-0.5 mr-2 hidden cursor-pointer p-2 lg:block"
|
||||
>
|
||||
<menu-icon size="17" />
|
||||
</div>
|
||||
|
||||
@@ -12,13 +15,13 @@
|
||||
'-translate-x-3 opacity-0': !isLoadedFolder || !isNotHomepage,
|
||||
'translate-x-0 opacity-100': isLoadedFolder && isNotHomepage,
|
||||
}"
|
||||
class="lg:-mt-0.5 mr-2 -ml-1 cursor-pointer align-middle transition-all duration-200"
|
||||
class="mr-2 -ml-1 cursor-pointer align-middle transition-all duration-200 lg:-mt-0.5"
|
||||
/>
|
||||
|
||||
<!--Folder Title-->
|
||||
<b
|
||||
:class="{ '-translate-x-4': !isLoadedFolder || !isNotHomepage }"
|
||||
class="inline-block transform overflow-hidden text-ellipsis whitespace-nowrap align-middle text-sm font-bold transition-all duration-200 max-w-[200px]"
|
||||
class="inline-block max-w-[200px] transform overflow-hidden text-ellipsis whitespace-nowrap align-middle text-sm font-bold transition-all duration-200"
|
||||
>
|
||||
{{ $getCurrentLocationName() }}
|
||||
</b>
|
||||
@@ -29,60 +32,56 @@
|
||||
'-translate-x-4 opacity-0': !currentFolder || !isNotHomepage,
|
||||
'translate-x-0 opacity-100': currentFolder && isNotHomepage,
|
||||
}"
|
||||
class="relative ml-3 transform rounded-md bg-light-background py-0.5 px-1.5 transition-all duration-200 dark:bg-dark-foreground cursor-pointer"
|
||||
id="folder-actions"
|
||||
class="relative ml-3 transform cursor-pointer rounded-md bg-light-background py-0.5 px-1.5 transition-all duration-200 dark:bg-dark-foreground"
|
||||
id="folder-actions"
|
||||
>
|
||||
<more-horizontal-icon size="14" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import {events} from "../../bus";
|
||||
import { mapGetters } from 'vuex'
|
||||
import { events } from '../../bus'
|
||||
import { MenuIcon, ChevronLeftIcon, MoreHorizontalIcon } from 'vue-feather-icons'
|
||||
|
||||
export default {
|
||||
name: 'NavigationBar',
|
||||
components: {
|
||||
MoreHorizontalIcon,
|
||||
ChevronLeftIcon,
|
||||
MenuIcon,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isVisibleNavigationBars',
|
||||
'currentFolder',
|
||||
'sharedDetail',
|
||||
]),
|
||||
isNotHomepage() {
|
||||
if (this.$isThisRoute(this.$route, ['Public'])) {
|
||||
return this.sharedDetail && this.sharedDetail.data.attributes.item_id !== this.$route.params.id
|
||||
}
|
||||
components: {
|
||||
MoreHorizontalIcon,
|
||||
ChevronLeftIcon,
|
||||
MenuIcon,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['isVisibleNavigationBars', 'currentFolder', 'sharedDetail']),
|
||||
isNotHomepage() {
|
||||
if (this.$isThisRoute(this.$route, ['Public'])) {
|
||||
return this.sharedDetail && this.sharedDetail.data.attributes.item_id !== this.$route.params.id
|
||||
}
|
||||
|
||||
return this.$route.params.id
|
||||
},
|
||||
isLoadedFolder() {
|
||||
return this.$route.params.id
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
if (this.isNotHomepage) this.$router.back()
|
||||
},
|
||||
showItemActions() {
|
||||
if (window.innerWidth > 1024) {
|
||||
events.$emit('context-menu:current-folder', this.currentFolder)
|
||||
} else {
|
||||
this.$store.commit('CLIPBOARD_CLEAR')
|
||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.currentFolder)
|
||||
return this.$route.params.id
|
||||
},
|
||||
isLoadedFolder() {
|
||||
return this.$route.params.id
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
if (this.isNotHomepage) this.$router.back()
|
||||
},
|
||||
showItemActions() {
|
||||
if (window.innerWidth > 1024) {
|
||||
events.$emit('context-menu:current-folder', this.currentFolder)
|
||||
} else {
|
||||
this.$store.commit('CLIPBOARD_CLEAR')
|
||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', this.currentFolder)
|
||||
|
||||
this.$showMobileMenu('file-menu')
|
||||
events.$emit('mobile-context-menu:show', this.currentFolder)
|
||||
}
|
||||
},
|
||||
toggleNavigationBars() {
|
||||
this.$store.dispatch('toggleNavigationBars')
|
||||
},
|
||||
}
|
||||
this.$showMobileMenu('file-menu')
|
||||
events.$emit('mobile-context-menu:show', this.currentFolder)
|
||||
}
|
||||
},
|
||||
toggleNavigationBars() {
|
||||
this.$store.dispatch('toggleNavigationBars')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,54 +1,244 @@
|
||||
<template>
|
||||
<li
|
||||
class="flex items-center justify-between py-4 px-5"
|
||||
:class="{'group cursor-pointer hover:bg-light-background dark:hover:bg-4x-dark-foreground': !isHoverDisabled}"
|
||||
class="flex items-center justify-between py-3.5 px-5"
|
||||
:class="{ 'group cursor-pointer hover:bg-light-background dark:hover:bg-4x-dark-foreground': !isHoverDisabled }"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<div class="mr-4">
|
||||
<calendar-icon v-if="icon === 'calendar'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<grid-icon v-if="icon === 'grid'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<list-icon v-if="icon === 'list'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<trash-2-icon v-if="icon === 'trash'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<life-buoy-icon v-if="icon === 'restore'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<trash-icon v-if="icon === 'empty-trash'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<eye-icon v-if="icon === 'detail'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<download-cloud-icon v-if="icon === 'download'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<edit2-icon v-if="icon === 'rename'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<corner-down-right-icon v-if="icon === 'move-item'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<link-icon v-if="icon === 'share'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<star-icon v-if="icon === 'favourites'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<folder-plus-icon v-if="icon === 'create-folder'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<smile-icon v-if="icon === 'no-options'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<paperclip-icon v-if="icon === 'zip-folder'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<alphabet-icon v-if="icon === 'alphabet'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<star-icon v-if="icon === 'star'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<hard-drive-icon v-if="icon === 'hard-drive'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<upload-cloud-icon v-if="icon === 'upload-cloud'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<users-icon v-if="icon === 'users'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<user-icon v-if="icon === 'user'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<user-plus-icon v-if="icon === 'user-plus'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<user-minus-icon v-if="icon === 'user-minus'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<user-check-icon v-if="icon === 'user-check'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<settings-icon v-if="icon === 'settings'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<power-icon v-if="icon === 'power'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<lock-icon v-if="icon === 'lock'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<cloud-icon v-if="icon === 'cloud'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<credit-card-icon v-if="icon === 'credit-card'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<file-text-icon v-if="icon === 'file-text'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<database-icon v-if="icon === 'database'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<globe-icon v-if="icon === 'globe'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<monitor-icon v-if="icon === 'monitor'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<box-icon v-if="icon === 'box'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<folder-plus-icon v-if="icon === 'folder-plus'" size="17" class="vue-feather group-hover-text-theme" :class="{ 'text-theme': isActive }" />
|
||||
<calendar-icon
|
||||
v-if="icon === 'calendar'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<grid-icon
|
||||
v-if="icon === 'grid'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<list-icon
|
||||
v-if="icon === 'list'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<trash-2-icon
|
||||
v-if="icon === 'trash'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<life-buoy-icon
|
||||
v-if="icon === 'restore'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<trash-icon
|
||||
v-if="icon === 'empty-trash'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<eye-icon
|
||||
v-if="icon === 'detail'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<download-cloud-icon
|
||||
v-if="icon === 'download'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<edit2-icon
|
||||
v-if="icon === 'rename'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<corner-down-right-icon
|
||||
v-if="icon === 'move-item'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<link-icon
|
||||
v-if="icon === 'share'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<star-icon
|
||||
v-if="icon === 'favourites'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<folder-plus-icon
|
||||
v-if="icon === 'create-folder'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<smile-icon
|
||||
v-if="icon === 'no-options'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<paperclip-icon
|
||||
v-if="icon === 'zip-folder'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<alphabet-icon
|
||||
v-if="icon === 'alphabet'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<star-icon
|
||||
v-if="icon === 'star'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<hard-drive-icon
|
||||
v-if="icon === 'hard-drive'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<upload-cloud-icon
|
||||
v-if="icon === 'upload-cloud'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<users-icon
|
||||
v-if="icon === 'users'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<user-icon
|
||||
v-if="icon === 'user'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<user-plus-icon
|
||||
v-if="icon === 'user-plus'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<user-minus-icon
|
||||
v-if="icon === 'user-minus'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<user-check-icon
|
||||
v-if="icon === 'user-check'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<settings-icon
|
||||
v-if="icon === 'settings'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<power-icon
|
||||
v-if="icon === 'power'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<lock-icon
|
||||
v-if="icon === 'lock'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<cloud-icon
|
||||
v-if="icon === 'cloud'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<credit-card-icon
|
||||
v-if="icon === 'credit-card'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<file-text-icon
|
||||
v-if="icon === 'file-text'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<database-icon
|
||||
v-if="icon === 'database'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<globe-icon
|
||||
v-if="icon === 'globe'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<monitor-icon
|
||||
v-if="icon === 'monitor'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<box-icon
|
||||
v-if="icon === 'box'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<folder-plus-icon
|
||||
v-if="icon === 'folder-plus'"
|
||||
size="17"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
</div>
|
||||
<b class="group-hover-text-theme text-sm font-bold" :class="{ 'text-theme': isActive }">
|
||||
{{ title }}
|
||||
</b>
|
||||
</div>
|
||||
<div v-if="arrow" class="ml-2">
|
||||
<chevron-right-icon v-if="arrow === 'right'" size="14" class="vue-feather group-hover-text-theme opacity-50" :class="{ 'text-theme': isActive }" />
|
||||
<arrow-up-icon v-if="arrow === 'up'" size="14" class="vue-feather group-hover-text-theme opacity-50" :class="{ 'text-theme': isActive }" />
|
||||
<arrow-down-icon v-if="arrow === 'down'" size="14" class="vue-feather group-hover-text-theme opacity-50" :class="{ 'text-theme': isActive }" />
|
||||
<chevron-right-icon
|
||||
v-if="arrow === 'right'"
|
||||
size="14"
|
||||
class="vue-feather group-hover-text-theme opacity-50"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<arrow-up-icon
|
||||
v-if="arrow === 'up'"
|
||||
size="14"
|
||||
class="vue-feather group-hover-text-theme opacity-50"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
<arrow-down-icon
|
||||
v-if="arrow === 'down'"
|
||||
size="14"
|
||||
class="vue-feather group-hover-text-theme opacity-50"
|
||||
:class="{ 'text-theme': isActive }"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<b v-if="title" class="py-0.5 px-4 mt-2 block text-xs text-gray-400 dark-text-theme">
|
||||
{{ title }}
|
||||
</b>
|
||||
<ul class="option-group py-1">
|
||||
<slot></slot>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<b v-if="title" class="dark-text-theme mt-2 block py-0.5 px-4 text-xs text-gray-400">
|
||||
{{ title }}
|
||||
</b>
|
||||
<ul class="option-group py-1">
|
||||
<slot></slot>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'OptionGroup',
|
||||
props: [
|
||||
'title'
|
||||
]
|
||||
props: ['title'],
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
<template>
|
||||
<label
|
||||
class="flex items-center py-4 px-5 group cursor-pointer hover:bg-light-background dark:hover:bg-4x-dark-foreground"
|
||||
>
|
||||
class="group flex cursor-pointer items-center py-4 px-5 hover:bg-light-background dark:hover:bg-4x-dark-foreground"
|
||||
>
|
||||
<div class="mr-4">
|
||||
<upload-cloud-icon v-if="type === 'file'" size="17" class="vue-feather group-hover-text-theme" />
|
||||
<folder-upload-icon v-if="type === 'folder'" size="17" class="vue-feather group-hover-text-theme" />
|
||||
</div>
|
||||
<div class="group-hover-text-theme text-sm font-bold text-left">
|
||||
<div class="group-hover-text-theme text-left text-sm font-bold">
|
||||
{{ title }}
|
||||
|
||||
<input v-if="type === 'file'" @change="emmitFiles" v-show="false" id="file" type="file" name="files[]" multiple />
|
||||
<input v-if="type === 'folder'" @change="emmitFolder" v-show="false" id="folder" type="file" name="folders[]" webkitdirectory mozdirectory />
|
||||
<input
|
||||
v-if="type === 'file'"
|
||||
@change="emmitFiles"
|
||||
v-show="false"
|
||||
id="file"
|
||||
type="file"
|
||||
name="files[]"
|
||||
multiple
|
||||
/>
|
||||
<input
|
||||
v-if="type === 'folder'"
|
||||
@change="emmitFolder"
|
||||
v-show="false"
|
||||
id="folder"
|
||||
type="file"
|
||||
name="folders[]"
|
||||
webkitdirectory
|
||||
mozdirectory
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
@@ -30,8 +47,8 @@ export default {
|
||||
emmitFiles(e) {
|
||||
this.$uploadFiles(e.target.files)
|
||||
},
|
||||
emmitFolder(e) {
|
||||
this.$store.commit('UPDATE_UPLOADING_FOLDER_STATE', true)
|
||||
emmitFolder(e) {
|
||||
this.$store.commit('UPDATE_UPLOADING_FOLDER_STATE', true)
|
||||
|
||||
this.$uploadFiles(e.target.files)
|
||||
},
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div @click="$openSpotlight()" class="relative cursor-pointer rounded-lg bg-light-background dark:bg-dark-foreground">
|
||||
<div
|
||||
@click="$openSpotlight()"
|
||||
class="relative cursor-pointer rounded-lg bg-light-background dark:bg-dark-foreground"
|
||||
>
|
||||
<div class="flex w-56 items-center justify-between px-4 py-2.5 text-left xl:w-64">
|
||||
<div class="flex items-center">
|
||||
<search-icon size="18" class="vue-feather text-gray-400 dark:text-gray-600" />
|
||||
@@ -7,7 +10,9 @@
|
||||
{{ $t('inputs.placeholder_search_files') }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="rounded dark:border-slate-200 border px-1 py-0.5 text-xs font-bold tracking-normal text-gray-400 dark:border-opacity-5 dark:text-gray-600">
|
||||
<span
|
||||
class="rounded border px-1 py-0.5 text-xs font-bold tracking-normal text-gray-400 dark:border-slate-200 dark:border-opacity-5 dark:text-gray-600"
|
||||
>
|
||||
{{ metaKeyIcon }}+K
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<button class="group h-[42px] w-[42px] inline-flex items-center justify-center cursor-pointer rounded-lg dark:hover:bg-2x-dark-foreground hover:bg-light-background" :title="action">
|
||||
<button
|
||||
class="group inline-flex h-[42px] w-[42px] cursor-pointer items-center justify-center rounded-lg hover:bg-light-background dark:hover:bg-2x-dark-foreground"
|
||||
:title="action"
|
||||
>
|
||||
<corner-down-right-icon v-if="source === 'move'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<download-cloud-icon v-if="source === 'download'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<folder-plus-icon v-if="source === 'folder-plus'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
@@ -10,14 +13,19 @@
|
||||
<printer-icon v-if="source === 'print'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<trash-2-icon v-if="source === 'trash'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<list-icon v-if="source === 'th-list'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<info-icon v-if="source === 'info'" size="19" class="vue-feather group-hover-text-theme" :class="{'text-theme': isVisibleSidebar}" />
|
||||
<info-icon
|
||||
v-if="source === 'info'"
|
||||
size="19"
|
||||
class="vue-feather group-hover-text-theme"
|
||||
:class="{ 'text-theme': isVisibleSidebar }"
|
||||
/>
|
||||
<grid-icon v-if="source === 'th'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<link-icon v-if="source === 'share'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<x-icon v-if="source === 'close'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<search-icon v-if="source === 'search'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<cloud-off-icon v-if="source === 'shared-off'" size="19" class="vue-feather group-hover-text-theme" />
|
||||
<sorting-icon v-if="source === 'preview-sorting'" class="scale-125 vue-feather group-hover-text-theme" />
|
||||
<CloudPlusIcon v-if="source === 'cloud-plus'" class="scale-125 vue-feather group-hover-text-theme" />
|
||||
<sorting-icon v-if="source === 'preview-sorting'" class="vue-feather group-hover-text-theme scale-125" />
|
||||
<CloudPlusIcon v-if="source === 'cloud-plus'" class="vue-feather group-hover-text-theme scale-125" />
|
||||
</button>
|
||||
</template>
|
||||
|
||||
@@ -42,16 +50,14 @@ import {
|
||||
LinkIcon,
|
||||
XIcon,
|
||||
} from 'vue-feather-icons'
|
||||
import {mapGetters} from "vuex";
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'ToolbarButton',
|
||||
props: ['source', 'action'],
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'isVisibleSidebar'
|
||||
])
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['isVisibleSidebar']),
|
||||
},
|
||||
components: {
|
||||
SearchIcon,
|
||||
CloudPlusIcon,
|
||||
@@ -73,4 +79,4 @@ export default {
|
||||
XIcon,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@@ -43,7 +43,13 @@ export default {
|
||||
XIcon,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['filesInQueueUploaded', 'filesInQueueTotal', 'uploadingProgress', 'isProcessingFile', 'fileQueue']),
|
||||
...mapGetters([
|
||||
'filesInQueueUploaded',
|
||||
'filesInQueueTotal',
|
||||
'uploadingProgress',
|
||||
'isProcessingFile',
|
||||
'fileQueue',
|
||||
]),
|
||||
},
|
||||
methods: {
|
||||
cancelUpload() {
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
<footer class="plan-footer">
|
||||
<b class="price text-theme">
|
||||
{{ plan.data.attributes.price }}/{{ $t('global.monthly_ac') }}
|
||||
<small v-if="plan.data.attributes.tax_rates.length > 0" class="vat-disclaimer">{{ $t('page_pricing_tables.vat_excluded') }}</small>
|
||||
<small v-if="plan.data.attributes.tax_rates.length > 0" class="vat-disclaimer">{{
|
||||
$t('page_pricing_tables.vat_excluded')
|
||||
}}</small>
|
||||
</b>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
<template>
|
||||
<div class="page-wrapper large get-started" v-if="index.section_get_started === '1'">
|
||||
<PageTitle class="page-title" type="center" :title="index.get_started_title" :description="index.get_started_description"></PageTitle>
|
||||
<PageTitle
|
||||
class="page-title"
|
||||
type="center"
|
||||
:title="index.get_started_title"
|
||||
:description="index.get_started_description"
|
||||
></PageTitle>
|
||||
|
||||
<router-link tag="button" class="get-started-button bg-theme-800 hover-bg-theme shadow-theme" :to="{ name: 'SignUp' }">
|
||||
<router-link
|
||||
tag="button"
|
||||
class="get-started-button bg-theme-800 hover-bg-theme shadow-theme"
|
||||
:to="{ name: 'SignUp' }"
|
||||
>
|
||||
<span class="content">{{ $t('page_index.get_started_button') }}</span>
|
||||
<chevron-right-icon size="22"></chevron-right-icon>
|
||||
</router-link>
|
||||
|
||||
@@ -23,7 +23,18 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { FolderPlusIcon, HardDriveIcon, SettingsIcon, Trash2Icon, SearchIcon, ImageIcon, GridIcon, LinkIcon, StarIcon, EyeIcon } from 'vue-feather-icons'
|
||||
import {
|
||||
FolderPlusIcon,
|
||||
HardDriveIcon,
|
||||
SettingsIcon,
|
||||
Trash2Icon,
|
||||
SearchIcon,
|
||||
ImageIcon,
|
||||
GridIcon,
|
||||
LinkIcon,
|
||||
StarIcon,
|
||||
EyeIcon,
|
||||
} from 'vue-feather-icons'
|
||||
|
||||
export default {
|
||||
name: 'IndexHeroScreenshot',
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<section class="main-features page-wrapper medium">
|
||||
<PageTitle v-if="index.section_features === '1'" type="center" :title="index.features_title" :description="index.features_description"></PageTitle>
|
||||
<PageTitle
|
||||
v-if="index.section_features === '1'"
|
||||
type="center"
|
||||
:title="index.features_title"
|
||||
:description="index.features_description"
|
||||
></PageTitle>
|
||||
<div v-if="index.section_feature_boxes === '1'" class="content">
|
||||
<div class="hero">
|
||||
<img src="/assets/images/hero-Illustration.svg" alt="Hero" />
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<nav class="main-navigation">
|
||||
<router-link :to="{ name: 'Homepage' }" tag="div" class="logo">
|
||||
<img v-if="config.app_logo_horizontal" :src="$getImage(config.app_logo_horizontal)" :alt="config.app_name" />
|
||||
<img
|
||||
v-if="config.app_logo_horizontal"
|
||||
:src="$getImage(config.app_logo_horizontal)"
|
||||
:alt="config.app_name"
|
||||
/>
|
||||
<b v-if="!config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
|
||||
</router-link>
|
||||
<div class="navigation">
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<footer class="page-wrapper medium">
|
||||
<router-link :to="{ name: 'Homepage' }" tag="div" class="logo">
|
||||
<img v-if="config.app_logo_horizontal" :src="$getImage(config.app_logo_horizontal)" :alt="config.app_name" />
|
||||
<img
|
||||
v-if="config.app_logo_horizontal"
|
||||
:src="$getImage(config.app_logo_horizontal)"
|
||||
:alt="config.app_name"
|
||||
/>
|
||||
<b v-if="!config.app_logo_horizontal" class="logo-text">{{ config.app_name }}</b>
|
||||
</router-link>
|
||||
<ul class="navigation-links">
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div class="page-wrapper medium pricing" v-if="!isEmpty && index.section_pricing_content === '1' && config.stripe_public_key">
|
||||
<div
|
||||
class="page-wrapper medium pricing"
|
||||
v-if="!isEmpty && index.section_pricing_content === '1' && config.stripe_public_key"
|
||||
>
|
||||
<div id="pricing" class="page-title center">
|
||||
<h1 class="title" v-html="index.pricing_title"></h1>
|
||||
</div>
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
<slot />
|
||||
</div>
|
||||
</transition>
|
||||
<transition name="vignette">
|
||||
<div
|
||||
v-if="isVisible"
|
||||
@click="closeMenu"
|
||||
class="fixed left-0 right-0 top-0 bottom-0 z-20 bg-dark-background bg-opacity-[0.35] dark:bg-opacity-[0.45]"
|
||||
></div>
|
||||
</transition>
|
||||
<transition name="vignette">
|
||||
<div
|
||||
v-if="isVisible"
|
||||
@click="closeMenu"
|
||||
class="fixed left-0 right-0 top-0 bottom-0 z-20 bg-dark-background bg-opacity-[0.35] dark:bg-opacity-[0.45]"
|
||||
></div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -75,19 +75,19 @@ export default {
|
||||
}
|
||||
|
||||
.vignette-enter-active {
|
||||
animation: vignette-in 0.15s cubic-bezier(0.4, 0, 1, 1);
|
||||
animation: vignette-in 0.15s cubic-bezier(0.4, 0, 1, 1);
|
||||
}
|
||||
|
||||
.vignette-leave-active {
|
||||
animation: vignette-in 0.15s linear reverse;
|
||||
animation: vignette-in 0.15s linear reverse;
|
||||
}
|
||||
|
||||
@keyframes vignette-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,7 +23,13 @@
|
||||
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary">
|
||||
{{ $t('global.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="confirmPassword" button-style="theme" :loading="isLoading" :disabled="isLoading">
|
||||
<ButtonBase
|
||||
class="w-full"
|
||||
@click.native="confirmPassword"
|
||||
button-style="theme"
|
||||
:loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
{{ $t('popup_2fa.confirm_button') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
|
||||
@@ -39,7 +39,8 @@ export default {
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.isVisibleDisclaimer = this.config.installation === 'installation-done' && !localStorage.getItem('isHiddenDisclaimer')
|
||||
this.isVisibleDisclaimer =
|
||||
this.config.installation === 'installation-done' && !localStorage.getItem('isHiddenDisclaimer')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -21,7 +21,11 @@
|
||||
</AppInputText>
|
||||
</ValidationProvider>
|
||||
|
||||
<AppInputSwitch :title="$t('Emoji as an Icon')" :description="$t('Replace folder icon with an Emoji')" :is-last="!isEmoji">
|
||||
<AppInputSwitch
|
||||
:title="$t('Emoji as an Icon')"
|
||||
:description="$t('Replace folder icon with an Emoji')"
|
||||
:is-last="!isEmoji"
|
||||
>
|
||||
<SwitchInput v-model="isEmoji" :state="isEmoji" />
|
||||
</AppInputSwitch>
|
||||
|
||||
@@ -32,8 +36,12 @@
|
||||
|
||||
<!--Actions-->
|
||||
<PopupActions>
|
||||
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary">{{ $t('popup_move_item.cancel') }} </ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="createFolder" button-style="theme">{{ $t('popup_create_folder.title') }} </ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary"
|
||||
>{{ $t('popup_move_item.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="createFolder" button-style="theme"
|
||||
>{{ $t('popup_create_folder.title') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
</PopupWrapper>
|
||||
</template>
|
||||
|
||||
@@ -7,9 +7,20 @@
|
||||
<PopupContent>
|
||||
<!--Form to set sharing-->
|
||||
<ValidationObserver @submit.prevent="createLanguage" ref="createForm" v-slot="{ invalid }" tag="form">
|
||||
<ValidationProvider tag="div" mode="passive" name="Language Locale" rules="required" v-slot="{ errors }">
|
||||
<ValidationProvider
|
||||
tag="div"
|
||||
mode="passive"
|
||||
name="Language Locale"
|
||||
rules="required"
|
||||
v-slot="{ errors }"
|
||||
>
|
||||
<AppInputText :title="$t('select_locale')" :error="errors[0]">
|
||||
<SelectInput v-model="form.locale" :options="locales" :placeholder="$t('select_language_locale')" :isError="errors[0]" />
|
||||
<SelectInput
|
||||
v-model="form.locale"
|
||||
:options="locales"
|
||||
:placeholder="$t('select_language_locale')"
|
||||
:isError="errors[0]"
|
||||
/>
|
||||
</AppInputText>
|
||||
</ValidationProvider>
|
||||
<ValidationProvider tag="div" mode="passive" name="Language Name" rules="required" v-slot="{ errors }">
|
||||
@@ -32,7 +43,13 @@
|
||||
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary">
|
||||
{{ $t('global.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="createLanguage" button-style="theme" :loading="isLoading" :disabled="isLoading">
|
||||
<ButtonBase
|
||||
class="w-full"
|
||||
@click.native="createLanguage"
|
||||
button-style="theme"
|
||||
:loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
{{ $t('create_language') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
|
||||
@@ -3,7 +3,13 @@
|
||||
<PopupHeader :title="$t('popup_personal_token.title')" icon="key" />
|
||||
|
||||
<PopupContent>
|
||||
<ValidationObserver v-if="!token" @submit.prevent="createTokenForm" ref="createToken" v-slot="{ invalid }" tag="form">
|
||||
<ValidationObserver
|
||||
v-if="!token"
|
||||
@submit.prevent="createTokenForm"
|
||||
ref="createToken"
|
||||
v-slot="{ invalid }"
|
||||
tag="form"
|
||||
>
|
||||
<ValidationProvider tag="div" mode="passive" name="Token Name" rules="required" v-slot="{ errors }">
|
||||
<AppInputText :title="$t('popup_personal_token.label')" :error="errors[0]" :is-last="true">
|
||||
<input
|
||||
@@ -31,7 +37,13 @@
|
||||
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary">
|
||||
{{ $t('global.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="createTokenForm" button-style="theme" :loading="isLoading" :disabled="isLoading">
|
||||
<ButtonBase
|
||||
class="w-full"
|
||||
@click.native="createTokenForm"
|
||||
button-style="theme"
|
||||
:loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
{{ $t('personal_token.create_token') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<div v-if="emoji">
|
||||
<div v-if="config.defaultEmoji === 'twemoji'" v-html="transferEmoji" style="font-size: inherit; transform: scale(0.95)"></div>
|
||||
<div
|
||||
v-if="config.defaultEmoji === 'twemoji'"
|
||||
v-html="transferEmoji"
|
||||
style="font-size: inherit; transform: scale(0.95)"
|
||||
></div>
|
||||
<div v-if="config.defaultEmoji === 'applemoji'" style="font-size: inherit">
|
||||
{{ emoji.char }}
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,13 @@
|
||||
</div>
|
||||
|
||||
<!-- Search input -->
|
||||
<input @click="openList" v-model="query" class="focus-border-theme input-dark" type="text" :placeholder="$t('Select or search emoji icon...')" />
|
||||
<input
|
||||
@click="openList"
|
||||
v-model="query"
|
||||
class="focus-border-theme input-dark"
|
||||
type="text"
|
||||
:placeholder="$t('Select or search emoji icon...')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Spinner -->
|
||||
@@ -17,9 +23,18 @@
|
||||
</div>
|
||||
|
||||
<!-- Emojis List -->
|
||||
<div v-if="isOpen && isLoaded && emojis" @scroll="checkGroupInView" id="group-box" class="relative h-96 select-none overflow-y-auto lg:h-60 2xl:h-96">
|
||||
<div
|
||||
v-if="isOpen && isLoaded && emojis"
|
||||
@scroll="checkGroupInView"
|
||||
id="group-box"
|
||||
class="relative h-96 select-none overflow-y-auto lg:h-60 2xl:h-96"
|
||||
>
|
||||
<!-- Navigation of Emojis Groups -->
|
||||
<ul v-if="!query" class="sticky top-0 z-10 flex items-center justify-between space-x-1 bg-white dark:bg-dark-background sm:dark:bg-4x-dark-foreground" id="group-bar">
|
||||
<ul
|
||||
v-if="!query"
|
||||
class="sticky top-0 z-10 flex items-center justify-between space-x-1 bg-white dark:bg-dark-background sm:dark:bg-4x-dark-foreground"
|
||||
id="group-bar"
|
||||
>
|
||||
<li
|
||||
@click.stop="scrollToGroup(group.name)"
|
||||
v-for="(group, i) in emojis.groups"
|
||||
@@ -39,7 +54,12 @@
|
||||
{{ name }}
|
||||
</label>
|
||||
<ul class="space-between grid grid-cols-7 gap-4 md:grid-cols-9">
|
||||
<li @click="setEmoji(emoji)" v-for="(emoji, i) in group" :key="i" class="flex cursor-pointer items-center justify-center">
|
||||
<li
|
||||
@click="setEmoji(emoji)"
|
||||
v-for="(emoji, i) in group"
|
||||
:key="i"
|
||||
class="flex cursor-pointer items-center justify-center"
|
||||
>
|
||||
<Emoji :emoji="emoji" class="text-4xl" />
|
||||
</li>
|
||||
</ul>
|
||||
@@ -47,7 +67,12 @@
|
||||
|
||||
<!-- Searched emojis -->
|
||||
<ul v-if="query" class="space-between grid grid-cols-7 gap-4 md:grid-cols-9">
|
||||
<li @click="setEmoji(emoji)" v-for="(emoji, i) in filteredEmojis" :key="i" class="flex cursor-pointer items-center justify-center">
|
||||
<li
|
||||
@click="setEmoji(emoji)"
|
||||
v-for="(emoji, i) in filteredEmojis"
|
||||
:key="i"
|
||||
class="flex cursor-pointer items-center justify-center"
|
||||
>
|
||||
<Emoji :emoji="emoji" class="text-4xl" />
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -9,10 +9,24 @@
|
||||
/>
|
||||
|
||||
<!--Audio-->
|
||||
<audio v-if="singleFile.data.type === 'audio'" :src="singleFile.data.attributes.file_url" controlsList="nodownload" controls class="w-full"></audio>
|
||||
<audio
|
||||
v-if="singleFile.data.type === 'audio'"
|
||||
:src="singleFile.data.attributes.file_url"
|
||||
controlsList="nodownload"
|
||||
controls
|
||||
class="w-full"
|
||||
></audio>
|
||||
|
||||
<!--Video-->
|
||||
<video v-if="singleFile.data.type === 'video'" ref="video" class="h-auto w-full overflow-hidden rounded-sm" controlsList="nodownload" disablePictureInPicture playsinline controls>
|
||||
<video
|
||||
v-if="singleFile.data.type === 'video'"
|
||||
ref="video"
|
||||
class="h-auto w-full overflow-hidden rounded-sm"
|
||||
controlsList="nodownload"
|
||||
disablePictureInPicture
|
||||
playsinline
|
||||
controls
|
||||
>
|
||||
<source :src="singleFile.data.attributes.file_url" type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
@@ -33,12 +47,12 @@ export default {
|
||||
return this.singleFile && !includes(['folder', 'file'], this.singleFile.data.type)
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'singleFile': function (val) {
|
||||
if (val.data.type === 'video') {
|
||||
this.$refs.video.load()
|
||||
}
|
||||
}
|
||||
}
|
||||
watch: {
|
||||
singleFile: function (val) {
|
||||
if (val.data.type === 'video') {
|
||||
this.$refs.video.load()
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
<template>
|
||||
<div class="relative cursor-pointer">
|
||||
<input ref="file" type="file" @change="showImagePreview($event)" class="absolute top-0 bottom-0 left-0 right-0 z-10 w-full cursor-pointer opacity-0" />
|
||||
<img v-if="imagePreview" ref="image" :src="imagePreview" class="relative z-0 h-14 w-14 cursor-pointer rounded-xl object-cover shadow-lg md:h-16 md:w-16" alt="avatar" />
|
||||
<input
|
||||
ref="file"
|
||||
type="file"
|
||||
@change="showImagePreview($event)"
|
||||
class="absolute top-0 bottom-0 left-0 right-0 z-10 w-full cursor-pointer opacity-0"
|
||||
/>
|
||||
<img
|
||||
v-if="imagePreview"
|
||||
ref="image"
|
||||
:src="imagePreview"
|
||||
class="relative z-0 h-14 w-14 cursor-pointer rounded-xl object-cover shadow-lg md:h-16 md:w-16"
|
||||
alt="avatar"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
</div>
|
||||
|
||||
<!--Hidden options-->
|
||||
<ul v-if="isOpenedMoreOptions" class="absolute top-12 left-0 right-0 z-10 select-none overflow-y-auto overflow-x-hidden rounded-lg shadow-xl">
|
||||
<ul
|
||||
v-if="isOpenedMoreOptions"
|
||||
class="absolute top-12 left-0 right-0 z-10 select-none overflow-y-auto overflow-x-hidden rounded-lg shadow-xl"
|
||||
>
|
||||
<li
|
||||
@click="getQrCode"
|
||||
class="block flex cursor-pointer items-center bg-white py-2.5 px-5 hover:bg-light-background dark:bg-2x-dark-foreground dark:hover:bg-4x-dark-foreground"
|
||||
@@ -57,7 +60,11 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<textarea v-model="iframeCode" ref="iframe" class="pointer-events-none absolute right-full opacity-0"></textarea>
|
||||
<textarea
|
||||
v-model="iframeCode"
|
||||
ref="iframe"
|
||||
class="pointer-events-none absolute right-full opacity-0"
|
||||
></textarea>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
|
||||
<script>
|
||||
import {
|
||||
InfoIcon,
|
||||
DatabaseIcon,
|
||||
InfoIcon,
|
||||
DatabaseIcon,
|
||||
UsersIcon,
|
||||
ShieldIcon,
|
||||
CreditCardIcon,
|
||||
@@ -44,8 +44,8 @@ export default {
|
||||
name: 'FormLabel',
|
||||
props: ['icon'],
|
||||
components: {
|
||||
InfoIcon,
|
||||
DatabaseIcon,
|
||||
InfoIcon,
|
||||
DatabaseIcon,
|
||||
UsersIcon,
|
||||
CreditCardIcon,
|
||||
DollarSignIcon,
|
||||
|
||||
@@ -1,86 +1,97 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-center rounded-lg relative h-[175px] dark:bg-2x-dark-foreground bg-light-background" :class="{ 'is-error': error }">
|
||||
|
||||
<!--Reset Image-->
|
||||
<div
|
||||
v-if="imagePreview"
|
||||
@click="resetImage"
|
||||
class="absolute z-10 right-0 top-0 flex h-7 w-7 cursor-pointer items-center justify-center rounded-md bg-white shadow-lg rounded-full -translate-y-3 translate-x-3"
|
||||
>
|
||||
<div
|
||||
class="relative flex h-[175px] items-center justify-center rounded-lg bg-light-background dark:bg-2x-dark-foreground"
|
||||
:class="{ 'is-error': error }"
|
||||
>
|
||||
<!--Reset Image-->
|
||||
<div
|
||||
v-if="imagePreview"
|
||||
@click="resetImage"
|
||||
class="absolute right-0 top-0 z-10 flex h-7 w-7 -translate-y-3 translate-x-3 cursor-pointer items-center justify-center rounded-md rounded-full bg-white shadow-lg"
|
||||
>
|
||||
<x-icon size="14" class="vue-feather" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input
|
||||
@change="showImagePreview($event)"
|
||||
ref="file"
|
||||
type="file"
|
||||
class="opacity-0 absolute top-0 left-0 right-0 bottom-0 z-10 w-full cursor-pointer"
|
||||
/>
|
||||
@change="showImagePreview($event)"
|
||||
ref="file"
|
||||
type="file"
|
||||
class="absolute top-0 left-0 right-0 bottom-0 z-10 w-full cursor-pointer opacity-0"
|
||||
/>
|
||||
|
||||
<!--Default image preview-->
|
||||
<img v-if="imagePreview" :src="imagePreview" ref="image" class="absolute w-full h-full object-contain py-4 px-12" />
|
||||
<!--Default image preview-->
|
||||
<img
|
||||
v-if="imagePreview"
|
||||
:src="imagePreview"
|
||||
ref="image"
|
||||
class="absolute h-full w-full object-contain py-4 px-12"
|
||||
/>
|
||||
|
||||
<!--Drop image zone-->
|
||||
<!--Drop image zone-->
|
||||
<div v-if="!isData" class="text-center">
|
||||
<image-icon size="34" class="vue-feather text-theme inline-block mb-4" />
|
||||
<image-icon size="34" class="vue-feather text-theme mb-4 inline-block" />
|
||||
|
||||
<b class="font-bold text-base block leading-3">
|
||||
<b class="block text-base font-bold leading-3">
|
||||
{{ $te('input_image.title') ? $t('input_image.title') : 'Upload Image' }}
|
||||
</b>
|
||||
<small class="text-xs text-gray-500">
|
||||
{{ $te('input_image.supported') ? $t('input_image.supported') : 'Supported formats are .png, .jpg, .jpeg.' }}
|
||||
{{
|
||||
$te('input_image.supported')
|
||||
? $t('input_image.supported')
|
||||
: 'Supported formats are .png, .jpg, .jpeg.'
|
||||
}}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {XIcon, ImageIcon} from 'vue-feather-icons'
|
||||
import { XIcon, ImageIcon } from 'vue-feather-icons'
|
||||
|
||||
export default {
|
||||
name: 'ImageInput',
|
||||
props: ['image', 'error'],
|
||||
components: {
|
||||
ImageIcon,
|
||||
XIcon,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imagePreview: undefined,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isData() {
|
||||
return !(typeof this.imagePreview === 'undefined' || this.imagePreview === '')
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
resetImage() {
|
||||
this.imagePreview = undefined
|
||||
this.$emit('input', undefined)
|
||||
},
|
||||
showImagePreview(event) {
|
||||
const imgPath = event.target.files[0].name,
|
||||
extn = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase()
|
||||
name: 'ImageInput',
|
||||
props: ['image', 'error'],
|
||||
components: {
|
||||
ImageIcon,
|
||||
XIcon,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imagePreview: undefined,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isData() {
|
||||
return !(typeof this.imagePreview === 'undefined' || this.imagePreview === '')
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
resetImage() {
|
||||
this.imagePreview = undefined
|
||||
this.$emit('input', undefined)
|
||||
},
|
||||
showImagePreview(event) {
|
||||
const imgPath = event.target.files[0].name,
|
||||
extn = imgPath.substring(imgPath.lastIndexOf('.') + 1).toLowerCase()
|
||||
|
||||
if (['png', 'jpg', 'jpeg', 'svg'].includes(extn)) {
|
||||
const file = event.target.files[0],
|
||||
reader = new FileReader()
|
||||
if (['png', 'jpg', 'jpeg', 'svg'].includes(extn)) {
|
||||
const file = event.target.files[0],
|
||||
reader = new FileReader()
|
||||
|
||||
reader.onload = () => (this.imagePreview = reader.result)
|
||||
reader.onload = () => (this.imagePreview = reader.result)
|
||||
|
||||
reader.readAsDataURL(file)
|
||||
reader.readAsDataURL(file)
|
||||
|
||||
// Update user avatar
|
||||
this.$emit('input', event.target.files[0])
|
||||
} else {
|
||||
alert(this.$t('validation_errors.wrong_image'))
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// If has default image then load
|
||||
if (this.image) this.imagePreview = this.image
|
||||
},
|
||||
// Update user avatar
|
||||
this.$emit('input', event.target.files[0])
|
||||
} else {
|
||||
alert(this.$t('validation_errors.wrong_image'))
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
// If has default image then load
|
||||
if (this.image) this.imagePreview = this.image
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
<script>
|
||||
export default {
|
||||
name: 'InfoBox',
|
||||
props: [
|
||||
'type'
|
||||
],
|
||||
props: ['type'],
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<!--<label class="input-label">{{ label }}:</label>-->
|
||||
<div class="input-wrapper focus-within-border-theme" :class="{ 'is-error': isError }" @click="$refs.input.focus()">
|
||||
<div
|
||||
class="input-wrapper focus-within-border-theme"
|
||||
:class="{ 'is-error': isError }"
|
||||
@click="$refs.input.focus()"
|
||||
>
|
||||
<div class="email-list">
|
||||
<div class="email-tag bg-theme-100" :class="{ 'mb-offset': getCharactersLength > 45 }" v-for="(email, i) in emails" :key="i">
|
||||
<div
|
||||
class="email-tag bg-theme-100"
|
||||
:class="{ 'mb-offset': getCharactersLength > 45 }"
|
||||
v-for="(email, i) in emails"
|
||||
:key="i"
|
||||
>
|
||||
<span class="text-theme">{{ email }}</span>
|
||||
<x-icon @click="removeEmail(email)" class="icon" size="14" />
|
||||
</div>
|
||||
|
||||
@@ -6,7 +6,14 @@
|
||||
<div @click="clearInput" v-if="query" class="icon">
|
||||
<x-icon class="pointer" size="19"></x-icon>
|
||||
</div>
|
||||
<input v-model="query" @input="$emit('input', query)" class="query focus-border-theme" type="text" name="searchInput" :placeholder="$t('search_translations')" />
|
||||
<input
|
||||
v-model="query"
|
||||
@input="$emit('input', query)"
|
||||
class="query focus-border-theme"
|
||||
type="text"
|
||||
name="searchInput"
|
||||
:placeholder="$t('search_translations')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<template>
|
||||
<div class="select-box">
|
||||
<div class="box-item active-bg-theme-100 active-border-theme" :class="{ active: item.value === input }" @click="getSelectedValue(item)" v-for="(item, i) in data" :key="i">
|
||||
<div
|
||||
class="box-item active-bg-theme-100 active-border-theme"
|
||||
:class="{ active: item.value === input }"
|
||||
@click="getSelectedValue(item)"
|
||||
v-for="(item, i) in data"
|
||||
:key="i"
|
||||
>
|
||||
<span class="box-value active-text-theme">{{ item.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<template>
|
||||
<div class="select">
|
||||
<!--Area-->
|
||||
<div class="input-area rounded-lg dark:bg-2x-dark-foreground bg-light-background" :class="{ 'is-active': isOpen, 'is-error': isError }" @click="openMenu">
|
||||
<div
|
||||
class="input-area rounded-lg bg-light-background dark:bg-2x-dark-foreground"
|
||||
:class="{ 'is-active': isOpen, 'is-error': isError }"
|
||||
@click="openMenu"
|
||||
>
|
||||
<!--If is selected-->
|
||||
<div class="selected flex w-full items-center" v-if="selected">
|
||||
<div class="option-icon" v-if="selected.icon">
|
||||
@@ -25,7 +29,13 @@
|
||||
<transition name="slide-in">
|
||||
<div class="input-options rounded-lg" v-if="isOpen">
|
||||
<div v-if="options.length > 5" class="select-search">
|
||||
<input v-model="query" ref="search" type="text" :placeholder="$t('select_search_placeholder')" class="search-input focus-border-theme rounded-lg" />
|
||||
<input
|
||||
v-model="query"
|
||||
ref="search"
|
||||
type="text"
|
||||
:placeholder="$t('select_search_placeholder')"
|
||||
class="search-input focus-border-theme rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
<ul class="option-list">
|
||||
<li class="option-item" @click="selectOption(option)" v-for="(option, i) in optionList" :key="i">
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
<UserHeadline v-if="!clickedSubmenu" class="p-5 pb-3" />
|
||||
|
||||
<!--User estimate-->
|
||||
<div v-if="config.subscriptionType === 'metered' && user && user.data.meta.usages && !clickedSubmenu" class="block px-5 pt-2">
|
||||
<div
|
||||
v-if="config.subscriptionType === 'metered' && user && user.data.meta.usages && !clickedSubmenu"
|
||||
class="block px-5 pt-2"
|
||||
>
|
||||
<div class="rounded-lg bg-light-background px-3 py-1.5 dark:bg-4x-dark-foreground">
|
||||
<span class="text-sm font-semibold">
|
||||
{{ $t('Your current estimated usage:') }}
|
||||
@@ -27,9 +30,27 @@
|
||||
<MenuMobileGroup>
|
||||
<!--Main navigation-->
|
||||
<OptionGroup v-if="!clickedSubmenu">
|
||||
<Option @click.native="goToFiles" :title="$t('menu.files')" icon="hard-drive" :is-hover-disabled="true" />
|
||||
<Option @click.native.stop="showSubmenu('settings')" :title="$t('menu.settings')" icon="user" arrow="right" :is-hover-disabled="true" />
|
||||
<Option v-if="isAdmin" @click.native.stop="showSubmenu('admin')" :title="$t('menu.admin')" icon="settings" arrow="right" :is-hover-disabled="true" />
|
||||
<Option
|
||||
@click.native="goToFiles"
|
||||
:title="$t('menu.files')"
|
||||
icon="hard-drive"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native.stop="showSubmenu('settings')"
|
||||
:title="$t('menu.settings')"
|
||||
icon="user"
|
||||
arrow="right"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
v-if="isAdmin"
|
||||
@click.native.stop="showSubmenu('admin')"
|
||||
:title="$t('menu.admin')"
|
||||
icon="settings"
|
||||
arrow="right"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
</OptionGroup>
|
||||
<OptionGroup v-if="!clickedSubmenu">
|
||||
<Option @click.native="logOut" :title="$t('menu.logout')" icon="power" :is-hover-disabled="true" />
|
||||
@@ -37,28 +58,79 @@
|
||||
|
||||
<!--Submenu: User settings-->
|
||||
<OptionGroup v-if="clickedSubmenu === 'settings'">
|
||||
<Option @click.native="goToRoute('Profile')" :title="$t('menu.profile')" icon="user" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToRoute('Password')" :title="$t('menu.password')" icon="lock" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToRoute('Storage')" :title="$t('menu.storage')" icon="hard-drive" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToRoute('Billing')" v-if="config.subscriptionType !== 'none'" :title="$t('Billing')" icon="cloud" :is-hover-disabled="true" />
|
||||
<Option
|
||||
@click.native="goToRoute('Profile')"
|
||||
:title="$t('menu.profile')"
|
||||
icon="user"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToRoute('Password')"
|
||||
:title="$t('menu.password')"
|
||||
icon="lock"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToRoute('Storage')"
|
||||
:title="$t('menu.storage')"
|
||||
icon="hard-drive"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToRoute('Billing')"
|
||||
v-if="config.subscriptionType !== 'none'"
|
||||
:title="$t('Billing')"
|
||||
icon="cloud"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
</OptionGroup>
|
||||
|
||||
<!--Submenu: Admin settings-->
|
||||
<OptionGroup v-if="clickedSubmenu === 'admin'">
|
||||
<Option @click.native="goToRoute('Dashboard')" :title="$t('admin_menu.dashboard')" icon="box" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToRoute('Users')" :title="$t('admin_menu.users')" icon="users" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToRoute('AppOthers')" :title="$t('admin_menu.settings')" icon="settings" :is-hover-disabled="true" />
|
||||
<Option
|
||||
@click.native="goToRoute('Dashboard')"
|
||||
:title="$t('admin_menu.dashboard')"
|
||||
icon="box"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToRoute('Users')"
|
||||
:title="$t('admin_menu.users')"
|
||||
icon="users"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToRoute('AppOthers')"
|
||||
:title="$t('admin_menu.settings')"
|
||||
icon="settings"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
</OptionGroup>
|
||||
|
||||
<!--Submenu: Content settings-->
|
||||
<OptionGroup v-if="clickedSubmenu === 'admin'">
|
||||
<Option @click.native="goToRoute('Pages')" :title="$t('admin_menu.pages')" icon="monitor" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToRoute('Language')" :title="$t('languages')" icon="globe" :is-hover-disabled="true" />
|
||||
<Option
|
||||
@click.native="goToRoute('Pages')"
|
||||
:title="$t('admin_menu.pages')"
|
||||
icon="monitor"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToRoute('Language')"
|
||||
:title="$t('languages')"
|
||||
icon="globe"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
</OptionGroup>
|
||||
|
||||
<!--Submenu: Billing settings-->
|
||||
<OptionGroup v-if="clickedSubmenu === 'admin' && config.subscriptionType !== 'none'">
|
||||
<Option @click.native="goToRoute('AppPayments')" :title="$t('Payments')" icon="credit-card" :is-hover-disabled="true" />
|
||||
<Option
|
||||
@click.native="goToRoute('AppPayments')"
|
||||
:title="$t('Payments')"
|
||||
icon="credit-card"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToRoute('Subscriptions')"
|
||||
v-if="config.subscriptionType === 'fixed'"
|
||||
@@ -66,8 +138,18 @@
|
||||
icon="credit-card"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option @click.native="goToRoute('Plans')" :title="$t('admin_menu.plans')" icon="database" :is-hover-disabled="true" />
|
||||
<Option @click.native="goToRoute('Invoices')" :title="$t('Transactions')" icon="file-text" :is-hover-disabled="true" />
|
||||
<Option
|
||||
@click.native="goToRoute('Plans')"
|
||||
:title="$t('admin_menu.plans')"
|
||||
icon="database"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
<Option
|
||||
@click.native="goToRoute('Invoices')"
|
||||
:title="$t('Transactions')"
|
||||
icon="file-text"
|
||||
:is-hover-disabled="true"
|
||||
/>
|
||||
</OptionGroup>
|
||||
</MenuMobileGroup>
|
||||
</MenuMobile>
|
||||
|
||||
@@ -20,14 +20,25 @@
|
||||
v-if="clipboard.length > 1 && !isSelectedItem"
|
||||
/>
|
||||
|
||||
<TreeMenu class="-mx-4" :disabled-by-id="pickedItem" :depth="1" :nodes="items" v-for="items in navigation" :key="items.id" />
|
||||
<TreeMenu
|
||||
class="-mx-4"
|
||||
:disabled-by-id="pickedItem"
|
||||
:depth="1"
|
||||
:nodes="items"
|
||||
v-for="items in navigation"
|
||||
:key="items.id"
|
||||
/>
|
||||
</div>
|
||||
</PopupContent>
|
||||
|
||||
<!--Actions-->
|
||||
<PopupActions>
|
||||
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary">{{ $t('popup_move_item.cancel') }} </ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="moveItem" :button-style="selectedFolder ? 'theme' : 'secondary'">{{ $t('popup_move_item.submit') }} </ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary"
|
||||
>{{ $t('popup_move_item.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="moveItem" :button-style="selectedFolder ? 'theme' : 'secondary'"
|
||||
>{{ $t('popup_move_item.submit') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
</PopupWrapper>
|
||||
</template>
|
||||
@@ -76,7 +87,11 @@ export default {
|
||||
if (!this.selectedFolder) return
|
||||
|
||||
// Prevent to move items to the same parent
|
||||
if (isArray(this.selectedFolder) && this.clipboard.find((item) => item.parent_id === this.selectedFolder.id)) return
|
||||
if (
|
||||
isArray(this.selectedFolder) &&
|
||||
this.clipboard.find((item) => item.parent_id === this.selectedFolder.id)
|
||||
)
|
||||
return
|
||||
|
||||
// Move item
|
||||
if (!this.isSelectedItem) {
|
||||
|
||||
@@ -18,9 +18,16 @@
|
||||
<footer class="plan-footer">
|
||||
<b class="price text-theme">
|
||||
{{ plan.data.attributes.price }}/{{ $t('global.monthly_ac') }}
|
||||
<small v-if="plan.data.attributes.tax_rates.length > 0" class="vat-disclaimer">{{ $t('page_pricing_tables.vat_excluded') }}</small>
|
||||
<small v-if="plan.data.attributes.tax_rates.length > 0" class="vat-disclaimer">{{
|
||||
$t('page_pricing_tables.vat_excluded')
|
||||
}}</small>
|
||||
</b>
|
||||
<ButtonBase @click.native="selectPlan(plan)" type="submit" button-style="secondary" class="sign-in-button">
|
||||
<ButtonBase
|
||||
@click.native="selectPlan(plan)"
|
||||
type="submit"
|
||||
button-style="secondary"
|
||||
class="sign-in-button"
|
||||
>
|
||||
{{ $t('global.get_it') }}
|
||||
</ButtonBase>
|
||||
</footer>
|
||||
|
||||
@@ -14,8 +14,12 @@
|
||||
</div>
|
||||
|
||||
<PopupActions>
|
||||
<ButtonBase @click.native="closePopup" button-style="secondary" class="w-full">{{ $t('global.cancel') }} </ButtonBase>
|
||||
<ButtonBase @click.native="confirm" :button-style="buttonColor" class="w-full">{{ $t('global.confirm_action') }} </ButtonBase>
|
||||
<ButtonBase @click.native="closePopup" button-style="secondary" class="w-full"
|
||||
>{{ $t('global.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase @click.native="confirm" :button-style="buttonColor" class="w-full"
|
||||
>{{ $t('global.confirm_action') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
</PopupWrapper>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div :class="type" class="absolute top-16 bottom-24 left-0 right-0 h-auto overflow-x-auto overflow-y-auto px-6 md:relative md:top-0 md:bottom-0">
|
||||
<div
|
||||
:class="type"
|
||||
class="absolute top-16 bottom-24 left-0 right-0 h-auto overflow-x-auto overflow-y-auto px-6 md:relative md:top-0 md:bottom-0"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -22,7 +22,17 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { CreditCardIcon, KeyIcon, UserPlusIcon, CornerDownRightIcon, LinkIcon, XIcon, Edit2Icon, ShareIcon, UsersIcon } from 'vue-feather-icons'
|
||||
import {
|
||||
CreditCardIcon,
|
||||
KeyIcon,
|
||||
UserPlusIcon,
|
||||
CornerDownRightIcon,
|
||||
LinkIcon,
|
||||
XIcon,
|
||||
Edit2Icon,
|
||||
ShareIcon,
|
||||
UsersIcon,
|
||||
} from 'vue-feather-icons'
|
||||
import { events } from '../../../bus'
|
||||
|
||||
export default {
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<template>
|
||||
<transition name="popup">
|
||||
<div v-if="isVisibleWrapper" @click.self="closePopup" class="popup z-50 fixed top-0 left-0 right-0 bottom-0 grid h-full overflow-y-auto p-10 lg:absolute">
|
||||
<div class="fixed md:relative top-0 bottom-0 left-0 right-0 w-full dark:bg-2x-dark-foreground bg-white m-auto z-10 md:w-[490px] md:rounded-xl shadow-xl">
|
||||
<div
|
||||
v-if="isVisibleWrapper"
|
||||
@click.self="closePopup"
|
||||
class="popup fixed top-0 left-0 right-0 bottom-0 z-50 grid h-full overflow-y-auto p-10 lg:absolute"
|
||||
>
|
||||
<div
|
||||
class="fixed top-0 bottom-0 left-0 right-0 z-10 m-auto w-full bg-white shadow-xl dark:bg-2x-dark-foreground md:relative md:w-[490px] md:rounded-xl"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
@@ -44,41 +50,40 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.popup-leave-active {
|
||||
animation: popup-slide-in 0.15s ease reverse;
|
||||
}
|
||||
|
||||
.popup-leave-active {
|
||||
animation: popup-slide-in 0.15s ease reverse;
|
||||
}
|
||||
@media only screen and (min-width: 960px) {
|
||||
.popup-enter-active {
|
||||
animation: popup-slide-in 0.25s 0.1s ease both;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 960px) {
|
||||
.popup-enter-active {
|
||||
animation: popup-slide-in 0.25s 0.10s ease both;
|
||||
}
|
||||
@keyframes popup-slide-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(100px);
|
||||
}
|
||||
|
||||
@keyframes popup-slide-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(100px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@media only screen and (max-width: 960px) {
|
||||
.popup-enter-active {
|
||||
animation: popup-slide-in 0.35s 0.15s ease both;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 960px) {
|
||||
.popup-enter-active {
|
||||
animation: popup-slide-in 0.35s 0.15s ease both;
|
||||
}
|
||||
|
||||
@keyframes popup-slide-in {
|
||||
0% {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@keyframes popup-slide-in {
|
||||
0% {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -12,7 +12,11 @@
|
||||
<ValidationObserver @submit.prevent="changeName" ref="renameForm" v-slot="{ invalid }" tag="form">
|
||||
<!--Update item name-->
|
||||
<ValidationProvider tag="div" mode="passive" name="Name" rules="required" v-slot="{ errors }">
|
||||
<AppInputText :title="$t('popup_rename.label')" :error="errors[0]" :is-last="pickedItem.data.type !== 'folder'">
|
||||
<AppInputText
|
||||
:title="$t('popup_rename.label')"
|
||||
:error="errors[0]"
|
||||
:is-last="pickedItem.data.type !== 'folder'"
|
||||
>
|
||||
<div class="relative flex items-center">
|
||||
<input
|
||||
v-model="pickedItem.data.attributes.name"
|
||||
@@ -30,12 +34,21 @@
|
||||
</ValidationProvider>
|
||||
|
||||
<!--Emoji-->
|
||||
<AppInputSwitch v-if="pickedItem.data.type === 'folder'" :title="$t('Emoji as an Icon')" :description="$t('Replace folder icon with an Emoji')" :is-last="!isEmoji">
|
||||
<AppInputSwitch
|
||||
v-if="pickedItem.data.type === 'folder'"
|
||||
:title="$t('Emoji as an Icon')"
|
||||
:description="$t('Replace folder icon with an Emoji')"
|
||||
:is-last="!isEmoji"
|
||||
>
|
||||
<SwitchInput v-model="isEmoji" :state="isEmoji" />
|
||||
</AppInputSwitch>
|
||||
|
||||
<!--Set emoji-->
|
||||
<EmojiPicker v-if="pickedItem.data.type === 'folder' && isEmoji" v-model="emoji" :default-emoji="emoji" />
|
||||
<EmojiPicker
|
||||
v-if="pickedItem.data.type === 'folder' && isEmoji"
|
||||
v-model="emoji"
|
||||
:default-emoji="emoji"
|
||||
/>
|
||||
</ValidationObserver>
|
||||
</PopupContent>
|
||||
|
||||
@@ -87,7 +100,9 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
itemTypeTitle() {
|
||||
return this.pickedItem && this.pickedItem.data.type === 'folder' ? this.$t('types.folder') : this.$t('types.file')
|
||||
return this.pickedItem && this.pickedItem.data.type === 'folder'
|
||||
? this.$t('types.folder')
|
||||
: this.$t('types.file')
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
@@ -10,11 +10,19 @@
|
||||
'mb-2 rounded-xl bg-light-background px-4 dark:bg-2x-dark-foreground': paypal.isMethodsLoaded,
|
||||
}"
|
||||
>
|
||||
<PaymentMethod @click.native="pickedPaymentMethod('paypal')" driver="paypal" :description="config.paypal_payment_description">
|
||||
<PaymentMethod
|
||||
@click.native="pickedPaymentMethod('paypal')"
|
||||
driver="paypal"
|
||||
:description="config.paypal_payment_description"
|
||||
>
|
||||
<div v-if="paypal.isMethodLoading" class="translate-y-3 scale-50 transform">
|
||||
<Spinner />
|
||||
</div>
|
||||
<span v-if="!paypal.isMethodsLoaded" :class="{ 'opacity-0': paypal.isMethodLoading }" class="text-theme cursor-pointer text-sm font-bold">
|
||||
<span
|
||||
v-if="!paypal.isMethodsLoaded"
|
||||
:class="{ 'opacity-0': paypal.isMethodLoading }"
|
||||
class="text-theme cursor-pointer text-sm font-bold"
|
||||
>
|
||||
{{ $t('Select') }}
|
||||
</span>
|
||||
</PaymentMethod>
|
||||
@@ -24,7 +32,11 @@
|
||||
</div>
|
||||
|
||||
<!--Paystack implementation-->
|
||||
<PaymentMethod v-if="config.isPaystack" driver="paystack" :description="config.paystack_payment_description">
|
||||
<PaymentMethod
|
||||
v-if="config.isPaystack"
|
||||
driver="paystack"
|
||||
:description="config.paystack_payment_description"
|
||||
>
|
||||
<paystack
|
||||
@click.native="pickedPaymentMethod('paystack')"
|
||||
v-if="user && config"
|
||||
|
||||
@@ -9,9 +9,22 @@
|
||||
<ThumbnailItem class="mb-5" :item="pickedItem" />
|
||||
|
||||
<!--Form to set sharing-->
|
||||
<ValidationObserver v-if="!isGeneratedShared" @submit.prevent ref="shareForm" v-slot="{ invalid }" tag="form">
|
||||
<ValidationObserver
|
||||
v-if="!isGeneratedShared"
|
||||
@submit.prevent
|
||||
ref="shareForm"
|
||||
v-slot="{ invalid }"
|
||||
tag="form"
|
||||
>
|
||||
<!--Permission Select-->
|
||||
<ValidationProvider v-if="isFolder" tag="div" mode="passive" name="Permission" rules="required" v-slot="{ errors }">
|
||||
<ValidationProvider
|
||||
v-if="isFolder"
|
||||
tag="div"
|
||||
mode="passive"
|
||||
name="Permission"
|
||||
rules="required"
|
||||
v-slot="{ errors }"
|
||||
>
|
||||
<AppInputText :title="$t('shared_form.label_permission')" :error="errors[0]">
|
||||
<SelectInput
|
||||
v-model="shareOptions.permission"
|
||||
@@ -24,12 +37,26 @@
|
||||
|
||||
<!--Password Switch-->
|
||||
<div>
|
||||
<AppInputSwitch :title="$t('shared_form.label_password_protection')" :description="$t('popup.share.password_description')">
|
||||
<SwitchInput v-model="shareOptions.isPassword" class="switch" :state="shareOptions.isPassword" />
|
||||
<AppInputSwitch
|
||||
:title="$t('shared_form.label_password_protection')"
|
||||
:description="$t('popup.share.password_description')"
|
||||
>
|
||||
<SwitchInput
|
||||
v-model="shareOptions.isPassword"
|
||||
class="switch"
|
||||
:state="shareOptions.isPassword"
|
||||
/>
|
||||
</AppInputSwitch>
|
||||
|
||||
<!--Set password-->
|
||||
<ValidationProvider v-if="shareOptions.isPassword" tag="div" mode="passive" name="Password" rules="required" v-slot="{ errors }">
|
||||
<ValidationProvider
|
||||
v-if="shareOptions.isPassword"
|
||||
tag="div"
|
||||
mode="passive"
|
||||
name="Password"
|
||||
rules="required"
|
||||
v-slot="{ errors }"
|
||||
>
|
||||
<AppInputText :error="errors[0]" class="-mt-2">
|
||||
<input
|
||||
v-model="shareOptions.password"
|
||||
@@ -50,19 +77,40 @@
|
||||
|
||||
<!--Set expiration-->
|
||||
<AppInputText v-if="isExpiration" class="-mt-2">
|
||||
<SelectBoxInput v-model="shareOptions.expiration" :data="$translateSelectOptions(expirationList)" class="box" />
|
||||
<SelectBoxInput
|
||||
v-model="shareOptions.expiration"
|
||||
:data="$translateSelectOptions(expirationList)"
|
||||
class="box"
|
||||
/>
|
||||
</AppInputText>
|
||||
</div>
|
||||
|
||||
<!--Send on emails switch-->
|
||||
<div>
|
||||
<AppInputSwitch :title="$t('popup.share.email_send')" :description="$t('popup.share.email_description')" :is-last="!isEmailSharing">
|
||||
<AppInputSwitch
|
||||
:title="$t('popup.share.email_send')"
|
||||
:description="$t('popup.share.email_description')"
|
||||
:is-last="!isEmailSharing"
|
||||
>
|
||||
<SwitchInput v-model="isEmailSharing" class="switch" :state="isEmailSharing" />
|
||||
</AppInputSwitch>
|
||||
|
||||
<!--Set expiration-->
|
||||
<ValidationProvider v-if="isEmailSharing" tag="div" mode="passive" name="Email" rules="required" v-slot="{ errors }" class="-mt-2">
|
||||
<MultiEmailInput rules="required" v-model="shareOptions.emails" :label="$t('shared_form.recipients_label')" :isError="errors[0]" />
|
||||
<ValidationProvider
|
||||
v-if="isEmailSharing"
|
||||
tag="div"
|
||||
mode="passive"
|
||||
name="Email"
|
||||
rules="required"
|
||||
v-slot="{ errors }"
|
||||
class="-mt-2"
|
||||
>
|
||||
<MultiEmailInput
|
||||
rules="required"
|
||||
v-model="shareOptions.emails"
|
||||
:label="$t('shared_form.recipients_label')"
|
||||
:isError="errors[0]"
|
||||
/>
|
||||
</ValidationProvider>
|
||||
</div>
|
||||
</ValidationObserver>
|
||||
@@ -78,7 +126,13 @@
|
||||
<ButtonBase v-if="!isGeneratedShared" class="w-full" @click.native="$closePopup()" button-style="secondary">
|
||||
{{ $t('popup_move_item.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="submitShareOptions" button-style="theme" :loading="isLoading" :disabled="isLoading">
|
||||
<ButtonBase
|
||||
class="w-full"
|
||||
@click.native="submitShareOptions"
|
||||
button-style="theme"
|
||||
:loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
{{ submitButtonText }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
@@ -135,7 +189,9 @@ export default {
|
||||
computed: {
|
||||
...mapGetters(['permissionOptions', 'expirationList']),
|
||||
itemTypeTitle() {
|
||||
return this.pickedItem && this.pickedItem.data.type === 'folder' ? this.$t('types.folder') : this.$t('types.file')
|
||||
return this.pickedItem && this.pickedItem.data.type === 'folder'
|
||||
? this.$t('types.folder')
|
||||
: this.$t('types.file')
|
||||
},
|
||||
isFolder() {
|
||||
return this.pickedItem && this.pickedItem.data.type === 'folder'
|
||||
|
||||
@@ -31,7 +31,11 @@
|
||||
<ValidationObserver @submit.prevent v-slot="{ invalid }" ref="shareEmail" tag="form">
|
||||
<ValidationProvider tag="div" mode="passive" name="Email" rules="required" v-slot="{ errors }">
|
||||
<AppInputText title="Share with" :error="errors[0]" :is-last="true">
|
||||
<MultiEmailInput rules="required" v-model="emails" :label="$t('shared_form.label_send_to_recipients')" />
|
||||
<MultiEmailInput
|
||||
rules="required"
|
||||
v-model="emails"
|
||||
:label="$t('shared_form.label_send_to_recipients')"
|
||||
/>
|
||||
</AppInputText>
|
||||
</ValidationProvider>
|
||||
</ValidationObserver>
|
||||
@@ -41,7 +45,13 @@
|
||||
<ButtonBase class="w-full" @click.native="showSection(undefined)" button-style="secondary">
|
||||
{{ $t('Show Details') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="sendViaEmail" button-style="theme" :loading="isLoading" :disabled="isLoading">
|
||||
<ButtonBase
|
||||
class="w-full"
|
||||
@click.native="sendViaEmail"
|
||||
button-style="theme"
|
||||
:loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
{{ $t('Send') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
@@ -60,7 +70,14 @@
|
||||
|
||||
<ValidationObserver @submit.prevent ref="shareForm" v-slot="{ invalid }" tag="form">
|
||||
<!--Permission Select-->
|
||||
<ValidationProvider v-if="isFolder" tag="div" mode="passive" name="Permission" rules="required" v-slot="{ errors }">
|
||||
<ValidationProvider
|
||||
v-if="isFolder"
|
||||
tag="div"
|
||||
mode="passive"
|
||||
name="Permission"
|
||||
rules="required"
|
||||
v-slot="{ errors }"
|
||||
>
|
||||
<AppInputText :title="$t('shared_form.label_permission')" :error="errors[0]">
|
||||
<SelectInput
|
||||
v-model="shareOptions.permission"
|
||||
@@ -74,12 +91,23 @@
|
||||
|
||||
<!--Password Switch-->
|
||||
<div>
|
||||
<AppInputSwitch :title="$t('shared_form.label_password_protection')" :description="$t('popup.share.password_description')">
|
||||
<SwitchInput v-model="shareOptions.isProtected" class="switch" :state="shareOptions.isProtected" />
|
||||
<AppInputSwitch
|
||||
:title="$t('shared_form.label_password_protection')"
|
||||
:description="$t('popup.share.password_description')"
|
||||
>
|
||||
<SwitchInput
|
||||
v-model="shareOptions.isProtected"
|
||||
class="switch"
|
||||
:state="shareOptions.isProtected"
|
||||
/>
|
||||
</AppInputSwitch>
|
||||
|
||||
<ActionButton
|
||||
v-if="pickedItem.data.relationships.shared.data.attributes.protected && canChangePassword && shareOptions.isProtected"
|
||||
v-if="
|
||||
pickedItem.data.relationships.shared.data.attributes.protected &&
|
||||
canChangePassword &&
|
||||
shareOptions.isProtected
|
||||
"
|
||||
@click.native="changePassword"
|
||||
class="mb-6 -mt-4"
|
||||
>
|
||||
@@ -87,7 +115,14 @@
|
||||
</ActionButton>
|
||||
|
||||
<!--Set password-->
|
||||
<ValidationProvider v-if="shareOptions.isProtected && !canChangePassword" tag="div" mode="passive" name="Password" rules="required" v-slot="{ errors }">
|
||||
<ValidationProvider
|
||||
v-if="shareOptions.isProtected && !canChangePassword"
|
||||
tag="div"
|
||||
mode="passive"
|
||||
name="Password"
|
||||
rules="required"
|
||||
v-slot="{ errors }"
|
||||
>
|
||||
<AppInputText :error="errors[0]" class="-mt-2">
|
||||
<input
|
||||
v-model="shareOptions.password"
|
||||
@@ -102,23 +137,48 @@
|
||||
|
||||
<!--Expiration switch-->
|
||||
<div>
|
||||
<AppInputSwitch :title="$t('expiration')" :description="$t('popup.share.expiration_description')" :is-last="!shareOptions.expiration">
|
||||
<SwitchInput v-model="shareOptions.expiration" class="switch" :state="shareOptions.expiration ? 1 : 0" />
|
||||
<AppInputSwitch
|
||||
:title="$t('expiration')"
|
||||
:description="$t('popup.share.expiration_description')"
|
||||
:is-last="!shareOptions.expiration"
|
||||
>
|
||||
<SwitchInput
|
||||
v-model="shareOptions.expiration"
|
||||
class="switch"
|
||||
:state="shareOptions.expiration ? 1 : 0"
|
||||
/>
|
||||
</AppInputSwitch>
|
||||
|
||||
<!--Set expiration-->
|
||||
<AppInputText v-if="shareOptions.expiration" class="-mt-2" :is-last="true">
|
||||
<SelectBoxInput v-model="shareOptions.expiration" :data="$translateSelectOptions(expirationList)" :value="shareOptions.expiration" class="box" />
|
||||
<SelectBoxInput
|
||||
v-model="shareOptions.expiration"
|
||||
:data="$translateSelectOptions(expirationList)"
|
||||
:value="shareOptions.expiration"
|
||||
class="box"
|
||||
/>
|
||||
</AppInputText>
|
||||
</div>
|
||||
</ValidationObserver>
|
||||
</PopupContent>
|
||||
|
||||
<PopupActions>
|
||||
<ButtonBase class="w-full" @click.native="destroySharing" :button-style="destroyButtonStyle" :loading="isDeleting" :disabled="isDeleting">
|
||||
<ButtonBase
|
||||
class="w-full"
|
||||
@click.native="destroySharing"
|
||||
:button-style="destroyButtonStyle"
|
||||
:loading="isDeleting"
|
||||
:disabled="isDeleting"
|
||||
>
|
||||
{{ destroyButtonText }}
|
||||
</ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="updateShareOptions" button-style="theme" :loading="isLoading" :disabled="isLoading">
|
||||
<ButtonBase
|
||||
class="w-full"
|
||||
@click.native="updateShareOptions"
|
||||
button-style="theme"
|
||||
:loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
>
|
||||
{{ $t('Store Changes') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="tab-wrapper">
|
||||
<div class="tab" :class="{ active: tab.isActive }" @click="selectTab(tab)" v-for="(tab, i) in tabs" :key="i">
|
||||
<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 text-theme dark-text-theme" size="17" />
|
||||
<link-icon v-if="tab.icon === 'link'" class="tab-icon text-theme dark-text-theme" size="17" />
|
||||
|
||||
@@ -55,7 +55,12 @@
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li v-for="(page, index) in data.meta.last_page" :key="index" class="inline-block p-1" @click="goToPage(page)">
|
||||
<li
|
||||
v-for="(page, index) in data.meta.last_page"
|
||||
:key="index"
|
||||
class="inline-block p-1"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
<a
|
||||
class="page-link"
|
||||
:class="{
|
||||
@@ -100,7 +105,13 @@
|
||||
<a class="page-link"> 1 </a>
|
||||
</li>
|
||||
|
||||
<li v-if="pageIndex < 5" v-for="(page, index) in 5" :key="index" class="inline-block p-1" @click="goToPage(page)">
|
||||
<li
|
||||
v-if="pageIndex < 5"
|
||||
v-for="(page, index) in 5"
|
||||
:key="index"
|
||||
class="inline-block p-1"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
<a
|
||||
class="page-link"
|
||||
:class="{
|
||||
@@ -116,7 +127,13 @@
|
||||
</li>
|
||||
|
||||
<!--Floated Pages-->
|
||||
<li v-if="pageIndex >= 5 && pageIndex < data.meta.last_page - 3" v-for="(page, index) in floatPages" :key="index" class="inline-block p-1" @click="goToPage(page)">
|
||||
<li
|
||||
v-if="pageIndex >= 5 && pageIndex < data.meta.last_page - 3"
|
||||
v-for="(page, index) in floatPages"
|
||||
:key="index"
|
||||
class="inline-block p-1"
|
||||
@click="goToPage(page)"
|
||||
>
|
||||
<a
|
||||
class="page-link"
|
||||
:class="{
|
||||
@@ -141,7 +158,8 @@
|
||||
<a
|
||||
class="page-link"
|
||||
:class="{
|
||||
'bg-light-background dark:bg-4x-dark-foreground dark:text-gray-300': pageIndex === data.meta.last_page - (4 - index),
|
||||
'bg-light-background dark:bg-4x-dark-foreground dark:text-gray-300':
|
||||
pageIndex === data.meta.last_page - (4 - index),
|
||||
}"
|
||||
>
|
||||
{{ data.meta.last_page - (4 - index) }}
|
||||
@@ -149,7 +167,11 @@
|
||||
</li>
|
||||
|
||||
<!--Show last page-->
|
||||
<li class="inline-block p-1" v-if="pageIndex < data.meta.last_page - 3" @click="goToPage(data.meta.last_page)">
|
||||
<li
|
||||
class="inline-block p-1"
|
||||
v-if="pageIndex < data.meta.last_page - 3"
|
||||
@click="goToPage(data.meta.last_page)"
|
||||
>
|
||||
<a class="page-link">
|
||||
{{ data.meta.last_page }}
|
||||
</a>
|
||||
@@ -169,7 +191,9 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<span class="text-xs text-gray-600 dark:text-gray-500"> Showing {{ data.meta.from }} - {{ data.meta.to }} from {{ data.meta.total }} records </span>
|
||||
<span class="text-xs text-gray-600 dark:text-gray-500">
|
||||
Showing {{ data.meta.from }} - {{ data.meta.to }} from {{ data.meta.total }} records
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -239,7 +263,14 @@ export default {
|
||||
if (this.paginator) this.URI = this.URI + '?page=' + page
|
||||
|
||||
// Add filder URI if is defined sorting
|
||||
if (this.filter.field) this.URI = this.URI + (this.paginator ? '&' : '?') + 'sort=' + this.filter.field + '&direction=' + this.filter.sort
|
||||
if (this.filter.field)
|
||||
this.URI =
|
||||
this.URI +
|
||||
(this.paginator ? '&' : '?') +
|
||||
'sort=' +
|
||||
this.filter.field +
|
||||
'&direction=' +
|
||||
this.filter.sort
|
||||
|
||||
this.isLoading = true
|
||||
|
||||
|
||||
@@ -3,16 +3,30 @@
|
||||
<!--Item thumbnail-->
|
||||
<div class="relative w-16">
|
||||
<!--Member thumbnail for team folders-->
|
||||
<MemberAvatar v-if="user && canShowAuthor" :size="28" :is-border="true" :member="item.data.relationships.owner" class="absolute right-1.5 -bottom-2 z-10" />
|
||||
<MemberAvatar
|
||||
v-if="user && canShowAuthor"
|
||||
:size="28"
|
||||
:is-border="true"
|
||||
:member="item.data.relationships.owner"
|
||||
class="absolute right-1.5 -bottom-2 z-10"
|
||||
/>
|
||||
|
||||
<!--Emoji Icon-->
|
||||
<Emoji v-if="item.data.attributes.emoji" :emoji="item.data.attributes.emoji" class="ml-1 scale-110 transform text-5xl" />
|
||||
<Emoji
|
||||
v-if="item.data.attributes.emoji"
|
||||
:emoji="item.data.attributes.emoji"
|
||||
class="ml-1 scale-110 transform text-5xl"
|
||||
/>
|
||||
|
||||
<!--Folder Icon-->
|
||||
<FolderIcon v-if="isFolder && !item.data.attributes.emoji" :item="item" />
|
||||
|
||||
<!--File Icon-->
|
||||
<FileIconThumbnail v-if="isFile || isVideo || isAudio || (isImage && !item.data.attributes.thumbnail)" :item="item" class="pr-2" />
|
||||
<FileIconThumbnail
|
||||
v-if="isFile || isVideo || isAudio || (isImage && !item.data.attributes.thumbnail)"
|
||||
:item="item"
|
||||
class="pr-2"
|
||||
/>
|
||||
|
||||
<!--Image thumbnail-->
|
||||
<img
|
||||
@@ -27,7 +41,10 @@
|
||||
<!--Item Info-->
|
||||
<div class="pl-2">
|
||||
<!--Item Title-->
|
||||
<b class="mb-0.5 block overflow-hidden text-ellipsis whitespace-nowrap text-sm hover:underline" style="max-width: 240px">
|
||||
<b
|
||||
class="mb-0.5 block overflow-hidden text-ellipsis whitespace-nowrap text-sm hover:underline"
|
||||
style="max-width: 240px"
|
||||
>
|
||||
{{ item.data.attributes.name }}
|
||||
</b>
|
||||
|
||||
@@ -39,11 +56,14 @@
|
||||
</div>
|
||||
|
||||
<!--File & Image sub line-->
|
||||
<small v-if="!isFolder" class="block text-xs text-gray-500"> {{ item.data.attributes.filesize }}, {{ timeStamp }} </small>
|
||||
<small v-if="!isFolder" class="block text-xs text-gray-500">
|
||||
{{ item.data.attributes.filesize }}, {{ timeStamp }}
|
||||
</small>
|
||||
|
||||
<!--Folder sub line-->
|
||||
<small v-if="isFolder" class="block text-xs text-gray-500">
|
||||
{{ folderItems === 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ timeStamp }}
|
||||
{{ folderItems === 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }},
|
||||
{{ timeStamp }}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
@@ -105,7 +125,9 @@ export default {
|
||||
)
|
||||
},
|
||||
folderItems() {
|
||||
return this.item.data.attributes.deleted_at ? this.item.data.attributes.trashed_items : this.item.data.attributes.items
|
||||
return this.item.data.attributes.deleted_at
|
||||
? this.item.data.attributes.trashed_items
|
||||
: this.item.data.attributes.items
|
||||
},
|
||||
canShowAuthor() {
|
||||
return !this.isFolder && this.user.data.id !== this.item.data.relationships.owner.data.id
|
||||
|
||||
@@ -24,10 +24,30 @@
|
||||
</span>
|
||||
|
||||
<!--Item icon-->
|
||||
<hard-drive-icon v-if="['public', 'files'].includes(nodes.location)" size="17" class="icon vue-feather" :class="{ 'text-theme dark-text-theme': isSelectedItem }" />
|
||||
<users-icon v-if="nodes.location === 'team-folders'" size="17" class="icon vue-feather" :class="{ 'text-theme dark-text-theme': isSelectedItem }" />
|
||||
<user-plus-icon v-if="nodes.location === 'shared-with-me'" size="17" class="icon vue-feather" :class="{ 'text-theme dark-text-theme': isSelectedItem }" />
|
||||
<folder-icon v-if="!nodes.location" size="17" class="icon vue-feather" :class="{ 'text-theme dark-text-theme': isSelectedItem }" />
|
||||
<hard-drive-icon
|
||||
v-if="['public', 'files'].includes(nodes.location)"
|
||||
size="17"
|
||||
class="icon vue-feather"
|
||||
:class="{ 'text-theme dark-text-theme': isSelectedItem }"
|
||||
/>
|
||||
<users-icon
|
||||
v-if="nodes.location === 'team-folders'"
|
||||
size="17"
|
||||
class="icon vue-feather"
|
||||
:class="{ 'text-theme dark-text-theme': isSelectedItem }"
|
||||
/>
|
||||
<user-plus-icon
|
||||
v-if="nodes.location === 'shared-with-me'"
|
||||
size="17"
|
||||
class="icon vue-feather"
|
||||
:class="{ 'text-theme dark-text-theme': isSelectedItem }"
|
||||
/>
|
||||
<folder-icon
|
||||
v-if="!nodes.location"
|
||||
size="17"
|
||||
class="icon vue-feather"
|
||||
:class="{ 'text-theme dark-text-theme': isSelectedItem }"
|
||||
/>
|
||||
|
||||
<!--Item label-->
|
||||
<b
|
||||
@@ -40,7 +60,14 @@
|
||||
</div>
|
||||
|
||||
<!--Children-->
|
||||
<tree-node :disabled-by-id="disabledById" :depth="depth + 1" v-if="isVisible" :nodes="item" v-for="item in nodes.folders" :key="item.id" />
|
||||
<tree-node
|
||||
:disabled-by-id="disabledById"
|
||||
:depth="depth + 1"
|
||||
v-if="isVisible"
|
||||
:nodes="item"
|
||||
v-for="item in nodes.folders"
|
||||
:key="item.id"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -23,11 +23,21 @@
|
||||
/>
|
||||
</div>
|
||||
<folder-icon size="17" class="vue-feather mr-2.5" :class="{ 'text-theme': isSelected }" />
|
||||
<b class="max-w-1 overflow-hidden text-ellipsis whitespace-nowrap text-xs font-bold" :class="{ 'text-theme': isSelected }">
|
||||
<b
|
||||
class="max-w-1 overflow-hidden text-ellipsis whitespace-nowrap text-xs font-bold"
|
||||
:class="{ 'text-theme': isSelected }"
|
||||
>
|
||||
{{ nodes.name }}
|
||||
</b>
|
||||
</div>
|
||||
<tree-node :disabled="disableChildren" :depth="depth + 1" v-if="isVisible" :nodes="item" v-for="item in nodes.folders" :key="item.id" />
|
||||
<tree-node
|
||||
:disabled="disableChildren"
|
||||
:depth="depth + 1"
|
||||
v-if="isVisible"
|
||||
:nodes="item"
|
||||
v-for="item in nodes.folders"
|
||||
:key="item.id"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<transition name="vignette">
|
||||
<div v-if="isVisible" class="vignette bg-dark-background bg-opacity-[0.35] dark:bg-opacity-[0.45]" @click="closePopup"></div>
|
||||
<div
|
||||
v-if="isVisible"
|
||||
class="vignette bg-dark-background bg-opacity-[0.35] dark:bg-opacity-[0.45]"
|
||||
@click="closePopup"
|
||||
></div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
<small class="text-xs font-bold text-gray-400 dark:text-gray-600">
|
||||
{{ title }}
|
||||
</small>
|
||||
<chevron-up-icon v-if="canCollapseWrapper" size="12" class="vue-feather mr-5 transform cursor-pointer text-gray-300" :class="{ 'rotate-180': !isVisible }" />
|
||||
<chevron-up-icon
|
||||
v-if="canCollapseWrapper"
|
||||
size="12"
|
||||
class="vue-feather mr-5 transform cursor-pointer text-gray-300"
|
||||
:class="{ 'rotate-180': !isVisible }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<slot v-if="isVisible" />
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<section class="content-sidebar z-10 hidden w-52 flex-none select-none overflow-y-auto bg-light-background pt-6 dark:bg-dark-background lg:block xl:w-56" id="content-sidebar">
|
||||
<section
|
||||
class="content-sidebar z-10 hidden w-52 flex-none select-none overflow-y-auto bg-light-background pt-6 dark:bg-dark-background lg:block xl:w-56"
|
||||
id="content-sidebar"
|
||||
>
|
||||
<slot></slot>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
<template>
|
||||
<nav v-if="isVisibleNavigationBars" class="menu-bar z-10 hidden w-16 flex-none select-none bg-light-background pt-7 dark:bg-dark-foreground lg:grid xl:w-20">
|
||||
<nav
|
||||
v-if="isVisibleNavigationBars"
|
||||
class="menu-bar z-10 hidden w-16 flex-none select-none bg-light-background pt-7 dark:bg-dark-foreground lg:grid xl:w-20"
|
||||
>
|
||||
<!--Navigation-->
|
||||
<div v-if="user" class="mb-auto text-center">
|
||||
<MemberAvatar class="mx-auto inline-block" :size="44" :is-border="false" :member="user" />
|
||||
|
||||
<!--Usage-->
|
||||
<div v-if="config.subscriptionType === 'metered' && user.data.meta.usages" class="mt-1 text-center leading-3">
|
||||
<div
|
||||
v-if="config.subscriptionType === 'metered' && user.data.meta.usages"
|
||||
class="mt-1 text-center leading-3"
|
||||
>
|
||||
<b class="text-theme block text-xs font-bold leading-3">
|
||||
{{ user.data.meta.usages.costEstimate }}
|
||||
</b>
|
||||
@@ -24,7 +30,9 @@
|
||||
:class="[{ 'router-link-active': isSection(item.section) }, item.icon]"
|
||||
class="mb-1.5 block"
|
||||
>
|
||||
<div class="button-icon text-theme inline-block cursor-pointer rounded-xl p-3 hover:bg-light-300 dark:hover:bg-4x-dark-foreground">
|
||||
<div
|
||||
class="button-icon text-theme inline-block cursor-pointer rounded-xl p-3 hover:bg-light-300 dark:hover:bg-4x-dark-foreground"
|
||||
>
|
||||
<hard-drive-icon v-if="item.icon === 'home'" size="20" />
|
||||
<settings-icon v-if="item.icon === 'settings'" size="20" />
|
||||
<user-icon v-if="item.icon === 'user'" size="20" />
|
||||
@@ -34,7 +42,9 @@
|
||||
|
||||
<!--Toggle Dark/Light mode-->
|
||||
<div @click="$store.dispatch('toggleThemeMode')" :title="$t('dark_mode_toggle')" class="mt-6 block">
|
||||
<div class="button-icon inline-block cursor-pointer rounded-xl p-3 hover:bg-light-300 dark:hover:bg-4x-dark-foreground">
|
||||
<div
|
||||
class="button-icon inline-block cursor-pointer rounded-xl p-3 hover:bg-light-300 dark:hover:bg-4x-dark-foreground"
|
||||
>
|
||||
<sun-icon v-if="isDarkMode" size="20" />
|
||||
<moon-icon v-if="!isDarkMode" size="20" />
|
||||
</div>
|
||||
@@ -57,7 +67,16 @@
|
||||
<script>
|
||||
import MemberAvatar from '../FilesView/MemberAvatar'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { MoonIcon, SunIcon, HardDriveIcon, SettingsIcon, Trash2Icon, UserIcon, PowerIcon, ShareIcon } from 'vue-feather-icons'
|
||||
import {
|
||||
MoonIcon,
|
||||
SunIcon,
|
||||
HardDriveIcon,
|
||||
SettingsIcon,
|
||||
Trash2Icon,
|
||||
UserIcon,
|
||||
PowerIcon,
|
||||
ShareIcon,
|
||||
} from 'vue-feather-icons'
|
||||
|
||||
export default {
|
||||
name: 'SidebarNavigation',
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<div class="flex cursor-pointer items-center py-2">
|
||||
<span class="dark-text-theme rounded-lg bg-light-background py-1 px-2 text-sm font-bold dark:bg-4x-dark-foreground"> {{ keyword }} + {{ $t('space') }} </span>
|
||||
<span
|
||||
class="dark-text-theme rounded-lg bg-light-background py-1 px-2 text-sm font-bold dark:bg-4x-dark-foreground"
|
||||
>
|
||||
{{ keyword }} + {{ $t('space') }}
|
||||
</span>
|
||||
<p class="ml-3 text-sm font-semibold text-gray-500">
|
||||
{{ description }}
|
||||
</p>
|
||||
|
||||
@@ -1,17 +1,33 @@
|
||||
<template>
|
||||
<div v-if="isVisible" @keyup.esc="exitSpotlight" @click.exact.self="exitSpotlight" tabindex="-1" class="fixed z-50 h-full w-full left-0 right-0 bottom-0 top-0 z-50 md:absolute dark:bg-dark-background bg-white md:bg-dark-background dark:md:bg-opacity-[0.45] md:bg-opacity-[0.35]">
|
||||
<div class="relative z-50 mx-auto w-full overflow-y-auto md:mt-8 md:max-w-xl md:rounded-xl 2xl:mt-20 md:bg-white dark:md:bg-2x-dark-foreground md:shadow-xl">
|
||||
<div
|
||||
v-if="isVisible"
|
||||
@keyup.esc="exitSpotlight"
|
||||
@click.exact.self="exitSpotlight"
|
||||
tabindex="-1"
|
||||
class="fixed left-0 right-0 bottom-0 top-0 z-50 z-50 h-full w-full bg-white dark:bg-dark-background md:absolute md:bg-dark-background md:bg-opacity-[0.35] dark:md:bg-opacity-[0.45]"
|
||||
>
|
||||
<div
|
||||
class="relative z-50 mx-auto w-full overflow-y-auto md:mt-8 md:max-w-xl md:rounded-xl md:bg-white md:shadow-xl dark:md:bg-2x-dark-foreground 2xl:mt-20"
|
||||
>
|
||||
<!--Query bar-->
|
||||
<div class="z-50 mx-auto flex items-center px-5 py-4">
|
||||
<div class="relative mr-4">
|
||||
<div v-if="isLoading" class="spinner-icon origin-center translate-y-2.5 scale-50 transform">
|
||||
<Spinner />
|
||||
</div>
|
||||
<search-icon :class="{ 'opacity-0': isLoading }" size="22" class="magnify dark-text-theme text-theme vue-feather" />
|
||||
<search-icon
|
||||
:class="{ 'opacity-0': isLoading }"
|
||||
size="22"
|
||||
class="magnify dark-text-theme text-theme vue-feather"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!--Filter-->
|
||||
<div v-if="activeFilter" @click="removeFilter" class="mr-3 flex cursor-pointer items-center rounded-lg bg-light-background px-2 py-1 dark:bg-4x-dark-foreground">
|
||||
<div
|
||||
v-if="activeFilter"
|
||||
@click="removeFilter"
|
||||
class="mr-3 flex cursor-pointer items-center rounded-lg bg-light-background px-2 py-1 dark:bg-4x-dark-foreground"
|
||||
>
|
||||
<b class="dark-text-theme -mt-0.5 pr-1.5 text-sm font-bold">
|
||||
{{ activeFilter }}
|
||||
</b>
|
||||
@@ -44,12 +60,21 @@
|
||||
</div>
|
||||
|
||||
<!--Show tips-->
|
||||
<div v-if="isEmptyQuery && !activeFilter && ! $isThisRoute($route, ['Public'])" class="relative z-50 px-4 pb-4">
|
||||
<div
|
||||
v-if="isEmptyQuery && !activeFilter && !$isThisRoute($route, ['Public'])"
|
||||
class="relative z-50 px-4 pb-4"
|
||||
>
|
||||
<CategoryName>
|
||||
{{ $t('Suggested Filters') }}
|
||||
</CategoryName>
|
||||
|
||||
<FilterSuggestion v-for="filter in filters" :key="filter.slug" :keyword="filter.keyword" :description="filter.description" @click.native="setFilter(filter.slug)" />
|
||||
<FilterSuggestion
|
||||
v-for="filter in filters"
|
||||
:key="filter.slug"
|
||||
:keyword="filter.keyword"
|
||||
:description="filter.description"
|
||||
@click.native="setFilter(filter.slug)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!--Results-->
|
||||
@@ -68,30 +93,126 @@
|
||||
'rounded-xl bg-light-background dark:bg-4x-dark-foreground': i === index,
|
||||
}"
|
||||
>
|
||||
<settings-icon v-if="['AppOthers', 'Profile', 'Password'].includes(result.action.value)" size="18" class="vue-feather text-theme" />
|
||||
<credit-card-icon v-if="result.action.value === 'AppPayments'" size="18" class="vue-feather text-theme" />
|
||||
<home-icon v-if="result.action.value === 'Files'" size="18" class="vue-feather text-theme" />
|
||||
<trash2-icon v-if="result.action.value === 'Trash'" size="18" class="vue-feather text-theme" />
|
||||
<database-icon v-if="['CreateFixedPlan', 'CreateMeteredPlan'].includes(result.action.value)" size="18" class="vue-feather text-theme" />
|
||||
<user-plus-icon v-if="result.action.value === 'UserCreate'" size="18" class="vue-feather text-theme" />
|
||||
<users-icon v-if="['TeamFolders', 'Users'].includes(result.action.value)" size="18" class="vue-feather text-theme" />
|
||||
<user-check-icon v-if="result.action.value === 'SharedWithMe'" size="18" class="vue-feather text-theme" />
|
||||
<link-icon v-if="result.action.value === 'MySharedItems'" size="18" class="vue-feather text-theme" />
|
||||
<upload-cloud-icon v-if="result.action.value === 'RecentUploads'" size="18" class="vue-feather text-theme" />
|
||||
<file-text-icon v-if="['Invoices', 'Invoice'].includes(result.action.value)" size="18" class="vue-feather text-theme" />
|
||||
<database-icon v-if="result.action.value === 'Plans'" size="18" class="vue-feather text-theme" />
|
||||
<dollar-sign-icon v-if="['Subscriptions', 'Billing'].includes(result.action.value)" size="18" class="vue-feather text-theme" />
|
||||
<globe-icon v-if="result.action.value === 'Language'" size="18" class="vue-feather text-theme" />
|
||||
<monitor-icon v-if="result.action.value === 'Pages'" size="18" class="vue-feather text-theme" />
|
||||
<box-icon v-if="result.action.value === 'Dashboard'" size="18" class="vue-feather text-theme" />
|
||||
<hard-drive-icon v-if="result.action.value === 'Storage'" size="18" class="vue-feather text-theme" />
|
||||
<moon-icon v-if="result.action.value === 'dark-mode'" size="18" class="vue-feather text-theme" />
|
||||
<maximize2-icon v-if="result.action.value === 'full-screen-mode'" size="18" class="vue-feather text-theme" />
|
||||
<power-icon v-if="result.action.value === 'log-out'" size="18" class="vue-feather text-theme" />
|
||||
<trash-icon v-if="result.action.value === 'empty-trash'" size="18" class="vue-feather text-theme" />
|
||||
<grid-icon v-if="result.action.value === 'toggle-grid-list'" size="18" class="vue-feather text-theme" />
|
||||
<smile-icon v-if="result.action.value === 'toggle-emoji'" size="18" class="vue-feather text-theme" />
|
||||
<folder-plus-icon v-if="result.action.value === 'create-team-folder'" size="18" class="vue-feather text-theme" />
|
||||
<settings-icon
|
||||
v-if="['AppOthers', 'Profile', 'Password'].includes(result.action.value)"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<credit-card-icon
|
||||
v-if="result.action.value === 'AppPayments'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<home-icon
|
||||
v-if="result.action.value === 'Files'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<trash2-icon
|
||||
v-if="result.action.value === 'Trash'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<database-icon
|
||||
v-if="['CreateFixedPlan', 'CreateMeteredPlan'].includes(result.action.value)"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<user-plus-icon
|
||||
v-if="result.action.value === 'UserCreate'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<users-icon
|
||||
v-if="['TeamFolders', 'Users'].includes(result.action.value)"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<user-check-icon
|
||||
v-if="result.action.value === 'SharedWithMe'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<link-icon
|
||||
v-if="result.action.value === 'MySharedItems'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<upload-cloud-icon
|
||||
v-if="result.action.value === 'RecentUploads'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<file-text-icon
|
||||
v-if="['Invoices', 'Invoice'].includes(result.action.value)"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<database-icon
|
||||
v-if="result.action.value === 'Plans'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<dollar-sign-icon
|
||||
v-if="['Subscriptions', 'Billing'].includes(result.action.value)"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<globe-icon
|
||||
v-if="result.action.value === 'Language'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<monitor-icon
|
||||
v-if="result.action.value === 'Pages'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<box-icon
|
||||
v-if="result.action.value === 'Dashboard'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<hard-drive-icon
|
||||
v-if="result.action.value === 'Storage'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<moon-icon
|
||||
v-if="result.action.value === 'dark-mode'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<maximize2-icon
|
||||
v-if="result.action.value === 'full-screen-mode'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<power-icon
|
||||
v-if="result.action.value === 'log-out'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<trash-icon
|
||||
v-if="result.action.value === 'empty-trash'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<grid-icon
|
||||
v-if="result.action.value === 'toggle-grid-list'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<smile-icon
|
||||
v-if="result.action.value === 'toggle-emoji'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
<folder-plus-icon
|
||||
v-if="result.action.value === 'create-team-folder'"
|
||||
size="18"
|
||||
class="vue-feather text-theme"
|
||||
/>
|
||||
|
||||
<b class="ml-3.5 text-sm font-bold">
|
||||
{{ result.title }}
|
||||
@@ -122,7 +243,10 @@
|
||||
>
|
||||
<MemberAvatar :is-border="false" :size="44" :member="result" />
|
||||
<div class="ml-3">
|
||||
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||
<b
|
||||
class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold"
|
||||
style="max-width: 155px"
|
||||
>
|
||||
{{ result.data.attributes.name }}
|
||||
</b>
|
||||
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||
@@ -145,12 +269,17 @@
|
||||
|
||||
<!--Keyboard shortcut hint-->
|
||||
<div v-if="!$isMobile()" class="absolute right-4 top-1/2 -translate-y-1/2 transform">
|
||||
<span class="text-xs text-gray-400">{{ i + actions.length === 0 ? '↵' : metaKeyIcon + (i + actions.length) }}</span>
|
||||
<span class="text-xs text-gray-400">{{
|
||||
i + actions.length === 0 ? '↵' : metaKeyIcon + (i + actions.length)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Show Empty message-->
|
||||
<span v-if="results.length === 0 && actions.length === 0" class="p-2.5 text-sm text-gray-700 dark:text-gray-400">
|
||||
<span
|
||||
v-if="results.length === 0 && actions.length === 0"
|
||||
class="p-2.5 text-sm text-gray-700 dark:text-gray-400"
|
||||
>
|
||||
{{ $t('messages.nothing_was_found') }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -172,7 +301,7 @@ import KeyboardHints from './KeyboardHints'
|
||||
import axios from 'axios'
|
||||
import { debounce } from 'lodash'
|
||||
import {
|
||||
FolderPlusIcon,
|
||||
FolderPlusIcon,
|
||||
SmileIcon,
|
||||
BoxIcon,
|
||||
CreditCardIcon,
|
||||
@@ -203,7 +332,7 @@ import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'Spotlight',
|
||||
components: {
|
||||
FolderPlusIcon,
|
||||
FolderPlusIcon,
|
||||
SmileIcon,
|
||||
KeyboardHints,
|
||||
CreditCardIcon,
|
||||
@@ -381,31 +510,31 @@ export default {
|
||||
value: 'Billing',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: this.$t('Empty Your Trash'),
|
||||
action: {
|
||||
type: 'function',
|
||||
value: 'empty-trash',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: this.$t('Log Out'),
|
||||
action: {
|
||||
type: 'function',
|
||||
value: 'log-out',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: this.$t('Empty Your Trash'),
|
||||
action: {
|
||||
type: 'function',
|
||||
value: 'empty-trash',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: this.$t('Log Out'),
|
||||
action: {
|
||||
type: 'function',
|
||||
value: 'log-out',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
let createList = [
|
||||
{
|
||||
title: this.$t('Create Team Folder'),
|
||||
action: {
|
||||
type: 'function',
|
||||
value: 'create-team-folder',
|
||||
},
|
||||
},
|
||||
]
|
||||
let createList = [
|
||||
{
|
||||
title: this.$t('Create Team Folder'),
|
||||
action: {
|
||||
type: 'function',
|
||||
value: 'create-team-folder',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
let functionList = [
|
||||
{
|
||||
@@ -442,12 +571,12 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
// Return commands for public page
|
||||
if (this.$isThisRoute(this.$route, ['Public'])) {
|
||||
return [].concat.apply([], [functionList])
|
||||
}
|
||||
// Return commands for public page
|
||||
if (this.$isThisRoute(this.$route, ['Public'])) {
|
||||
return [].concat.apply([], [functionList])
|
||||
}
|
||||
|
||||
// Return commands for logged admin
|
||||
// Return commands for logged admin
|
||||
if (this.user.data.attributes.role === 'admin') {
|
||||
// Available only for fixed subscription
|
||||
if (this.config.subscriptionType === 'fixed') {
|
||||
@@ -461,7 +590,10 @@ export default {
|
||||
}
|
||||
|
||||
// Available only when is metered billing and plan doesnt exist or when is fixed billing
|
||||
if ((this.config.subscriptionType === 'metered' && !this.config.isCreatedMeteredPlan) || this.config.subscriptionType === 'fixed') {
|
||||
if (
|
||||
(this.config.subscriptionType === 'metered' && !this.config.isCreatedMeteredPlan) ||
|
||||
this.config.subscriptionType === 'fixed'
|
||||
) {
|
||||
adminActions.push({
|
||||
title: this.$t('Create Plan'),
|
||||
action: {
|
||||
@@ -471,11 +603,14 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
return [].concat.apply([], [functionList, createList, userSettings, fileLocations, adminLocations, adminActions])
|
||||
return [].concat.apply(
|
||||
[],
|
||||
[functionList, createList, userSettings, fileLocations, adminLocations, adminActions]
|
||||
)
|
||||
}
|
||||
|
||||
// Return commands for logged user
|
||||
if (this.user.data.attributes.role === 'user') {
|
||||
// Return commands for logged user
|
||||
if (this.user.data.attributes.role === 'user') {
|
||||
return [].concat.apply([], [functionList, createList, userSettings, fileLocations])
|
||||
}
|
||||
},
|
||||
@@ -533,7 +668,9 @@ export default {
|
||||
|
||||
// Browse actions
|
||||
if (!this.activeFilter) {
|
||||
this.actions = this.actionList.filter((el) => el.title.toLowerCase().indexOf(formattedQuery) > -1).slice(0, 3)
|
||||
this.actions = this.actionList
|
||||
.filter((el) => el.title.toLowerCase().indexOf(formattedQuery) > -1)
|
||||
.slice(0, 3)
|
||||
}
|
||||
|
||||
this.findResult(formattedQuery)
|
||||
@@ -623,16 +760,15 @@ export default {
|
||||
openItem(file) {
|
||||
// Show folder
|
||||
if (file.data.type === 'folder') {
|
||||
|
||||
if (this.$isThisRoute(this.$route, ['Public'])) {
|
||||
this.$router.push({
|
||||
name: 'Public',
|
||||
params: {
|
||||
token: this.sharedDetail.data.attributes.token,
|
||||
id: file.data.id,
|
||||
},
|
||||
})
|
||||
} else if (file.data.attributes.isTeamFolder) {
|
||||
if (this.$isThisRoute(this.$route, ['Public'])) {
|
||||
this.$router.push({
|
||||
name: 'Public',
|
||||
params: {
|
||||
token: this.sharedDetail.data.attributes.token,
|
||||
id: file.data.id,
|
||||
},
|
||||
})
|
||||
} else if (file.data.attributes.isTeamFolder) {
|
||||
if (file.data.relationships.owner.data.id === this.user.data.id) {
|
||||
this.$router.push({
|
||||
name: 'TeamFolders',
|
||||
@@ -657,7 +793,10 @@ export default {
|
||||
|
||||
events.$emit('file-preview:show')
|
||||
} else {
|
||||
this.$downloadFile(file.data.attributes.file_url, file.data.attributes.name + '.' + file.data.attributes.mimetype)
|
||||
this.$downloadFile(
|
||||
file.data.attributes.file_url,
|
||||
file.data.attributes.name + '.' + file.data.attributes.mimetype
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -671,8 +810,8 @@ export default {
|
||||
|
||||
// Get route
|
||||
let route = this.$store.getters.sharedDetail
|
||||
? `/api/browse/search/${this.$router.currentRoute.params.token}`
|
||||
: '/api/browse/search'
|
||||
? `/api/browse/search/${this.$router.currentRoute.params.token}`
|
||||
: '/api/browse/search'
|
||||
|
||||
axios
|
||||
.get(`${route}?filter=${this.activeFilter}`, {
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
<div v-if="row.data.relationships.user" class="flex items-center">
|
||||
<MemberAvatar :is-border="false" :size="36" :member="row.data.relationships.user" />
|
||||
<div class="ml-3 pr-10">
|
||||
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||
<b
|
||||
class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold"
|
||||
style="max-width: 155px"
|
||||
>
|
||||
{{ row.data.relationships.user.data.attributes.name }}
|
||||
</b>
|
||||
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||
@@ -38,7 +41,11 @@
|
||||
</td>
|
||||
<td class="px-3 md:px-1">
|
||||
<div class="w-28">
|
||||
<img class="inline-block max-h-5" :src="$getPaymentLogo(row.data.attributes.driver)" :alt="row.data.attributes.driver" />
|
||||
<img
|
||||
class="inline-block max-h-5"
|
||||
:src="$getPaymentLogo(row.data.attributes.driver)"
|
||||
:alt="row.data.attributes.driver"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<td class="pl-3 text-right md:pl-1">
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
<div v-if="row.data.relationships.user" class="flex items-center">
|
||||
<MemberAvatar :is-border="false" :size="36" :member="row.data.relationships.user" />
|
||||
<div class="ml-3 pr-10">
|
||||
<b class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold" style="max-width: 155px">
|
||||
<b
|
||||
class="max-w-1 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold"
|
||||
style="max-width: 155px"
|
||||
>
|
||||
{{ row.data.relationships.user.data.attributes.name }}
|
||||
</b>
|
||||
<span class="block text-xs text-gray-600 dark:text-gray-500">
|
||||
@@ -43,7 +46,11 @@
|
||||
</td>
|
||||
<td class="px-3 md:px-1">
|
||||
<div class="w-28">
|
||||
<img class="inline-block max-h-5" :src="$getPaymentLogo(row.data.attributes.driver)" :alt="row.data.attributes.driver" />
|
||||
<img
|
||||
class="inline-block max-h-5"
|
||||
:src="$getPaymentLogo(row.data.attributes.driver)"
|
||||
:alt="row.data.attributes.driver"
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
<td class="pl-3 text-right md:pl-1">
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<template>
|
||||
<div class="flex items-center justify-between rounded-lg bg-light-background py-3 px-2 dark:bg-2x-dark-foreground md:px-4">
|
||||
<div
|
||||
class="flex items-center justify-between rounded-lg bg-light-background py-3 px-2 dark:bg-2x-dark-foreground md:px-4"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<img :src="`/assets/gateways/${card.data.attributes.brand}.svg`" alt="" class="mr-3 h-5 rounded" />
|
||||
<b class="whitespace-nowrap text-sm font-bold capitalize leading-none">
|
||||
@@ -26,7 +28,9 @@ export default {
|
||||
deleteCreditCard(id) {
|
||||
events.$emit('confirm:open', {
|
||||
title: this.$t('Are you sure you want to delete your credit card?'),
|
||||
message: this.$t('We will no longer settle your payments automatically and you will have to fund your account for the next payments.'),
|
||||
message: this.$t(
|
||||
'We will no longer settle your payments automatically and you will have to fund your account for the next payments.'
|
||||
),
|
||||
action: {
|
||||
id: id,
|
||||
operation: 'delete-credit-card',
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
<b class="flex-1 pl-4 text-left text-lg">
|
||||
{{ plan.data.attributes.name }}
|
||||
</b>
|
||||
<span class="text-theme bg-theme-100 ml-9 inline-block whitespace-nowrap rounded-xl py-1 px-2 text-sm font-extrabold">
|
||||
<span
|
||||
class="text-theme bg-theme-100 ml-9 inline-block whitespace-nowrap rounded-xl py-1 px-2 text-sm font-extrabold"
|
||||
>
|
||||
{{ plan.data.attributes.price }} /
|
||||
{{ $t(`interval.${plan.data.attributes.interval}`) }}
|
||||
</span>
|
||||
|
||||
@@ -6,11 +6,19 @@
|
||||
<div v-if="isPaymentOptionPage">
|
||||
<PopupContent>
|
||||
<!--Stripe implementation-->
|
||||
<PaymentMethod v-if="config.isStripe" driver="stripe" :description="$t('Pay by your credit card or Apple Pay')">
|
||||
<PaymentMethod
|
||||
v-if="config.isStripe"
|
||||
driver="stripe"
|
||||
:description="$t('Pay by your credit card or Apple Pay')"
|
||||
>
|
||||
<div v-if="stripe.isGettingCheckoutLink" class="translate-y-3 scale-50 transform">
|
||||
<Spinner />
|
||||
</div>
|
||||
<span @click="payByStripe" :class="{ 'opacity-0': stripe.isGettingCheckoutLink }" class="text-theme cursor-pointer text-sm font-bold">
|
||||
<span
|
||||
@click="payByStripe"
|
||||
:class="{ 'opacity-0': stripe.isGettingCheckoutLink }"
|
||||
class="text-theme cursor-pointer text-sm font-bold"
|
||||
>
|
||||
{{ $t('Select') }}
|
||||
</span>
|
||||
</PaymentMethod>
|
||||
@@ -22,11 +30,19 @@
|
||||
'mb-2 rounded-xl bg-light-background px-4 dark:bg-2x-dark-foreground': paypal.isMethodsLoaded,
|
||||
}"
|
||||
>
|
||||
<PaymentMethod @click.native="pickedPaymentMethod('paypal')" driver="paypal" :description="$t('Available PayPal Credit, Debit or Credit Card.')">
|
||||
<PaymentMethod
|
||||
@click.native="pickedPaymentMethod('paypal')"
|
||||
driver="paypal"
|
||||
:description="$t('Available PayPal Credit, Debit or Credit Card.')"
|
||||
>
|
||||
<div v-if="paypal.isMethodLoading" class="translate-y-3 scale-50 transform">
|
||||
<Spinner />
|
||||
</div>
|
||||
<span v-if="!paypal.isMethodsLoaded" :class="{ 'opacity-0': paypal.isMethodLoading }" class="text-theme cursor-pointer text-sm font-bold">
|
||||
<span
|
||||
v-if="!paypal.isMethodsLoaded"
|
||||
:class="{ 'opacity-0': paypal.isMethodLoading }"
|
||||
class="text-theme cursor-pointer text-sm font-bold"
|
||||
>
|
||||
{{ $t('Select') }}
|
||||
</span>
|
||||
</PaymentMethod>
|
||||
@@ -36,7 +52,11 @@
|
||||
</div>
|
||||
|
||||
<!--Paystack implementation-->
|
||||
<PaymentMethod v-if="config.isPaystack" driver="paystack" :description="$t('Available Bank Account, USSD, Mobile Money, Apple Pay')">
|
||||
<PaymentMethod
|
||||
v-if="config.isPaystack"
|
||||
driver="paystack"
|
||||
:description="$t('Available Bank Account, USSD, Mobile Money, Apple Pay')"
|
||||
>
|
||||
<paystack
|
||||
v-if="user && config"
|
||||
:channels="['bank', 'ussd', 'qr', 'mobile_money', 'bank_transfer']"
|
||||
@@ -67,18 +87,24 @@
|
||||
<!--Select Payment Plans-->
|
||||
<div v-if="!isPaymentOptionPage">
|
||||
<PopupContent v-if="plans">
|
||||
|
||||
<InfoBox v-if="plans.data.length === 0" class="!mb-0">
|
||||
<p>There isn't any plan yet.</p>
|
||||
</InfoBox>
|
||||
<InfoBox v-if="plans.data.length === 0" class="!mb-0">
|
||||
<p>There isn't any plan yet.</p>
|
||||
</InfoBox>
|
||||
|
||||
<!--Toggle yearly billing-->
|
||||
<div v-if="hasYearlyPlans.length > 0" class="mb-2 px-5 text-right">
|
||||
<label :class="{ 'text-gray-400': !isSelectedYearlyPlans }" class="cursor-pointer text-xs font-bold">
|
||||
<label
|
||||
:class="{ 'text-gray-400': !isSelectedYearlyPlans }"
|
||||
class="cursor-pointer text-xs font-bold"
|
||||
>
|
||||
{{ $t('Billed Annually') }}
|
||||
</label>
|
||||
<div class="relative inline-block w-12 select-none align-middle">
|
||||
<SwitchInput class="scale-75 transform" v-model="isSelectedYearlyPlans" :state="isSelectedYearlyPlans" />
|
||||
<SwitchInput
|
||||
class="scale-75 transform"
|
||||
v-model="isSelectedYearlyPlans"
|
||||
:state="isSelectedYearlyPlans"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -88,7 +114,9 @@
|
||||
v-for="(plan, i) in plans.data"
|
||||
:plan="plan"
|
||||
:key="plan.data.id"
|
||||
v-if="plan.data.attributes.interval === intervalPlanType && userSubscribedPlanId !== plan.data.id"
|
||||
v-if="
|
||||
plan.data.attributes.interval === intervalPlanType && userSubscribedPlanId !== plan.data.id
|
||||
"
|
||||
:is-selected="selectedPlan && selectedPlan.data.id === plan.data.id"
|
||||
@click.native="selectPlan(plan)"
|
||||
/>
|
||||
@@ -97,8 +125,16 @@
|
||||
|
||||
<!--Actions-->
|
||||
<PopupActions>
|
||||
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary">{{ $t('popup_move_item.cancel') }} </ButtonBase>
|
||||
<ButtonBase class="w-full" v-if="plans.data.length !== 0" :button-style="buttonStyle" @click.native="isPaymentOptionPage = true">{{ $t('Upgrade Account') }} </ButtonBase>
|
||||
<ButtonBase class="w-full" @click.native="$closePopup()" button-style="secondary"
|
||||
>{{ $t('popup_move_item.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
class="w-full"
|
||||
v-if="plans.data.length !== 0"
|
||||
:button-style="buttonStyle"
|
||||
@click.native="isPaymentOptionPage = true"
|
||||
>{{ $t('Upgrade Account') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
</div>
|
||||
</PopupWrapper>
|
||||
@@ -119,12 +155,12 @@ import { mapGetters } from 'vuex'
|
||||
import { events } from '../../bus'
|
||||
import axios from 'axios'
|
||||
import Spinner from '../FilesView/Spinner'
|
||||
import InfoBox from "../Others/Forms/InfoBox";
|
||||
import InfoBox from '../Others/Forms/InfoBox'
|
||||
|
||||
export default {
|
||||
name: 'SelectPlanSubscriptionPopup',
|
||||
components: {
|
||||
InfoBox,
|
||||
InfoBox,
|
||||
Spinner,
|
||||
PaymentMethod,
|
||||
paystack,
|
||||
@@ -150,7 +186,11 @@ export default {
|
||||
return this.selectedPlan ? 'theme' : 'secondary'
|
||||
},
|
||||
userSubscribedPlanId() {
|
||||
return this.user && this.user.data.relationships.subscription && this.user.data.relationships.subscription.data.relationships.plan.data.id
|
||||
return (
|
||||
this.user &&
|
||||
this.user.data.relationships.subscription &&
|
||||
this.user.data.relationships.subscription.data.relationships.plan.data.id
|
||||
)
|
||||
},
|
||||
hasYearlyPlans() {
|
||||
return this.plans.data.filter((plan) => plan.data.attributes.interval === 'year')
|
||||
|
||||
@@ -9,9 +9,27 @@
|
||||
</b>
|
||||
|
||||
<!-- Make payment form -->
|
||||
<ValidationObserver ref="fundAccount" @submit.prevent="makePayment" v-slot="{ invalid }" tag="form" class="mt-6">
|
||||
<ValidationProvider tag="div" v-slot="{ errors }" mode="passive" name="Amount" :rules="`required|min_value:${user.data.meta.totalDebt.amount}`">
|
||||
<AppInputText :description="$t('The amount will be increased as soon as we register your charge from payment gateway.')" :error="errors[0]" :is-last="true">
|
||||
<ValidationObserver
|
||||
ref="fundAccount"
|
||||
@submit.prevent="makePayment"
|
||||
v-slot="{ invalid }"
|
||||
tag="form"
|
||||
class="mt-6"
|
||||
>
|
||||
<ValidationProvider
|
||||
tag="div"
|
||||
v-slot="{ errors }"
|
||||
mode="passive"
|
||||
name="Amount"
|
||||
:rules="`required|min_value:${user.data.meta.totalDebt.amount}`"
|
||||
>
|
||||
<AppInputText
|
||||
:description="
|
||||
$t('The amount will be increased as soon as we register your charge from payment gateway.')
|
||||
"
|
||||
:error="errors[0]"
|
||||
:is-last="true"
|
||||
>
|
||||
<div class="space-y-4 sm:flex sm:space-x-4 sm:space-y-0">
|
||||
<input
|
||||
v-model="chargeAmount"
|
||||
|
||||
@@ -13,7 +13,12 @@
|
||||
size="12"
|
||||
class="vue-feather ml-2 -translate-y-0.5 transform cursor-pointer"
|
||||
/>
|
||||
<trash2-icon v-if="showUpdateBillingAlertForm" @click="deleteBillingAlert" size="12" class="vue-feather ml-2 -translate-y-0.5 transform cursor-pointer" />
|
||||
<trash2-icon
|
||||
v-if="showUpdateBillingAlertForm"
|
||||
@click="deleteBillingAlert"
|
||||
size="12"
|
||||
class="vue-feather ml-2 -translate-y-0.5 transform cursor-pointer"
|
||||
/>
|
||||
</b>
|
||||
|
||||
<b class="block text-sm text-gray-400">
|
||||
@@ -21,9 +26,24 @@
|
||||
</b>
|
||||
</div>
|
||||
|
||||
<ValidationObserver v-if="showUpdateBillingAlertForm" ref="updatebillingAlertForm" @submit.prevent="updateBillingAlert" v-slot="{ invalid }" tag="form" class="mt-6">
|
||||
<ValidationObserver
|
||||
v-if="showUpdateBillingAlertForm"
|
||||
ref="updatebillingAlertForm"
|
||||
@submit.prevent="updateBillingAlert"
|
||||
v-slot="{ invalid }"
|
||||
tag="form"
|
||||
class="mt-6"
|
||||
>
|
||||
<ValidationProvider tag="div" v-slot="{ errors }" mode="passive" name="Billing Alert" rules="required">
|
||||
<AppInputText :description="$t('You will receive an email whenever your monthly balance reaches the specified amount above.')" :error="errors[0]" :is-last="true">
|
||||
<AppInputText
|
||||
:description="
|
||||
$t(
|
||||
'You will receive an email whenever your monthly balance reaches the specified amount above.'
|
||||
)
|
||||
"
|
||||
:error="errors[0]"
|
||||
:is-last="true"
|
||||
>
|
||||
<div class="space-y-4 sm:flex sm:space-x-4 sm:space-y-0">
|
||||
<input
|
||||
v-model="billingAlertAmount"
|
||||
@@ -34,7 +54,13 @@
|
||||
class="focus-border-theme input-dark"
|
||||
:class="{ 'border-red': errors[0] }"
|
||||
/>
|
||||
<ButtonBase :loadint="isSendingBillingAlert" :disabled="isSendingBillingAlert" type="submit" button-style="theme" class="w-full sm:w-auto">
|
||||
<ButtonBase
|
||||
:loadint="isSendingBillingAlert"
|
||||
:disabled="isSendingBillingAlert"
|
||||
type="submit"
|
||||
button-style="theme"
|
||||
class="w-full sm:w-auto"
|
||||
>
|
||||
{{ $t('Update Alert') }}
|
||||
</ButtonBase>
|
||||
</div>
|
||||
@@ -42,9 +68,24 @@
|
||||
</ValidationProvider>
|
||||
</ValidationObserver>
|
||||
|
||||
<ValidationObserver v-if="!user.data.relationships.alert" ref="billingAlertForm" @submit.prevent="setBillingAlert" v-slot="{ invalid }" tag="form" class="mt-6">
|
||||
<ValidationObserver
|
||||
v-if="!user.data.relationships.alert"
|
||||
ref="billingAlertForm"
|
||||
@submit.prevent="setBillingAlert"
|
||||
v-slot="{ invalid }"
|
||||
tag="form"
|
||||
class="mt-6"
|
||||
>
|
||||
<ValidationProvider tag="div" v-slot="{ errors }" mode="passive" name="Billing Alert" rules="required">
|
||||
<AppInputText :description="$t('You will receive an email whenever your monthly balance reaches the specified amount above.')" :error="errors[0]" :is-last="true">
|
||||
<AppInputText
|
||||
:description="
|
||||
$t(
|
||||
'You will receive an email whenever your monthly balance reaches the specified amount above.'
|
||||
)
|
||||
"
|
||||
:error="errors[0]"
|
||||
:is-last="true"
|
||||
>
|
||||
<div class="space-y-4 sm:flex sm:space-x-4 sm:space-y-0">
|
||||
<input
|
||||
v-model="billingAlertAmount"
|
||||
@@ -55,7 +96,13 @@
|
||||
class="focus-border-theme input-dark"
|
||||
:class="{ 'border-red': errors[0] }"
|
||||
/>
|
||||
<ButtonBase :loadint="isSendingBillingAlert" :disabled="isSendingBillingAlert" type="submit" button-style="theme" class="w-full sm:w-auto">
|
||||
<ButtonBase
|
||||
:loadint="isSendingBillingAlert"
|
||||
:disabled="isSendingBillingAlert"
|
||||
type="submit"
|
||||
button-style="theme"
|
||||
class="w-full sm:w-auto"
|
||||
>
|
||||
{{ $t('Set Alert') }}
|
||||
</ButtonBase>
|
||||
</div>
|
||||
@@ -161,7 +208,9 @@ export default {
|
||||
deleteBillingAlert() {
|
||||
events.$emit('confirm:open', {
|
||||
title: this.$t('Are you sure you want to delete your alert?'),
|
||||
message: this.$t('You will no longer receive any notifications that your billing limit has been exceeded.'),
|
||||
message: this.$t(
|
||||
'You will no longer receive any notifications that your billing limit has been exceeded.'
|
||||
),
|
||||
action: {
|
||||
id: this.user.data.relationships.alert.data.id,
|
||||
operation: 'delete-billing-alert',
|
||||
|
||||
@@ -7,14 +7,27 @@
|
||||
<AppInputButton
|
||||
v-if="subscription.attributes.status !== 'cancelled'"
|
||||
:title="$t('Cancel Subscription')"
|
||||
:description="$t('You can cancel your subscription now. You\'ll continue to have access to the features you\'ve paid for until the end of your billing cycle.')"
|
||||
:description="
|
||||
$t(
|
||||
'You can cancel your subscription now. You\'ll continue to have access to the features you\'ve paid for until the end of your billing cycle.'
|
||||
)
|
||||
"
|
||||
>
|
||||
<ButtonBase @click.native="cancelSubscriptionConfirmation" :loading="isCancelling" class="w-full sm:w-auto" button-style="secondary">
|
||||
<ButtonBase
|
||||
@click.native="cancelSubscriptionConfirmation"
|
||||
:loading="isCancelling"
|
||||
class="w-full sm:w-auto"
|
||||
button-style="secondary"
|
||||
>
|
||||
{{ $t('Cancel Now') }}
|
||||
</ButtonBase>
|
||||
</AppInputButton>
|
||||
|
||||
<AppInputButton :title="$t('Upgrade or Downgrade Plan')" :description="$t('You can upgrade your plan at any time you want.')" :is-last="true">
|
||||
<AppInputButton
|
||||
:title="$t('Upgrade or Downgrade Plan')"
|
||||
:description="$t('You can upgrade your plan at any time you want.')"
|
||||
:is-last="true"
|
||||
>
|
||||
<ButtonBase @click.native="$openUpgradeOptions" class="w-full sm:w-auto" button-style="secondary">
|
||||
{{ $t('Change Plan') }}
|
||||
</ButtonBase>
|
||||
@@ -57,7 +70,9 @@ export default {
|
||||
cancelSubscriptionConfirmation() {
|
||||
events.$emit('confirm:open', {
|
||||
title: this.$t('Are you sure you want to cancel subscription?'),
|
||||
message: this.$t("You'll continue to have access to the features you've paid for until the end of your billing cycle."),
|
||||
message: this.$t(
|
||||
"You'll continue to have access to the features you've paid for until the end of your billing cycle."
|
||||
),
|
||||
action: {
|
||||
operation: 'cancel-subscription',
|
||||
},
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
{{ $t('Upgrade your account to get more.') }}
|
||||
</b>
|
||||
|
||||
<ButtonBase v-if="$store.getters.config.allowed_payments" @click.native="$openUpgradeOptions" type="submit" button-style="theme" class="mt-4 w-full">
|
||||
<ButtonBase
|
||||
v-if="$store.getters.config.allowed_payments"
|
||||
@click.native="$openUpgradeOptions"
|
||||
type="submit"
|
||||
button-style="theme"
|
||||
class="mt-4 w-full"
|
||||
>
|
||||
{{ $t('Upgrade Your Account') }}
|
||||
</ButtonBase>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
<template>
|
||||
<div v-if="user.data.relationships.failedPayments && user.data.relationships.failedPayments.data.length > 0" class="card shadow-card">
|
||||
<div
|
||||
v-if="user.data.relationships.failedPayments && user.data.relationships.failedPayments.data.length > 0"
|
||||
class="card shadow-card"
|
||||
>
|
||||
<FormLabel icon="frown">
|
||||
{{ $t('Failed Payments') }}
|
||||
</FormLabel>
|
||||
|
||||
<b class="-mt-3 mb-0.5 block text-2xl font-extrabold sm:text-3xl"> -{{ user.data.meta.totalDebt.formatted }} </b>
|
||||
<b class="-mt-3 mb-0.5 block text-2xl font-extrabold sm:text-3xl">
|
||||
-{{ user.data.meta.totalDebt.formatted }}
|
||||
</b>
|
||||
|
||||
<b class="mb-3 mb-5 block text-sm text-gray-400">
|
||||
{{ $t("We are unable to charge your usage. Please register new credit card or fund your account with sufficient amount and we'll give it another try!") }}
|
||||
{{
|
||||
$t(
|
||||
"We are unable to charge your usage. Please register new credit card or fund your account with sufficient amount and we'll give it another try!"
|
||||
)
|
||||
}}
|
||||
</b>
|
||||
|
||||
<!--Failed Payments-->
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user