From 6f49dd892dbda9f5e8af0c6a79b3795a7ef6d5d4 Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Wed, 31 Jan 2024 17:02:02 +0100 Subject: [PATCH] fix(attestation): multiple tags improvements - no menu when no matching tags - insert a space after clicking a button - allow no space before mention --- app/javascript/controllers/tiptap_controller.ts | 14 +++++++++++--- app/javascript/shared/tiptap/tags.ts | 6 ++++++ .../attestation_template_v2s/edit.html.haml | 2 +- .../procedure_attestation_template_spec.rb | 1 + 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/javascript/controllers/tiptap_controller.ts b/app/javascript/controllers/tiptap_controller.ts index b93881567..caf7c4a66 100644 --- a/app/javascript/controllers/tiptap_controller.ts +++ b/app/javascript/controllers/tiptap_controller.ts @@ -9,11 +9,15 @@ import { createEditor } from '../shared/tiptap/editor'; export class TiptapController extends ApplicationController { static targets = ['editor', 'input', 'button', 'tag']; + static values = { + insertAfterTag: { type: String, default: '' } + }; declare editorTarget: Element; declare inputTarget: HTMLInputElement; declare buttonTargets: HTMLButtonElement[]; declare tagTargets: HTMLElement[]; + declare insertAfterTagValue: string; #initializing = true; #editor?: Editor; @@ -58,11 +62,15 @@ export class TiptapController extends ApplicationController { insertTag(event: MouseEvent) { if (this.#editor && isHTMLElement(event.target)) { const tag = tagSchema.parse(event.target.dataset); - this.#editor + const editor = this.#editor .chain() .focus() - .insertContent({ type: 'mention', attrs: tag }) - .run(); + .insertContent({ type: 'mention', attrs: tag }); + + if (this.insertAfterTagValue != '') { + editor.insertContent({ type: 'text', text: this.insertAfterTagValue }); + } + editor.run(); } } diff --git a/app/javascript/shared/tiptap/tags.ts b/app/javascript/shared/tiptap/tags.ts index b017ff833..3a76ca1cd 100644 --- a/app/javascript/shared/tiptap/tags.ts +++ b/app/javascript/shared/tiptap/tags.ts @@ -88,6 +88,11 @@ class SuggestionMenu { } private render() { + if (this.#props.items.length == 0) { + this.#element?.remove(); + return; + } + this.#element ??= this.createMenu(); const list = this.#element.firstChild as HTMLUListElement; @@ -161,6 +166,7 @@ export function createSuggestionMenu( ): Omit, 'editor'> { return { char: '@', + allowedPrefixes: null, allowSpaces: true, items: ({ query }) => { return matchSorter(tags, query, { keys: ['label'] }).slice(0, 6); diff --git a/app/views/administrateurs/attestation_template_v2s/edit.html.haml b/app/views/administrateurs/attestation_template_v2s/edit.html.haml index 2459e8d49..44fe57a0d 100644 --- a/app/views/administrateurs/attestation_template_v2s/edit.html.haml +++ b/app/views/administrateurs/attestation_template_v2s/edit.html.haml @@ -11,7 +11,7 @@ attestation_logo_attachment_official_label_value: AttestationTemplate.human_attribute_name(:logo_additional), attestation_logo_attachment_free_label_value: AttestationTemplate.human_attribute_name(:logo) } do |f| - #attestation-edit.fr-container.fr-mt-4w{ data: { controller: 'tiptap' } } + #attestation-edit.fr-container.fr-mt-4w{ data: { controller: 'tiptap', tiptap_insert_after_tag_value: ' ' } } .fr-mb-6w = render Dsfr::AlertComponent.new(state: :info, title: "Nouvel éditeur d’attestation", heading_level: 'h3') do |c| - c.with_body do diff --git a/spec/system/administrateurs/procedure_attestation_template_spec.rb b/spec/system/administrateurs/procedure_attestation_template_spec.rb index b9be3c31e..b09302939 100644 --- a/spec/system/administrateurs/procedure_attestation_template_spec.rb +++ b/spec/system/administrateurs/procedure_attestation_template_spec.rb @@ -106,6 +106,7 @@ describe 'As an administrateur, I want to manage the procedure’s attestation', first_content == [ { "type" => "mention", "attrs" => { "id" => "dossier_processed_at", "label" => "date de décision" } }, # added by click above + { "type" => "text", "text" => " " }, { "type" => "mention", "attrs" => { "id" => "dossier_service_name", "label" => "nom du service" } } # defaut initial content ] }