Skip to content

Commit

Permalink
Add feature to multilingualize item names defined in DB(draft) #2
Browse files Browse the repository at this point in the history
  • Loading branch information
ishikawa999 committed Jun 5, 2019
1 parent f4993cc commit 0a75581
Show file tree
Hide file tree
Showing 21 changed files with 245 additions and 33 deletions.
9 changes: 7 additions & 2 deletions app/controllers/custom_message_settings_controller.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
class CustomMessageSettingsController < ApplicationController
layout 'admin'
before_action :require_admin, :set_custom_message_setting, :set_lang
require_sudo_mode :edit, :update, :toggle_enabled
require_sudo_mode :edit, :yaml_edit, :update, :toggle_enabled

def edit
end

def yaml_edit
end

def update
languages = @setting.using_languages

if setting_params.key?(:custom_messages) || params[:tab] == 'normal'
@setting.update_with_custom_messages(setting_params[:custom_messages].try(:to_unsafe_h).try(:to_hash) || {}, @lang)
elsif setting_params.key?(:custom_names) || params[:tab] == 'names'
@setting.update_with_custom_names(setting_params[:custom_names].try(:to_unsafe_h).try(:to_hash) || {}, @lang)
elsif setting_params.key?(:custom_messages_yaml)
@setting.update_with_custom_messages_yaml(setting_params[:custom_messages_yaml])
end
Expand All @@ -22,7 +27,7 @@ def update

redirect_to edit_custom_message_settings_path(tab: params[:tab], lang: @lang)
else
render :edit
render :yaml_edit
end
end

Expand Down
39 changes: 38 additions & 1 deletion app/helpers/custom_message_settings_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module CustomMessageSettingsHelper
CustomizableNameClasses = [CustomField, IssueCategory, IssuePriority, IssueStatus, Tracker]
def available_message_options(setting, lang)
options = [['', '']] +
CustomMessageSetting.available_messages(lang).map{|k, v| ["#{k}: #{v}", k]}
Expand All @@ -10,13 +11,49 @@ def normal_mode_input_fields(setting, lang)
return '' if setting.value[:custom_messages].is_a?(String) || setting.value[:custom_messages].blank?
content = ActiveSupport::SafeBuffer.new
custom_messages_hash = setting.custom_messages_to_flatten_hash(lang.to_s)
custom_messages_hash.each do |k, v|
custom_messages_hash, custom_names = custom_messages_hash.to_a.partition{|k, v| !k.to_s.include?('custom_object_name') }

custom_messages_hash.to_h.each do |k, v|
content += content_tag(:p) do
content_tag(:label, k) +
text_field_tag("settings[custom_messages[#{k}]]", v.to_s) +
link_to_function('', '$(this).closest("p").remove();', class: 'icon icon-del clear-key-link')
end
end

custom_names.each do |k, v|
content += hidden_field_tag("settings[custom_messages[#{k}]]", v)
end
content
end

def customizable_name_options(setting, lang)
options = CustomizableNameClasses.map{|c| [c, c.all.map{|r| [r[:name], "#{c.to_s.underscore}_#{r.id}"]}]}

disabled = setting.custom_names(lang).keys
grouped_options_for_select(options, disabled: disabled)
end

def customizable_name_input_fields(setting, lang)
contents = ActiveSupport::SafeBuffer.new
selected_names = setting.custom_names(lang)

CustomizableNameClasses.each do |cl|
original_names = cl.all.select(:id, :name)
names = selected_names.select{|v| v.include?(cl.to_s.underscore)}

contents +=
content_tag(:div, id: cl.to_s.underscore, class: 'class-box') do
concat content_tag(:span, cl.to_s)
names.each do |key, value|
concat(content_tag(:p) do
concat content_tag(:label, original_names.find(key.delete("^0-9").to_i)[:name])
concat text_field_tag("settings[custom_names[#{key}]]", value)
concat link_to_function('', '$(this).closest("p").remove();', class: 'icon icon-del clear-key-link')
end)
end
end
end
contents
end
end
18 changes: 18 additions & 0 deletions app/models/custom_message_setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def custom_messages(lang=nil, check_enabled=false)
end
end

def custom_names(lang)
self.custom_messages(lang)['custom_object_name'] || {}
end

def custom_messages_to_flatten_hash(lang=nil)
self.class.flatten_hash(custom_messages(lang))
end
Expand Down Expand Up @@ -53,6 +57,14 @@ def update_with_custom_messages(custom_messages, lang)
self.save
end

def update_with_custom_names(custom_names, lang)
custom_messages = self.custom_messages
custom_messages[lang]['custom_object_name'] = custom_names

self.value = {custom_messages: (custom_messages.present? ? custom_messages : {})}
self.save
end

