attestation_template v2: edit / update

This commit is contained in:
simon lehericey 2023-11-15 09:53:07 +01:00
parent f6001c8eae
commit af53a9b9db
5 changed files with 215 additions and 1 deletions

View file

@ -0,0 +1,16 @@
#attestation-edit {
.mention {
border: 1px solid var(--text-default-grey);
padding: 8px;
}
.selected {
border: 1px solid #000000;
}
.tiptap {
padding: 8px;
min-height: 300px;
}
}

View file

@ -9,9 +9,22 @@ module Administrateurs
render layout: 'attestation'
end
def edit
end
def update
@attestation_template
.update(json_body: editor_params)
end
private
def retrieve_attestation_template
@attestation_template = @procedure.attestation_template || @procedure.build_attestation_template
end
def editor_params
params.permit(content: [:type, content: [:type, :text, attrs: [:id, :label]]])
end
end
end

View file

@ -0,0 +1,175 @@
import { ApplicationController } from './application_controller';
import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';
import Mention from '@tiptap/extension-mention';
import tippy from 'tippy.js';
import { httpRequest } from '@utils';
export class AttestationController extends ApplicationController {
static values = {
tags: Array,
url: String
};
static targets = ['editor', 'bold'];
declare readonly tagsValue: string[];
declare readonly urlValue: string;
declare editor: Editor;
declare editorTarget: HTMLElement;
declare boldTarget: HTMLButtonElement;
connect() {
const conf = {
element: this.editorTarget,
editorProps: {
attributes: {
class: 'fr-input'
}
},
extensions: [
StarterKit,
Mention.configure({
HTMLAttributes: {
class: 'mention'
},
suggestion: {
items: ({ query }) => {
return this.tagsValue
.filter((item) =>
item.toLowerCase().startsWith(query.toLowerCase())
)
.slice(0, 5);
},
render: () => {
let popup: { setProps: Function, hide: Function, destroy: Function }[];
let div: HTMLElement;
let selectedIndex = 0;
let items: string[];
let command: (props: object) => void;
const makeList = () => {
return items
.map((item, i) => {
if (i == selectedIndex) {
return `<li class='selected'>${item}</li>`;
} else {
return `<li>${item}</li>`;
}
})
.join('');
};
return {
onStart: (props) => {
items = props.items;
command = props.command;
div = document.createElement('UL');
div.innerHTML = makeList();
if (!props.clientRect) {
return;
}
let body: Element = document.body;
popup = tippy(body, {
getReferenceClientRect: props.clientRect,
appendTo: () => this.element,
content: div,
showOnCreate: true,
interactive: true,
trigger: 'manual',
placement: 'bottom-start'
});
},
onUpdate(props) {
command = props.command;
items = props.items;
div.innerHTML = makeList();
if (!props.clientRect) {
return;
}
popup[0].setProps({
getReferenceClientRect: props.clientRect
});
},
onKeyDown(props) {
if (props.event.key === 'Escape') {
popup[0].hide();
return true;
}
if (props.event.key === 'ArrowDown') {
selectedIndex = (selectedIndex + 1) % items.length;
div.innerHTML = makeList();
return true;
}
if (props.event.key === 'ArrowUp') {
selectedIndex =
(selectedIndex + items.length - 1) % items.length;
div.innerHTML = makeList();
return true;
}
if (props.event.key === 'Enter') {
const item = items[selectedIndex];
if (item) {
command({ id: item });
}
return true;
}
return false;
},
onExit() {
popup[0].destroy();
div.remove();
}
};
}
}
})
],
content:
'<p>La situation de M. <span data-type="mention" data-id="nom"></span> dont la demande de logement social</p>'
};
this.editor = new Editor(conf);
this.editor.on('transaction', () => {
this.boldTarget.disabled = !this.editor
.can()
.chain()
.focus()
.toggleBold()
.run();
if (this.editor.isActive('bold')) {
this.boldTarget.classList.add('fr-btn--secondary');
} else {
this.boldTarget.classList.remove('fr-btn--secondary');
}
});
}
bold() {
this.editor.chain().focus().toggleBold().run();
}
send() {
const json = this.editor.getJSON();
httpRequest(this.urlValue, { method: 'put', json }).json();
}
}

View file

@ -0,0 +1,10 @@
#attestation-edit.fr-container.mt-2{
data: {
controller: 'attestation',
attestation_tags_value: @attestation_template.tags.map { _1[:libelle] },
attestation_url_value: admin_procedure_attestation_template_v2_path(@procedure)} }
%button.fr-btn{ data: { action: 'click->attestation#bold', attestation_target: 'bold' } } Gras
.editor.mt-2{ data: { attestation_target: 'editor' } }
%button.fr-btn.mt-2{ data: { action: 'click->attestation#send' } } Envoyer

View file

@ -626,7 +626,7 @@ Rails.application.routes.draw do
get 'add_champ_engagement_juridique'
end
resource :attestation_template_v2, only: [:show]
resource :attestation_template_v2, only: [:show, :edit, :update]
resource :dossier_submitted_message, only: [:edit, :update, :create]
# ADDED TO ACCESS IT FROM THE IFRAME