From 57e815471b667f8034de145a3fe6e08f67c09da0 Mon Sep 17 00:00:00 2001 From: niv Date: Wed, 13 May 2026 14:41:25 +0200 Subject: [PATCH 1/2] fix(assistant): render markdown in TextInput output Wrap the output field in NcRichText when isOutput is true, falling back to NcRichContenteditable for the input case. Headings, lists, bold, italic, code blocks and links are now rendered. Tables are not rendered due to the markdown-it configuration of NcRichText in @nextcloud/vue, which does not enable the table plugin by default. The copy still functions and keeps the markdown as expected. Signed-off-by: niv --- src/components/fields/TextInput.vue | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/components/fields/TextInput.vue b/src/components/fields/TextInput.vue index c88045ee..4ecd6379 100644 --- a/src/components/fields/TextInput.vue +++ b/src/components/fields/TextInput.vue @@ -9,7 +9,14 @@
{{ limitLabel ?? '' }} + Date: Wed, 20 May 2026 12:05:28 +0200 Subject: [PATCH 2/2] fix(assistant): allow editing rendered markdown output via double-click Wrap the rendered output in a bounded scrollable container and allow switching to edit mode with a double-click. The contenteditable returns to rendered mode on blur. This preserves the editing capability while keeping the markdown rendering as the default view. Addresses review feedback on #540. Signed-off-by: Nicolas Varlot --- src/components/fields/TextInput.vue | 69 ++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/src/components/fields/TextInput.vue b/src/components/fields/TextInput.vue index 4ecd6379..7adeaae2 100644 --- a/src/components/fields/TextInput.vue +++ b/src/components/fields/TextInput.vue @@ -9,12 +9,17 @@
{{ limitLabel ?? '' }} - +
+ +
+ @update:model-value="$emit('update:value', $event)" + @blur="onEditableBlur" /> { + const ref = this.$refs.input + if (!ref) { + return + } + if (typeof ref.focus === 'function') { + ref.focus() + return + } + const el = ref.$el + if (!el) { + return + } + if (typeof el.focus === 'function') { + el.focus() + return + } + const editable = el.querySelector?.('[contenteditable]') + if (editable && typeof editable.focus === 'function') { + editable.focus() + } + }) + }, + onEditableBlur() { + if (this.isOutput && this.isEditing) { + this.isEditing = false + } + }, }, } @@ -224,6 +264,7 @@ body[dir="rtl"] .choose-file-button { .copy-button, .choose-file-button { position: absolute !important; + z-index: 10; } .choose-file-button { @@ -235,6 +276,18 @@ body[dir="rtl"] .choose-file-button { right: 4px; } + .output-wrapper { + display: block !important; + box-sizing: border-box !important; + border: 2px solid var(--color-primary-element) !important; + border-radius: var(--border-radius) !important; + padding: 8px !important; + padding-bottom: 42px !important; + max-height: 35vh !important; + overflow-y: auto !important; + cursor: text; + } + .rich-contenteditable__input { min-height: calc(var(--default-clickable-area) + 4px); padding-top: 5px !important; @@ -243,6 +296,8 @@ body[dir="rtl"] .choose-file-button { .shadowed .rich-contenteditable__input { border: 2px solid var(--color-primary-element) !important; padding-bottom: 38px !important; + max-height: 35vh !important; + overflow-y: auto !important; } }