module ActiveList module Renderers class SimpleRenderer < AbstractRenderer include ActiveList::Helpers DATATYPE_ABBREVIATION = { binary: :bin, boolean: :bln, date: :dat, datetime: :dtt, decimal: :dec, measure: :dec, float: :flt, integer: :int, string: :str, text: :txt, time: :tim, timestamp: :dtt } def remote_update_code code = "if params[:column] and params[:visibility]\n" code << " column = params[:column].to_sym\n" # Removes potentially unwanted columns code << " #{var_name(:params)}[:hidden_columns].delete_if{|c| !#{table.data_columns.map(&:name).inspect}.include?(c)}\n" code << " #{var_name(:params)}[:hidden_columns].delete(column) if params[:visibility] == 'shown'\n" code << " #{var_name(:params)}[:hidden_columns] << column if params[:visibility] == 'hidden'\n" code << " head :ok\n" code << "elsif params[:only]\n" code << " render(inline: '<%=#{generator.view_method_name}(only: params[:only])-%>')\n" code << "else\n" code << " render(inline: '<%=#{generator.view_method_name}-%>')\n" code << "end\n" return code end def build_table_code record = "r" child = "c" # colgroup = columns_definition_code header = header_code extras = extras_codes code = generator.select_data_code code << "#{var_name(:tbody)} = ''\n" code << "if #{var_name(:count)} > 0\n" code << " #{generator.records_variable_name}.each do |#{record}|\n" code << " #{var_name(:attrs)} = {id: 'r' + #{record}.id.to_s}\n" if table.options[:line_class] code << " #{var_name(:attrs)}[:class] = (#{recordify!(table.options[:line_class], record)}).to_s\n" code << " #{var_name(:attrs)}[:class] << ' focus' if params['#{table.name}-id'].to_i == #{record}.id\n" else code << " #{var_name(:attrs)}[:class] = 'focus' if params['#{table.name}-id'].to_i == #{record}.id\n" end code << " #{var_name(:tbody)} << content_tag(:tr, #{var_name(:attrs)}) do\n" code << columns_to_cells(:body, record: record).dig(3) code << " end\n" # if table.options[:children].is_a? Symbol # children = table.options[:children].to_s # code << " for #{child} in #{record}.#{children}\n" # code << " #{var_name(:tbody)} << content_tag(:tr, :class => #{line_class}+' child') do\n" # code << columns_to_cells(:children, table.children, record: child).dig(4) # code << " end\n" # code << " end\n" # end code << " end\n" code << "else\n" code << " #{var_name(:tbody)} << '' + ::I18n.translate('list.no_records') + ''\n" code << "end\n" code << "#{var_name(:tbody)} << ''\n" code << "return #{var_name(:tbody)}.html_safe if options[:only] == 'table-body'\n" # Build content code << "#{var_name(:content)} = ''\n" if extras.any? # code << "#{var_name(:content)} << #{extras}\n" unless extras.blank? code << "options[:content_for] ||= {}\n" code << "#{var_name(:extras)} = ''\n" extras.each do |name, ecode| code << "if options[:content_for][:#{name}]\n" code << " content_for(options[:content_for][:#{name}], (#{ecode}).html_safe)\n" code << "else\n" code << " #{var_name(:extras)} << #{ecode}\n" code << "end\n" end code << "#{var_name(:content)} << content_tag(:div, (#{var_name(:extras)}).html_safe, class: 'list-control') unless #{var_name(:extras)}.blank?\n" end code << "#{var_name(:content)} << '
'\n" code << "#{var_name(:content)} << (#{header})\n" code << "if block_given?\n" code << " #{var_name(:content)} << '' + capture(" + table.columns.collect{|c| {name: c.name, id: c.id}}.inspect + ", &block).to_s + ''\n" code << "end\n" code << "#{var_name(:content)} << #{var_name(:tbody)}\n" code << "#{var_name(:content)} << '
'\n" # code << "return #{var_name(:content)}.html_safe if options[:only] == 'content'\n" # Build whole code << "return ('
'#{generator.controller_method_name}')))+'\" data-list-redirect=\"' + params[:redirect].to_s + '\" class=\"active-list\">' + #{var_name(:content)} + '
').html_safe\n" return code end def columns_to_cells(nature, options={}) code = '' unless [:body, :children].include?(nature) raise ArgumentError, "Nature is invalid" end record = options[:record] || 'record_of_the_death' if table.selectable? code << "content_tag(:td, class: 'list-selector') do\n" code << " tag(:input, type: 'checkbox', value: #{record}.id, data: {list_selector: #{record}.id})\n" code << "end +\n" end children_mode = !!(nature == :children) for column in table.columns value_code = "" if column.is_a? ActiveList::Definition::EmptyColumn value_code = 'nil' elsif column.is_a? ActiveList::Definition::StatusColumn value_code = column.datum_code(record, children_mode) levels = %w(go caution stop) lights = levels.collect do |light| "content_tag(:span, '', :class => #{light.inspect})" end.join(" + ") # Expected value are :valid, :warning, :error value_code = "content_tag(:span, #{lights}, :class => 'lights lights-' + (#{levels.inspect}.include?(#{value_code}.to_s) ? #{value_code}.to_s : 'undefined'))" elsif column.is_a? ActiveList::Definition::DataColumn if column.options[:children].is_a? FalseClass and children_mode value_code = 'nil' else value_code = column.datum_code(record, children_mode) if column.datatype == :boolean value_code = "content_tag(:div, '', :class => 'checkbox-'+("+value_code.to_s+" ? 'true' : 'false'))" elsif [:date, :datetime, :timestamp, :measure].include? column.datatype value_code = "(#{value_code}.nil? ? '' : #{value_code}.l)" elsif [:item].include? column.datatype value_code = "(#{value_code}.nil? ? '' : #{value_code}.human_name)" end if !column.options[:currency].is_a?(FalseClass) and currency = column.options[:currency] currency = currency[nature] if currency.is_a?(Hash) currency = :currency if currency.is_a?(TrueClass) # currency = "#{record}.#{currency}".c if currency.is_a?(Symbol) currency = "#{column.record_expr(record)}.#{currency}".c if currency.is_a?(Symbol) value_code = "(#{value_code}.nil? ? '' : #{value_code}.l(currency: #{currency.inspect}))" elsif column.datatype == :decimal value_code = "(#{value_code}.nil? ? '' : #{value_code}.l)" elsif column.enumerize? value_code = "(#{value_code}.nil? ? '' : #{value_code}.text)" end if column.options[:url] and nature == :body column.options[:url] = {} unless column.options[:url].is_a?(Hash) column.options[:url][:id] ||= (column.record_expr(record)+'.id').c column.options[:url][:action] ||= :show column.options[:url][:controller] ||= column.class_name.tableize.to_sym # (self.generator.collection? ? "RECORD.class.name.tableize".c : column.class_name.tableize.to_sym) # column.options[:url][:controller] ||= "#{value_code}.class.name.tableize".c url = column.options[:url].collect{|k, v| "#{k}: " + urlify(v, record)}.join(", ") value_code = "(#{value_code}.blank? ? '' : link_to(#{value_code}.to_s, #{url}))" elsif column.options[:mode]||column.label_method == :email value_code = "(#{value_code}.blank? ? '' : mail_to(#{value_code}))" elsif column.options[:mode]||column.label_method == :website value_code = "(#{value_code}.blank? ? '' : link_to("+value_code+", "+value_code+"))" elsif column.label_method == :color value_code = "content_tag(:div, #{column.datum_code(record)}, style: 'background: #'+"+column.datum_code(record)+")" elsif column.label_method.to_s.match(/(^|\_)currency$/) and column.datatype == :string value_code = "(Nomen::Currencies[#{value_code}] ? Nomen::Currencies[#{value_code}].human_name : #{value_code})" elsif column.label_method.to_s.match(/(^|\_)language$/) and column.datatype == :string value_code = "(Nomen::Languages[#{value_code}] ? Nomen::Languages[#{value_code}].human_name : #{value_code})" elsif column.label_method.to_s.match(/(^|\_)country$/) and column.datatype == :string value_code = "(Nomen::Countries[#{value_code}] ? (image_tag('countries/' + #{value_code}.to_s + '.png') + ' ' + Nomen::Countries[#{value_code}].human_name).html_safe : #{value_code})" else # if column.datatype == :string value_code = "h(#{value_code}.to_s)" end value_code = "if #{record}\n#{value_code.dig}end" if column.is_a?(ActiveList::Definition::AssociationColumn) end elsif column.is_a?(ActiveList::Definition::CheckBoxColumn) if nature == :body form_name = column.form_name || "'#{table.name}[' + #{record}.id.to_s + '][#{column.name}]'".c value = "nil" if column.form_value value = recordify(column.form_value, record) else value = 1 value_code << "hidden_field_tag(#{form_name.inspect}, 0, id: nil) + \n" end value_code << "check_box_tag(#{form_name.inspect}, #{value}, #{recordify!(column.options[:value] || column.name, record)})" # , id: '#{table.name}_'+#{record}.id.to_s+'_#{column.name}' else value_code << "nil" end elsif column.is_a?(ActiveList::Definition::TextFieldColumn) form_name = column.form_name || "'#{table.name}[' + #{record}.id.to_s + '][#{column.name}]'".c value_code = (nature == :body ? "text_field_tag(#{form_name.inspect}, #{recordify!(column.options[:value] || column.name, record)}#{column.options[:size] ? ', size: ' + column.options[:size].to_s : ''})" : "nil") # , id: '#{table.name}_'+#{record}.id.to_s + '_#{column.name}' elsif column.is_a?(ActiveList::Definition::ActionColumn) next unless column.use_single? value_code = (nature == :body ? column.operation(record) : "nil") else value_code = "' ∅ '.html_safe" end code << "content_tag(:td, :class => \"#{column_classes(column)}\") do\n" code << value_code.dig code << "end +\n" end # if nature == :header # code << "'#{menu_code}'" # else # code << "content_tag(:td)" # end code << "''.html_safe" # code << "content_tag(:td)" return code.c end # Produces main menu code def menu_code menu = "" menu << "' + h('list.menu'.t) + '" menu << "" return menu end # Produces the code to create the header line using top-end menu for columns # and pagination management def header_code code = "'" if table.selectable? code << "" end for column in table.columns next if column.is_a?(ActiveList::Definition::ActionColumn) and !column.use_single? code << "" code << "' + h(#{column.header_code}) + '" code << "" code << "" end # code << "#{menu_code}" code << "'" return code end # Produces the code to create bottom menu and pagination def extras_codes code = [] codes = {} if table.global_action_columns.any? actions = "" actions << "'" for column in table.global_action_columns actions << " + link_to(content_tag(:i) + h(' ' + :#{column.name.to_s}.t(scope: 'rest.actions')), #{column.default_url.inspect}, class: 'btn btn-#{column.name}'#{', style: "display: none"' unless column.use_none?}#{', method: "' + column.options[:method].to_s + '"' if column.options[:method]}, data: {list_actioner: :#{column.use_none? ? 'none' : 'many'}#{', confirm: :' + column.options[:confirm].to_s + '.t(scope: "labels")' if column.options[:confirm]}})" end actions << " + '" code << "'#{actions}'" codes[:actions] = "'#{actions}'" end code << "'#{menu_code}'" codes[:settings] = "'#{menu_code}'" if table.paginate? pagination = "" current_page = "#{var_name(:page)}" last_page = "#{var_name(:last)}" pagination << "" pagination << "' + 'list.pagination.x_to_y_of_total'.t(x: (#{var_name(:offset)} + (#{var_name(:count)} > 0 ? 1 : 0)), y: ((#{var_name(:last)} == #{var_name(:page)}) ? #{var_name(:count)} : #{var_name(:offset)} + #{var_name(:limit)}), total: #{var_name(:count)}) + '" pagination << "" pagination << "' + ::I18n.translate('list.pagination.previous') + '" x = '@@PAGE-NUMBER@@' y = '@@PAGE-COUNT@@' pagination << "' + ::I18n.translate('list.pagination.next')+'" pagination << "" pagination << "" code << "'#{pagination}'" codes[:pagination] = "'#{pagination}'" end return codes unless code.empty? code = "content_tag(:div, (#{code.join(' + ')}).html_safe, class: 'list-control')" end return code end def uid "#{table.name}-list" end # # Not used # def columns_definition_code # code = table.columns.collect do |column| # " :#{generator.controller_method_name}, :column => #{column.id.to_s.inspect})\}\\\" />" # end.join # return "\"#{code}\"" # end # Finds all default styles for column def column_classes(column, without_id = false, without_interpolation = false) classes, conds = [], [] conds << [:sor, "#{var_name(:params)}[:sort] == '#{column.sort_id}'".c] if column.sortable? conds << [:hidden, "#{var_name(:params)}[:hidden_columns].include?(:#{column.name})".c] if column.is_a? ActiveList::Definition::DataColumn classes << column.options[:class].to_s.strip unless column.options[:class].blank? classes << column.short_id unless without_id if column.is_a? ActiveList::Definition::ActionColumn classes << :act elsif column.is_a? ActiveList::Definition::StatusColumn classes << :status elsif column.is_a? ActiveList::Definition::DataColumn classes << :col classes << DATATYPE_ABBREVIATION[column.datatype] classes << :url if column.options[:url].is_a?(Hash) classes << column.label_method if [:code, :color].include? column.label_method.to_sym if column.options[:mode] == :download classes << :dld elsif column.options[:mode]||column.label_method == :email classes << :eml elsif column.options[:mode]||column.label_method == :website classes << :web end elsif column.is_a? ActiveList::Definition::TextFieldColumn classes << :tfd elsif column.is_a? ActiveList::Definition::CheckBoxColumn classes << :chk else classes << :unk end html = classes.join(' ').strip if conds.any? if without_interpolation html << "' + " html << conds.collect do |c| "(#{c[1]} ? ' #{c[0]}' : '')" end.join(' + ') html << " + '" else html << conds.collect do |c| "\#\{' #{c[0]}' if #{c[1]}\}" end.join end end return html end end end end