fix(attestation): multiple tags improvements
- no menu when no matching tags - insert a space after clicking a button - allow no space before mention
This commit is contained in:
parent
58064dc6cd
commit
6f49dd892d
4 changed files with 19 additions and 4 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<SuggestionOptions<TagSchema>, 'editor'> {
|
||||
return {
|
||||
char: '@',
|
||||
allowedPrefixes: null,
|
||||
allowSpaces: true,
|
||||
items: ({ query }) => {
|
||||
return matchSorter(tags, query, { keys: ['label'] }).slice(0, 6);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue