From 3ab4141f635ba21fbaeb0fc59a5b9848f811b3dc Mon Sep 17 00:00:00 2001 From: Arnaud Levy <contact@arnaudlevy.com> Date: Tue, 26 Dec 2023 18:39:16 +0100 Subject: [PATCH] working --- .../javascripts/admin/commons/translation.js | 58 +++++++++++++++++++ .../admin/translation_controller.rb | 3 + .../i18n/_translate_button.html.erb | 21 +++++++ .../meta_description/_form.html.erb | 2 + .../admin/application/summary/_form.html.erb | 1 + .../websites/posts/_form.html.erb | 22 +++---- app/views/admin/translation/translate.js.erb | 13 ----- config/locales/en.yml | 4 +- config/locales/fr.yml | 4 +- config/routes.rb | 2 +- 10 files changed, 100 insertions(+), 30 deletions(-) create mode 100644 app/assets/javascripts/admin/commons/translation.js create mode 100644 app/views/admin/application/i18n/_translate_button.html.erb delete mode 100644 app/views/admin/translation/translate.js.erb diff --git a/app/assets/javascripts/admin/commons/translation.js b/app/assets/javascripts/admin/commons/translation.js new file mode 100644 index 000000000..ab91b8767 --- /dev/null +++ b/app/assets/javascripts/admin/commons/translation.js @@ -0,0 +1,58 @@ +window.osuny.translation = { + init: function () { + 'use strict'; + this.component = document.querySelector('#translation-button'); + this.start = document.querySelector('.js-translation-start'); + this.loader = document.querySelector('.js-translation-loader'); + this.done = document.querySelector('.js-translation-done'); + this.start.addEventListener('click', this.run.bind(this)); + this.url = this.component.dataset.translationUrl; + this.translatableFields = document.querySelectorAll('[data-translatable]'); + }, + + run: function () { + this.start.hidden = true; + this.loader.hidden = false; + setTimeout(this.translateAllFields.bind(this), 100); + }, + + translateAllFields: function () { + for (var i = 0; i < this.translatableFields.length; i++) { + var field = this.translatableFields[i]; + this.translate(field); + } + this.loader.hidden = true; + this.done.hidden = false; + }, + + translate: function (field) { + var text = field.value, + xhr = new XMLHttpRequest(); + xhr.open("POST", this.url, false); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.onreadystatechange = function () { + if (this.readyState != 4) return; + if (this.status == 200) { + var data = JSON.parse(this.responseText); + field.value = data.translatedText; + } + }; + xhr.send(JSON.stringify({ + text: text + })); + }, + + invoke: function () { + 'use strict'; + return { + init: this.init.bind(this) + }; + } +}.invoke(); + +window.addEventListener('DOMContentLoaded', function () { + 'use strict'; + if (document.querySelector('#translation-button')) { + window.osuny.translation.init(); + } +}); diff --git a/app/controllers/admin/translation_controller.rb b/app/controllers/admin/translation_controller.rb index 5bd966ace..973d82267 100644 --- a/app/controllers/admin/translation_controller.rb +++ b/app/controllers/admin/translation_controller.rb @@ -1,9 +1,12 @@ class Admin::TranslationController < Admin::ApplicationController + skip_before_action :verify_authenticity_token + def translate @target = translation_params[:target] @response = LibreTranslate.translate translation_params[:text], source: translation_params[:from], target: translation_params[:to] + render json: @response end protected diff --git a/app/views/admin/application/i18n/_translate_button.html.erb b/app/views/admin/application/i18n/_translate_button.html.erb new file mode 100644 index 000000000..03590325e --- /dev/null +++ b/app/views/admin/application/i18n/_translate_button.html.erb @@ -0,0 +1,21 @@ +<% if about.is_a_translation? %> + <% + path = admin_translate_path from: about.original.language.iso_code, + to: about.language.iso_code, + lang: nil, + website_id: nil + %> + <span id="translation-button" data-translation-url="<%= path %>"> + <a class="btn btn-light btn-xs js-translation-start"> + <%= t('admin.translation.button') %> + </a> + <span class="spinner-border spinner-border-sm js-translation-loader" role="status" hidden> + <span class="sr-only"> + <%= t('admin.translation.running') %> + </span> + </span> + <span class="js-translation-done small" hidden> + <%= t('admin.translation.done') %> + </span> + </span> +<% end %> \ No newline at end of file diff --git a/app/views/admin/application/meta_description/_form.html.erb b/app/views/admin/application/meta_description/_form.html.erb index 0deb74c7d..b2fa7057e 100644 --- a/app/views/admin/application/meta_description/_form.html.erb +++ b/app/views/admin/application/meta_description/_form.html.erb @@ -3,6 +3,8 @@ label: t('admin.meta_description.label'), hint: t('admin.meta_description.hint'), input_html: { + data: { translatable: true }, + rows: 3, value: about.meta_description&.gsub('&', '&') } %> <% end %> diff --git a/app/views/admin/application/summary/_form.html.erb b/app/views/admin/application/summary/_form.html.erb index a81bccd8b..23d1058a5 100644 --- a/app/views/admin/application/summary/_form.html.erb +++ b/app/views/admin/application/summary/_form.html.erb @@ -2,5 +2,6 @@ label: t('admin.summary.label'), hint: t('admin.summary.hint'), input_html: { + data: { translatable: true }, value: about.summary&.gsub('&', '&') } %> diff --git a/app/views/admin/communication/websites/posts/_form.html.erb b/app/views/admin/communication/websites/posts/_form.html.erb index 5db38e3d8..1caf9af94 100644 --- a/app/views/admin/communication/websites/posts/_form.html.erb +++ b/app/views/admin/communication/websites/posts/_form.html.erb @@ -5,17 +5,7 @@ <div class="row"> <div class="col-md-8"> <%= osuny_panel t('content') do %> - <%= link_to 'Traduire', - admin_translate_path( - text: post.title, - from: post.original.language.iso_code, - to: post.language.iso_code, - target: 'communication_website_post_title' - ), - method: :post, - class: 'action float-end', - remote: true if post.is_a_translation? %> - <%= f.input :title %> + <%= f.input :title, input_html: { data: { translatable: true } } %> <%= render 'admin/application/summary/form', f: f, about: post %> <%= f.input :text, as: :summernote if strip_tags(post.text).present? %> <% end %> @@ -30,9 +20,7 @@ <% end %> </div> <% end %> - <div class="col-md-6"> - <%= render 'admin/application/meta_description/form', f: f, about: post %> - </div> + <%= render 'admin/application/meta_description/form', f: f, about: post %> </div> </div> <div class="col-md-4"> @@ -61,6 +49,12 @@ <%= render 'admin/application/featured_image/edit', about: @post, f: f %> </div> </div> + + + <% content_for :action_bar_left do %> + <%= render 'admin/application/i18n/translate_button', about: @post %> + <% end %> + <% content_for :action_bar_right do %> <%= submit f %> <% end %> diff --git a/app/views/admin/translation/translate.js.erb b/app/views/admin/translation/translate.js.erb deleted file mode 100644 index 974d6e578..000000000 --- a/app/views/admin/translation/translate.js.erb +++ /dev/null @@ -1,13 +0,0 @@ -document.getElementById("<%= @target %>").value = "<%= @response['translatedText'] %>"; -notyf = new Notyf(); -notyf.open({ - type: 'success', - position: { - x: 'center', - y: 'bottom' - }, - message: "<%= t('admin.translation.done') %>", - duration: 9000, - ripple: true, - dismissible: true -}); \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index a4c4afbd4..4a2aea9d5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -145,7 +145,9 @@ en: label: Summary hint: A short text, like a heading for an article. Don't write all the content here, there are blocks for that. translation: - done: Translation done! + button: Translate automatically + done: Translation done! Please proof read before you save. + running: Currently translating users_alerts: already_confirmed: "Your account has already been confirmed." not_locked_html: '<i>%{model}</i> was not locked.' diff --git a/config/locales/fr.yml b/config/locales/fr.yml index f53544748..679021523 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -145,7 +145,9 @@ fr: label: Résumé hint: Un texte court, comme un chapô pour un article. Ne mettez pas tout le contenu ici, pour ça, il y a les blocs ! translation: - done: Traduction effectuée ! + button: Traduire automatiquement + done: Traduction effectuée ! Merci de relire avant d'enregistrer. + running: Traduction en cours users_alerts: already_confirmed: "Votre compte est déjà confirmé." not_locked_html: "<i>%{model}</i> n'était pas verrouillé(e)." diff --git a/config/routes.rb b/config/routes.rb index 8c25c18d2..a95647a60 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -23,7 +23,7 @@ Rails.application.routes.draw do post 'resend_confirmation_email' => 'users#resend_confirmation_email', on: :member patch 'unlock' => 'users#unlock', on: :member end - post 'translate' => 'translation#translate', as: :translate + post 'translate/:from/:to' => 'translation#translate', as: :translate put 'theme' => 'application#set_theme', as: :set_theme put 'favorite' => 'users#favorite', as: :favorite draw 'admin/administration' -- GitLab