require "ui_bibz/ui/ux/table/components/store" require "ui_bibz/ui/ux/table/components/columns" require "ui_bibz/ui/ux/table/components/column" require "ui_bibz/ui/ux/table/components/actions" require "ui_bibz/ui/ux/table/components/thead" require "ui_bibz/ui/ux/table/components/as" require "ui_bibz/ui/ux/table/extensions/paginable" require "ui_bibz/ui/ux/table/extensions/paginable" require "ui_bibz/ui/ux/table/extensions/searchable" require "ui_bibz/ui/ux/table/extensions/sortable" require "ui_bibz/ui/ux/table/extensions/actionable" module UiBibz::Ui::Ux # Create a Table # # This element is an extend of UiBibz::Ui::Ux::Component. # # ==== Attributes # # * +content+ - Content of element # * +options+ - Options of element # * +html_options+ - Html Options of element # # ==== Options # # You can add HTML attributes using the +html_options+. # You can pass arguments in options attribute: # * +store+ - Store generate by '+table_search_pagination+' method # * +url+ - String # * +tap+ - Boolean # * +actionable+ - Boolean # * +sortable+ - Boolean # * +searchable+ - Boolean # * +default_actions+ - Boolean # * +status+ # (+:inverse+, +:default+, +:success+, +:primary+, +:secondary+, +:info+, # +:danger+, +:warning+) # * +thead+ - Hash # (+status+) # (+:inverse+, +:default+) # * +bordered+ - Boolean # * +hoverable+ - Boolean # * +size+ # (+:sm+) # * +responsive+ - Boolean # * +reflow+ - Boolean # # ==== Signatures # # UiBibz::Ui::Ux::Table.new(store: @store) # # UiBibz::Ui::Ux::Table.new(store: @store, tap: true) do |t| # t.columns do |c| # c.column :id, name: '#' # end # t.actions do |a| # a.link '', url: url, glyph: '' # end # end # # ==== Examples # # UiBibz::Ui::Ux::Table.new(store: @users).render # # UiBibz::Ui::Ux::Table.new(store: @users).tap do |t| # t.columns do |c| # c.column :id, { name: '#' } # c.column :name_fr', { link: edit_user_path(:id), order: 2 } # c.column :name_en' # c.column :state_id, { name: 'state', format: lambda{ |records, record| "Test #{ record.id}"} } # end # t.actions do |a| # a.link 'state', url: users_path(:id), glyph: 'eye' # a.divider # a.link 'momo', url: users_path(:id), glyph: 'home' # end # end.render # # ==== Helper # # table(options = {}, html_options = {}) # # table(options = { tap: true }, html_options = {}) do |t| # t.columns do |cls| # cls.column(name, options = {}, html_options = {}) # cls.column(options = {}, html_options = {}) do # name # end # end # t.actions do |acs| # acs.link(content, options = {}, html_options = {}) # acs.link(options = {}, html_options = {}) do # content # end # end # end class Table < UiBibz::Ui::Core::Component attr_accessor :columns # See UiBibz::Ui::Core::Component.initialize def initialize content = nil, options = nil, html_options = nil, &block super @columns = Columns.new @actions = Actions.new store end # Add table columns items def columns &block @columns.tap(&block) end # Add table actions items def actions &block @actions.tap(&block) end # for test def actions_list @actions end # Render html tag def render table_html end # Store must be generated by *table_search_pagination* method def store @store ||= if @options[:store].nil? raise 'Store is nil!' elsif @options[:store].try(:records).nil? raise 'Store can be created only with "table_search_pagination" method!' else Store.new @options.delete :store end end protected def sort @sort ||= Sortable.new store, @options end def action @action ||= Actionable.new store, @options, @actions end def cols @columns.list.empty? ? store.columns.list : @columns.list end def type "table-#{ @options[:type] }" unless @options[:type].nil? end def table_html content_tag(:table, html_options) do ths = cols.collect do |col| content_tag(:th, sort.header(col), class: col.class) unless col.hidden? end ths = action.header ths concat Thead.new(content_tag(:tr, ths.join.html_safe), @options[:thead]).render trs = store.records.collect do |record| tds = cols.collect do |col| content_tag(:td, td_content(record, col), class: col.class) unless col.hidden? end tds = action.body record, tds content_tag(:tr, tds.join.html_safe) end concat content_tag :tbody, trs.join.html_safe end end # Maybe create a class for td_content def td_content record, col content = col.count ? record.send(col.data_index).count : record.send(col.data_index) unless content.nil? content = content.strftime(col.date_format) unless col.date_format.nil? content = link_to content, action.inject_url(col.link, record) unless col.link.nil? content = col.format.call(@store.records, record) unless col.format.nil? end content = As.new(col, record, content, @options).render unless col.as.nil? content end private def component_html_classes ["table", striped, bordered, hoverable, size, responsive, reflow] end def status "table-#{ @options[:status] }" unless @options[:status].nil? end def striped "table-striped" unless @options[:striped].nil? end def bordered "table-bordered" unless @options[:bordered].nil? end def hoverable "table-hoverable" unless @options[:hoverable].nil? end def size "table-#{ @options[:size] }" unless @options[:size].nil? end def responsive "table-responsive" unless @options[:responsive].nil? end def reflow "table-reflow" unless @options[:reflow].nil? end end end