mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-05-22 21:14:42 +00:00
UI improvements part 4
This commit is contained in:
@@ -161,6 +161,10 @@ export default {
|
||||
@apply whitespace-nowrap overflow-ellipsis overflow-x-hidden block
|
||||
}
|
||||
|
||||
input:-webkit-autofill {
|
||||
transition-delay: 999999999999s;
|
||||
}
|
||||
|
||||
[v-cloak],
|
||||
[v-cloak] > * {
|
||||
display: none
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div :class="{'dark:bg-dark-foreground bg-light-background': isClicked && highlight, 'dark:hover:bg-dark-foreground hover:bg-light-background': highlight}" class="flex items-center px-2.5 py-2 rounded-xl select-none border-2 border-transparent border-dashed" :draggable="canDrag" spellcheck="false">
|
||||
|
||||
<!--MultiSelecting for the mobile version-->
|
||||
<CheckBox v-if="isMultiSelectMode" v-model="isClicked" class="mr-5"/>
|
||||
<CheckBox v-if="isMultiSelectMode" v-model="isClicked" :is-clicked="isClicked" class="mr-5"/>
|
||||
|
||||
<!--Item thumbnail-->
|
||||
<div class="w-16 relative">
|
||||
@@ -105,6 +105,7 @@
|
||||
return {
|
||||
mobileMultiSelect: false,
|
||||
itemName: undefined,
|
||||
isSelected: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
<div class="input-area bg-light-background rounded-lg" :class="{'is-active': isOpen, 'is-error': isError}" @click="openMenu">
|
||||
|
||||
<!--If is selected-->
|
||||
<div class="selected" v-if="selected">
|
||||
<div class="selected w-full flex items-center" v-if="selected">
|
||||
<div class="option-icon" v-if="selected.icon">
|
||||
<user-icon v-if="selected.icon === 'user'" size="14" class="text-theme dark-text-theme" />
|
||||
<edit2-icon v-if="selected.icon === 'user-edit'" size="14" class="text-theme dark-text-theme" />
|
||||
<user-icon v-if="selected.icon === 'user'" size="14" class="vue-feather text-theme" />
|
||||
<edit2-icon v-if="selected.icon === 'user-edit'" size="14" class="vue-feather text-theme" />
|
||||
</div>
|
||||
<span class="option-value">{{ selected.label }}</span>
|
||||
<span class="whitespace-nowrap w-full inline-block overflow-hidden overflow-ellipsis option-value pl-2">
|
||||
{{ selected.label }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!--If is empty-->
|
||||
@@ -115,6 +117,8 @@
|
||||
@import '/resources/sass/vuefilemanager/_variables';
|
||||
@import '/resources/sass/vuefilemanager/_mixins';
|
||||
|
||||
/* TODO: refactor to the tailwind */
|
||||
|
||||
.select {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
@@ -203,21 +207,11 @@
|
||||
width: 20px;
|
||||
display: inline-block;
|
||||
@include font-size(10);
|
||||
|
||||
svg {
|
||||
margin-top: -4px;
|
||||
vertical-align: middle;
|
||||
|
||||
line, path, circle {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.option-value {
|
||||
@include font-size(14);
|
||||
font-weight: 700;
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
|
||||
&.placehoder {
|
||||
|
||||
@@ -1,19 +1,37 @@
|
||||
<template>
|
||||
<transition appear name="fade">
|
||||
<li v-show="isActive" class="toaster-item" :class="item.type">
|
||||
<div class="toaster-content-wrapper">
|
||||
<span class="toaster-icon">
|
||||
<check-icon v-if="item.type === 'success'" size="22" />
|
||||
<x-icon v-if="item.type === 'danger'" size="22" />
|
||||
</span>
|
||||
<div class="toaster-content">
|
||||
<p class="toaster-description">{{ item.message }}</p>
|
||||
</div>
|
||||
<div
|
||||
v-if="isActive"
|
||||
class="relative mt-4 p-4 md:w-96 w-full shadow-lg rounded-xl overflow-hidden backdrop-filter backdrop-blur-lg bg-opacity-80"
|
||||
:class="{'dark:bg-2x-dark-foreground bg-red-50': isDanger, 'dark:bg-2x-dark-foreground bg-green-50': isSuccess}"
|
||||
>
|
||||
|
||||
<!--Content-->
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center">
|
||||
<div>
|
||||
<check-icon v-if="isSuccess" size="22" class="vue-feather text-green-600" />
|
||||
<x-icon v-if="isDanger" size="22" class="vue-feather text-red-600" />
|
||||
</div>
|
||||
|
||||
<p
|
||||
class="px-4 font-bold"
|
||||
:class="{'text-green-600': isSuccess, 'text-red-600': isDanger}"
|
||||
>
|
||||
{{ item.message }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div @click="isActive = false" class="p-2 cursor-pointer">
|
||||
<x-icon size="16" class="vue-feather dark:text-white text-black opacity-50" />
|
||||
</div>
|
||||
</div>
|
||||
<div :class="{'success': item.type === 'success', 'danger': item.type === 'danger'}" class="progressbar">
|
||||
<span></span>
|
||||
|
||||
<!--Progress bar-->
|
||||
<div class="absolute bottom-0 left-0 right-0">
|
||||
<span class="w-0 h-1 block bar-animation" :class="{'bg-green-400': isSuccess, 'bg-red-400': isDanger}"></span>
|
||||
</div>
|
||||
</li>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
@@ -28,143 +46,47 @@
|
||||
props: [
|
||||
'item'
|
||||
],
|
||||
computed: {
|
||||
isDanger() {
|
||||
return this.item.type === 'danger'
|
||||
},
|
||||
isSuccess() {
|
||||
return this.item.type === 'success'
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isActive: 0
|
||||
isActive: 1
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.isActive = 1
|
||||
|
||||
setTimeout(() => (this.isActive = 0), 6000)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '/resources/sass/vuefilemanager/_variables';
|
||||
@import '/resources/sass/vuefilemanager/_mixins';
|
||||
.bar-animation {
|
||||
animation: progressbar 6s linear;
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: 0.3s ease;
|
||||
}
|
||||
|
||||
.fade-enter,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
@include transform(translateX(100%));
|
||||
}
|
||||
|
||||
.toaster-content-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.progressbar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
opacity: 0.35;
|
||||
|
||||
span {
|
||||
width: 0;
|
||||
height: 3px;
|
||||
display: block;
|
||||
animation: progressbar 6s linear;
|
||||
}
|
||||
|
||||
&.success span {
|
||||
background: $theme;
|
||||
@keyframes progressbar {
|
||||
0% {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
&.danger span {
|
||||
background: $danger;
|
||||
100% {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes progressbar {
|
||||
0% {
|
||||
width: 0;
|
||||
}
|
||||
100% {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: 0.3s ease;
|
||||
}
|
||||
|
||||
.toaster-item {
|
||||
max-width: 320px;
|
||||
margin-top: 20px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
border-radius: 8px;
|
||||
|
||||
.toaster-description {
|
||||
@include font-size(15);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.toaster-icon {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
font-size: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
&.success {
|
||||
background: $theme_light;
|
||||
|
||||
line, polyline {
|
||||
stroke: $theme;
|
||||
}
|
||||
|
||||
.toaster-description {
|
||||
color: $theme;
|
||||
}
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background: rgba($danger, 0.1);
|
||||
|
||||
line, polyline {
|
||||
stroke: $danger;
|
||||
}
|
||||
|
||||
.toaster-description {
|
||||
color: $danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 690px) {
|
||||
|
||||
.toaster-item {
|
||||
margin-bottom: 0;
|
||||
margin-top: 20px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.fade-enter,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
@include transform(translateY(100%));
|
||||
}
|
||||
}
|
||||
|
||||
.dark {
|
||||
.toaster-item {
|
||||
|
||||
&.success, &.danger {
|
||||
background: $dark_mode_foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
.fade-enter,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateX(100%)
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div id="toaster-wrapper">
|
||||
<div v-if="notifications.length > 0" class="fixed lg:bottom-8 bottom-4 lg:right-8 right-4 md:left-auto left-4 z-50">
|
||||
<ToasterItem :item="item" v-for="(item, i) in notifications" :key="i"/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -22,40 +22,3 @@
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '/resources/sass/vuefilemanager/_variables';
|
||||
@import '/resources/sass/vuefilemanager/_mixins';
|
||||
|
||||
.toaster-list {
|
||||
transition: all 5s ease;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.toaster-list-enter,
|
||||
.toaster-list-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
.toaster-list-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#toaster-wrapper {
|
||||
position: fixed;
|
||||
right: 30px;
|
||||
bottom: 30px;
|
||||
z-index: 90;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 690px) {
|
||||
|
||||
#toaster-wrapper {
|
||||
right: 15px;
|
||||
left: 15px;
|
||||
bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="2xl:w-3 md:w-2 w-1 block lg:mr-2 mr-1.5 relative cursor-pointer"
|
||||
class="2xl:w-3 lg:w-2 block lg:mr-2 relative cursor-pointer"
|
||||
:style="{height: bar.percentage + '%'}"
|
||||
@mouseover="isVisible = true"
|
||||
@mouseleave="isVisible = false"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex items-end justify-between sm:h-28 h-20">
|
||||
<div class="lg:flex lg:items-end lg:justify-between grid grid-flow-col lg:gap-0 sm:gap-2 gap-1 items-end sm:h-28 h-20">
|
||||
<!--Data bar-->
|
||||
<Bar
|
||||
v-for="(item, i) in data"
|
||||
|
||||
+14
-14
@@ -25,7 +25,7 @@ const FunctionHelpers = {
|
||||
|
||||
if ((value === '' || value === ' ' || typeof value === 'object') && !allowEmpty) return
|
||||
|
||||
axios.post(this.$store.getters.api + route, {
|
||||
axios.post(store.getters.api + route, {
|
||||
[name]: value,
|
||||
_method: 'patch'
|
||||
})
|
||||
@@ -47,7 +47,7 @@ const FunctionHelpers = {
|
||||
formData.append(name, image)
|
||||
formData.append('_method', 'PATCH')
|
||||
|
||||
axios.post(this.$store.getters.api + route, formData, {
|
||||
axios.post(store.getters.api + route, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
}
|
||||
@@ -138,7 +138,7 @@ const FunctionHelpers = {
|
||||
}
|
||||
|
||||
Vue.prototype.$getImage = function (source) {
|
||||
return source ? this.$store.getters.config.host + '/' + source : ''
|
||||
return source ? store.getters.config.host + '/' + source : ''
|
||||
}
|
||||
|
||||
Vue.prototype.$getCreditCardBrand = function (brand) {
|
||||
@@ -163,7 +163,7 @@ const FunctionHelpers = {
|
||||
|
||||
// Push items to file queue
|
||||
[...files].map(item => {
|
||||
this.$store.commit('ADD_FILES_TO_QUEUE', {
|
||||
store.commit('ADD_FILES_TO_QUEUE', {
|
||||
parent_id: store.getters.currentFolder ? store.getters.currentFolder.data.id : '',
|
||||
file: item,
|
||||
path: '/' + item.webkitRelativePath
|
||||
@@ -171,11 +171,11 @@ const FunctionHelpers = {
|
||||
});
|
||||
|
||||
// Start uploading if uploading process isn't running
|
||||
if (this.$store.getters.filesInQueueTotal == 0)
|
||||
if (store.getters.filesInQueueTotal == 0)
|
||||
this.$handleUploading(store.getters.fileQueue[0])
|
||||
|
||||
// Increase total files in upload bar
|
||||
this.$store.commit('INCREASE_FILES_IN_QUEUES_TOTAL', files.length)
|
||||
store.commit('INCREASE_FILES_IN_QUEUES_TOTAL', files.length)
|
||||
}
|
||||
|
||||
Vue.prototype.$uploadDraggedFiles = async function (event, parent_id) {
|
||||
@@ -191,18 +191,18 @@ const FunctionHelpers = {
|
||||
|
||||
// Push items to file queue
|
||||
[...event.dataTransfer.items].map(item => {
|
||||
this.$store.commit('ADD_FILES_TO_QUEUE', {
|
||||
store.commit('ADD_FILES_TO_QUEUE', {
|
||||
parent_id: parent_id ? parent_id : '',
|
||||
file: item.getAsFile(),
|
||||
})
|
||||
});
|
||||
|
||||
// Start uploading if uploading process isn't running
|
||||
if (this.$store.getters.filesInQueueTotal == 0)
|
||||
this.$handleUploading(this.$store.getters.fileQueue[0])
|
||||
if (store.getters.filesInQueueTotal == 0)
|
||||
this.$handleUploading(store.getters.fileQueue[0])
|
||||
|
||||
// Increase total files in upload bar
|
||||
this.$store.commit('INCREASE_FILES_IN_QUEUES_TOTAL', [...event.dataTransfer.items].length)
|
||||
store.commit('INCREASE_FILES_IN_QUEUES_TOTAL', [...event.dataTransfer.items].length)
|
||||
}
|
||||
|
||||
Vue.prototype.$handleUploading = async function (item) {
|
||||
@@ -559,11 +559,11 @@ const FunctionHelpers = {
|
||||
|
||||
Vue.prototype.$openInDetailPanel = function (entry) {
|
||||
// Dispatch load file info detail
|
||||
this.$store.commit('CLIPBOARD_CLEAR')
|
||||
this.$store.commit('ADD_ITEM_TO_CLIPBOARD', entry)
|
||||
store.commit('CLIPBOARD_CLEAR')
|
||||
store.commit('ADD_ITEM_TO_CLIPBOARD', entry)
|
||||
|
||||
// Show panel if is not open
|
||||
this.$store.dispatch('fileInfoToggle', true)
|
||||
store.dispatch('fileInfoToggle', true)
|
||||
}
|
||||
|
||||
Vue.prototype.$openSpotlight = function (filter = undefined) {
|
||||
@@ -571,7 +571,7 @@ const FunctionHelpers = {
|
||||
}
|
||||
|
||||
Vue.prototype.$enableMultiSelectMode = function () {
|
||||
this.$store.commit('TOGGLE_MULTISELECT_MODE')
|
||||
store.commit('TOGGLE_MULTISELECT_MODE')
|
||||
}
|
||||
|
||||
Vue.prototype.$showMobileMenu = function (name) {
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<router-view :user="user" />
|
||||
</div>
|
||||
<div id="loader" v-if="isLoading">
|
||||
<Spinner></Spinner>
|
||||
<Spinner />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
-6
@@ -18,12 +18,6 @@
|
||||
transform: $effect;
|
||||
}
|
||||
|
||||
@mixin no-yellow {
|
||||
&:-webkit-autofill {
|
||||
-webkit-box-shadow: 0 0 0 30px white inset;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin blurred-image {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
||||
Reference in New Issue
Block a user