mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 15:36:49 +08:00
fix aliyunpan
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { Axios } from 'axios'
|
import type { Axios } from 'axios'
|
||||||
import axios from 'axios'
|
|
||||||
import FileList from './filebrowser/FileList.vue'
|
import FileList from './filebrowser/FileList.vue'
|
||||||
import FileToolbar from './filebrowser/FileToolbar.vue'
|
import FileToolbar from './filebrowser/FileToolbar.vue'
|
||||||
import type { EndPoints } from '@/api/types'
|
import type { EndPoints, FileItem } from '@/api/types'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import AliyunAuthDialog from './dialog/AliyunAuthDialog.vue'
|
import AliyunAuthDialog from './dialog/AliyunAuthDialog.vue'
|
||||||
import { isNullOrEmptyObject } from '@/@core/utils'
|
import { isNullOrEmptyObject } from '@/@core/utils'
|
||||||
@@ -11,8 +10,9 @@ import { isNullOrEmptyObject } from '@/@core/utils'
|
|||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
storages: String,
|
storages: String,
|
||||||
storage: String,
|
|
||||||
path: String,
|
path: String,
|
||||||
|
fileid: String,
|
||||||
|
fileidstack: Array as PropType<string[]>,
|
||||||
tree: Boolean,
|
tree: Boolean,
|
||||||
endpoints: Object as PropType<EndPoints>,
|
endpoints: Object as PropType<EndPoints>,
|
||||||
axios: Object as PropType<Axios>,
|
axios: Object as PropType<Axios>,
|
||||||
@@ -65,8 +65,6 @@ const activeStorage = ref('local')
|
|||||||
const refreshPending = ref(false)
|
const refreshPending = ref(false)
|
||||||
// 排序
|
// 排序
|
||||||
const sort = ref('name')
|
const sort = ref('name')
|
||||||
// axios实例
|
|
||||||
const axiosInstance = ref<Axios>()
|
|
||||||
// 阿里云盘认证对话框
|
// 阿里云盘认证对话框
|
||||||
const aliyunAuthDialog = ref(false)
|
const aliyunAuthDialog = ref(false)
|
||||||
// 阿里云盘认证参数
|
// 阿里云盘认证参数
|
||||||
@@ -109,8 +107,8 @@ async function storageChanged(storage: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 路径变化
|
// 路径变化
|
||||||
function pathChanged(_path: string) {
|
function pathChanged(item: FileItem) {
|
||||||
emit('pathchanged', _path)
|
emit('pathchanged', item)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 排序变化
|
// 排序变化
|
||||||
@@ -124,23 +122,19 @@ function aliyunAuthDone() {
|
|||||||
aliyunAuthDialog.value = false
|
aliyunAuthDialog.value = false
|
||||||
activeStorage.value = 'aliyun'
|
activeStorage.value = 'aliyun'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化
|
|
||||||
onMounted(() => {
|
|
||||||
activeStorage.value = props.storage ?? 'local'
|
|
||||||
axiosInstance.value = props.axios ?? axios.create(props.axiosconfig)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VCard class="mx-auto" :loading="loading > 0 || !path">
|
<VCard class="mx-auto" :loading="loading > 0">
|
||||||
<div v-if="path">
|
<div v-if="path || fileid">
|
||||||
<FileToolbar
|
<FileToolbar
|
||||||
:path="path"
|
:path="path"
|
||||||
|
:fileid="fileid"
|
||||||
|
:fileidstack="fileidstack"
|
||||||
:storages="storagesArray"
|
:storages="storagesArray"
|
||||||
:storage="activeStorage"
|
:storage="activeStorage"
|
||||||
:endpoints="endpoints"
|
:endpoints="endpoints"
|
||||||
:axios="axiosInstance"
|
:axios="axios"
|
||||||
@storagechanged="storageChanged"
|
@storagechanged="storageChanged"
|
||||||
@pathchanged="pathChanged"
|
@pathchanged="pathChanged"
|
||||||
@foldercreated="refreshPending = true"
|
@foldercreated="refreshPending = true"
|
||||||
@@ -148,10 +142,11 @@ onMounted(() => {
|
|||||||
/>
|
/>
|
||||||
<FileList
|
<FileList
|
||||||
:path="path"
|
:path="path"
|
||||||
|
:fileid="fileid"
|
||||||
:storage="activeStorage"
|
:storage="activeStorage"
|
||||||
:icons="fileIcons"
|
:icons="fileIcons"
|
||||||
:endpoints="endpoints"
|
:endpoints="endpoints"
|
||||||
:axios="axiosInstance"
|
:axios="axios"
|
||||||
:refreshpending="refreshPending"
|
:refreshpending="refreshPending"
|
||||||
:sort="sort"
|
:sort="sort"
|
||||||
@pathchanged="pathChanged"
|
@pathchanged="pathChanged"
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const inProps = defineProps({
|
|||||||
icons: Object,
|
icons: Object,
|
||||||
storage: String,
|
storage: String,
|
||||||
path: String,
|
path: String,
|
||||||
|
fileid: String,
|
||||||
endpoints: Object as PropType<EndPoints>,
|
endpoints: Object as PropType<EndPoints>,
|
||||||
axios: Object as PropType<Axios>,
|
axios: Object as PropType<Axios>,
|
||||||
refreshpending: Boolean,
|
refreshpending: Boolean,
|
||||||
@@ -81,10 +82,10 @@ const nameTestResult = ref<Context>()
|
|||||||
const nameTestDialog = ref(false)
|
const nameTestDialog = ref(false)
|
||||||
|
|
||||||
// 目录过滤
|
// 目录过滤
|
||||||
const dirs = computed(() => items.value.filter(item => item.type === 'dir' && item.basename.includes(filter.value)))
|
const dirs = computed(() => items.value.filter(item => item.type === 'dir' && item.name.includes(filter.value)))
|
||||||
|
|
||||||
// 文件过滤
|
// 文件过滤
|
||||||
const files = computed(() => items.value.filter(item => item.type === 'file' && item.basename.includes(filter.value)))
|
const files = computed(() => items.value.filter(item => item.type === 'file' && item.name.includes(filter.value)))
|
||||||
|
|
||||||
// 是否目录
|
// 是否目录
|
||||||
const isDir = computed(() => inProps.path?.endsWith('/'))
|
const isDir = computed(() => inProps.path?.endsWith('/'))
|
||||||
@@ -107,6 +108,7 @@ async function load() {
|
|||||||
.replace(/{storage}/g, inProps.storage)
|
.replace(/{storage}/g, inProps.storage)
|
||||||
.replace(/{path}/g, encodeURIComponent(inProps.path || ''))
|
.replace(/{path}/g, encodeURIComponent(inProps.path || ''))
|
||||||
.replace(/{sort}/g, inProps.sort || 'name')
|
.replace(/{sort}/g, inProps.sort || 'name')
|
||||||
|
.replace(/{fileid}/g, inProps.fileid || '')
|
||||||
const config = {
|
const config = {
|
||||||
url,
|
url,
|
||||||
method: inProps.endpoints?.list.method || 'get',
|
method: inProps.endpoints?.list.method || 'get',
|
||||||
@@ -121,7 +123,7 @@ async function load() {
|
|||||||
async function deleteItem(item: FileItem) {
|
async function deleteItem(item: FileItem) {
|
||||||
const confirmed = await createConfirm({
|
const confirmed = await createConfirm({
|
||||||
title: '确认',
|
title: '确认',
|
||||||
content: `是否确认删除${item.type === 'dir' ? '目录' : '文件'} ${item.basename}?`,
|
content: `是否确认删除${item.type === 'dir' ? '目录' : '文件'} ${item.name}?`,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
@@ -129,6 +131,7 @@ async function deleteItem(item: FileItem) {
|
|||||||
const url = inProps.endpoints?.delete.url
|
const url = inProps.endpoints?.delete.url
|
||||||
.replace(/{storage}/g, inProps.storage)
|
.replace(/{storage}/g, inProps.storage)
|
||||||
.replace(/{path}/g, encodeURIComponent(item.path))
|
.replace(/{path}/g, encodeURIComponent(item.path))
|
||||||
|
.replace(/{fileid}/g, inProps.fileid || '')
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
url,
|
url,
|
||||||
@@ -144,8 +147,8 @@ async function deleteItem(item: FileItem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 切换路径
|
// 切换路径
|
||||||
function changePath(_path: string) {
|
function changePath(item: FileItem) {
|
||||||
emit('pathchanged', _path)
|
emit('pathchanged', item)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新窗口中下载文件
|
// 新窗口中下载文件
|
||||||
@@ -155,6 +158,7 @@ function download(path: string) {
|
|||||||
const url_path = inProps.endpoints?.download.url
|
const url_path = inProps.endpoints?.download.url
|
||||||
.replace(/{storage}/g, inProps.storage)
|
.replace(/{storage}/g, inProps.storage)
|
||||||
.replace(/{path}/g, encodeURIComponent(path))
|
.replace(/{path}/g, encodeURIComponent(path))
|
||||||
|
.replace(/{fileid}/g, inProps.fileid || '')
|
||||||
const url = `${import.meta.env.VITE_API_BASE_URL}${url_path.slice(1)}&token=${token}`
|
const url = `${import.meta.env.VITE_API_BASE_URL}${url_path.slice(1)}&token=${token}`
|
||||||
// 下载文件
|
// 下载文件
|
||||||
window.open(url, '_blank')
|
window.open(url, '_blank')
|
||||||
@@ -167,6 +171,7 @@ function getImgLink(path: string) {
|
|||||||
const url_path = inProps.endpoints?.image.url
|
const url_path = inProps.endpoints?.image.url
|
||||||
.replace(/{storage}/g, inProps.storage)
|
.replace(/{storage}/g, inProps.storage)
|
||||||
.replace(/{path}/g, encodeURIComponent(path))
|
.replace(/{path}/g, encodeURIComponent(path))
|
||||||
|
.replace(/{fileid}/g, inProps.fileid || '')
|
||||||
return `${import.meta.env.VITE_API_BASE_URL}${url_path.slice(1)}&token=${token}`
|
return `${import.meta.env.VITE_API_BASE_URL}${url_path.slice(1)}&token=${token}`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,6 +188,7 @@ async function rename() {
|
|||||||
const url = inProps.endpoints?.rename.url
|
const url = inProps.endpoints?.rename.url
|
||||||
.replace(/{storage}/g, inProps.storage)
|
.replace(/{storage}/g, inProps.storage)
|
||||||
.replace(/{path}/g, encodeURIComponent(currentItem.value?.path || ''))
|
.replace(/{path}/g, encodeURIComponent(currentItem.value?.path || ''))
|
||||||
|
.replace(/{fileid}/g, inProps.fileid || '')
|
||||||
.replace(/{newname}/g, encodeURIComponent(newName.value))
|
.replace(/{newname}/g, encodeURIComponent(newName.value))
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
@@ -214,7 +220,7 @@ function formatTime(timestape: number) {
|
|||||||
|
|
||||||
// 监听path变化或者storage变化
|
// 监听path变化或者storage变化
|
||||||
watch(
|
watch(
|
||||||
[() => inProps.path, () => inProps.storage],
|
[() => inProps.path, () => inProps.fileid, () => inProps.storage],
|
||||||
async () => {
|
async () => {
|
||||||
items.value = []
|
items.value = []
|
||||||
nameTestResult.value = undefined
|
nameTestResult.value = undefined
|
||||||
@@ -358,7 +364,9 @@ onMounted(() => {
|
|||||||
<VCardText v-if="loading" class="text-center flex flex-col items-center">
|
<VCardText v-if="loading" class="text-center flex flex-col items-center">
|
||||||
<VProgressCircular size="48" indeterminate color="primary" />
|
<VProgressCircular size="48" indeterminate color="primary" />
|
||||||
</VCardText>
|
</VCardText>
|
||||||
<VCardText v-if="!path" class="grow d-flex justify-center align-center grey--text"> 选择目录或文件 </VCardText>
|
<VCardText v-if="!inProps.path" class="grow d-flex justify-center align-center grey--text">
|
||||||
|
选择目录或文件
|
||||||
|
</VCardText>
|
||||||
<VCardText v-else-if="isFile && !isImage" class="text-center break-all">
|
<VCardText v-else-if="isFile && !isImage" class="text-center break-all">
|
||||||
<strong>{{ items[0]?.name }}</strong
|
<strong>{{ items[0]?.name }}</strong
|
||||||
><br />
|
><br />
|
||||||
@@ -366,7 +374,7 @@ onMounted(() => {
|
|||||||
修改时间:{{ formatTime(items[0]?.modify_time || 0) }}
|
修改时间:{{ formatTime(items[0]?.modify_time || 0) }}
|
||||||
</VCardText>
|
</VCardText>
|
||||||
<VCardText v-else-if="isFile && isImage" class="grow d-flex justify-center align-center">
|
<VCardText v-else-if="isFile && isImage" class="grow d-flex justify-center align-center">
|
||||||
<VImg :src="getImgLink(path)" max-width="100%" max-height="100%" />
|
<VImg :src="getImgLink(inProps.path)" max-width="100%" max-height="100%" />
|
||||||
</VCardText>
|
</VCardText>
|
||||||
<VCardText v-else-if="dirs.length || files.length" class="p-0">
|
<VCardText v-else-if="dirs.length || files.length" class="p-0">
|
||||||
<VList subheader>
|
<VList subheader>
|
||||||
@@ -381,7 +389,7 @@ onMounted(() => {
|
|||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<VHover>
|
<VHover>
|
||||||
<template #default="hover">
|
<template #default="hover">
|
||||||
<VListItem v-bind="hover.props" class="px-3 pe-1" @click="changePath(item.path)">
|
<VListItem v-bind="hover.props" class="px-3 pe-1" @click="changePath(item)">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon
|
<VIcon
|
||||||
v-if="inProps.icons && item.extension"
|
v-if="inProps.icons && item.extension"
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ const inProps = defineProps({
|
|||||||
storages: Array as PropType<any[]>,
|
storages: Array as PropType<any[]>,
|
||||||
storage: String,
|
storage: String,
|
||||||
path: String,
|
path: String,
|
||||||
|
fileid: String,
|
||||||
|
fileidstack: {
|
||||||
|
type: Array as PropType<string[]>,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
endpoints: Object as PropType<EndPoints>,
|
endpoints: Object as PropType<EndPoints>,
|
||||||
axios: Object as PropType<Axios>,
|
axios: Object as PropType<Axios>,
|
||||||
})
|
})
|
||||||
@@ -36,13 +41,14 @@ const pathSegments = computed(() => {
|
|||||||
let path_str = ''
|
let path_str = ''
|
||||||
const isFolder = inProps.path?.endsWith('/')
|
const isFolder = inProps.path?.endsWith('/')
|
||||||
const segments = inProps.path?.split('/').filter(item => item)
|
const segments = inProps.path?.split('/').filter(item => item)
|
||||||
|
const fileids = inProps.fileidstack ?? []
|
||||||
return (
|
return (
|
||||||
segments?.map((item, index) => {
|
segments?.map((item, index) => {
|
||||||
path_str += item + (index < segments.length - 1 || isFolder ? '/' : '')
|
path_str += item + (index < segments.length - 1 || isFolder ? '/' : '')
|
||||||
return {
|
return {
|
||||||
name: item,
|
name: item,
|
||||||
path: path_str,
|
path: path_str,
|
||||||
|
fileid: fileids[index],
|
||||||
}
|
}
|
||||||
}) ?? []
|
}) ?? []
|
||||||
)
|
)
|
||||||
@@ -56,20 +62,27 @@ const storageObject = computed(() => {
|
|||||||
function changeStorage(code: string) {
|
function changeStorage(code: string) {
|
||||||
if (inProps.storage !== code) {
|
if (inProps.storage !== code) {
|
||||||
emit('storagechanged', code)
|
emit('storagechanged', code)
|
||||||
emit('pathchanged', '/')
|
emit('pathchanged', {
|
||||||
|
path: '/',
|
||||||
|
fileid: 'root',
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 路径变化
|
// 路径变化
|
||||||
function changePath(_path: string) {
|
function changePath(_path: string, _fileid: string) {
|
||||||
emit('pathchanged', _path)
|
emit('pathchanged', {
|
||||||
|
path: _path,
|
||||||
|
fileid: _fileid,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回上一级
|
// 返回上一级
|
||||||
function goUp() {
|
function goUp() {
|
||||||
const segments = pathSegments.value ?? []
|
const segments = pathSegments.value ?? []
|
||||||
const path = segments?.length === 1 ? '/' : segments[segments.length - 2].path
|
const path = segments?.length === 1 ? '/' : segments[segments.length - 2].path
|
||||||
changePath(path)
|
const fileid = segments?.length === 1 ? 'root' : segments[segments.length - 2].fileid
|
||||||
|
changePath(path, fileid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建目录
|
// 创建目录
|
||||||
@@ -78,6 +91,7 @@ async function mkdir() {
|
|||||||
const url = inProps.endpoints?.mkdir.url
|
const url = inProps.endpoints?.mkdir.url
|
||||||
.replace(/{storage}/g, inProps.storage)
|
.replace(/{storage}/g, inProps.storage)
|
||||||
.replace(/{path}/g, encodeURIComponent(inProps.path + newFolderName.value))
|
.replace(/{path}/g, encodeURIComponent(inProps.path + newFolderName.value))
|
||||||
|
.replace(/{fileid}/g, inProps.fileid || '')
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
url,
|
url,
|
||||||
@@ -125,7 +139,7 @@ const sortIcon = computed(() => {
|
|||||||
</VListItem>
|
</VListItem>
|
||||||
</VList>
|
</VList>
|
||||||
</VMenu>
|
</VMenu>
|
||||||
<VBtn variant="text" :input-value="path === '/'" class="px-1" @click="changePath('/')">
|
<VBtn variant="text" :input-value="path === '/'" class="px-1" @click="changePath('/', 'root')">
|
||||||
<VIcon :icon="storageObject?.icon" class="mr-2" />
|
<VIcon :icon="storageObject?.icon" class="mr-2" />
|
||||||
{{ storageObject?.name }}
|
{{ storageObject?.name }}
|
||||||
</VBtn>
|
</VBtn>
|
||||||
@@ -134,7 +148,7 @@ const sortIcon = computed(() => {
|
|||||||
variant="text"
|
variant="text"
|
||||||
:input-value="index === pathSegments.length - 1"
|
:input-value="index === pathSegments.length - 1"
|
||||||
class="px-1 d-none d-md-block"
|
class="px-1 d-none d-md-block"
|
||||||
@click="changePath(segment.path)"
|
@click="changePath(segment.path, inProps.fileidstack[index])"
|
||||||
>
|
>
|
||||||
<VIcon icon=" mdi-chevron-right" />
|
<VIcon icon=" mdi-chevron-right" />
|
||||||
{{ segment.name }}
|
{{ segment.name }}
|
||||||
|
|||||||
@@ -1,37 +1,43 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { MediaDirectory } from '@/api/types'
|
import { FileItem, MediaDirectory } from '@/api/types'
|
||||||
import FileBrowser from '@/components/FileBrowser.vue'
|
import FileBrowser from '@/components/FileBrowser.vue'
|
||||||
|
|
||||||
const endpoints = {
|
const endpoints = {
|
||||||
list: {
|
list: {
|
||||||
url: '/filebrowser/{storage}/list?path={path}&sort={sort}',
|
url: '/filebrowser/{storage}/list?path={path}&sort={sort}&fileid={fileid}',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
},
|
},
|
||||||
mkdir: {
|
mkdir: {
|
||||||
url: '/filebrowser/{storage}/mkdir?path={path}',
|
url: '/filebrowser/{storage}/mkdir?path={path}&fileid={fileid}',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
},
|
},
|
||||||
delete: {
|
delete: {
|
||||||
url: '/filebrowser/{storage}/delete?path={path}',
|
url: '/filebrowser/{storage}/delete?path={path}&fileid={fileid}',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
},
|
},
|
||||||
download: {
|
download: {
|
||||||
url: '/filebrowser/{storage}/download?path={path}',
|
url: '/filebrowser/{storage}/download?path={path}&fileid={fileid}',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
},
|
},
|
||||||
image: {
|
image: {
|
||||||
url: '/filebrowser/{storage}/image?path={path}',
|
url: '/filebrowser/{storage}/image?path={path}&fileid={fileid}',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
},
|
},
|
||||||
rename: {
|
rename: {
|
||||||
url: '/filebrowser/{storage}/rename?path={path}&new_name={newname}',
|
url: '/filebrowser/{storage}/rename?path={path}&new_name={newname}&fileid={fileid}',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前目录
|
// 当前目录
|
||||||
const path: Ref<string | undefined> = ref()
|
const path = ref<string>('')
|
||||||
|
|
||||||
|
// 当前fileid
|
||||||
|
const fileid = ref<string>('root')
|
||||||
|
|
||||||
|
// fileid的堆栈
|
||||||
|
const fileidstack = ref<string[]>(['root'])
|
||||||
|
|
||||||
// 下载目录列表
|
// 下载目录列表
|
||||||
const downloadDirectories = ref<MediaDirectory[]>([])
|
const downloadDirectories = ref<MediaDirectory[]>([])
|
||||||
@@ -84,8 +90,14 @@ async function loadDownloadDirectories() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 目录变化
|
// 目录变化
|
||||||
function pathChanged(_path: string) {
|
function pathChanged(item: FileItem) {
|
||||||
path.value = _path
|
path.value = item.path
|
||||||
|
fileid.value = item.fileid
|
||||||
|
if (fileidstack.value.includes(item.fileid)) {
|
||||||
|
fileidstack.value = fileidstack.value.slice(0, fileidstack.value.indexOf(item.fileid) + 1)
|
||||||
|
} else {
|
||||||
|
fileidstack.value.push(item.fileid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(loadDownloadDirectories)
|
onBeforeMount(loadDownloadDirectories)
|
||||||
@@ -97,6 +109,8 @@ onBeforeMount(loadDownloadDirectories)
|
|||||||
storages="local,aliyun"
|
storages="local,aliyun"
|
||||||
:tree="false"
|
:tree="false"
|
||||||
:path="path"
|
:path="path"
|
||||||
|
:fileid="fileid"
|
||||||
|
:fileidstack="fileidstack"
|
||||||
:endpoints="endpoints"
|
:endpoints="endpoints"
|
||||||
:axios="api"
|
:axios="api"
|
||||||
@pathchanged="pathChanged"
|
@pathchanged="pathChanged"
|
||||||
|
|||||||
Reference in New Issue
Block a user