aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElizabeth Danzberger <lizzy7128@tutanota.de>2025-04-28 13:22:19 -0400
committerElizabeth Danzberger <lizzy7128@tutanota.de>2025-04-28 15:19:31 -0400
commit9112dce0512304e1317a7298d22b9b172c1ce340 (patch)
tree774a9545aead40aff6353f5b9bf3ea1a0548121d
parent40e52e212ac32758b6d8b7a06e8e6f747fefe823 (diff)
downloadnextcloud-server-feat/template-field-extraction-improvements.tar.gz
nextcloud-server-feat/template-field-extraction-improvements.zip
feat: only get template fields once selectedfeat/template-field-extraction-improvements
In order to improve the performance and flow of creating a new file from a template, the `setFields` method will be deprecated and we instead use a new property, `setFieldsUrl`, which allows apps to specify an endpoint for extracting the template fields. This endpoint is used by the template picker to request the fields only once the user has selected a template, instead of fetching all template fields before opening and causing a terribly slow experience. Signed-off-by: Elizabeth Danzberger <lizzy7128@tutanota.de>
-rw-r--r--apps/files/lib/ResponseDefinitions.php1
-rw-r--r--apps/files/src/services/Templates.js5
-rw-r--r--apps/files/src/views/TemplatePicker.vue31
-rw-r--r--lib/public/Files/Template/Template.php13
4 files changed, 44 insertions, 6 deletions
diff --git a/apps/files/lib/ResponseDefinitions.php b/apps/files/lib/ResponseDefinitions.php
index c5d094e7bd8..f10edd3216c 100644
--- a/apps/files/lib/ResponseDefinitions.php
+++ b/apps/files/lib/ResponseDefinitions.php
@@ -46,6 +46,7 @@ namespace OCA\Files;
* hasPreview: bool,
* previewUrl: ?string,
* fields: list<FilesTemplateField>,
+ * fieldsUrl: ?string,
* }
*
* @psalm-type FilesTemplateFileCreator = array{
diff --git a/apps/files/src/services/Templates.js b/apps/files/src/services/Templates.js
index 3a0a0fdb809..cd75d105fd5 100644
--- a/apps/files/src/services/Templates.js
+++ b/apps/files/src/services/Templates.js
@@ -11,6 +11,11 @@ export const getTemplates = async function() {
return response.data.ocs.data
}
+export const getTemplateFields = async function(fieldsUrl) {
+ const response = await axios.get(fieldsUrl)
+ return response.data.ocs.data
+}
+
/**
* Create a new file from a specified template
*
diff --git a/apps/files/src/views/TemplatePicker.vue b/apps/files/src/views/TemplatePicker.vue
index 15286a220e9..12226e7b07b 100644
--- a/apps/files/src/views/TemplatePicker.vue
+++ b/apps/files/src/views/TemplatePicker.vue
@@ -57,7 +57,7 @@ import { translate as t } from '@nextcloud/l10n'
import { generateRemoteUrl } from '@nextcloud/router'
import { normalize, extname, join } from 'path'
import { defineComponent } from 'vue'
-import { createFromTemplate, getTemplates } from '../services/Templates.js'
+import { createFromTemplate, getTemplates, getTemplateFields } from '../services/Templates.js'
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
import NcModal from '@nextcloud/vue/components/NcModal'
@@ -215,7 +215,7 @@ export default defineComponent({
}
},
- async createFile(templateFields) {
+ async createFile(templateFields = []) {
const currentDirectory = new URL(window.location.href).searchParams.get('dir') || '/'
// If the file doesn't have an extension, add the default one
@@ -274,14 +274,33 @@ export default defineComponent({
},
async onSubmit() {
- if (this.selectedTemplate?.fields?.length > 0) {
+ const fieldsUrl = this.selectedTemplate?.fieldsUrl
+
+ if (!fieldsUrl) {
+ this.loading = true
+ return await this.createFile()
+ }
+
+ try {
+ const fields = await getTemplateFields(fieldsUrl)
+
+ if (fields.length < 1) {
+ this.loading = true
+ return await this.createFile()
+ }
+
spawnDialog(TemplateFiller, {
- fields: this.selectedTemplate.fields,
onSubmit: this.createFile,
+ fields,
})
- } else {
+ } catch (error) {
+ logger.error('Error while extracting fields from template', { error })
+ showError(t('files', 'Could not extract fields from template'))
+
+ // If fetching the template fields fails, we can create
+ // a file anyway without any fields filled
this.loading = true
- await this.createFile()
+ await this.createFile([])
}
},
},
diff --git a/lib/public/Files/Template/Template.php b/lib/public/Files/Template/Template.php
index 7f01c2afa48..b3ecbb91073 100644
--- a/lib/public/Files/Template/Template.php
+++ b/lib/public/Files/Template/Template.php
@@ -26,6 +26,8 @@ final class Template implements \JsonSerializable {
private $previewUrl = null;
/** @var list<Field> */
private $fields = [];
+ /** @var string|null */
+ private $fieldsUrl = null;
/**
* @since 21.0.0
@@ -51,6 +53,7 @@ final class Template implements \JsonSerializable {
}
/**
+ * @deprecated
* @param list<Field> $fields
* @since 30.0.0
*/
@@ -59,6 +62,14 @@ final class Template implements \JsonSerializable {
}
/**
+ * @param string $fieldsUrl
+ * @since 32.0.0
+ */
+ public function setFieldsUrl(string $fieldsUrl): void {
+ $this->fieldsUrl = $fieldsUrl;
+ }
+
+ /**
* @return array{
* templateType: string,
* templateId: string,
@@ -72,6 +83,7 @@ final class Template implements \JsonSerializable {
* type: string,
* hasPreview: bool,
* previewUrl: ?string,
+ * fieldsUrl: ?string,
* fields: list<array{
* index: string,
* type: string,
@@ -99,6 +111,7 @@ final class Template implements \JsonSerializable {
'hasPreview' => $this->hasPreview,
'previewUrl' => $this->previewUrl,
'fields' => array_map(static fn (Field $field) => $field->jsonSerialize(), $this->fields),
+ 'fieldsUrl' => $this->fieldsUrl,
];
}
}