def update_with_custom_messages_yaml(yaml)
begin
messages = YAML.load(yaml)
Expand Down Expand Up @@ -141,6 +153,8 @@ def custom_message_keys_are_available
custom_messages.values.compact.each do |val|
custom_messages_hash = self.class.flatten_hash(custom_messages_hash.merge(val)) if val.is_a?(Hash)
end
custom_messages_hash = remove_custom_object_name_keys(custom_messages_hash)

available_keys = self.class.flatten_hash(self.class.available_messages('en')).keys
unavailable_keys = custom_messages_hash.keys.reject{|k| available_keys.include?(k.to_sym)}
if unavailable_keys.present?
Expand All @@ -149,6 +163,10 @@ def custom_message_keys_are_available
end
end

def remove_custom_object_name_keys(custom_messages)
custom_messages.reject{|k| k.to_s.include?('custom_object_name')}
end

def custom_message_languages_are_available
return false if !value[:custom_messages].is_a?(Hash) || errors.present?

Expand Down
6 changes: 3 additions & 3 deletions app/views/custom_message_settings/_messages.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<%= javascript_tag do %>
$(document).ready(function() {
setSelect2();
setCustomMessagesSelect2();
});

$('#key-selector').on('select2:select', function (e) {
Expand All @@ -30,11 +30,11 @@ $('#key-selector').on('select2:select', function (e) {
}).appendTo($('#edit-custom-messages .tabular p:first'));
$('#key-selector').val('').change();
$('#key-selector option[value="' + key + '"]').prop("disabled", true).change();
setSelect2();
setCustomMessagesSelect2();
}
});

function setSelect2(){
function setCustomMessagesSelect2(){
$("#key-selector").select2({
width: '100%',
placeholder: '<%= l(:text_placeholder_choose_key) %>',
Expand Down
6 changes: 6 additions & 0 deletions app/views/custom_message_settings/_messages_tab.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%= form_tag custom_message_settings_path, method: :post do %>
<div id='edit-custom-messages'>
<%= render 'custom_message_settings/messages', lang: @lang %>
</div>
<%= submit_tag l(:button_save) %>
<% end %>
45 changes: 45 additions & 0 deletions app/views/custom_message_settings/_names.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<div>
<%= select_tag 'select-key', customizable_name_options(@setting, lang), id: 'customizable-name-selector', :include_blank => true %><br>
<span class='icon icon-help'><%= l(:text_description_of_search_box) %></span>
</div>
<br>
<div class='tabular'>
<%= customizable_name_input_fields(@setting, lang) %>
</div>
<%= javascript_tag do %>
$(document).ready(function() {
setCustomNamesSelect2();
});

$('#customizable-name-selector').on('select2:select', function (e) {
const key = e.params.data.id;
const val = e.params.data.text;
const category = key.replace(/[0-9]/g, '').slice(0, -1);
const selector = '#edit-custom-names div#' + category;

if($(selector + ' input[name="settings[custom_names[' + key + ']]"]').length === 0){
$(selector).prepend('<p></p>');
$('<label>' + val + '</label><br>').appendTo($(selector + ' p:first'));
$('<input>').attr({
type: 'text',
value: val,
name: 'settings[custom_names[' + key + ']]',
}).appendTo($(selector + ' p:first'));
$('<a>').attr({
class: 'icon icon-del clear-key-link',
href: '#',
onclick: '$(this).closest("p").remove(); return false;'
}).appendTo($(selector + ' p:first'));
$('#customizable-name-selector').val('').change();
$('#customizable-name-selector option[value="' + key + '"]').prop("disabled", true).change();
setCustomNamesSelect2();
}
});

function setCustomNamesSelect2(){
$("#customizable-name-selector").select2({
width: '100%',
placeholder: '<%= l(:text_placeholder_choose_key) %>'
});
}
<% end %>
6 changes: 6 additions & 0 deletions app/views/custom_message_settings/_names_tab.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%= form_tag custom_message_settings_path, method: :post do %>
<div id='edit-custom-names'>
<%= render 'custom_message_settings/names', lang: @lang %>
</div>
<%= submit_tag l(:button_save) %>
<% end %>
11 changes: 0 additions & 11 deletions app/views/custom_message_settings/_normal_tab.html.erb

This file was deleted.

19 changes: 13 additions & 6 deletions app/views/custom_message_settings/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@

<% if @setting.errors.any? %>
<%= error_messages_for(@setting) %>
<% end %>
<p class='toggle-enable'>
<span class='icon icon-settings'></span>
<%= link_to (@setting.enabled? ? l(:label_disable_customize) : l(:label_enable_customize)), toggle_enabled_custom_message_settings_path, method: :post %>
</p>
<%= render_tabs (@setting.errors.any? ? [] : [{name: 'normal', partial: 'normal_tab', label: 'label_normal_tab'}]) + [{name: 'yaml', partial: 'yaml_tab', label: 'label_yaml_tab'}] %>
<% else %>
<p class='customize-action-menu'>
<span class='icon icon-settings'></span>
<%= link_to (@setting.enabled? ? l(:label_disable_customize) : l(:label_enable_customize)), toggle_enabled_custom_message_settings_path, method: :post %> /
<%= link_to(l(:label_yaml_edit), yaml_edit_custom_message_settings_path) %>
</p>

<label><%= l(:field_language) %>: </label>
<%= select_tag 'lang', options_for_select(languages_options, @lang), include_blank: true, data: {remote: true, url: url_for(action: :edit)}, onchange: '$("#ajax-indicator").show();' %>
<hr>

<%= render_tabs (@setting.errors.any? ? [] : [{name: 'messages', partial: 'messages_tab', label: 'label_messages_tab'}, {name: 'names', partial: 'names_tab', label: 'label_names_tab'}]) %>
<% end %>
1 change: 1 addition & 0 deletions app/views/custom_message_settings/edit.js.erb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
$('#edit-custom-messages').html("<%= j (render 'custom_message_settings/messages', lang: @lang) %>");
$('#edit-custom-names').html("<%= j (render 'custom_message_settings/names', lang: @lang) %>");
$('#ajax-indicator').hide();
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<h2><%= l(:label_yaml_edit) %></h2>
<%= form_tag custom_message_settings_path, method: :post do %>
<%= hidden_field_tag :tab, 'yaml' %>
<div class='help-message wiki'>
Expand Down
35 changes: 29 additions & 6 deletions assets/stylesheets/custom_messages.css
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
#edit-custom-messages label {
#edit-custom-messages label,
#edit-custom-names label {
width: 100%;
margin-left: 3px;
word-break: break-all;
text-align: left;
}

#edit-custom-messages input {
#edit-custom-messages input,
#edit-custom-names input {
width: 100%;
}

#edit-custom-messages p {
#edit-custom-messages p,
#edit-custom-names p {
padding-left: 3px;
margin-top: 1px;
margin-top: 2px;
border: solid 1px #d1d1d1;
background: #eee;
}

#key-selector {
#key-selector,
#customizable-name-selector {
width: 80%;
}

