diff --git a/app/admin/newsletter.rb b/app/admin/newsletter.rb index a92046f9c..4367ad951 100644 --- a/app/admin/newsletter.rb +++ b/app/admin/newsletter.rb @@ -128,11 +128,16 @@ end form data: { - controller: 'code-editor form-select-hidder', + controller: 'code-editor form-select-hidder auto-save', code_editor_target: 'form', - code_editor_preview_path_value: '/newsletters/preview.js' + code_editor_preview_path_value: '/newsletters/preview.js', + auto_save_target: 'form', + action: 'change->auto-save#saveToLocalStorage trix-change->auto-save#saveToLocalStorage submit->auto-save#clearLocalStorage' } do |f| newsletter = f.object + div class: 'form-warning', data: { 'auto-save-target' => 'warningMessage' } do + span t('newsletters.auto_save_recovered') + end f.inputs t('.details') do f.input :id, as: :hidden translated_input(f, :subjects, @@ -229,8 +234,11 @@ hint: t('formtastic.hints.liquid_data_preview'), wrapper_html: { class: 'ace-editor' }, input_html: { - class: 'ace-edito', - data: { mode: 'yaml', code_editor_target: 'editor' }, + class: 'ace-editor', + data: { + mode: 'yaml', + code_editor_target: 'editor' + }, name: "newsletter[liquid_data_preview_yamls][#{locale}]" }) end diff --git a/app/assets/stylesheets/active_admin.css.erb b/app/assets/stylesheets/active_admin.css.erb index e7cb36723..905da54fb 100644 --- a/app/assets/stylesheets/active_admin.css.erb +++ b/app/assets/stylesheets/active_admin.css.erb @@ -37,6 +37,24 @@ form legend span { color: #ff2600; } +.form-warning { + display: none; + width: 100%; + text-align: center; + margin-top: -37px; + margin-bottom: 10px; +} + +.form-warning span { + display: inline-block; + padding: 5px 10px; + background-color: #fff4f2; + font-size: 14px; + border-color: rgba(255, 38, 0, 0.5); + color: #ff2600; + border-radius: 8px; +} + .flash_alert:hover { border-color: #ff2600; } diff --git a/app/javascript/controllers/admin/auto_save_controller.js b/app/javascript/controllers/admin/auto_save_controller.js new file mode 100644 index 000000000..969af85f3 --- /dev/null +++ b/app/javascript/controllers/admin/auto_save_controller.js @@ -0,0 +1,66 @@ +import { Controller } from "@hotwired/stimulus" +import { show } from "components/utils" + +export default class extends Controller { + static targets = ["form", "warningMessage"]; + + connect() { + this.localStorageKey = window.location + this.setFormData() + } + + clearLocalStorage() { + if (localStorage.getItem(this.localStorageKey) != null) { + localStorage.removeItem(this.localStorageKey) + } + } + + getFormData() { + const form = new FormData(this.formTarget) + let data = [] + + for (var pair of form.entries()) { + if (pair[0] != "authenticity_token") { + let editor = this.formTarget.querySelector(`[name='${pair[0]}'] ~ trix-editor`) + if (editor) { + data.push([pair[0], JSON.stringify(editor.editor)]) + } + else { + data.push([pair[0], pair[1]]) + } + } + } + + return Object.fromEntries(data) + } + + saveToLocalStorage() { + const data = this.getFormData() + localStorage.setItem(this.localStorageKey, JSON.stringify(data)) + } + + setFormData() { + if (localStorage.getItem(this.localStorageKey) != null) { + show(this.warningMessageTarget) + const data = JSON.parse(localStorage.getItem(this.localStorageKey)) + const form = this.formTarget + Object.entries(data).forEach((entry) => { + let name = entry[0] + let value = entry[1] + let input = form.querySelector(`[name='${name}']`) + if (input) { + let editor = form.querySelector(`[name='${name}'] ~ trix-editor`) + if (editor) { + editor.editor.loadJSON(JSON.parse(value)) + } else { + input.value = value + // Wait for other Stimulus controllers loading before triggering a change event. + setTimeout(() => { + this.dispatch('change', { target: input, prefix: false }) + }, 100) + } + } + }) + } + } +} diff --git a/config/locales/newsletters.yml b/config/locales/newsletters.yml index 9b20061d4..d6a2828f2 100644 --- a/config/locales/newsletters.yml +++ b/config/locales/newsletters.yml @@ -9,6 +9,10 @@ _: _de: Fehlende _fr: Manquantes _it: Mancanti + auto_save_recovered: + _de: Lokale automatische Sicherung wiederhergestellt, vergessen Sie nicht, Ihren Entwurf zu speichern! + _fr: Sauvegarde automatique locale récupérée, n'oubliez pas de sauver votre brouillon! + _it: Backup automatico locale recuperato, non dimenticare di salvare la tua bozza! member_state: all: _de: Alle