Skip to content

Commit 0886176

Browse files
committed
feat(overview): derive nav categories from template providers, use barrel imports
Nav items are now driven by whatever TemplateFileCreator objects are registered with the NC Files API, so installing or removing an office suite automatically updates the sidebar. Uses a single fetch on mount for both the category list and the MIME filter for DAV SEARCH. Shows NcEmptyContent when no providers are installed rather than displaying an empty nav with no files. Signed-off-by: James Manuel <moodyjmz@users.noreply.github.com>
1 parent 20d4454 commit 0886176

1 file changed

Lines changed: 66 additions & 99 deletions

File tree

src/views/OfficeOverview.vue

Lines changed: 66 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -6,70 +6,66 @@
66
<NcContent app-name="richdocuments">
77
<NcAppNavigation>
88
<template #list>
9-
<NcAppNavigationItem :name="t('richdocuments', 'Documents')"
10-
icon="icon-filetype-document"
11-
:active="currentView === 'documents'"
12-
@click="setView('documents')" />
13-
14-
<NcAppNavigationItem :name="t('richdocuments', 'Presentations')"
15-
icon="icon-filetype-presentation"
16-
:active="currentView === 'presentations'"
17-
@click="setView('presentations')" />
18-
19-
<NcAppNavigationItem :name="t('richdocuments', 'Spreadsheets')"
20-
icon="icon-filetype-spreadsheet"
21-
:active="currentView === 'spreadsheets'"
22-
@click="setView('spreadsheets')" />
23-
24-
<NcAppNavigationItem :name="t('richdocuments', 'Diagrams')"
25-
icon="icon-filetype-draw"
26-
:active="currentView === 'diagrams'"
27-
@click="setView('diagrams')" />
9+
<NcAppNavigationItem v-for="creator in creators"
10+
:key="creator.app + '-' + creator.extension"
11+
:name="creator.label"
12+
:active="activeCreator === creator"
13+
@click="setCreator(creator)" />
2814
</template>
2915
</NcAppNavigation>
3016

3117
<NcAppContent>
3218
<NcLoadingIcon v-if="loading" class="office-overview__loading" />
3319

3420
<template v-else>
35-
<div v-if="!error" class="office-overview__search">
36-
<NcTextField v-model="searchQuery"
37-
:label="searchLabel"
38-
type="search" />
39-
</div>
40-
41-
<NcEmptyContent v-if="error"
42-
:name="error" />
43-
44-
<NcEmptyContent v-else-if="files.length === 0"
45-
:name="emptyMessage">
21+
<NcEmptyContent v-if="creators.length === 0"
22+
:name="t('richdocuments', 'No office suite installed')">
4623
<template #icon>
4724
<FileDocumentOutline />
4825
</template>
4926
</NcEmptyContent>
5027

51-
<div v-else class="office-overview__grid">
52-
<FileCard v-for="file in files"
53-
:key="file.id"
54-
@click="openFile(file)">
55-
<template #preview>
56-
<img v-if="previewEnabled"
57-
:src="getPreviewUrl(file)"
58-
:alt="file.basename"
59-
class="overview-file-preview">
60-
<span v-else
61-
:class="['icon-filetype-' + fileTypeClass, 'overview-file-icon']" />
62-
</template>
28+
<template v-else>
29+
<div class="office-overview__search">
30+
<NcTextField v-model="searchQuery"
31+
:label="t('richdocuments', 'Search {category}', { category: activeCreator.label })"
32+
type="search" />
33+
</div>
6334

64-
<template #name>
65-
{{ file.basename }}
66-
</template>
35+
<NcEmptyContent v-if="error"
36+
:name="error" />
6737