Expand All @@ -36,6 +40,25 @@
color: white;
}

p.toggle-enable {
p.customize-action-menu {
text-align: right;
}

div.class-box {
border-top: solid 2px #d1d1d1;
position: relative;
margin: 15px 0;
padding: 0.5em 1em;
}
div.class-box span {
position: absolute;
display: inline-block;
top: -13px;
left: 10px;
padding: 0 9px;
line-height: 1;
font-size: 19px;
background: #FFF;
color: #95ccff;
font-weight: bold;
}
5 changes: 3 additions & 2 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ en:
error_invalid_yaml_format: The format of yaml is invalid.
notice_enabled_customize: Successful in enable messages customization.
notice_disabled_customize: Successful in disable messages customization.
label_normal_tab: Normal mode
label_yaml_tab: YAML mode
label_messages_tab: Customize messages
label_names_tab: Customize item names(Tracker, Category, etc.)
label_yaml_edit: Edit in YAML format
label_enable_customize: Enable customize
label_disable_customize: Disable customize
5 changes: 3 additions & 2 deletions config/locales/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ ja:
error_invalid_yaml_format: YAMLの形式が正しくありません。
notice_enabled_customize: メッセージのカスタマイズを有効に変更しました。
notice_disabled_customize: メッセージのカスタマイズを無効に変更しました。
label_normal_tab: 通常モード
label_yaml_tab: YAMLモード
label_messages_tab: メッセージをカスタマイズ
label_names_tab: 項目の名前をカスタマイズ(トラッカー、カテゴリーなど)
label_yaml_edit: YAMLを直接編集する
label_enable_customize: カスタマイズを有効にする
label_disable_customize: カスタマイズを無効にする
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Rails.application.routes.draw do
resources :custom_message_settings, only: [] do
get :edit, on: :collection
get :yaml_edit, on: :collection
post :update, on: :collection
post :toggle_enabled, on: :collection
end
Expand Down
6 changes: 6 additions & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
require_dependency 'issue_status_patch'
require_dependency 'issue_category_patch'
require_dependency 'issue_priority_patch'
require_dependency 'tracker_patch'
require_dependency 'custom_field_patch'

p = Redmine::Plugin.register :redmine_message_customize do
name 'Redmine customize messages plugin'
description 'This is a plugin that allows messages in Redmine to be overwritten from the admin view'
Expand Down
13 changes: 13 additions & 0 deletions lib/custom_field_patch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require_dependency 'custom_field'

module CustomMessages
module CustomFieldPatch
def name
l("custom_object_name.custom_field_#{self.id}", {default: super, fallback: false})
end
end
end

unless CustomField.included_modules.include?(CustomMessages::CustomFieldPatch)
CustomField.prepend(CustomMessages::CustomFieldPatch)
end
Loading

0 comments on commit 0a75581

Please sign in to comment.