new code for attribute fields and values for new member interface
This commit is contained in:
		
							parent
							
								
									293dc80ceb
								
							
						
					
					
						commit
						8b9cffd4f2
					
				|  | @ -310,3 +310,6 @@ | |||
| .user-role .staff h4 .gender { | ||||
| 	border-color: #139E2F transparent transparent #139E2F; | ||||
| } | ||||
| .user-role .tab-content, .user-role .tabs-right > .nav-tabs { | ||||
| 	float: left; | ||||
| } | ||||
|  | @ -12,12 +12,12 @@ | |||
| 	border-radius: 4px; | ||||
| 	margin-bottom: 10px; | ||||
| } | ||||
| .site-map .map-block ul { | ||||
| .site-map .map-block > ul { | ||||
| 	margin: 0px; | ||||
| 	list-style: none; | ||||
| 	width: 220px \9; | ||||
| } | ||||
| .site-map .map-block li { | ||||
| .site-map .map-block li.clear { | ||||
| 	background-color: #F7F7F7; | ||||
| 	padding: 5px 15px; | ||||
| 	border-top: 1px solid #FFF; | ||||
|  |  | |||
|  | @ -32,6 +32,7 @@ class Admin::InfosController < ApplicationController | |||
|    | ||||
|   def update | ||||
|     @attribute = Info.find(params[:id]) | ||||
|     # binding.pry | ||||
|     @attribute.update_attributes(params[:info]) | ||||
|     respond_to do |format| | ||||
|       format.html { redirect_to :action => :index } | ||||
|  |  | |||
|  | @ -2,6 +2,16 @@ module ApplicationHelper | |||
| 
 | ||||
|   FLASH_NOTICE_KEYS = [:error, :notice, :warning] | ||||
| 
 | ||||
|   def show_attribute_value(value) | ||||
|     if value.kind_of? Hash | ||||
|         result = [] | ||||
|         value.each{|t| result.push(t.last)} | ||||
|         result.join "," | ||||
|       else | ||||
|         value | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def create_guest_user | ||||
|     u = User.create(:name => "guest", :email => "guest_#{Time.now.to_i}#{rand(99)}@example.com") | ||||
|     u.admin = false | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| #encoding: utf-8 | ||||
| # require ActionView::Helpers::FormTagHelper | ||||
| 
 | ||||
| module AttributeFieldsHelper | ||||
|  | @ -5,6 +6,7 @@ module AttributeFieldsHelper | |||
|   include ActionView::Helpers::FormOptionsHelper | ||||
|   include ActionView::Helpers::DateHelper | ||||
|   include ActionView::Helpers::TagHelper | ||||
|   include ActionView::Helpers::RenderingHelper | ||||
| 
 | ||||
|   def block_helper(user,index) | ||||
|     @index = index | ||||
|  | @ -16,114 +18,124 @@ module AttributeFieldsHelper | |||
|     return instance_eval("render_#{markup}") #rescue "" | ||||
|   end | ||||
| 
 | ||||
|   def render_text_area | ||||
|     result = "" | ||||
|     result << label | ||||
|     if self.locale? | ||||
|       @prefiled_value.each do |key,value| | ||||
|         result << controls_wrapper{text_area_tag("#{get_field_name_base}[#{key.to_s}]",  value, {})} | ||||
|       end | ||||
|     else | ||||
|       value = @prefiled_value | ||||
|       result << controls_wrapper{text_area_tag(get_field_name_base,  value, {})} | ||||
|     end | ||||
|     result << end_block | ||||
|     result.html_safe  | ||||
|   def lang_tab(str,lang) | ||||
|       content_tag(:div,str,:class=>"tab-pane fade",:id=>(get_field_name_base+"tab_#{lang}")) | ||||
|   end | ||||
| 
 | ||||
|   def render_radio_button | ||||
|     result = "" | ||||
|     result << label | ||||
|     markup_value.each do |key,value| | ||||
|       result <<  controls_wrapper{label_tag(key,radio_button_tag(get_field_name_base+"[#{key}]", value[I18n.locale.to_s],  (@prefiled_value==value ? true : false), {})+value[I18n.locale.to_s],:class=>"control-label")} | ||||
|   def render_address | ||||
|     control_group_wrapper do |key,value| | ||||
|       result = '<div class="input-append">'.html_safe | ||||
| 
 | ||||
|       if(add_more and value.is_a?(Array)) | ||||
|         values = value | ||||
|         result << values.each_with_index.collect  do |value,index| | ||||
|           text_field_tag(get_field_name_base + (key.nil? ? '' : "[#{key}][#{index}]"),  value.last,markup_options) | ||||
|         end.join.html_safe | ||||
|       else | ||||
|       result << text_field_tag(get_field_name_base + (key.nil? ? '' : "[#{key}]"),  value,markup_options) | ||||
|       end | ||||
|      | ||||
|       result << ('<a href="#'+self.key+'-edit" class="btn" type="button" data-toggle="modal"><i class="icon-edit"></i></a>').html_safe | ||||
|       result << '<a href="#" class="btn" type="button"><i class="icon-trash"></i></a>'.html_safe | ||||
|       result << '</div>'.html_safe | ||||
|       result <<  gen_modal_dialog | ||||
|     end | ||||
|     result << end_block | ||||
|     result.html_safe | ||||
|   end | ||||
| 
 | ||||
|   def render_checkbox | ||||
|     # label+ "" + end_block | ||||
|     # check_box_tag(name, value = "1", checked = false, options = {}) | ||||
| 
 | ||||
|     result = "" | ||||
|     result << label | ||||
|     markup_value.each do |key,value| | ||||
|       result <<  controls_wrapper{label_tag(key,check_box_tag(get_field_name_base+"[#{key}]", value[I18n.locale.to_s],  (@prefiled_value==value ? true : false), {})+value[I18n.locale.to_s],:class=>"control-label")} | ||||
|     end | ||||
|     result << end_block | ||||
|     result.html_safe | ||||
| 
 | ||||
|   end | ||||
| 
 | ||||
|   def render_date_durnation | ||||
|     control_group_wrapper do  | ||||
|       if @new_attribute | ||||
|         @prefiled_value = {} | ||||
|       end | ||||
|       label+controls_wrapper{date_select(get_field_name_base+"[value][from]",@prefiled_value["from"]) +date_select(get_field_name_base+"[value][end]",@prefiled_value["end"])} + end_block | ||||
|       markup_value.collect do |key,value| | ||||
|         label_tag(key,check_box_tag(get_field_name_base+"[#{key}]", value[I18n.locale.to_s],  (@prefiled_value==value ? true : false), {})+value[I18n.locale.to_s],markup_options.merge(:class=>"control-label")) | ||||
|       end.join rescue "" | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def render_text_field_ext | ||||
|     result = "" | ||||
|     result << label | ||||
|     if self.locale? | ||||
|       @prefiled_value.each do |key,value| | ||||
|         result << controls_wrapper{text_field_tag("#{get_field_name_base}[#{key.to_s}]",  value, {})} | ||||
|       end | ||||
|     else | ||||
|       value = @prefiled_value | ||||
|       result << controls_wrapper{text_field_tag(get_field_name_base,  value, {})} | ||||
|     end | ||||
|     result << end_block | ||||
|     result.html_safe  | ||||
|   end | ||||
| 
 | ||||
| 
 | ||||
|   def render_date  | ||||
|     label+controls_wrapper{date_select(get_field_name_base+"[value]",@prefiled_value)} + end_block | ||||
|     control_group_wrapper{date_select(get_field_name_base+"[value]",@prefiled_value,markup_options,:class=>"input-small")}  | ||||
|   end | ||||
| 
 | ||||
|   def render_date_durnation #Need re-write low priority | ||||
| 
 | ||||
|   end | ||||
| 
 | ||||
|   def render_radio_button  | ||||
|     control_group_wrapper do  | ||||
|       markup_value.collect do |key,value| | ||||
|         label_tag(key,radio_button_tag(get_field_name_base, value[I18n.locale.to_s],  (@prefiled_value==value ? true : false), {})+value[I18n.locale.to_s],markup_options.merge(:class=>"control-label")) | ||||
|       end.join rescue "" | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def render_select  | ||||
|     label+controls_wrapper{select_tag( get_field_name_base+"[value]",options_for_select(markup_value.collect{|p| [p[1][I18n.locale.to_s],p[0]]},@prefiled_value))} + end_block | ||||
|     control_group_wrapper{select_tag( get_field_name_base+"[value]",options_for_select(markup_value.collect{|p| [p[1][I18n.locale.to_s],p[0]]},@prefiled_value),markup_options)} rescue "" | ||||
|   end | ||||
| 
 | ||||
|   def render_text_area  | ||||
|     control_group_wrapper{|key,value|text_area_tag(get_field_name_base + (key.nil? ? '' : "[#{key}]"),  value,markup_options)} | ||||
|   end | ||||
| 
 | ||||
|   def render_text_field | ||||
|     result = "" | ||||
|     result << label | ||||
|     if self.locale? | ||||
|       @prefiled_value.each do |key,value| | ||||
|         result << controls_wrapper{text_field_tag("#{get_field_name_base}[#{key.to_s}]",  value, {})} | ||||
|       end | ||||
|     control_group_wrapper do |key,value| | ||||
|       if(add_more and value.is_a?(Hash)) | ||||
|         values = value | ||||
|         values.each_with_index.collect  do |value,index| | ||||
|           text_field_tag(get_field_name_base + (key.nil? ? '' : "[#{key}][#{index}]"),  value.last,markup_options) | ||||
|         end.join.html_safe | ||||
|       else | ||||
|       value = @prefiled_value | ||||
|       result << controls_wrapper{text_field_tag(get_field_name_base,  value, {})} | ||||
|       text_field_tag(get_field_name_base + (key.nil? ? '' : "[#{key}]"),  value,markup_options) | ||||
|     end | ||||
|     result << end_block | ||||
|   end | ||||
| end | ||||
| protected | ||||
|   def lang_panel_control_wrapper(&block) | ||||
|     result = '<div class="tabbable tabs-right">' | ||||
|     result <<   '<div class="tab-content">' | ||||
|     result <<       controls_wrapper{yield} | ||||
|     result <<   '</div>' | ||||
|     result << '</div>' | ||||
|     result.html_safe | ||||
|   end | ||||
| 
 | ||||
|   def render_email | ||||
|     label+controls_wrapper{email_field_tag(get_field_name_base, value,  {})}+ end_block | ||||
|   end | ||||
| 
 | ||||
|   def render_addr | ||||
|     label+controls_wrapper{text_field_tag(get_field_name_base, value,  {})} + end_block | ||||
|   end | ||||
| 
 | ||||
| protected | ||||
| 
 | ||||
|   def controls_wrapper(&block) | ||||
|     result = "<div class='controls'>" | ||||
|     if can_muti_lang_input | ||||
|       result << "<div class='tabbable tabs-right'>" | ||||
|       result << "<div class='tab-content'>" | ||||
|       VALID_LOCALES.collect do |key| | ||||
|         value  = @prefiled_value[key.to_s] rescue nil | ||||
|         div_class = ["tab-pane" ,"fade"].join(" ") | ||||
|         div_class << (key == I18n.locale.to_s ?  " active in" : '') | ||||
|         result << content_tag(:div,yield(key,value),:class=>div_class,:id=>"tab"+id.to_s+"_#{key}") | ||||
|       end | ||||
|       result << "</div>" | ||||
|       result << "<ul class='nav nav-tabs'>" | ||||
|       VALID_LOCALES.each do |key| | ||||
|         result << content_tag(:li,link_to(I18n.t("langs."+key),"#tab"+id.to_s+"_#{key}",:data=>{:toggle=>"tab"}),:class=>(key == I18n.locale.to_s ?  "active" : nil)) | ||||
|       end | ||||
|       result << "</ul>" | ||||
|       result << "</div>" | ||||
|       # @prefiled_value.collect do |key,value| | ||||
|       #   result << yield(key,value) | ||||
|       # end | ||||
|     else | ||||
|     result << yield   | ||||
|     end | ||||
|     if can_add_more | ||||
|       result << '<span class="help-block">' | ||||
|       result << '<a href="#"><i class="icon-plus-sign"></i> Add</a>' | ||||
|       result << '</span>' | ||||
|     end | ||||
|     result << "</div>" | ||||
|     result.html_safe | ||||
|   end | ||||
| 
 | ||||
|   def control_group_wrapper(&block)  | ||||
|     result = "<div class='control-group'>" | ||||
|     result << yield | ||||
|     result << "</div>" | ||||
|     div_class = can_muti_lang_input ? "control-group language-swich" : "control-group" | ||||
|     temp = label + controls_wrapper(&block) | ||||
| 
 | ||||
|     result = content_tag(:div,temp,:class=>div_class) | ||||
|     result << end_block | ||||
|      | ||||
|     result.html_safe | ||||
|   end | ||||
| 
 | ||||
|  | @ -148,4 +160,36 @@ protected | |||
|     label_tag(key,title,:class=>"control-label") | ||||
|   end | ||||
| 
 | ||||
|   def can_muti_lang_input | ||||
|     locale and LIST[:markups][markup]["muti_lang_input_supprt"] | ||||
|   end | ||||
| 
 | ||||
|   def can_add_more | ||||
|     locale and LIST[:markups][markup]["ext_support"] && add_more | ||||
|   end | ||||
| 
 | ||||
| def render_anywhere(partial, assigns) | ||||
|   view = ActionView::Base.new(Rails::Configuration.new.view_path, assigns) | ||||
|   ActionView::Base.helper_modules.each { |helper| view.extend helper } | ||||
|   view.extend ApplicationHelper | ||||
|   view.render(:partial => partial) | ||||
| end | ||||
| 
 | ||||
| def gen_modal_dialog | ||||
|   result = '<div class="modal hide fade" id="address-edit" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display: none; ">' | ||||
|   result << '<div class="modal-header">' | ||||
|   result << '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>' | ||||
|   result << '<h3 id="myModalLabel">'+title+'</h3>' | ||||
|   result << '</div>' | ||||
|   result << '<div class="modal-body">' | ||||
|   result << '<p>One fine body…</p>' | ||||
|   result << '</div>' | ||||
|   result << '<div class="modal-footer">' | ||||
|   result << '<button class="btn" data-dismiss="modal" aria-hidden="true">'+I18n.t("modal.close")+'</button>' | ||||
|   result << '<button class="btn btn-primary">'+I18n.t("modal.save_and_close")+'</button>' | ||||
|   result << '</div>' | ||||
|   result << '</div>' | ||||
|   result.html_safe | ||||
| end | ||||
| 
 | ||||
| end | ||||
|  | @ -5,12 +5,15 @@ class AttributeField | |||
|   include AttributeFieldHelper | ||||
| 
 | ||||
|   field :key | ||||
|   field :markup #[select,text_field,email,date,addr] | ||||
|   field :markup  | ||||
|   field :markup_value ,:type => Hash | ||||
|   field :markup_options,:type => Hash | ||||
|   field :locale, :type => Boolean, :default => true | ||||
|   field :list_options, :type => Array | ||||
|   # field :list_options, :type => Array | ||||
|   field :built_in, :type => Boolean, :default => false | ||||
|   field :disabled, :type => Boolean, :default => false | ||||
|   field :add_more,:type => Boolean, :default => false | ||||
| 
 | ||||
|   #field :title, localize: true | ||||
| 
 | ||||
|   field :locale_title, localize: true | ||||
|  | @ -21,6 +24,20 @@ class AttributeField | |||
|   has_many :attribute_values | ||||
|    | ||||
|   # validates_uniqueness_of :key | ||||
| 
 | ||||
|   def markup_options=(var) | ||||
|     self[:markup_options] = (eval(var)  rescue {}) | ||||
|   end | ||||
| 
 | ||||
|   def markup_options | ||||
|     if self[:markup_options].nil? | ||||
|       return {} | ||||
|     else | ||||
|       Hash[self[:markup_options].map{|key,val|[key.to_sym,val]}]  rescue {} | ||||
|     end | ||||
| 
 | ||||
|   end | ||||
| 
 | ||||
|   def role | ||||
|     self.attribute.role | ||||
|   end | ||||
|  | @ -56,15 +73,15 @@ class AttributeField | |||
|     end | ||||
|   end | ||||
| 
 | ||||
|   # Convert the string list_options into an array | ||||
|   def select_list_options=(var) | ||||
|     self.list_options = var.gsub(' ', '').split(',') | ||||
|   end | ||||
|   # # Convert the string list_options into an array | ||||
|   # def select_list_options=(var) | ||||
|   #   self.list_options = var.gsub(' ', '').split(',') | ||||
|   # end | ||||
|    | ||||
|   # Convert the array list_options into a string | ||||
|   def select_list_options | ||||
|     self.list_options.to_a.join(', ') | ||||
|   end | ||||
|   # # Convert the array list_options into a string | ||||
|   # def select_list_options | ||||
|   #   self.list_options.to_a.join(', ') | ||||
|   # end | ||||
|    | ||||
|   def is_built_in? | ||||
|     self.built_in | ||||
|  |  | |||
|  | @ -11,7 +11,7 @@ class AttributeValue | |||
| 
 | ||||
|   before_save :check_key | ||||
| 
 | ||||
|   NO_MULTI_TAG = ["select","date","radio_button","checkbox","date_durnation"] | ||||
|   # NO_MULTI_TAG = ["select","date","radio_button","checkbox","date_durnation"] | ||||
| 
 | ||||
|   def check_key | ||||
|     self.key = attribute_field.key | ||||
|  | @ -31,19 +31,25 @@ class AttributeValue | |||
|         self.attribute_field.locale ? self[locale]  : self[:value] | ||||
|       when "select" | ||||
|         self.attribute_field.markup_value[self[:value]][locale.to_s] || NoData | ||||
|       when "email" | ||||
|         self[:value] | ||||
|       when "text_area" | ||||
|         #self[:value] | ||||
|       when "date" | ||||
|         Date.new(self[:value]["(1i)"].to_i,self[:value]["(2i)"].to_i,self[:value]["(3i)"].to_i) | ||||
|       when "addr" | ||||
|         self[:value] | ||||
|       when "radio_button" | ||||
|         self[:value] | ||||
|       when "checkbox" | ||||
|         self[:value] | ||||
|       when "date_durnation" | ||||
|         self[:value] | ||||
|       else | ||||
|         self.attribute_field.locale ? self[locale]  : self[:value] | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def get_values | ||||
|     if self.attribute_field.locale && !(NO_MULTI_TAG.include? self.attribute_field.markup)  | ||||
|     if self.attribute_field.locale && LIST[:markups][self.attribute_field.markup]["muti_lang_input_supprt"] | ||||
|       return Hash[VALID_LOCALES.collect{|lang|  [lang,self[lang.to_sym]]}] | ||||
|     else | ||||
|         return self[:value]   | ||||
|  |  | |||
|  | @ -11,10 +11,18 @@ | |||
|   <td class='select_type'> | ||||
| 
 | ||||
|     <ul> | ||||
|       <li><%= f.select :markup, LIST[:markups], {}, {:style => "width:90px"} %> </li> | ||||
|       <li><%= f.check_box :locale %><%= label_tag "Locale" %>  </li> | ||||
|       <li><%= attribute_field[:markup].eql?('select') ? nil : "style='display:none'"%> </li> | ||||
|       <li><%= t('admin.options') %>: <%= f.text_field :markup_value%></li> | ||||
|       <li>markup<%= f.select :markup, LIST[:markups].keys, {}, {:style => "width:90px"} %> </li> | ||||
|       <li>markup_value<%= f.text_field :markup_value,:size=>50 %></li> | ||||
|       <li>markup_options<%= f.text_field :markup_options,:size=>50 %></li> | ||||
|       <li>locale<%= f.check_box :locale,{},true,false %></li> | ||||
|       <li>built_in<%= f.check_box :built_in,{},true,false %></li> | ||||
|       <li>disabled<%= f.check_box :disabled,{},true,false %></li> | ||||
|       <li>add_more<%= f.check_box :add_more,{},true,false %></li> | ||||
|       <li>neutral_title<%= f.text_field :neutral_title,:size=>50 %></li> | ||||
|     <!--   | ||||
|       <li><%#= attribute_field[:markup].eql?('select') ? nil : "style='display:none'"%> </li> | ||||
|       <li><%#= t('admin.options') %>: <%#= f.text_field :markup_value%></li> | ||||
|     --> | ||||
|     </ul> | ||||
|      | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,9 +3,7 @@ | |||
|   <div class="form-horizontal"> | ||||
|        | ||||
|     <% info.attribute_fields.each  do |af|%> | ||||
|       <div class="control-group"> | ||||
|         <%= af.block_helper(@user,@form_index)%> | ||||
|       </div> | ||||
|         <% @form_index = @form_index +1 %> | ||||
|     <% end %> | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,9 +1,7 @@ | |||
| <td> | ||||
| <%= temp_profile.title %> | ||||
| <% temp_profile.attribute_fields.each  do |af|%> | ||||
| <div class="control-group"> | ||||
|   <%= af.block_helper(@user,@form_index)%> | ||||
| </div> | ||||
|   <% @form_index = @form_index +1 %> | ||||
| <% end %> | ||||
| </td> | ||||
|  | @ -8,7 +8,7 @@ | |||
|                                     <% items.each do |item| %> | ||||
|                                         <tr> | ||||
|                                             <td class="span1"><%= item[:name] %></td> | ||||
|                                             <td><%= item[:value] %></td> | ||||
|                                             <td><%= show_attribute_value(item[:value]) %></td> | ||||
|                                         </tr> | ||||
|                                     <% end -%> | ||||
|                                 </tbody> | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ | |||
| 			<%= yield %> | ||||
| 		</div> | ||||
| 		<div class="tertiary"><%= yield :tertiary %></div> | ||||
| 		<div id="back_footer"><p><%= APP_CONFIG['ruling_digital'] %></p></div> | ||||
| 		 | ||||
| 	</div> | ||||
| </body> | ||||
| </html> | ||||
|  |  | |||
|  | @ -71,3 +71,5 @@ module Orbit | |||
| end | ||||
| Orbit_Apps = [] | ||||
| VALID_LOCALES = ["en", "zh_tw"] | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,15 +3,34 @@ forbidden_item_names: | |||
|   - panel | ||||
|   - appfront | ||||
| 
 | ||||
| #NO_MULTI_TAG = ["select","date","radio_button","checkbox","date_durnation"] | ||||
| 
 | ||||
| markups: | ||||
|   - text_field | ||||
|   - select | ||||
|   - date | ||||
|   - text_area #NC | ||||
|   - radio_button #NC | ||||
|   - checkbox #NC | ||||
|   - date_durnation #NC | ||||
|   - text_field_ext #NC  for addr for phone | ||||
|   text_field: | ||||
|     muti_lang_input_supprt: true | ||||
|     ext_support: true | ||||
|   select: | ||||
|     muti_lang_input_supprt: false | ||||
|     ext_support: false | ||||
|   date: | ||||
|     muti_lang_input_supprt: false | ||||
|     ext_support: false | ||||
|   text_area: | ||||
|     muti_lang_input_supprt: true | ||||
|     ext_support: false | ||||
|   radio_button: | ||||
|     muti_lang_input_supprt: false | ||||
|     ext_support: false | ||||
|   checkbox: | ||||
|     muti_lang_input_supprt: false | ||||
|     ext_support: false | ||||
|   date_durnation: | ||||
|     muti_lang_input_supprt: false | ||||
|     ext_support: false | ||||
|   address: | ||||
|     muti_lang_input_supprt: true | ||||
|     ext_support: true | ||||
| 
 | ||||
|    | ||||
| public_r_tags: | ||||
|   - ad_banner | ||||
|  |  | |||
|  | @ -24,6 +24,9 @@ zh_tw: | |||
|   help: 協助 | ||||
|   hide: 隱藏 | ||||
|   homepage: 首頁 | ||||
|   langs: | ||||
|     zh_tw: 中文 | ||||
|     en: 英文 | ||||
|   login: 登入 | ||||
|   logout: 登出 | ||||
|   nccu: 政大 | ||||
|  | @ -558,6 +561,7 @@ zh_tw: | |||
|       update: "更新%{model}" | ||||
|       submit: "儲存%{model}" | ||||
|   modal: | ||||
|     save_and_close: "儲存並關閉" | ||||
|     close: "關閉" | ||||
|     preview: "預覽" | ||||
|   sys: | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue