mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-19 00:22:15 +00:00
vue frontend update
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div class="action-button">
|
||||
<FontAwesomeIcon class="icon" :icon="icon" />
|
||||
<span class="label">
|
||||
<slot></slot>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ActionButton',
|
||||
props: ['icon'],
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.action-button {
|
||||
cursor: pointer;
|
||||
|
||||
.label {
|
||||
@include font-size(12);
|
||||
color: $theme_light;
|
||||
font-weight: 600;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@include font-size(10);
|
||||
display: inline-block;
|
||||
margin-right: 2px;
|
||||
|
||||
path {
|
||||
fill: $theme_light;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<div class="inline-wrapper icon-append copy-input" :class="size" @click="copyUrl">
|
||||
<input ref="sel" :value="value" id="link-input" type="text" class="input-text" readonly>
|
||||
<div class="icon">
|
||||
<FontAwesomeIcon :icon="isCopiedLink ? 'check' : 'link'"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'CopyInput',
|
||||
props: ['size', 'value'],
|
||||
data() {
|
||||
return {
|
||||
isCopiedLink: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
copyUrl() {
|
||||
|
||||
// Get input value
|
||||
var copyText = document.getElementById("link-input");
|
||||
|
||||
// select link
|
||||
copyText.select();
|
||||
copyText.setSelectionRange(0, 99999);
|
||||
|
||||
// Copy
|
||||
document.execCommand("copy");
|
||||
|
||||
// Mark button as copied
|
||||
this.isCopiedLink = true
|
||||
|
||||
// Reset copy button
|
||||
setTimeout(() => {this.isCopiedLink = false}, 1000)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@assets/app.scss";
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
|
||||
// Single page
|
||||
.copy-input {
|
||||
|
||||
&.small {
|
||||
|
||||
&.icon-append {
|
||||
|
||||
.icon {
|
||||
padding: 8px 10px;
|
||||
@include font-size(11);
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 6px 10px;
|
||||
@include font-size(13);
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input {
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:disabled {
|
||||
color: $text;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<div class="select">
|
||||
|
||||
<!--Area-->
|
||||
<div class="input-area" :class="{'is-active': isOpen, 'is-error': isError}" @click="openMenu">
|
||||
|
||||
<!--If is selected-->
|
||||
<div class="selected" v-if="selected">
|
||||
<div class="option-icon" v-if="selected.icon">
|
||||
<FontAwesomeIcon :icon="selected.icon" />
|
||||
</div>
|
||||
<span class="option-value">{{ selected.label }}</span>
|
||||
</div>
|
||||
|
||||
<!--If is empty-->
|
||||
<div class="not-selected" v-if="! selected">
|
||||
<span class="option-value placehoder">Selected your permision</span>
|
||||
</div>
|
||||
|
||||
<FontAwesomeIcon icon="chevron-down" class="chevron"/>
|
||||
</div>
|
||||
|
||||
<!--Options-->
|
||||
<transition name="slide-in">
|
||||
<ul class="input-options" v-if="isOpen">
|
||||
<li class="option-item" @click="selectOption(option)" v-for="(option, i) in options" :key="i">
|
||||
<div class="option-icon" v-if="option.icon">
|
||||
<FontAwesomeIcon :icon="option.icon" />
|
||||
</div>
|
||||
<span class="option-value">{{ option.label }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'SelectInput',
|
||||
props: ['options', 'isError', 'default'],
|
||||
data() {
|
||||
return {
|
||||
selected: undefined,
|
||||
isOpen: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectOption(option) {
|
||||
|
||||
// Emit selected
|
||||
this.$emit('input', option.value)
|
||||
|
||||
// Get selected
|
||||
this.selected = option
|
||||
|
||||
// Close menu
|
||||
this.isOpen = false
|
||||
},
|
||||
openMenu() {
|
||||
this.isOpen = ! this.isOpen
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
if (this.default)
|
||||
this.selected = this.options.find(option => option.value === this.default)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.select {
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.input-options {
|
||||
background: $light_background;
|
||||
border-radius: 8px;
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
top: 65px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 9;
|
||||
|
||||
.option-item {
|
||||
padding: 13px 20px;
|
||||
display: block;
|
||||
border-bottom: 1px solid #EBEBEB;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $theme;
|
||||
background: rgba($theme, .1);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-area {
|
||||
justify-content: space-between;
|
||||
background: $light_background;
|
||||
border: 1px solid transparent;
|
||||
@include transition(150ms);
|
||||
align-items: center;
|
||||
border-radius: 8px;
|
||||
padding: 13px 20px;
|
||||
display: flex;
|
||||
outline: 0;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
|
||||
.chevron {
|
||||
@include transition(150ms);
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
border-color: $theme;
|
||||
box-shadow: 0 0 7px rgba($theme, 0.3);
|
||||
|
||||
.chevron {
|
||||
@include transform(rotate(180deg));
|
||||
}
|
||||
}
|
||||
|
||||
&.is-error {
|
||||
border-color: $danger;
|
||||
box-shadow: 0 0 7px rgba($danger, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.option-icon {
|
||||
width: 20px;
|
||||
display: inline-block;
|
||||
@include font-size(12);
|
||||
}
|
||||
|
||||
.option-value {
|
||||
@include font-size(15);
|
||||
font-weight: 700;
|
||||
width: 100%;
|
||||
|
||||
&.placehoder {
|
||||
color: $light_text;
|
||||
}
|
||||
}
|
||||
|
||||
.slide-in-enter-active {
|
||||
transition: all 150ms ease;
|
||||
}
|
||||
|
||||
.slide-in-enter /* .list-leave-active below version 2.1.8 */
|
||||
{
|
||||
opacity: 0;
|
||||
transform: translateY(-50px);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.input-area {
|
||||
background: $dark_mode_foreground;
|
||||
|
||||
.option-icon {
|
||||
path {
|
||||
fill: $theme
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-options {
|
||||
background: $dark_mode_foreground;
|
||||
|
||||
.option-item {
|
||||
border-bottom: none;
|
||||
|
||||
&:hover {
|
||||
color: $theme;
|
||||
background: rgba($theme, .1);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="input-wrapper">
|
||||
<div class="switch-content">
|
||||
<label class="input-label" v-if="label">{{ label }}:</label>
|
||||
<small class="input-info" v-if="info">{{ info }}</small>
|
||||
</div>
|
||||
|
||||
<div class="switch-content text-right">
|
||||
<div
|
||||
class="switch"
|
||||
:class="{ active: isSwitched }"
|
||||
@click="changeState"
|
||||
>
|
||||
<div class="switch-button"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'SwitchInput',
|
||||
props: ['label', 'name', 'state', 'info'],
|
||||
data() {
|
||||
return {
|
||||
isSwitched: undefined
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeState() {
|
||||
|
||||
this.isSwitched = ! this.isSwitched
|
||||
this.$emit('input', this.isSwitched)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.isSwitched = this.state
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.input-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
.input-label {
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.switch-content {
|
||||
width: 100%;
|
||||
|
||||
&:last-child {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.switch {
|
||||
width: 50px;
|
||||
height: 28px;
|
||||
border-radius: 50px;
|
||||
display: block;
|
||||
background: #f1f1f5;
|
||||
position: relative;
|
||||
@include transition;
|
||||
|
||||
.switch-button {
|
||||
@include transition;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50px;
|
||||
display: block;
|
||||
background: white;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
box-shadow: 0 2px 4px rgba(37, 38, 94, 0.1);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: $theme;
|
||||
|
||||
.switch-button {
|
||||
left: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,132 @@
|
||||
<template>
|
||||
<PopupWrapper name="move">
|
||||
<!--Title-->
|
||||
<PopupHeader :title="$t('popup_move_item.title')" />
|
||||
|
||||
<!--Content-->
|
||||
<PopupContent type="height-limited" v-if="app && pickedItem">
|
||||
|
||||
<!--Show Spinner when loading folders-->
|
||||
<Spinner v-if="isLoadingTree"/>
|
||||
|
||||
<!--Folder tree-->
|
||||
<div v-if="! isLoadingTree">
|
||||
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="location"/>
|
||||
<TreeMenu :depth="1" :nodes="items" v-for="items in app.folders" :key="items.unique_id"/>
|
||||
</div>
|
||||
</PopupContent>
|
||||
|
||||
<!--Actions-->
|
||||
<PopupActions>
|
||||
<ButtonBase
|
||||
class="popup-button"
|
||||
@click.native="$closePopup()"
|
||||
button-style="secondary"
|
||||
>{{ $t('popup_move_item.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
class="popup-button"
|
||||
@click.native="moveItem"
|
||||
:button-style="selectedFolder ? 'theme' : 'secondary'"
|
||||
>{{ $t('popup_move_item.submit') }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
</PopupWrapper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PopupWrapper from '@/components/VueFileManagerComponents/Others/Popup/PopupWrapper'
|
||||
import PopupActions from '@/components/VueFileManagerComponents/Others/Popup/PopupActions'
|
||||
import PopupContent from '@/components/VueFileManagerComponents/Others/Popup/PopupContent'
|
||||
import PopupHeader from '@/components/VueFileManagerComponents/Others/Popup/PopupHeader'
|
||||
import ThumbnailItem from '@/components/VueFileManagerComponents/Others/ThumbnailItem'
|
||||
import ButtonBase from '@/components/VueFileManagerComponents/FilesView/ButtonBase'
|
||||
import Spinner from '@/components/VueFileManagerComponents/FilesView/Spinner'
|
||||
import TreeMenu from '@/components/VueFileManagerComponents/Others/TreeMenu'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
|
||||
export default {
|
||||
name: 'MoveItem',
|
||||
components: {
|
||||
ThumbnailItem,
|
||||
PopupWrapper,
|
||||
PopupActions,
|
||||
PopupContent,
|
||||
PopupHeader,
|
||||
ButtonBase,
|
||||
TreeMenu,
|
||||
Spinner,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['app']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedFolder: undefined,
|
||||
pickedItem: undefined,
|
||||
isLoadingTree: true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
moveItem() {
|
||||
|
||||
// Prevent empty submit
|
||||
if (! this.selectedFolder) return
|
||||
|
||||
// Move item
|
||||
this.$store.dispatch('moveItem', [this.pickedItem, this.selectedFolder])
|
||||
|
||||
// Close popup
|
||||
events.$emit('popup:close')
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
// Select folder in tree
|
||||
events.$on('pick-folder', folder => {
|
||||
|
||||
if (folder.unique_id === this.pickedItem.unique_id) {
|
||||
this.selectedFolder = undefined
|
||||
} else {
|
||||
this.selectedFolder = folder
|
||||
}
|
||||
})
|
||||
|
||||
// Show Move item popup
|
||||
events.$on('popup:open', args => {
|
||||
|
||||
if (args.name !== 'move') return
|
||||
|
||||
// Show tree spinner
|
||||
this.isLoadingTree = true
|
||||
|
||||
// Get folder tree and hide spinner
|
||||
this.$store.dispatch('getFolderTree').then(() => {
|
||||
this.isLoadingTree = false
|
||||
})
|
||||
|
||||
// Store picked item
|
||||
this.pickedItem = args.item
|
||||
})
|
||||
|
||||
// Close popup
|
||||
events.$on('popup:close', () => {
|
||||
|
||||
// Clear selected folder
|
||||
setTimeout(() => {
|
||||
this.selectedFolder = undefined
|
||||
}, 150)
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.item-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="actions">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PopupActions',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.actions {
|
||||
padding: 20px;
|
||||
margin: 0 -10px;
|
||||
display: flex;
|
||||
|
||||
.popup-button {
|
||||
width: 100%;
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.small {
|
||||
.actions {
|
||||
padding: 15px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="popup-content" :class="type">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PopupContent',
|
||||
props: [
|
||||
'type'
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.popup-content {
|
||||
|
||||
&.height-limited {
|
||||
height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.small {
|
||||
|
||||
.popup-content {
|
||||
top: 57px;
|
||||
bottom: 72px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: initial;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
}
|
||||
|
||||
@keyframes popup-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes popup-slide-in {
|
||||
0% {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<div class="popup-header">
|
||||
<h1 class="title">{{ title }}</h1>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'PopupHeader',
|
||||
props: [
|
||||
'title'
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.popup-header {
|
||||
padding: 20px;
|
||||
|
||||
.title {
|
||||
@include font-size(18);
|
||||
font-weight: 700;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.message {
|
||||
@include font-size(16);
|
||||
color: #8b8f9a;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.small {
|
||||
.popup-header {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.popup-header {
|
||||
.title {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
|
||||
.message {
|
||||
color: $dark_mode_text_secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<transition name="popup">
|
||||
<div class="popup" @click.self="closePopup" v-show="isVisibleWrapper">
|
||||
<div class="popup-wrapper">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {events} from '@/bus'
|
||||
|
||||
export default {
|
||||
name: 'PopupWrapper',
|
||||
props: [
|
||||
'name'
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
isVisibleWrapper: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closePopup() {
|
||||
events.$emit('popup:close')
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
// Open called popup
|
||||
events.$on('popup:open', ({name}) => {
|
||||
|
||||
if (this.name === name) this.isVisibleWrapper = true
|
||||
})
|
||||
|
||||
// Close popup
|
||||
events.$on('popup:close', () => {
|
||||
|
||||
// Close popup
|
||||
this.isVisibleWrapper = false
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.popup {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 20;
|
||||
overflow-y: auto;
|
||||
display: grid;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.popup-wrapper {
|
||||
box-shadow: $light_mode_popup_shadow;
|
||||
border-radius: 8px;
|
||||
background: white;
|
||||
margin: auto;
|
||||
width: 480px;
|
||||
z-index: 12;
|
||||
}
|
||||
|
||||
// Desktop, tablet
|
||||
.medium, .large {
|
||||
|
||||
// Animations
|
||||
.popup-enter-active {
|
||||
animation: popup-in 0.35s 0.15s ease both;
|
||||
}
|
||||
|
||||
.popup-leave-active {
|
||||
animation: popup-in 0.15s ease reverse;
|
||||
}
|
||||
}
|
||||
|
||||
.small {
|
||||
.popup {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.popup-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
transform: translateY(0) scale(1);
|
||||
box-shadow: none;
|
||||
width: 100%;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
// Animations
|
||||
.popup-enter-active {
|
||||
animation: popup-slide-in 0.35s 0.15s ease both;
|
||||
}
|
||||
|
||||
.popup-leave-active {
|
||||
animation: popup-slide-in 0.15s ease reverse;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes popup-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
@keyframes popup-slide-in {
|
||||
0% {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.popup-wrapper {
|
||||
background: $dark_mode_background;
|
||||
box-shadow: $dark_mode_popup_shadow;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) and (max-width: 690px) {
|
||||
.popup-wrapper {
|
||||
background: $dark_mode_background;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,299 +0,0 @@
|
||||
<template>
|
||||
<transition name="popup">
|
||||
<div class="popup" @click.self="closePopup" v-if="isVisibleWrapper">
|
||||
<div class="popup-wrapper">
|
||||
|
||||
<!--Title-->
|
||||
<div class="popup-header">
|
||||
<h1 class="title">{{ $t('popup_move_item.title') }}</h1>
|
||||
<!--<p v-if="message" class="message">{{ message }}</p>-->
|
||||
</div>
|
||||
|
||||
<!--Content-->
|
||||
<div class="popup-content" v-if="app && pickedItem">
|
||||
<Spinner v-if="isLoadingTree"/>
|
||||
<div v-if="! isLoadingTree">
|
||||
<ThumbnailItem class="item-thumbnail" :file="pickedItem"/>
|
||||
<TreeMenu :depth="1" :nodes="items" v-for="items in app.folders" :key="items.unique_id"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Actions-->
|
||||
<div class="actions">
|
||||
<ButtonBase
|
||||
class="popup-button"
|
||||
@click.native="closePopup"
|
||||
button-style="secondary"
|
||||
>{{ $t('popup_move_item.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
class="popup-button"
|
||||
@click.native="moveItem"
|
||||
:button-style="selectedFolder ? 'theme' : 'secondary'"
|
||||
>{{ $t('popup_move_item.submit') }}
|
||||
</ButtonBase>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ThumbnailItem from '@/components/VueFileManagerComponents/Others/ThumbnailItem'
|
||||
import ButtonBase from '@/components/VueFileManagerComponents/FilesView/ButtonBase'
|
||||
import Spinner from '@/components/VueFileManagerComponents/FilesView/Spinner'
|
||||
import TreeMenu from '@/components/VueFileManagerComponents/Others/TreeMenu'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
|
||||
export default {
|
||||
name: 'PopupMoveItem',
|
||||
components: {
|
||||
ThumbnailItem,
|
||||
ButtonBase,
|
||||
TreeMenu,
|
||||
Spinner,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['app']),
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isVisibleWrapper: false,
|
||||
selectedFolder: undefined,
|
||||
pickedItem: undefined,
|
||||
isLoadingTree: true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
moveItem() {
|
||||
|
||||
// Prevent empty submit
|
||||
if (! this.selectedFolder) return
|
||||
|
||||
// Move item
|
||||
this.$store.dispatch('moveItem', [this.pickedItem, this.selectedFolder])
|
||||
|
||||
// Close popup
|
||||
events.$emit('popup:close')
|
||||
},
|
||||
closePopup() {
|
||||
events.$emit('popup:close')
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
// Select folder in tree
|
||||
events.$on('pick-folder', folder => {
|
||||
|
||||
if (folder.unique_id == this.pickedItem.unique_id) {
|
||||
this.selectedFolder = undefined
|
||||
} else {
|
||||
this.selectedFolder = folder
|
||||
}
|
||||
})
|
||||
|
||||
// Show popup
|
||||
events.$on('popup:move-item', item => {
|
||||
|
||||
// Show tree spinner
|
||||
this.isLoadingTree = true
|
||||
|
||||
// Get folder tree and hide spinner
|
||||
this.$store.dispatch('getFolderTree').then(() => {
|
||||
this.isLoadingTree = false
|
||||
}).catch(() => {
|
||||
this.isLoadingTree = false
|
||||
})
|
||||
|
||||
// Make popup visible
|
||||
this.isVisibleWrapper = true
|
||||
|
||||
// Store picked item
|
||||
this.pickedItem = item
|
||||
})
|
||||
|
||||
// Close popup
|
||||
events.$on('popup:close', () => {
|
||||
|
||||
// Hide popup wrapper
|
||||
this.isVisibleWrapper = false
|
||||
|
||||
// Clear selected folder
|
||||
this.selectedFolder = undefined
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.popup {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 20;
|
||||
overflow-y: auto;
|
||||
display: grid;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.popup-wrapper {
|
||||
box-shadow: $light_mode_popup_shadow;
|
||||
border-radius: 8px;
|
||||
background: white;
|
||||
margin: auto;
|
||||
width: 480px;
|
||||
z-index: 12;
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
padding: 20px;
|
||||
|
||||
.title {
|
||||
@include font-size(18);
|
||||
font-weight: 700;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.message {
|
||||
@include font-size(16);
|
||||
color: #8b8f9a;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.item-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
padding: 20px;
|
||||
margin: 0 -10px;
|
||||
display: flex;
|
||||
|
||||
.popup-button {
|
||||
width: 100%;
|
||||
margin: 0 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// Desktop, tablet
|
||||
.medium, .large {
|
||||
|
||||
// Animations
|
||||
.popup-enter-active {
|
||||
animation: popup-in 0.35s 0.15s ease both;
|
||||
}
|
||||
|
||||
.popup-leave-active {
|
||||
animation: popup-in 0.15s ease reverse;
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile styles
|
||||
.small {
|
||||
|
||||
.popup {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.popup-wrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
transform: translateY(0) scale(1);
|
||||
box-shadow: none;
|
||||
width: 100%;
|
||||
border-radius: 0px;
|
||||
|
||||
.popup-content {
|
||||
top: 57px;
|
||||
bottom: 72px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: initial;
|
||||
}
|
||||
|
||||
.actions {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
// Animations
|
||||
.popup-enter-active {
|
||||
animation: popup-slide-in 0.35s 0.15s ease both;
|
||||
}
|
||||
|
||||
.popup-leave-active {
|
||||
animation: popup-slide-in 0.15s ease reverse;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes popup-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes popup-slide-in {
|
||||
0% {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Dark mode
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.popup-wrapper {
|
||||
background: $dark_mode_background;
|
||||
box-shadow: $dark_mode_popup_shadow;
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
.title {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
|
||||
.message {
|
||||
color: $dark_mode_text_secondary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) and (max-width: 690px) {
|
||||
.popup-wrapper {
|
||||
background: $dark_mode_background;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<PopupWrapper name="share-create">
|
||||
<!--Title-->
|
||||
<PopupHeader :title="'Share Your ' + itemTypeTitle" />
|
||||
|
||||
<!--Content-->
|
||||
<PopupContent>
|
||||
|
||||
<!--Item Thumbnail-->
|
||||
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="metadata"/>
|
||||
|
||||
<!--Form to set sharing-->
|
||||
<ValidationObserver v-if="! isGeneratedShared" ref="shareForm" v-slot="{ invalid }" tag="form" class="form-wrapper">
|
||||
|
||||
<!--Permision Select-->
|
||||
<ValidationProvider v-if="isFolder" tag="div" mode="passive" class="input-wrapper" name="Permission" rules="required" v-slot="{ errors }">
|
||||
<label class="input-label">Permission:</label>
|
||||
<SelectInput v-model="shareOptions.permission" :options="permissionOptions" :isError="errors[0]"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
|
||||
<!--Password Switch-->
|
||||
<div class="input-wrapper">
|
||||
<div class="inline-wrapper">
|
||||
<label class="input-label">Password Protected:</label>
|
||||
<SwitchInput v-model="shareOptions.isPassword" class="switch" :state="0"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Set password-->
|
||||
<ValidationProvider v-if="shareOptions.isPassword" tag="div" mode="passive" class="input-wrapper password" name="Password" rules="required" v-slot="{ errors }">
|
||||
<input v-model="shareOptions.password" :class="{'is-error': errors[0]}" type="text" placeholder="Type your password">
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
</ValidationObserver>
|
||||
|
||||
<!--Copy generated link-->
|
||||
<div v-if="isGeneratedShared" class="form-wrapper">
|
||||
<div class="input-wrapper">
|
||||
<label class="input-label">Share url:</label>
|
||||
<CopyInput size="small" :value="shareLink" />
|
||||
</div>
|
||||
</div>
|
||||
</PopupContent>
|
||||
|
||||
<!--Actions-->
|
||||
<PopupActions>
|
||||
<ButtonBase
|
||||
v-if="! isGeneratedShared"
|
||||
class="popup-button"
|
||||
@click.native="$closePopup()"
|
||||
button-style="secondary"
|
||||
>{{ $t('popup_move_item.cancel') }}
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
class="popup-button"
|
||||
@click.native="submitShareOptions"
|
||||
button-style="theme"
|
||||
:loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
>{{ submitButtonText }}
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
</PopupWrapper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PopupWrapper from '@/components/VueFileManagerComponents/Others/Popup/PopupWrapper'
|
||||
import PopupActions from '@/components/VueFileManagerComponents/Others/Popup/PopupActions'
|
||||
import PopupContent from '@/components/VueFileManagerComponents/Others/Popup/PopupContent'
|
||||
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
|
||||
import PopupHeader from '@/components/VueFileManagerComponents/Others/Popup/PopupHeader'
|
||||
import SwitchInput from '@/components/VueFileManagerComponents/Others/Forms/SwitchInput'
|
||||
import SelectInput from '@/components/VueFileManagerComponents/Others/Forms/SelectInput'
|
||||
import ThumbnailItem from '@/components/VueFileManagerComponents/Others/ThumbnailItem'
|
||||
import CopyInput from '@/components/VueFileManagerComponents/Others/Forms/CopyInput'
|
||||
import ButtonBase from '@/components/VueFileManagerComponents/FilesView/ButtonBase'
|
||||
import {required} from 'vee-validate/dist/rules'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
name: 'ShareCreate',
|
||||
components: {
|
||||
ValidationProvider,
|
||||
ValidationObserver,
|
||||
ThumbnailItem,
|
||||
PopupWrapper,
|
||||
PopupActions,
|
||||
PopupContent,
|
||||
PopupHeader,
|
||||
SelectInput,
|
||||
SwitchInput,
|
||||
ButtonBase,
|
||||
CopyInput,
|
||||
required,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['app']),
|
||||
itemTypeTitle() {
|
||||
return this.pickedItem && this.pickedItem.type === 'folder' ? 'Folder' : 'File'
|
||||
},
|
||||
isFolder() {
|
||||
return this.pickedItem && this.pickedItem.type === 'folder'
|
||||
},
|
||||
submitButtonText() {
|
||||
return this.isGeneratedShared ? 'Awesome, I’m done!' : 'Generate Link'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shareOptions: {
|
||||
isPassword: false,
|
||||
password: undefined,
|
||||
permission: undefined,
|
||||
},
|
||||
permissionOptions: [
|
||||
{
|
||||
label: 'Can edit and upload files',
|
||||
value: 'editor',
|
||||
icon: 'user-edit',
|
||||
},
|
||||
{
|
||||
label: 'Can only view and download',
|
||||
value: 'visitor',
|
||||
icon: 'user',
|
||||
},
|
||||
],
|
||||
pickedItem: undefined,
|
||||
shareLink: undefined,
|
||||
isGeneratedShared: false,
|
||||
isLoading: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async submitShareOptions() {
|
||||
|
||||
// If shared was generated, then close popup
|
||||
if (this.isGeneratedShared) {
|
||||
events.$emit('popup:close')
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate fields
|
||||
const isValid = await this.$refs.shareForm.validate();
|
||||
|
||||
if (!isValid) return;
|
||||
|
||||
this.isLoading = true
|
||||
|
||||
// Send request to get share link
|
||||
axios
|
||||
.post('/api/share/generate', this.shareOptions)
|
||||
.then(response => {
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
|
||||
this.shareLink = response.data
|
||||
this.isGeneratedShared = true
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
// todo: catch errors
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
// Show popup
|
||||
events.$on('popup:open', args => {
|
||||
|
||||
if (args.name !== 'share-create') return
|
||||
|
||||
// Store picked item
|
||||
this.pickedItem = args.item
|
||||
})
|
||||
|
||||
// Close popup
|
||||
events.$on('popup:close', () => {
|
||||
|
||||
// Restore data
|
||||
setTimeout(() => {
|
||||
this.isGeneratedShared = false
|
||||
this.shareLink = undefined
|
||||
this.shareOptions = {
|
||||
permission: undefined,
|
||||
password: undefined,
|
||||
isPassword: false,
|
||||
}
|
||||
}, 150)
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/app.scss";
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
|
||||
.input-wrapper {
|
||||
|
||||
&.password {
|
||||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,237 @@
|
||||
<template>
|
||||
<PopupWrapper name="share-edit">
|
||||
<!--Title-->
|
||||
<PopupHeader title="Update sharing options" />
|
||||
|
||||
<!--Content-->
|
||||
<PopupContent>
|
||||
|
||||
<!--Item Thumbnail-->
|
||||
<ThumbnailItem class="item-thumbnail" :item="pickedItem" info="metadata"/>
|
||||
|
||||
<!--Form to set sharing-->
|
||||
<ValidationObserver ref="shareForm" v-slot="{ invalid }" tag="form" class="form-wrapper">
|
||||
|
||||
<!--Share link-->
|
||||
<div class="input-wrapper">
|
||||
<label class="input-label">Share url:</label>
|
||||
<CopyInput size="small" :value="shareLink" />
|
||||
</div>
|
||||
|
||||
<!--Permision Select-->
|
||||
<ValidationProvider v-if="isFolder" tag="div" mode="passive" class="input-wrapper" name="Permission" rules="required" v-slot="{ errors }">
|
||||
<label class="input-label">Permission:</label>
|
||||
<SelectInput v-model="shareOptions.permission" :options="permissionOptions" default="visitor" :isError="errors[0]"/>
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
|
||||
<!--Password Switch-->
|
||||
<div class="input-wrapper">
|
||||
<div class="inline-wrapper">
|
||||
<label class="input-label">Password Protected:</label>
|
||||
<SwitchInput v-model="shareOptions.isPassword" class="switch" :state="0"/>
|
||||
</div>
|
||||
<ActionButton @click.native="changePassword" v-if="isPasswordChangeButton" icon="pencil-alt">Change Password</ActionButton>
|
||||
</div>
|
||||
|
||||
<!--Set password-->
|
||||
<ValidationProvider v-if="isPasswordInput || shareOptions.isPassword" tag="div" mode="passive" class="input-wrapper password" name="Password" rules="required" v-slot="{ errors }">
|
||||
<input v-model="shareOptions.password" :class="{'is-error': errors[0]}" type="text" placeholder="Type your password">
|
||||
<span class="error-message" v-if="errors[0]">{{ errors[0] }}</span>
|
||||
</ValidationProvider>
|
||||
|
||||
</ValidationObserver>
|
||||
|
||||
</PopupContent>
|
||||
|
||||
<!--Actions-->
|
||||
<PopupActions>
|
||||
<ButtonBase
|
||||
class="popup-button"
|
||||
@click.native="destroySharing"
|
||||
:button-style="destroyButtonStyle"
|
||||
>{{ destroyButtonText }}
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
class="popup-button"
|
||||
@click.native="submitShareOptions"
|
||||
button-style="theme"
|
||||
:loading="isLoading"
|
||||
:disabled="isLoading"
|
||||
>Save Changes
|
||||
</ButtonBase>
|
||||
</PopupActions>
|
||||
</PopupWrapper>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PopupWrapper from '@/components/VueFileManagerComponents/Others/Popup/PopupWrapper'
|
||||
import PopupActions from '@/components/VueFileManagerComponents/Others/Popup/PopupActions'
|
||||
import PopupContent from '@/components/VueFileManagerComponents/Others/Popup/PopupContent'
|
||||
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
|
||||
import PopupHeader from '@/components/VueFileManagerComponents/Others/Popup/PopupHeader'
|
||||
import SwitchInput from '@/components/VueFileManagerComponents/Others/Forms/SwitchInput'
|
||||
import SelectInput from '@/components/VueFileManagerComponents/Others/Forms/SelectInput'
|
||||
import ThumbnailItem from '@/components/VueFileManagerComponents/Others/ThumbnailItem'
|
||||
import ActionButton from '@/components/VueFileManagerComponents/Others/ActionButton'
|
||||
import CopyInput from '@/components/VueFileManagerComponents/Others/Forms/CopyInput'
|
||||
import ButtonBase from '@/components/VueFileManagerComponents/FilesView/ButtonBase'
|
||||
import {required} from 'vee-validate/dist/rules'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
name: 'ShareEdit',
|
||||
components: {
|
||||
ValidationProvider,
|
||||
ValidationObserver,
|
||||
ThumbnailItem,
|
||||
ActionButton,
|
||||
PopupWrapper,
|
||||
PopupActions,
|
||||
PopupContent,
|
||||
PopupHeader,
|
||||
SelectInput,
|
||||
SwitchInput,
|
||||
ButtonBase,
|
||||
CopyInput,
|
||||
required,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['app']),
|
||||
isFolder() {
|
||||
return this.pickedItem && this.pickedItem.type === 'folder'
|
||||
},
|
||||
destroyButtonText() {
|
||||
return this.isConfirmedDestroy ? 'Confirm' : 'Stop Sharing'
|
||||
},
|
||||
destroyButtonStyle() {
|
||||
return this.isConfirmedDestroy ? 'danger-solid' : 'secondary'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shareOptions: {
|
||||
isPassword: false,
|
||||
password: undefined,
|
||||
permission: undefined,
|
||||
},
|
||||
permissionOptions: [
|
||||
{
|
||||
label: 'Can edit and upload files',
|
||||
value: 'editor',
|
||||
icon: 'user-edit',
|
||||
},
|
||||
{
|
||||
label: 'Can only view and download',
|
||||
value: 'visitor',
|
||||
icon: 'user',
|
||||
},
|
||||
],
|
||||
pickedItem: undefined,
|
||||
isLoading: false,
|
||||
isPasswordInput: false,
|
||||
isPasswordChangeButton: true,
|
||||
isConfirmedDestroy: false,
|
||||
shareLink: 'http://192.168.1.131:8000/shared?token=3ZlQLIoCR8izoc0PemekHNq3UIMj6OrC0aQ2zowclfjFYa8P6go8fMKPnXTJomvz'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changePassword() {
|
||||
this.isPasswordInput = true
|
||||
this.isPasswordChangeButton = false
|
||||
},
|
||||
destroySharing() {
|
||||
|
||||
if (! this.isConfirmedDestroy) {
|
||||
this.isConfirmedDestroy = true
|
||||
|
||||
return
|
||||
} else {
|
||||
|
||||
this.$closePopup()
|
||||
}
|
||||
},
|
||||
async submitShareOptions() {
|
||||
|
||||
// If shared was generated, then close popup
|
||||
if (this.isGeneratedShared) {
|
||||
events.$emit('popup:close')
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate fields
|
||||
const isValid = await this.$refs.shareForm.validate();
|
||||
|
||||
if (!isValid) return;
|
||||
|
||||
this.isLoading = true
|
||||
|
||||
// Send request to get share link
|
||||
axios
|
||||
.post('/api/share/generate', this.shareOptions)
|
||||
.then(response => {
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
|
||||
this.shareLink = response.data
|
||||
this.isGeneratedShared = true
|
||||
})
|
||||
.catch(error => {
|
||||
|
||||
// todo: catch errors
|
||||
|
||||
// End loading
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
||||
// Show popup
|
||||
events.$on('popup:open', args => {
|
||||
|
||||
if (args.name !== 'share-edit') return
|
||||
|
||||
// Store picked item
|
||||
this.pickedItem = args.item
|
||||
})
|
||||
|
||||
// Close popup
|
||||
events.$on('popup:close', () => {
|
||||
|
||||
// Restore data
|
||||
setTimeout(() => {
|
||||
this.isConfirmedDestroy = false
|
||||
this.isPasswordInput = false
|
||||
this.isPasswordChangeButton = true
|
||||
//this.shareLink = undefined
|
||||
this.shareOptions = {
|
||||
permission: undefined,
|
||||
password: undefined,
|
||||
isPassword: false,
|
||||
}
|
||||
}, 150)
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/app.scss";
|
||||
@import "@assets/vue-file-manager/_inapp-forms.scss";
|
||||
|
||||
.input-wrapper {
|
||||
|
||||
&.password {
|
||||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-thumbnail {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.text-label {
|
||||
color: rgba($dark_mode_text_secondary, .4);
|
||||
color: $theme;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<template>
|
||||
<div class="file-item">
|
||||
<div class="file-item" v-if="item">
|
||||
|
||||
<!--Thumbnail for item-->
|
||||
<div class="icon-item">
|
||||
|
||||
<!--If is file or image, then link item-->
|
||||
<span v-if="isFile" class="file-icon-text">{{ file.mimetype }}</span>
|
||||
<span v-if="isFile" class="file-icon-text">{{ item.mimetype }}</span>
|
||||
|
||||
<!--Folder thumbnail-->
|
||||
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file"/>
|
||||
|
||||
<!--Image thumbnail-->
|
||||
<img v-if="isImage" class="image" :src="file.thumbnail" :alt="file.name"/>
|
||||
<img v-if="isImage" class="image" :src="item.thumbnail" :alt="item.name"/>
|
||||
|
||||
<!--Else show only folder icon-->
|
||||
<FontAwesomeIcon v-if="isFolder" class="folder-icon" icon="folder"/>
|
||||
@@ -21,10 +21,20 @@
|
||||
<div class="item-name">
|
||||
|
||||
<!--Name-->
|
||||
<span class="name">{{ file.name }}</span>
|
||||
<span class="name">{{ item.name }}</span>
|
||||
|
||||
<div v-if="info === 'location'">
|
||||
<span class="subtitle">{{ $t('item_thumbnail.original_location') }}: {{ currentFolder.name }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="info === 'metadata'">
|
||||
<span v-if="! isFolder" class="item-size">{{ item.filesize }}, {{ item.created_at }}</span>
|
||||
|
||||
<span v-if="isFolder" class="item-length">
|
||||
{{ item.items == 0 ? $t('folder.empty') : $tc('folder.item_counts', item.items) }}, {{ item.created_at }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!--Other attributes-->
|
||||
<span class="subtitle">{{ $t('item_thumbnail.original_location') }}: {{ currentFolder.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -34,18 +44,18 @@
|
||||
|
||||
export default {
|
||||
name: 'ThumbnailItem',
|
||||
props: ['file'],
|
||||
props: ['item', 'info'],
|
||||
computed: {
|
||||
...mapGetters(['currentFolder']),
|
||||
isFolder() {
|
||||
return this.file.type === 'folder'
|
||||
return this.item.type === 'folder'
|
||||
},
|
||||
isFile() {
|
||||
return this.file.type !== 'folder' && this.file.type !== 'image'
|
||||
return this.item.type !== 'folder' && this.item.type !== 'image'
|
||||
},
|
||||
isImage() {
|
||||
return this.file.type === 'image'
|
||||
}
|
||||
return this.item.type === 'image'
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -66,6 +76,14 @@
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
.item-size,
|
||||
.item-length {
|
||||
@include font-size(12);
|
||||
font-weight: 400;
|
||||
color: $text-muted;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
@include font-size(11);
|
||||
font-weight: 400;
|
||||
@@ -141,7 +159,7 @@
|
||||
.small {
|
||||
.file-item {
|
||||
padding: 0 15px;
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
events.$on('popup:close', () => this.isVisibleVignette = false)
|
||||
|
||||
// Show vignette
|
||||
events.$on('popup:move-item', () => this.isVisibleVignette = true)
|
||||
events.$on('popup:open', () => this.isVisibleVignette = true)
|
||||
events.$on('alert:open', () => this.isVisibleVignette = true)
|
||||
events.$on('success:open', () => this.isVisibleVignette = true)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user