68-
<template #subname>
69-
<NcDateTime :timestamp="file.mtime" />
38+
<NcEmptyContent v-else-if="files.length === 0"
39+
:name="t('richdocuments', 'No {category} found', { category: activeCreator.label })">
40+
<template #icon>
41+
<FileDocumentOutline />
7042
</template>
71-
</FileCard>
72-
</div>
43+
</NcEmptyContent>
44+
45+
<div v-else class="office-overview__grid">
46+
<FileCard v-for="file in files"
47+
:key="file.id"
48+
@click="openFile(file)">
49+
<template #preview>
50+
<img v-if="previewEnabled"
51+
:src="getPreviewUrl(file)"
52+
:alt="file.basename"
53+
loading="lazy"
54+
class="overview-file-preview">
55+
<span v-else
56+
class="overview-file-icon" />
57+
</template>
58+
59+
<template #name>
60+
{{ file.basename }}
61+
</template>
62+
63+
<template #subname>
64+
<NcDateTime :timestamp="file.mtime" />
65+
</template>
66+
</FileCard>
67+
</div>
68+
</template>
7369
</template>
7470
</NcAppContent>
7571
</NcContent>
@@ -79,17 +75,11 @@
7975
import { sortNodes } from '@nextcloud/files'
8076
import { loadState } from '@nextcloud/initial-state'
8177
import { generateUrl } from '@nextcloud/router'
82-
import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js'
83-
import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js'
84-
import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js'
85-
import NcContent from '@nextcloud/vue/dist/Components/NcContent.js'
86-
import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js'
87-
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
88-
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
89-
import NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'
78+
import { NcAppContent, NcAppNavigation, NcAppNavigationItem, NcContent, NcDateTime, NcEmptyContent, NcLoadingIcon, NcTextField } from '@nextcloud/vue'
9079
import FileDocumentOutline from 'vue-material-design-icons/FileDocumentOutline.vue'
9180
import FileCard from '../components/FileCard.vue'
92-
import { getAllOfficeFiles, filterByCategory } from '../services/officeFiles.js'
81+
import { getAllOfficeFiles, filterByMimes } from '../services/officeFiles.js'
82+
import { getTemplates } from '../services/templates.js'
9383
9484
export default {
9585
name: 'OfficeOverview',
@@ -109,7 +99,8 @@ export default {
10999
110100
data() {
111101
return {
112-
currentView: 'documents',
102+
creators: [],
103+
activeCreator: null,
113104
allFiles: [],
114105
loading: false,
115106
error: null,
@@ -120,7 +111,10 @@ export default {
120111
121112
computed: {
122113
files() {
123-
const byCategory = filterByCategory(this.allFiles, this.currentView)
114+
if (!this.activeCreator) {
115+
return []
116+
}
117+
const byCategory = filterByMimes(this.allFiles, this.activeCreator.mimetypes)
124118
const filtered = this.searchQuery
125119
? byCategory.filter(f => f.basename.toLowerCase().includes(this.searchQuery.toLowerCase()))
126120
: byCategory
@@ -130,54 +124,21 @@ export default {
130124
sortingOrder: 'asc',
131125
})
132126
},
133-
134-
emptyMessage() {
135-
const labels = {
136-
documents: t('richdocuments', 'No documents found'),
137-
presentations: t('richdocuments', 'No presentations found'),
138-
spreadsheets: t('richdocuments', 'No spreadsheets found'),
139-
diagrams: t('richdocuments', 'No diagrams found'),
140-
}
141-
142-
return labels[this.currentView]
143-
},
144-
145-
fileTypeClass() {
146-
const map = {
147-
documents: 'document',
148-
presentations: 'presentation',
149-
spreadsheets: 'spreadsheet',
150-
diagrams: 'draw',
151-
}
152-
153-
return map[this.currentView]
154-
},
155-
156-
searchLabel() {
157-
const labels = {
158-
documents: t('richdocuments', 'Search documents'),
159-
presentations: t('richdocuments', 'Search presentations'),
160-
spreadsheets: t('richdocuments', 'Search spreadsheets'),
161-
diagrams: t('richdocuments', 'Search diagrams'),
162-
}
163-
164-
return labels[this.currentView]
165-
},
166127
},
167128
168129
watch: {
169-
currentView() {
130+
activeCreator() {
170131
this.searchQuery = ''
171132
},
172133
},
173134
174135
created() {
175-
this.fetchFiles()
136+
this.fetchAll()
176137
},
177138
178139
methods: {
179-
setView(view) {
180-
this.currentView = view
140+
setCreator(creator) {
141+
this.activeCreator = creator
181142
},
182143
183144
getPreviewUrl(file) {
@@ -194,12 +155,18 @@ export default {
194155
}
195156
},
196157
197-
async fetchFiles() {
158+
async fetchAll() {
198159
this.loading = true
199160
this.error = null
200161
201162
try {
202-
this.allFiles = await getAllOfficeFiles()
163+
this.creators = await getTemplates()
164+
this.activeCreator = this.creators[0] ?? null
165+
166+
if (this.creators.length > 0) {
167+
const allMimes = this.creators.flatMap(c => c.mimetypes)
168+
this.allFiles = await getAllOfficeFiles(allMimes)
169+
}
203170
} catch (e) {
204171
this.error = t('richdocuments', 'Failed to load files')
205172
this.allFiles = []

0 commit comments

Comments
 (0)