From b38cd3e235e709743447b93403369287e30f3496 Mon Sep 17 00:00:00 2001 From: James Manuel Date: Wed, 20 May 2026 14:36:38 +0200 Subject: [PATCH 1/3] feat(overview): add TemplateSection component with blank and template cards Signed-off-by: James Manuel --- src/components/TemplateSection.vue | 165 +++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 src/components/TemplateSection.vue diff --git a/src/components/TemplateSection.vue b/src/components/TemplateSection.vue new file mode 100644 index 0000000000..fbb5e389fb --- /dev/null +++ b/src/components/TemplateSection.vue @@ -0,0 +1,165 @@ + + + + + + From e8f96b722c7e2f364046d481e5d6221291f73218 Mon Sep 17 00:00:00 2001 From: James Manuel Date: Wed, 20 May 2026 14:38:36 +0200 Subject: [PATCH 2/3] feat(overview): wire TemplateSection into OfficeOverview with create dialog Signed-off-by: James Manuel --- src/views/OfficeOverview.vue | 78 ++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/src/views/OfficeOverview.vue b/src/views/OfficeOverview.vue index 4b8666b040..c341434ded 100644 --- a/src/views/OfficeOverview.vue +++ b/src/views/OfficeOverview.vue @@ -32,6 +32,10 @@ type="search" /> + + @@ -66,6 +70,25 @@ + + + + +
+ + +
@@ -75,26 +98,30 @@ import { sortNodes } from '@nextcloud/files' import { loadState } from '@nextcloud/initial-state' import { generateUrl } from '@nextcloud/router' -import { NcAppContent, NcAppNavigation, NcAppNavigationItem, NcContent, NcDateTime, NcEmptyContent, NcLoadingIcon, NcTextField } from '@nextcloud/vue' +import { NcAppContent, NcAppNavigation, NcAppNavigationItem, NcButton, NcContent, NcDateTime, NcDialog, NcEmptyContent, NcLoadingIcon, NcTextField } from '@nextcloud/vue' import FileDocumentOutline from 'vue-material-design-icons/FileDocumentOutline.vue' import FileCard from '../components/FileCard.vue' -import { getAllOfficeFiles, filterByMimes } from '../services/officeFiles.js' -import { getTemplates } from '../services/templates.js' +import TemplateSection from '../components/TemplateSection.vue' +import { getAllOfficeFiles, filterByMimes, invalidateOfficeFilesCache } from '../services/officeFiles.js' +import { getTemplates, createFromTemplate } from '../services/templates.js' export default { name: 'OfficeOverview', components: { FileCard, + FileDocumentOutline, NcAppContent, NcAppNavigation, NcAppNavigationItem, + NcButton, NcContent, NcDateTime, + NcDialog, NcEmptyContent, NcLoadingIcon, NcTextField, - FileDocumentOutline, + TemplateSection, }, data() { @@ -106,6 +133,11 @@ export default { error: null, previewEnabled: loadState('richdocuments', 'previewEnabled', false), searchQuery: '', + showCreateDialog: false, + newFileName: '', + pendingCreator: null, + pendingTemplate: null, + creating: false, } }, @@ -155,6 +187,40 @@ export default { } }, + onTemplateSelect(creator, template) { + this.pendingCreator = creator + this.pendingTemplate = template + this.newFileName = creator.label.replace(/^New\s+/i, '') + creator.extension + this.showCreateDialog = true + this.$nextTick(() => { + const input = this.$refs.createInput?.$el?.querySelector('input') + if (input) { + input.focus() + input.setSelectionRange(0, this.newFileName.length - creator.extension.length) + } + }) + }, + + async doCreateFromTemplate() { + if (!this.newFileName.trim() || this.creating) { + return + } + this.creating = true + try { + const filePath = '/' + this.newFileName.trim() + const templatePath = this.pendingTemplate?.filename ?? '' + const templateType = this.pendingTemplate ? 'user' : 'user_system' + await createFromTemplate(filePath, templatePath, templateType) + this.showCreateDialog = false + invalidateOfficeFilesCache() + await this.fetchAll() + } catch (e) { + this.error = t('richdocuments', 'Failed to create file') + } finally { + this.creating = false + } + }, + async fetchAll() { this.loading = true this.error = null @@ -211,4 +277,8 @@ export default { max-width: 400px; margin: 0 auto; } + +.office-overview__create-form { + min-height: calc(2 * var(--default-clickable-area)); +} From a556284c0e8c5adfb3886bf34c3134997c6599d6 Mon Sep 17 00:00:00 2001 From: James Manuel Date: Wed, 20 May 2026 15:17:26 +0200 Subject: [PATCH 3/3] fix(overview): correct nav category names, icons, dialog title, active creator and duplicate error Signed-off-by: James Manuel --- src/views/OfficeOverview.vue | 47 ++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/views/OfficeOverview.vue b/src/views/OfficeOverview.vue index c341434ded..c0c7e15515 100644 --- a/src/views/OfficeOverview.vue +++ b/src/views/OfficeOverview.vue @@ -8,9 +8,14 @@ @@ -28,7 +33,7 @@