mirror of
https://github.com/filebrowser/filebrowser.git
synced 2024-06-07 23:00:43 +00:00
chore: breadcrumbs component
This commit is contained in:
parent
7b6579ac8a
commit
d8306559fd
@ -69,13 +69,16 @@ nav > div {
|
|||||||
border-color: var(--divider);
|
border-color: var(--divider);
|
||||||
}
|
}
|
||||||
|
|
||||||
#breadcrumbs {
|
.breadcrumbs {
|
||||||
border-color: var(--divider);
|
border-color: var(--divider);
|
||||||
color: var(--textPrimary) !important;
|
color: var(--textPrimary) !important;
|
||||||
}
|
}
|
||||||
#breadcrumbs span {
|
.breadcrumbs span {
|
||||||
color: var(--textPrimary) !important;
|
color: var(--textPrimary) !important;
|
||||||
}
|
}
|
||||||
|
.breadcrumbs a:hover {
|
||||||
|
background-color: rgba(255, 255, 255, .1);
|
||||||
|
}
|
||||||
|
|
||||||
#listing .item {
|
#listing .item {
|
||||||
background: var(--surfacePrimary);
|
background: var(--surfacePrimary);
|
||||||
|
67
frontend/src/components/Breadcrumbs.vue
Normal file
67
frontend/src/components/Breadcrumbs.vue
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<div class="breadcrumbs">
|
||||||
|
<component :is="element" :to="base || ''" :aria-label="$t('files.home')" :title="$t('files.home')">
|
||||||
|
<i class="material-icons">home</i>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<span v-for="(link, index) in items" :key="index">
|
||||||
|
<span class="chevron"><i class="material-icons">keyboard_arrow_right</i></span>
|
||||||
|
<component :is="element" :to="link.url">{{ link.name }}</component>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'breadcrumbs',
|
||||||
|
props: [
|
||||||
|
'base',
|
||||||
|
'noLink'
|
||||||
|
],
|
||||||
|
computed: {
|
||||||
|
items () {
|
||||||
|
const relativePath = this.$route.path.replace(this.base, '')
|
||||||
|
let parts = relativePath.split('/')
|
||||||
|
|
||||||
|
if (parts[0] === '') {
|
||||||
|
parts.shift()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parts[parts.length - 1] === '') {
|
||||||
|
parts.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
let breadcrumbs = []
|
||||||
|
|
||||||
|
for (let i = 0; i < parts.length; i++) {
|
||||||
|
if (i === 0) {
|
||||||
|
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: this.base + '/' + parts[i] + '/' })
|
||||||
|
} else {
|
||||||
|
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: breadcrumbs[i - 1].url + parts[i] + '/' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (breadcrumbs.length > 3) {
|
||||||
|
while (breadcrumbs.length !== 4) {
|
||||||
|
breadcrumbs.shift()
|
||||||
|
}
|
||||||
|
|
||||||
|
breadcrumbs[0].name = '...'
|
||||||
|
}
|
||||||
|
|
||||||
|
return breadcrumbs
|
||||||
|
},
|
||||||
|
element () {
|
||||||
|
if (this.noLink !== undefined) {
|
||||||
|
return 'span'
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'router-link'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
@ -83,29 +83,29 @@ main {
|
|||||||
width: calc(100% - 19em);
|
width: calc(100% - 19em);
|
||||||
}
|
}
|
||||||
|
|
||||||
#breadcrumbs {
|
.breadcrumbs {
|
||||||
height: 3em;
|
height: 3em;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
#breadcrumbs span,
|
.breadcrumbs span,
|
||||||
#breadcrumbs {
|
.breadcrumbs {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #6f6f6f;
|
color: #6f6f6f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#breadcrumbs a {
|
.breadcrumbs a {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
transition: .1s ease-in;
|
transition: .1s ease-in;
|
||||||
border-radius: .125em;
|
border-radius: .125em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#breadcrumbs a:hover {
|
.breadcrumbs a:hover {
|
||||||
background-color: rgba(0,0,0, 0.05);
|
background-color: rgba(0,0,0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
#breadcrumbs span a {
|
.breadcrumbs span a {
|
||||||
padding: .2em;
|
padding: .2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,15 +220,19 @@
|
|||||||
height: calc(100vh - 8.4em);
|
height: calc(100vh - 8.4em);
|
||||||
}
|
}
|
||||||
|
|
||||||
#editor-container #breadcrumbs {
|
#editor-container .breadcrumbs {
|
||||||
height: 2.3em;
|
height: 2.3em;
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#editor-container #breadcrumbs span {
|
#editor-container .breadcrumbs span {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#editor-container .breadcrumbs i {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * *
|
||||||
* PROMPT *
|
* PROMPT *
|
||||||
* * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * */
|
||||||
|
@ -2,16 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<header-bar v-if="error || !req.type" showMenu showLogo />
|
<header-bar v-if="error || !req.type" showMenu showLogo />
|
||||||
|
|
||||||
<div id="breadcrumbs">
|
<breadcrumbs base="/files" />
|
||||||
<router-link to="/files/" :aria-label="$t('files.home')" :title="$t('files.home')">
|
|
||||||
<i class="material-icons">home</i>
|
|
||||||
</router-link>
|
|
||||||
|
|
||||||
<span v-for="(link, index) in breadcrumbs" :key="index">
|
|
||||||
<span class="chevron"><i class="material-icons">keyboard_arrow_right</i></span>
|
|
||||||
<router-link :to="link.url">{{ link.name }}</router-link>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<errors v-if="error" :errorCode="errorCode" />
|
<errors v-if="error" :errorCode="errorCode" />
|
||||||
<component v-else-if="currentView" :is="currentView"></component>
|
<component v-else-if="currentView" :is="currentView"></component>
|
||||||
@ -28,6 +19,7 @@ import { files as api } from '@/api'
|
|||||||
import { mapState, mapMutations } from 'vuex'
|
import { mapState, mapMutations } from 'vuex'
|
||||||
|
|
||||||
import HeaderBar from '@/components/header/HeaderBar'
|
import HeaderBar from '@/components/header/HeaderBar'
|
||||||
|
import Breadcrumbs from '@/components/Breadcrumbs'
|
||||||
import Errors from '@/views/Errors'
|
import Errors from '@/views/Errors'
|
||||||
import Preview from '@/views/files/Preview'
|
import Preview from '@/views/files/Preview'
|
||||||
import Listing from '@/views/files/Listing'
|
import Listing from '@/views/files/Listing'
|
||||||
@ -40,6 +32,7 @@ export default {
|
|||||||
name: 'files',
|
name: 'files',
|
||||||
components: {
|
components: {
|
||||||
HeaderBar,
|
HeaderBar,
|
||||||
|
Breadcrumbs,
|
||||||
Errors,
|
Errors,
|
||||||
Preview,
|
Preview,
|
||||||
Listing,
|
Listing,
|
||||||
@ -71,39 +64,6 @@ export default {
|
|||||||
return 'preview'
|
return 'preview'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
breadcrumbs () {
|
|
||||||
let parts = this.$route.path.split('/')
|
|
||||||
|
|
||||||
if (parts[0] === '') {
|
|
||||||
parts.shift()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parts[parts.length - 1] === '') {
|
|
||||||
parts.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let breadcrumbs = []
|
|
||||||
|
|
||||||
for (let i = 0; i < parts.length; i++) {
|
|
||||||
if (i === 0) {
|
|
||||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: '/' + parts[i] + '/' })
|
|
||||||
} else {
|
|
||||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: breadcrumbs[i - 1].url + parts[i] + '/' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
breadcrumbs.shift()
|
|
||||||
|
|
||||||
if (breadcrumbs.length > 3) {
|
|
||||||
while (breadcrumbs.length !== 4) {
|
|
||||||
breadcrumbs.shift()
|
|
||||||
}
|
|
||||||
|
|
||||||
breadcrumbs[0].name = '...'
|
|
||||||
}
|
|
||||||
|
|
||||||
return breadcrumbs
|
|
||||||
},
|
|
||||||
errorCode() {
|
errorCode() {
|
||||||
return (this.error.message === '404' || this.error.message === '403') ? parseInt(this.error.message) : 500
|
return (this.error.message === '404' || this.error.message === '403') ? parseInt(this.error.message) : 500
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,9 @@
|
|||||||
<action icon="check_circle" :label="$t('buttons.selectMultiple')" @action="toggleMultipleSelection" />
|
<action icon="check_circle" :label="$t('buttons.selectMultiple')" @action="toggleMultipleSelection" />
|
||||||
</header-bar>
|
</header-bar>
|
||||||
|
|
||||||
<div v-if="!loading">
|
<breadcrumbs :base="'/share/' + hash" />
|
||||||
<div id="breadcrumbs">
|
|
||||||
<router-link :to="'/share/' + hash" :aria-label="$t('files.home')" :title="$t('files.home')">
|
|
||||||
<i class="material-icons">home</i>
|
|
||||||
</router-link>
|
|
||||||
|
|
||||||
<span v-for="(link, index) in breadcrumbs" :key="index">
|
<div v-if="!loading">
|
||||||
<span class="chevron"><i class="material-icons">keyboard_arrow_right</i></span>
|
|
||||||
<router-link :to="link.url">{{ link.name }}</router-link>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="share">
|
<div class="share">
|
||||||
<div class="share__box share__box__info">
|
<div class="share__box share__box__info">
|
||||||
<div class="share__box__header">
|
<div class="share__box__header">
|
||||||
@ -112,6 +104,7 @@ import moment from 'moment'
|
|||||||
|
|
||||||
import HeaderBar from '@/components/header/HeaderBar'
|
import HeaderBar from '@/components/header/HeaderBar'
|
||||||
import Action from '@/components/header/Action'
|
import Action from '@/components/header/Action'
|
||||||
|
import Breadcrumbs from '@/components/Breadcrumbs'
|
||||||
import Errors from '@/views/Errors'
|
import Errors from '@/views/Errors'
|
||||||
import QrcodeVue from 'qrcode.vue'
|
import QrcodeVue from 'qrcode.vue'
|
||||||
import Item from "@/components/files/ListingItem"
|
import Item from "@/components/files/ListingItem"
|
||||||
@ -121,6 +114,7 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
HeaderBar,
|
HeaderBar,
|
||||||
Action,
|
Action,
|
||||||
|
Breadcrumbs,
|
||||||
Item,
|
Item,
|
||||||
QrcodeVue,
|
QrcodeVue,
|
||||||
Errors
|
Errors
|
||||||
@ -176,37 +170,6 @@ export default {
|
|||||||
humanTime: function () {
|
humanTime: function () {
|
||||||
return moment(this.req.modified).fromNow()
|
return moment(this.req.modified).fromNow()
|
||||||
},
|
},
|
||||||
breadcrumbs () {
|
|
||||||
let parts = this.path.split('/')
|
|
||||||
|
|
||||||
if (parts[0] === '') {
|
|
||||||
parts.shift()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parts[parts.length - 1] === '') {
|
|
||||||
parts.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
let breadcrumbs = []
|
|
||||||
|
|
||||||
for (let i = 0; i < parts.length; i++) {
|
|
||||||
if (i === 0) {
|
|
||||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: '/share/' + this.hash + '/' + parts[i] + '/' })
|
|
||||||
} else {
|
|
||||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: breadcrumbs[i - 1].url + parts[i] + '/' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (breadcrumbs.length > 3) {
|
|
||||||
while (breadcrumbs.length !== 4) {
|
|
||||||
breadcrumbs.shift()
|
|
||||||
}
|
|
||||||
|
|
||||||
breadcrumbs[0].name = '...'
|
|
||||||
}
|
|
||||||
|
|
||||||
return breadcrumbs
|
|
||||||
},
|
|
||||||
errorCode() {
|
errorCode() {
|
||||||
return (this.error.message === '404' || this.error.message === '403') ? parseInt(this.error.message) : 500
|
return (this.error.message === '404' || this.error.message === '403') ? parseInt(this.error.message) : 500
|
||||||
}
|
}
|
||||||
@ -233,6 +196,8 @@ export default {
|
|||||||
}
|
}
|
||||||
let file = await api.getHash(encodeURIComponent(this.$route.params.pathMatch), this.password)
|
let file = await api.getHash(encodeURIComponent(this.$route.params.pathMatch), this.password)
|
||||||
this.path = file.path
|
this.path = file.path
|
||||||
|
if (this.path.endsWith('/')) this.path = this.path.slice(0, -1)
|
||||||
|
|
||||||
this.token = file.token || ''
|
this.token = file.token || ''
|
||||||
this.$store.commit('setToken', this.token)
|
this.$store.commit('setToken', this.token)
|
||||||
if (file.isDir) file.items = file.items.map((item, index) => {
|
if (file.isDir) file.items = file.items.map((item, index) => {
|
||||||
|
@ -9,14 +9,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</header-bar>
|
</header-bar>
|
||||||
|
|
||||||
<div id="breadcrumbs">
|
<breadcrumbs base="/files" noLink />
|
||||||
<span><i class="material-icons">home</i></span>
|
|
||||||
|
|
||||||
<span v-for="(link, index) in breadcrumbs" :key="index">
|
|
||||||
<span class="chevron"><i class="material-icons">keyboard_arrow_right</i></span>
|
|
||||||
<span>{{ link.name }}</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form id="editor"></form>
|
<form id="editor"></form>
|
||||||
</div>
|
</div>
|
||||||
@ -35,12 +28,14 @@ import 'ace-builds/webpack-resolver'
|
|||||||
|
|
||||||
import HeaderBar from '@/components/header/HeaderBar'
|
import HeaderBar from '@/components/header/HeaderBar'
|
||||||
import Action from '@/components/header/Action'
|
import Action from '@/components/header/Action'
|
||||||
|
import Breadcrumbs from '@/components/Breadcrumbs'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'editor',
|
name: 'editor',
|
||||||
components: {
|
components: {
|
||||||
HeaderBar,
|
HeaderBar,
|
||||||
Action
|
Action,
|
||||||
|
Breadcrumbs
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {}
|
return {}
|
||||||
|
Loading…
Reference in New Issue
Block a user