feat: 完善知识库、策略预览与OnlyOffice集成,增强后端启动依赖检查
This commit is contained in:
@@ -1,177 +1,183 @@
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import { useSystemState } from '../../composables/useSystemState.js'
|
||||
import { useToast } from '../../composables/useToast.js'
|
||||
import {
|
||||
deleteKnowledgeDocument,
|
||||
fetchKnowledgeDocument,
|
||||
fetchKnowledgeDocumentBlob,
|
||||
fetchKnowledgeLibrary,
|
||||
fetchKnowledgeOnlyOfficeConfig,
|
||||
uploadKnowledgeDocument
|
||||
} from '../../services/knowledge.js'
|
||||
import { loadOnlyOfficeApi } from '../../services/onlyoffice.js'
|
||||
import { isManagerUser } from '../../utils/accessControl.js'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import { useSystemState } from '../../composables/useSystemState.js'
|
||||
import { useToast } from '../../composables/useToast.js'
|
||||
import {
|
||||
deleteKnowledgeDocument,
|
||||
fetchKnowledgeDocument,
|
||||
fetchKnowledgeDocumentBlob,
|
||||
fetchKnowledgeLibrary,
|
||||
fetchKnowledgeOnlyOfficeConfig,
|
||||
uploadKnowledgeDocument
|
||||
} from '../../services/knowledge.js'
|
||||
import { loadOnlyOfficeApi } from '../../services/onlyoffice.js'
|
||||
import { isManagerUser } from '../../utils/accessControl.js'
|
||||
import {
|
||||
buildExcelPreviewTable,
|
||||
buildPreviewMetaLine,
|
||||
buildPreviewSecondaryMetaLine
|
||||
} from './policiesPreviewFormatters.js'
|
||||
import { canUseOnlyOfficePreview, resolveKnowledgePreviewMode } from './knowledgePreviewMode.js'
|
||||
|
||||
function triggerFileDownload(blob, filename) {
|
||||
const url = URL.createObjectURL(blob)
|
||||
const anchor = document.createElement('a')
|
||||
const anchor = document.createElement('a')
|
||||
anchor.href = url
|
||||
anchor.download = filename
|
||||
anchor.click()
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
|
||||
const ONLYOFFICE_EXTENSIONS = new Set(['docx', 'xlsx', 'pptx'])
|
||||
|
||||
function supportsOnlyOfficePreview(document) {
|
||||
return ONLYOFFICE_EXTENSIONS.has(String(document?.extension || '').toLowerCase())
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'PoliciesView',
|
||||
emits: ['summary-change'],
|
||||
setup(_, { emit }) {
|
||||
const { currentUser } = useSystemState()
|
||||
const { toast } = useToast()
|
||||
|
||||
const documentSearch = ref('')
|
||||
const activeFolder = ref('差旅规范')
|
||||
const folders = ref([])
|
||||
const documents = ref([])
|
||||
const selectedDocument = ref(null)
|
||||
const pageSizeOpen = ref(false)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const pageSizes = [10, 20, 50]
|
||||
const loading = ref(false)
|
||||
const uploadInput = ref(null)
|
||||
const uploading = ref(false)
|
||||
const deletingId = ref('')
|
||||
const previewLoading = ref(false)
|
||||
|
||||
export default {
|
||||
name: 'PoliciesView',
|
||||
emits: ['summary-change'],
|
||||
setup(_, { emit }) {
|
||||
const { currentUser } = useSystemState()
|
||||
const { toast } = useToast()
|
||||
|
||||
const documentSearch = ref('')
|
||||
const activeFolder = ref('差旅规范')
|
||||
const folders = ref([])
|
||||
const documents = ref([])
|
||||
const selectedDocument = ref(null)
|
||||
const pageSizeOpen = ref(false)
|
||||
const currentPage = ref(1)
|
||||
const pageSize = ref(10)
|
||||
const pageSizes = [10, 20, 50]
|
||||
const loading = ref(false)
|
||||
const uploadInput = ref(null)
|
||||
const uploading = ref(false)
|
||||
const deletingId = ref('')
|
||||
const previewLoading = ref(false)
|
||||
const previewBlobUrl = ref('')
|
||||
const previewError = ref('')
|
||||
const onlyOfficeLoading = ref(false)
|
||||
const onlyOfficeError = ref('')
|
||||
const onlyOfficeAvailable = ref(false)
|
||||
const onlyOfficeEditor = ref(null)
|
||||
const onlyOfficeHostId = ref('knowledge-onlyoffice-preview')
|
||||
const currentPreviewPageIndex = ref(0)
|
||||
|
||||
const isAdmin = computed(() => isManagerUser(currentUser.value))
|
||||
const uploadHint = computed(() =>
|
||||
isAdmin.value
|
||||
? '支持 PDF / Word / Excel / PPT / 图片 / 文本文件,重复同名文件将自动覆盖并升级版本'
|
||||
: '当前账号只有查阅权限,上传、删除和修改仅管理员可用'
|
||||
)
|
||||
|
||||
const filteredFolders = computed(() => folders.value)
|
||||
|
||||
const filteredDocuments = computed(() => {
|
||||
const key = documentSearch.value.trim()
|
||||
|
||||
return documents.value.filter((doc) => {
|
||||
const inFolder = activeFolder.value ? doc.folder === activeFolder.value : true
|
||||
const matchesSearch = key ? doc.name.includes(key) : true
|
||||
return inFolder && matchesSearch
|
||||
|
||||
const isAdmin = computed(() => isManagerUser(currentUser.value))
|
||||
const uploadHint = computed(() =>
|
||||
isAdmin.value
|
||||
? '支持 PDF / Word / Excel / PPT / 图片 / 文本文件,重复同名文件将自动覆盖并升级版本'
|
||||
: '当前账号只有查阅权限,上传、删除和修改仅管理员可用'
|
||||
)
|
||||
|
||||
const filteredFolders = computed(() => folders.value)
|
||||
|
||||
const filteredDocuments = computed(() => {
|
||||
const key = documentSearch.value.trim()
|
||||
|
||||
return documents.value.filter((doc) => {
|
||||
const inFolder = activeFolder.value ? doc.folder === activeFolder.value : true
|
||||
const matchesSearch = key ? doc.name.includes(key) : true
|
||||
return inFolder && matchesSearch
|
||||
})
|
||||
})
|
||||
|
||||
const totalCount = computed(() => filteredDocuments.value.length)
|
||||
const totalPages = computed(() => Math.max(1, Math.ceil(totalCount.value / pageSize.value)))
|
||||
const visibleDocuments = computed(() => {
|
||||
const start = (currentPage.value - 1) * pageSize.value
|
||||
return filteredDocuments.value.slice(start, start + pageSize.value)
|
||||
})
|
||||
const activePreviewPage = computed(() => {
|
||||
const pages = selectedDocument.value?.previewPages || []
|
||||
return pages[currentPreviewPageIndex.value] || pages[0] || null
|
||||
})
|
||||
const previewMetaLine = computed(() => buildPreviewMetaLine(selectedDocument.value))
|
||||
const previewSecondaryMetaLine = computed(() =>
|
||||
buildPreviewSecondaryMetaLine(selectedDocument.value, activePreviewPage.value)
|
||||
)
|
||||
const previewMode = computed(() =>
|
||||
resolveKnowledgePreviewMode(selectedDocument.value, {
|
||||
onlyOfficeAvailable: onlyOfficeAvailable.value
|
||||
})
|
||||
})
|
||||
|
||||
const totalCount = computed(() => filteredDocuments.value.length)
|
||||
const totalPages = computed(() => Math.max(1, Math.ceil(totalCount.value / pageSize.value)))
|
||||
const visibleDocuments = computed(() => {
|
||||
const start = (currentPage.value - 1) * pageSize.value
|
||||
return filteredDocuments.value.slice(start, start + pageSize.value)
|
||||
})
|
||||
const activePreviewPage = computed(() => {
|
||||
const pages = selectedDocument.value?.previewPages || []
|
||||
return pages[currentPreviewPageIndex.value] || pages[0] || null
|
||||
})
|
||||
const previewMetaLine = computed(() => buildPreviewMetaLine(selectedDocument.value))
|
||||
const previewSecondaryMetaLine = computed(() =>
|
||||
buildPreviewSecondaryMetaLine(selectedDocument.value, activePreviewPage.value)
|
||||
)
|
||||
const shouldUseOnlyOffice = computed(() => supportsOnlyOfficePreview(selectedDocument.value))
|
||||
const shouldUseOnlyOffice = computed(() => previewMode.value === 'onlyoffice')
|
||||
const excelPreviewTable = computed(() =>
|
||||
selectedDocument.value?.previewKind === 'table'
|
||||
? buildExcelPreviewTable(activePreviewPage.value)
|
||||
: { headers: [], rows: [] }
|
||||
)
|
||||
|
||||
function revokePreviewBlob() {
|
||||
if (previewBlobUrl.value) {
|
||||
URL.revokeObjectURL(previewBlobUrl.value)
|
||||
previewBlobUrl.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
function destroyOnlyOfficeEditor() {
|
||||
if (onlyOfficeEditor.value?.destroyEditor) {
|
||||
onlyOfficeEditor.value.destroyEditor()
|
||||
}
|
||||
onlyOfficeEditor.value = null
|
||||
}
|
||||
|
||||
|
||||
function revokePreviewBlob() {
|
||||
if (previewBlobUrl.value) {
|
||||
URL.revokeObjectURL(previewBlobUrl.value)
|
||||
previewBlobUrl.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
function destroyOnlyOfficeEditor() {
|
||||
if (onlyOfficeEditor.value?.destroyEditor) {
|
||||
onlyOfficeEditor.value.destroyEditor()
|
||||
}
|
||||
onlyOfficeEditor.value = null
|
||||
}
|
||||
|
||||
async function mountOnlyOfficeEditor(documentId) {
|
||||
onlyOfficeLoading.value = true
|
||||
onlyOfficeError.value = ''
|
||||
onlyOfficeAvailable.value = false
|
||||
destroyOnlyOfficeEditor()
|
||||
|
||||
try {
|
||||
const payload = await fetchKnowledgeOnlyOfficeConfig(documentId)
|
||||
await loadOnlyOfficeApi(payload.documentServerUrl)
|
||||
await nextTick()
|
||||
|
||||
if (!window.DocsAPI?.DocEditor) {
|
||||
throw new Error('ONLYOFFICE 编辑器未正确加载。')
|
||||
}
|
||||
await nextTick()
|
||||
|
||||
if (!window.DocsAPI?.DocEditor) {
|
||||
throw new Error('ONLYOFFICE 编辑器未正确加载。')
|
||||
}
|
||||
|
||||
onlyOfficeHostId.value = `knowledge-onlyoffice-preview-${documentId}`
|
||||
await nextTick()
|
||||
onlyOfficeEditor.value = new window.DocsAPI.DocEditor(onlyOfficeHostId.value, payload.config)
|
||||
onlyOfficeAvailable.value = true
|
||||
return true
|
||||
} catch (error) {
|
||||
onlyOfficeError.value = error.message || 'ONLYOFFICE 预览加载失败。'
|
||||
return false
|
||||
} finally {
|
||||
onlyOfficeLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function loadLibrary(options = {}) {
|
||||
loading.value = true
|
||||
try {
|
||||
const payload = await fetchKnowledgeLibrary()
|
||||
folders.value = payload.folders || []
|
||||
documents.value = payload.documents || []
|
||||
emit('summary-change', { totalDocuments: documents.value.length })
|
||||
|
||||
const activeExists = folders.value.some((folder) => folder.name === activeFolder.value)
|
||||
if (!activeExists) {
|
||||
activeFolder.value = folders.value[0]?.name || ''
|
||||
}
|
||||
|
||||
if (options.preserveSelection && selectedDocument.value?.id) {
|
||||
const exists = documents.value.some((doc) => doc.id === selectedDocument.value.id)
|
||||
if (!exists) {
|
||||
selectedDocument.value = null
|
||||
revokePreviewBlob()
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
emit('summary-change', { totalDocuments: 0 })
|
||||
toast(error.message || '知识库加载失败。')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function selectDocument(documentId) {
|
||||
previewLoading.value = true
|
||||
|
||||
async function loadLibrary(options = {}) {
|
||||
loading.value = true
|
||||
try {
|
||||
const payload = await fetchKnowledgeLibrary()
|
||||
folders.value = payload.folders || []
|
||||
documents.value = payload.documents || []
|
||||
emit('summary-change', { totalDocuments: documents.value.length })
|
||||
|
||||
const activeExists = folders.value.some((folder) => folder.name === activeFolder.value)
|
||||
if (!activeExists) {
|
||||
activeFolder.value = folders.value[0]?.name || ''
|
||||
}
|
||||
|
||||
if (options.preserveSelection && selectedDocument.value?.id) {
|
||||
const exists = documents.value.some((doc) => doc.id === selectedDocument.value.id)
|
||||
if (!exists) {
|
||||
selectedDocument.value = null
|
||||
revokePreviewBlob()
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
emit('summary-change', { totalDocuments: 0 })
|
||||
toast(error.message || '知识库加载失败。')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function selectDocument(documentId) {
|
||||
previewLoading.value = true
|
||||
previewError.value = ''
|
||||
onlyOfficeError.value = ''
|
||||
onlyOfficeAvailable.value = false
|
||||
revokePreviewBlob()
|
||||
destroyOnlyOfficeEditor()
|
||||
|
||||
@@ -180,182 +186,187 @@ export default {
|
||||
selectedDocument.value = payload
|
||||
currentPreviewPageIndex.value = 0
|
||||
|
||||
if (supportsOnlyOfficePreview(payload)) {
|
||||
if (canUseOnlyOfficePreview(payload)) {
|
||||
await mountOnlyOfficeEditor(documentId)
|
||||
} else if (payload.previewKind === 'pdf' || payload.previewKind === 'image') {
|
||||
}
|
||||
|
||||
if (payload.previewKind === 'pdf' || payload.previewKind === 'image') {
|
||||
const blob = await fetchKnowledgeDocumentBlob(documentId, 'inline')
|
||||
previewBlobUrl.value = URL.createObjectURL(blob)
|
||||
}
|
||||
} catch (error) {
|
||||
previewError.value = error.message || '预览加载失败。'
|
||||
toast(previewError.value)
|
||||
} finally {
|
||||
previewLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDownload(document) {
|
||||
try {
|
||||
const blob = await fetchKnowledgeDocumentBlob(document.id, 'attachment')
|
||||
triggerFileDownload(blob, document.name)
|
||||
} catch (error) {
|
||||
toast(error.message || '下载失败。')
|
||||
}
|
||||
}
|
||||
|
||||
function triggerUpload() {
|
||||
if (!isAdmin.value || uploading.value) {
|
||||
return
|
||||
}
|
||||
uploadInput.value?.click()
|
||||
}
|
||||
|
||||
async function uploadFiles(fileList) {
|
||||
const files = Array.from(fileList || []).filter(Boolean)
|
||||
if (!files.length || !activeFolder.value || !isAdmin.value) {
|
||||
return
|
||||
}
|
||||
|
||||
uploading.value = true
|
||||
try {
|
||||
let latestDocumentId = ''
|
||||
for (const file of files) {
|
||||
const payload = await uploadKnowledgeDocument({ folder: activeFolder.value, file })
|
||||
latestDocumentId = payload.id
|
||||
}
|
||||
|
||||
await loadLibrary({ preserveSelection: true })
|
||||
toast(files.length > 1 ? `已上传 ${files.length} 个知识库文件。` : '知识库文件已上传。')
|
||||
|
||||
if (latestDocumentId) {
|
||||
await selectDocument(latestDocumentId)
|
||||
}
|
||||
} catch (error) {
|
||||
toast(error.message || '上传失败。')
|
||||
} finally {
|
||||
uploading.value = false
|
||||
if (uploadInput.value) {
|
||||
uploadInput.value.value = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function handleFileInput(event) {
|
||||
await uploadFiles(event.target.files)
|
||||
}
|
||||
|
||||
async function handleDrop(event) {
|
||||
if (!isAdmin.value) {
|
||||
return
|
||||
}
|
||||
await uploadFiles(event.dataTransfer?.files)
|
||||
}
|
||||
|
||||
async function handleDelete(document) {
|
||||
if (!isAdmin.value || deletingId.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const confirmed = window.confirm(`确认删除文件“${document.name}”吗?`)
|
||||
if (!confirmed) {
|
||||
return
|
||||
}
|
||||
|
||||
deletingId.value = document.id
|
||||
try {
|
||||
await deleteKnowledgeDocument(document.id)
|
||||
if (selectedDocument.value?.id === document.id) {
|
||||
selectedDocument.value = null
|
||||
revokePreviewBlob()
|
||||
}
|
||||
await loadLibrary()
|
||||
toast('知识库文件已删除。')
|
||||
} catch (error) {
|
||||
toast(error.message || '删除失败。')
|
||||
} finally {
|
||||
deletingId.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
function changePageSize(size) {
|
||||
pageSize.value = size
|
||||
pageSizeOpen.value = false
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
function closePreview() {
|
||||
selectedDocument.value = null
|
||||
previewError.value = ''
|
||||
currentPreviewPageIndex.value = 0
|
||||
toast(previewError.value)
|
||||
} finally {
|
||||
previewLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDownload(document) {
|
||||
try {
|
||||
const blob = await fetchKnowledgeDocumentBlob(document.id, 'attachment')
|
||||
triggerFileDownload(blob, document.name)
|
||||
} catch (error) {
|
||||
toast(error.message || '下载失败。')
|
||||
}
|
||||
}
|
||||
|
||||
function triggerUpload() {
|
||||
if (!isAdmin.value || uploading.value) {
|
||||
return
|
||||
}
|
||||
uploadInput.value?.click()
|
||||
}
|
||||
|
||||
async function uploadFiles(fileList) {
|
||||
const files = Array.from(fileList || []).filter(Boolean)
|
||||
if (!files.length || !activeFolder.value || !isAdmin.value) {
|
||||
return
|
||||
}
|
||||
|
||||
uploading.value = true
|
||||
try {
|
||||
let latestDocumentId = ''
|
||||
for (const file of files) {
|
||||
const payload = await uploadKnowledgeDocument({ folder: activeFolder.value, file })
|
||||
latestDocumentId = payload.id
|
||||
}
|
||||
|
||||
await loadLibrary({ preserveSelection: true })
|
||||
toast(files.length > 1 ? `已上传 ${files.length} 个知识库文件。` : '知识库文件已上传。')
|
||||
|
||||
if (latestDocumentId) {
|
||||
await selectDocument(latestDocumentId)
|
||||
}
|
||||
} catch (error) {
|
||||
toast(error.message || '上传失败。')
|
||||
} finally {
|
||||
uploading.value = false
|
||||
if (uploadInput.value) {
|
||||
uploadInput.value.value = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function handleFileInput(event) {
|
||||
await uploadFiles(event.target.files)
|
||||
}
|
||||
|
||||
async function handleDrop(event) {
|
||||
if (!isAdmin.value) {
|
||||
return
|
||||
}
|
||||
await uploadFiles(event.dataTransfer?.files)
|
||||
}
|
||||
|
||||
async function handleDelete(document) {
|
||||
if (!isAdmin.value || deletingId.value) {
|
||||
return
|
||||
}
|
||||
|
||||
const confirmed = window.confirm(`确认删除文件“${document.name}”吗?`)
|
||||
if (!confirmed) {
|
||||
return
|
||||
}
|
||||
|
||||
deletingId.value = document.id
|
||||
try {
|
||||
await deleteKnowledgeDocument(document.id)
|
||||
if (selectedDocument.value?.id === document.id) {
|
||||
selectedDocument.value = null
|
||||
revokePreviewBlob()
|
||||
}
|
||||
await loadLibrary()
|
||||
toast('知识库文件已删除。')
|
||||
} catch (error) {
|
||||
toast(error.message || '删除失败。')
|
||||
} finally {
|
||||
deletingId.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
function changePageSize(size) {
|
||||
pageSize.value = size
|
||||
pageSizeOpen.value = false
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
function closePreview() {
|
||||
selectedDocument.value = null
|
||||
previewError.value = ''
|
||||
currentPreviewPageIndex.value = 0
|
||||
revokePreviewBlob()
|
||||
destroyOnlyOfficeEditor()
|
||||
onlyOfficeError.value = ''
|
||||
onlyOfficeAvailable.value = false
|
||||
}
|
||||
|
||||
function selectPreviewPage(index) {
|
||||
currentPreviewPageIndex.value = index
|
||||
}
|
||||
|
||||
watch(filteredDocuments, () => {
|
||||
currentPage.value = 1
|
||||
pageSizeOpen.value = false
|
||||
|
||||
if (selectedDocument.value && !filteredDocuments.value.some((doc) => doc.id === selectedDocument.value.id)) {
|
||||
closePreview()
|
||||
}
|
||||
})
|
||||
|
||||
watch(activeFolder, () => {
|
||||
closePreview()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
loadLibrary()
|
||||
})
|
||||
|
||||
|
||||
function selectPreviewPage(index) {
|
||||
currentPreviewPageIndex.value = index
|
||||
}
|
||||
|
||||
watch(filteredDocuments, () => {
|
||||
currentPage.value = 1
|
||||
pageSizeOpen.value = false
|
||||
|
||||
if (selectedDocument.value && !filteredDocuments.value.some((doc) => doc.id === selectedDocument.value.id)) {
|
||||
closePreview()
|
||||
}
|
||||
})
|
||||
|
||||
watch(activeFolder, () => {
|
||||
closePreview()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
loadLibrary()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
revokePreviewBlob()
|
||||
destroyOnlyOfficeEditor()
|
||||
})
|
||||
|
||||
return {
|
||||
activeFolder,
|
||||
activePreviewPage,
|
||||
changePageSize,
|
||||
closePreview,
|
||||
excelPreviewTable,
|
||||
currentPage,
|
||||
currentPreviewPageIndex,
|
||||
deletingId,
|
||||
documentSearch,
|
||||
filteredFolders,
|
||||
handleDelete,
|
||||
handleDownload,
|
||||
handleDrop,
|
||||
handleFileInput,
|
||||
isAdmin,
|
||||
loading,
|
||||
pageSize,
|
||||
|
||||
return {
|
||||
activeFolder,
|
||||
activePreviewPage,
|
||||
changePageSize,
|
||||
closePreview,
|
||||
excelPreviewTable,
|
||||
currentPage,
|
||||
currentPreviewPageIndex,
|
||||
deletingId,
|
||||
documentSearch,
|
||||
filteredFolders,
|
||||
handleDelete,
|
||||
handleDownload,
|
||||
handleDrop,
|
||||
handleFileInput,
|
||||
isAdmin,
|
||||
loading,
|
||||
pageSize,
|
||||
pageSizeOpen,
|
||||
pageSizes,
|
||||
onlyOfficeError,
|
||||
onlyOfficeHostId,
|
||||
onlyOfficeLoading,
|
||||
previewMode,
|
||||
previewMetaLine,
|
||||
previewSecondaryMetaLine,
|
||||
previewBlobUrl,
|
||||
previewError,
|
||||
previewLoading,
|
||||
shouldUseOnlyOffice,
|
||||
selectDocument,
|
||||
selectPreviewPage,
|
||||
selectedDocument,
|
||||
totalCount,
|
||||
totalPages,
|
||||
triggerUpload,
|
||||
uploadHint,
|
||||
uploadInput,
|
||||
uploading,
|
||||
visibleDocuments
|
||||
}
|
||||
}
|
||||
}
|
||||
previewError,
|
||||
previewLoading,
|
||||
shouldUseOnlyOffice,
|
||||
selectDocument,
|
||||
selectPreviewPage,
|
||||
selectedDocument,
|
||||
totalCount,
|
||||
totalPages,
|
||||
triggerUpload,
|
||||
uploadHint,
|
||||
uploadInput,
|
||||
uploading,
|
||||
visibleDocuments
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user