active-list 5.0.1 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +2 -40
- metadata +19 -130
- checksums.yaml +0 -7
- data/VERSION +0 -1
- data/app/assets/images/active-list.png +0 -0
- data/app/assets/images/active-list.svg +0 -415
- data/app/assets/javascripts/active_list.jquery.js +0 -136
- data/app/assets/stylesheets/active_list.css.scss +0 -7
- data/app/assets/stylesheets/active_list/background.scss +0 -39
- data/app/assets/stylesheets/active_list/minimal.scss +0 -87
- data/app/assets/stylesheets/active_list/theme.scss +0 -189
- data/lib/active-list.rb +0 -1
- data/lib/active_list.rb +0 -43
- data/lib/active_list/action_pack.rb +0 -46
- data/lib/active_list/definition.rb +0 -17
- data/lib/active_list/definition/abstract_column.rb +0 -54
- data/lib/active_list/definition/action_column.rb +0 -76
- data/lib/active_list/definition/association_column.rb +0 -80
- data/lib/active_list/definition/attribute_column.rb +0 -58
- data/lib/active_list/definition/check_box_column.rb +0 -17
- data/lib/active_list/definition/data_column.rb +0 -88
- data/lib/active_list/definition/empty_column.rb +0 -10
- data/lib/active_list/definition/field_column.rb +0 -20
- data/lib/active_list/definition/status_column.rb +0 -10
- data/lib/active_list/definition/table.rb +0 -159
- data/lib/active_list/definition/text_field_column.rb +0 -10
- data/lib/active_list/exporters.rb +0 -28
- data/lib/active_list/exporters/abstract_exporter.rb +0 -55
- data/lib/active_list/exporters/csv_exporter.rb +0 -32
- data/lib/active_list/exporters/excel_csv_exporter.rb +0 -38
- data/lib/active_list/exporters/open_document_spreadsheet_exporter.rb +0 -82
- data/lib/active_list/generator.rb +0 -122
- data/lib/active_list/generator/finder.rb +0 -150
- data/lib/active_list/helpers.rb +0 -33
- data/lib/active_list/rails/engine.rb +0 -13
- data/lib/active_list/renderers.rb +0 -25
- data/lib/active_list/renderers/abstract_renderer.rb +0 -29
- data/lib/active_list/renderers/simple_renderer.rb +0 -356
- data/locales/eng.yml +0 -25
- data/locales/fra.yml +0 -25
@@ -1,122 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
module ActiveList
|
3
|
-
|
4
|
-
class Generator
|
5
|
-
|
6
|
-
attr_accessor :table, :controller, :controller_method_name, :view_method_name, :records_variable_name
|
7
|
-
|
8
|
-
def initialize(*args, &block)
|
9
|
-
options = args.extract_options!
|
10
|
-
@controller = options[:controller]
|
11
|
-
name = args.shift || @controller.controller_name.to_sym
|
12
|
-
model = (options[:model]||name).to_s.classify.constantize
|
13
|
-
@collection = !!(model.name == @controller.controller_name.to_s.classify)
|
14
|
-
@controller_method_name = "list#{'_'+name.to_s if name != @controller.controller_name.to_sym}"
|
15
|
-
@view_method_name = "_#{@controller.controller_name}_list_#{name}_tag"
|
16
|
-
@records_variable_name = "@#{name}"
|
17
|
-
@table = ActiveList::Definition::Table.new(name, model, options)
|
18
|
-
if block_given?
|
19
|
-
yield @table
|
20
|
-
else
|
21
|
-
@table.load_default_columns
|
22
|
-
end
|
23
|
-
@parameters = {:sort => :to_s, :dir => :to_s}
|
24
|
-
@parameters.merge!(:page => :to_i, :per_page => :to_i) if @table.paginate?
|
25
|
-
end
|
26
|
-
|
27
|
-
def collection?
|
28
|
-
@collection
|
29
|
-
end
|
30
|
-
|
31
|
-
def var_name(name)
|
32
|
-
"_#{name}"
|
33
|
-
end
|
34
|
-
|
35
|
-
def renderer
|
36
|
-
ActiveList::Renderers[@table.options[:renderer]].new(self)
|
37
|
-
end
|
38
|
-
|
39
|
-
def controller_method_code
|
40
|
-
code = "# encoding: utf-8\n"
|
41
|
-
code << "def #{self.controller_method_name}\n"
|
42
|
-
code << self.session_initialization_code.dig
|
43
|
-
code << " respond_to do |format|\n"
|
44
|
-
code << " format.html do\n"
|
45
|
-
code << " if request.xhr?\n"
|
46
|
-
code << self.renderer.remote_update_code.dig(4)
|
47
|
-
code << " else\n"
|
48
|
-
code << " render(inline: '<%=#{self.view_method_name}-%>')\n" # , layout: action_has_layout?
|
49
|
-
code << " end\n"
|
50
|
-
code << " end\n"
|
51
|
-
for format, exporter in ActiveList::Exporters.hash
|
52
|
-
code << " format.#{format} do\n"
|
53
|
-
code << exporter.new(self).send_data_code.dig(3)
|
54
|
-
code << " end\n"
|
55
|
-
end
|
56
|
-
code << " end\n"
|
57
|
-
# Save preferences of user
|
58
|
-
if defined? User and User.instance_methods.include? :pref
|
59
|
-
code << " p = current_user.pref('list.#{self.view_method_name}', YAML::dump({}))\n"
|
60
|
-
code << " p.set! YAML::dump(#{var_name(:params)}.stringify_keys)\n"
|
61
|
-
end
|
62
|
-
code << "end\n"
|
63
|
-
# code.split("\n").each_with_index{|l, x| puts((x+1).to_s.rjust(4)+": "+l)}
|
64
|
-
unless ::Rails.env.production?
|
65
|
-
file = ::Rails.root.join("tmp", "code", "active_list", "controllers", self.controller.controller_path, self.controller_method_name + ".rb")
|
66
|
-
FileUtils.mkdir_p(file.dirname)
|
67
|
-
File.write(file, code)
|
68
|
-
end
|
69
|
-
return code
|
70
|
-
end
|
71
|
-
|
72
|
-
def view_method_code
|
73
|
-
code = "# encoding: utf-8\n"
|
74
|
-
code << "def #{self.view_method_name}(options={}, &block)\n"
|
75
|
-
code << self.session_initialization_code.dig
|
76
|
-
code << self.renderer.build_table_code.dig
|
77
|
-
code << "end\n"
|
78
|
-
# code.split("\n").each_with_index{|l, x| puts((x+1).to_s.rjust(4)+": "+l)}
|
79
|
-
unless ::Rails.env.production?
|
80
|
-
file = ::Rails.root.join("tmp", "code", "active_list", "views", self.controller.controller_path, self.view_method_name + ".rb")
|
81
|
-
FileUtils.mkdir_p(file.dirname)
|
82
|
-
File.write(file, code)
|
83
|
-
end
|
84
|
-
return code
|
85
|
-
end
|
86
|
-
|
87
|
-
def session_initialization_code
|
88
|
-
code = "options = {} unless options.is_a? Hash\n"
|
89
|
-
code << "options.update(params)\n"
|
90
|
-
if defined? User and User.instance_methods.include? :pref
|
91
|
-
code << "#{var_name(:params)} = YAML::load(current_user.pref('list.#{self.view_method_name}', YAML::dump({})).value).symbolize_keys\n"
|
92
|
-
code << "#{var_name(:params)} = {} unless #{var_name(:params)}.is_a?(Hash)\n"
|
93
|
-
else
|
94
|
-
code << "#{var_name(:params)} = {}\n"
|
95
|
-
end
|
96
|
-
code << "#{var_name(:params)}.update(options.symbolize_keys)\n"
|
97
|
-
code << "unless #{var_name(:params)}[:hidden_columns].is_a? Array\n"
|
98
|
-
code << " #{var_name(:params)}[:hidden_columns] = #{@table.hidden_columns.map(&:name).map(&:to_sym).inspect}\n"
|
99
|
-
code << "end\n"
|
100
|
-
for parameter, convertor in @parameters.sort{|a,b| a[0].to_s <=> b[0].to_s}
|
101
|
-
# expr = "options.delete('#{@table.name}_#{parameter}') || options.delete('#{parameter}') || #{var_name(:params)}[:#{parameter}]"
|
102
|
-
# expr += " || #{@table.options[parameter]}" unless @table.options[parameter].blank?
|
103
|
-
# code << "#{var_name(:params)}[:#{parameter}] = (#{expr}).#{convertor}\n"
|
104
|
-
expr = "#{var_name(:params)}[:#{parameter}]"
|
105
|
-
expr = "(#{expr} || #{@table.options[parameter]})" unless @table.options[parameter].blank?
|
106
|
-
code << "#{var_name(:params)}[:#{parameter}] = #{expr}.#{convertor}\n"
|
107
|
-
end
|
108
|
-
# Order
|
109
|
-
code << "#{var_name(:order)} = #{@table.options[:order] ? @table.options[:order].inspect : 'nil'}\n"
|
110
|
-
code << "if #{var_name(:col)} = {" + @table.sortable_columns.collect{|c| "'#{c.sort_id}' => '#{c.sort_expression}'"}.join(', ') + "}[#{var_name(:params)}[:sort]]\n"
|
111
|
-
code << " #{var_name(:params)}[:dir] = 'asc' unless #{var_name(:params)}[:dir] == 'asc' or #{var_name(:params)}[:dir] == 'desc'\n"
|
112
|
-
code << " #{var_name(:order)} = #{var_name(:col)} + ' ' + #{var_name(:params)}[:dir]\n"
|
113
|
-
code << "end\n"
|
114
|
-
|
115
|
-
return code
|
116
|
-
end
|
117
|
-
|
118
|
-
end
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
require "active_list/generator/finder"
|
@@ -1,150 +0,0 @@
|
|
1
|
-
module ActiveList
|
2
|
-
|
3
|
-
# Manage data query
|
4
|
-
class Generator
|
5
|
-
|
6
|
-
# Generate select code for the table taking all parameters in account
|
7
|
-
def select_data_code(options = {})
|
8
|
-
paginate = (options.has_key?(:paginate) ? options[:paginate] : @table.paginate?)
|
9
|
-
# Check order
|
10
|
-
unless @table.options.keys.include?(:order)
|
11
|
-
columns = @table.table_columns
|
12
|
-
@table.options[:order] = (columns.size > 0 ? columns.first.name.to_sym : {id: :desc}) # "#{@table.model.table_name}.id DESC"
|
13
|
-
end
|
14
|
-
|
15
|
-
class_name = @table.model.name
|
16
|
-
class_name = "(controller_name != '#{class_name.tableize}' ? controller_name.to_s.classify.constantize : #{class_name})" if self.collection?
|
17
|
-
|
18
|
-
# Find data
|
19
|
-
query_code = "#{class_name}"
|
20
|
-
query_code << self.scope_code if self.scope_code
|
21
|
-
query_code << ".select(#{self.select_code})" if self.select_code
|
22
|
-
query_code << ".where(#{self.conditions_code})" unless @table.options[:conditions].blank?
|
23
|
-
query_code << ".joins(#{@table.options[:joins].inspect})" unless @table.options[:joins].blank?
|
24
|
-
unless self.includes_reflections.empty?
|
25
|
-
expr = self.includes_reflections.inspect[1..-2]
|
26
|
-
query_code << ".includes(#{expr})"
|
27
|
-
query_code << ".references(#{expr})"
|
28
|
-
end
|
29
|
-
|
30
|
-
code = ""
|
31
|
-
code << "#{var_name(:count)} = #{query_code}.count\n"
|
32
|
-
if paginate
|
33
|
-
code << "#{var_name(:limit)} = (#{var_name(:params)}[:per_page] || 25).to_i\n"
|
34
|
-
code << "#{var_name(:page)} = (#{var_name(:params)}[:page] || 1).to_i\n"
|
35
|
-
code << "#{var_name(:page)} = 1 if #{var_name(:page)} < 1\n"
|
36
|
-
code << "#{var_name(:offset)} = (#{var_name(:page)} - 1) * #{var_name(:limit)}\n"
|
37
|
-
code << "#{var_name(:last)} = (#{var_name(:count)}.to_f / #{var_name(:limit)}).ceil.to_i\n"
|
38
|
-
code << "#{var_name(:last)} = 1 if #{var_name(:last)} < 1\n"
|
39
|
-
code << "return #{self.view_method_name}(options.merge(page: 1)) if 1 > #{var_name(:page)}\n"
|
40
|
-
code << "return #{self.view_method_name}(options.merge(page: #{var_name(:last)})) if #{var_name(:page)} > #{var_name(:last)}\n"
|
41
|
-
end
|
42
|
-
code << "#{self.records_variable_name} = #{query_code}"
|
43
|
-
code << ".reorder(#{var_name(:order)})"
|
44
|
-
if paginate
|
45
|
-
code << ".offset(#{var_name(:offset)})"
|
46
|
-
code << ".limit(#{var_name(:limit)})"
|
47
|
-
end
|
48
|
-
code << " || {}\n"
|
49
|
-
return code
|
50
|
-
end
|
51
|
-
|
52
|
-
protected
|
53
|
-
|
54
|
-
# Compute includes Hash
|
55
|
-
def includes_reflections
|
56
|
-
hash = []
|
57
|
-
for column in @table.columns
|
58
|
-
if column.respond_to?(:reflection)
|
59
|
-
hash << column.reflection.name
|
60
|
-
end
|
61
|
-
end
|
62
|
-
return hash
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
def scope_code
|
67
|
-
return nil unless scopes = @table.options[:scope]
|
68
|
-
scopes = [scopes].flatten
|
69
|
-
code = ""
|
70
|
-
for scope in scopes
|
71
|
-
code << ".#{scope}"
|
72
|
-
end
|
73
|
-
return code
|
74
|
-
end
|
75
|
-
|
76
|
-
|
77
|
-
# Generate the code from a conditions option
|
78
|
-
def conditions_code
|
79
|
-
conditions = @table.options[:conditions]
|
80
|
-
code = ''
|
81
|
-
case conditions
|
82
|
-
when Array
|
83
|
-
case conditions[0]
|
84
|
-
when String # SQL
|
85
|
-
code << '[' + conditions.first.inspect
|
86
|
-
code << conditions[1..-1].collect{|p| ", " + sanitize_condition(p)}.join if conditions.size > 1
|
87
|
-
code << ']'
|
88
|
-
when Symbol # Method
|
89
|
-
raise "What?"
|
90
|
-
code << conditions.first.to_s + '('
|
91
|
-
code << conditions[1..-1].collect{|p| sanitize_condition(p)}.join(', ') if conditions.size > 1
|
92
|
-
code << ')'
|
93
|
-
else
|
94
|
-
raise ArgumentError.new("First element of an Array can only be String or Symbol.")
|
95
|
-
end
|
96
|
-
when Hash # SQL
|
97
|
-
code << '{' + conditions.collect{|key, value| key.to_s + ': ' + sanitize_condition(value)}.join(',') + '}'
|
98
|
-
when Symbol # Method
|
99
|
-
code << conditions.to_s + "(options)"
|
100
|
-
when Code
|
101
|
-
code << "(" + conditions.gsub(/\s*\n\s*/, ';') + ")"
|
102
|
-
when String
|
103
|
-
code << conditions.inspect
|
104
|
-
else
|
105
|
-
raise ArgumentError.new("Unsupported type for conditions: #{conditions.inspect}")
|
106
|
-
end
|
107
|
-
return code
|
108
|
-
end
|
109
|
-
|
110
|
-
def select_code
|
111
|
-
return nil unless @table.options[:distinct] or @table.options[:select]
|
112
|
-
code = ""
|
113
|
-
code << "DISTINCT " if @table.options[:distinct]
|
114
|
-
code << "#{@table.model.table_name}.*"
|
115
|
-
if @table.options[:select]
|
116
|
-
code << @table.options[:select].collect{|k, v| ", #{k[0].to_s+'.'+k[1].to_s} AS #{v}" }.join
|
117
|
-
end
|
118
|
-
return ("'" + code + "'").c
|
119
|
-
end
|
120
|
-
|
121
|
-
|
122
|
-
def sanitize_condition(value)
|
123
|
-
# if value.is_a? Array
|
124
|
-
# # if value.size==1 and value[0].is_a? String
|
125
|
-
# # value[0].to_s
|
126
|
-
# # else
|
127
|
-
# value.inspect
|
128
|
-
# # end
|
129
|
-
# elsif value.is_a? Code
|
130
|
-
# value.inspect
|
131
|
-
# elsif value.is_a? String
|
132
|
-
# '"' + value.gsub('"', '\"') + '"'
|
133
|
-
# els
|
134
|
-
if [Date, DateTime].include? value.class
|
135
|
-
'"' + value.to_formatted_s(:db) + '"'
|
136
|
-
elsif value.is_a? NilClass
|
137
|
-
'nil'
|
138
|
-
else
|
139
|
-
value.inspect
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
|
150
|
-
|
data/lib/active_list/helpers.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
module ActiveList
|
2
|
-
module Helpers
|
3
|
-
|
4
|
-
def recordify!(value, record_name)
|
5
|
-
if value.is_a?(Symbol)
|
6
|
-
return record_name + "." + value.to_s
|
7
|
-
elsif value.is_a?(Code)
|
8
|
-
return "(" + value.gsub(/RECORD/, record_name) + ")"
|
9
|
-
else
|
10
|
-
raise ArgumentError, "Code or Symbol must be given to be recordified)"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def recordify(value, record_name)
|
15
|
-
if value.is_a?(Symbol)
|
16
|
-
return record_name + "." + value.to_s
|
17
|
-
elsif value.is_a?(Code)
|
18
|
-
return "(" + value.gsub(/RECORD/, record_name) + ")"
|
19
|
-
else
|
20
|
-
return value.inspect
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def urlify(value, record_name)
|
25
|
-
if value.is_a?(Code)
|
26
|
-
return "(" + value.gsub(/RECORD/, record_name) + ")"
|
27
|
-
else
|
28
|
-
return value.inspect
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module ActiveList
|
2
|
-
module Rails
|
3
|
-
class Engine < ::Rails::Engine
|
4
|
-
engine_name "active_list"
|
5
|
-
initializer "active_list.integrate_methods" do |app|
|
6
|
-
::ActionController::Base.send(:include, ActiveList::ActionPack::ActionController)
|
7
|
-
::ActionView::Base.send(:include, ActiveList::ActionPack::ViewsHelper)
|
8
|
-
files = Dir[File.join(File.dirname(__FILE__), "..", "..", "..", "locales", "*.yml")]
|
9
|
-
::I18n.load_path.concat(files)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# require 'active_support/core_ext/module/attribute_accessors'
|
2
|
-
|
3
|
-
module ActiveList
|
4
|
-
|
5
|
-
module Renderers
|
6
|
-
|
7
|
-
def self.[](name)
|
8
|
-
ActiveList.renderers[name]
|
9
|
-
end
|
10
|
-
|
11
|
-
autoload :AbstractRenderer, 'active_list/renderers/abstract_renderer'
|
12
|
-
autoload :SimpleRenderer, 'active_list/renderers/simple_renderer'
|
13
|
-
end
|
14
|
-
|
15
|
-
mattr_reader :renderers
|
16
|
-
@@renderers = {}
|
17
|
-
|
18
|
-
def self.register_renderer(name, renderer)
|
19
|
-
raise ArgumentError.new("A renderer must be ActiveList::Renderers::Renderer") unless renderer < ActiveList::Renderers::AbstractRenderer
|
20
|
-
@@renderers[name] = renderer
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
ActiveList.register_renderer(:simple_renderer, ActiveList::Renderers::SimpleRenderer)
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module ActiveList
|
2
|
-
|
3
|
-
module Renderers
|
4
|
-
|
5
|
-
class AbstractRenderer
|
6
|
-
attr_reader :generator, :table
|
7
|
-
|
8
|
-
def initialize(generator)
|
9
|
-
@generator = generator
|
10
|
-
@table = generator.table
|
11
|
-
end
|
12
|
-
|
13
|
-
def var_name(name)
|
14
|
-
@generator.var_name(name)
|
15
|
-
end
|
16
|
-
|
17
|
-
def remote_update_code
|
18
|
-
raise NotImplementedError, "#{self.class.name}#remote_update_code is not implemented."
|
19
|
-
end
|
20
|
-
|
21
|
-
def build_data_code
|
22
|
-
raise NotImplementedError, "#{self.class.name}#build_table_code is not implemented."
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
@@ -1,356 +0,0 @@
|
|
1
|
-
module ActiveList
|
2
|
-
|
3
|
-
module Renderers
|
4
|
-
|
5
|
-
class SimpleRenderer < AbstractRenderer
|
6
|
-
include ActiveList::Helpers
|
7
|
-
|
8
|
-
|
9
|
-
DATATYPE_ABBREVIATION = {
|
10
|
-
:binary => :bin,
|
11
|
-
:boolean => :bln,
|
12
|
-
:date => :dat,
|
13
|
-
:datetime => :dtt,
|
14
|
-
:decimal => :dec,
|
15
|
-
:measure => :dec,
|
16
|
-
:float => :flt,
|
17
|
-
:integer => :int,
|
18
|
-
:string => :str,
|
19
|
-
:text => :txt,
|
20
|
-
:time => :tim,
|
21
|
-
:timestamp => :dtt
|
22
|
-
}
|
23
|
-
|
24
|
-
def remote_update_code
|
25
|
-
code = "if params[:column] and params[:visibility]\n"
|
26
|
-
code << " column = params[:column].to_sym\n"
|
27
|
-
# Removes potentially unwanted columns
|
28
|
-
code << " #{var_name(:params)}[:hidden_columns].delete_if{|c| !#{table.data_columns.map(&:name).inspect}.include?(c)}\n"
|
29
|
-
code << " #{var_name(:params)}[:hidden_columns].delete(column) if params[:visibility] == 'shown'\n"
|
30
|
-
code << " #{var_name(:params)}[:hidden_columns] << column if params[:visibility] == 'hidden'\n"
|
31
|
-
code << " head :ok\n"
|
32
|
-
code << "elsif params[:only]\n"
|
33
|
-
code << " render(:inline => '<%=#{generator.view_method_name}(:only => params[:only])-%>')\n"
|
34
|
-
code << "else\n"
|
35
|
-
code << " render(:inline => '<%=#{generator.view_method_name}-%>')\n"
|
36
|
-
code << "end\n"
|
37
|
-
return code
|
38
|
-
end
|
39
|
-
|
40
|
-
def build_table_code
|
41
|
-
record = "r"
|
42
|
-
child = "c"
|
43
|
-
|
44
|
-
# colgroup = columns_definition_code
|
45
|
-
header = header_code
|
46
|
-
extras = extras_code
|
47
|
-
|
48
|
-
code = generator.select_data_code
|
49
|
-
code << "#{var_name(:tbody)} = '<tbody data-total=\"'+#{var_name(:count)}.to_s+'\""
|
50
|
-
if table.paginate?
|
51
|
-
code << " data-per-page=\"'+#{var_name(:limit)}.to_s+'\""
|
52
|
-
code << " data-pages-count=\"'+#{var_name(:last)}.to_s+'\""
|
53
|
-
end
|
54
|
-
code << ">'\n"
|
55
|
-
code << "if #{var_name(:count)} > 0\n"
|
56
|
-
code << " for #{record} in #{generator.records_variable_name}\n"
|
57
|
-
line_class = ""
|
58
|
-
if table.options[:line_class]
|
59
|
-
line_class = ", class: (" + recordify!(table.options[:line_class], record) + ").to_s"
|
60
|
-
end
|
61
|
-
code << " #{var_name(:tbody)} << content_tag(:tr, id: 'r' + #{record}.id.to_s#{line_class}) do\n"
|
62
|
-
code << columns_to_cells(:body, record: record).dig(3)
|
63
|
-
code << " end\n"
|
64
|
-
# if table.options[:children].is_a? Symbol
|
65
|
-
# children = table.options[:children].to_s
|
66
|
-
# code << " for #{child} in #{record}.#{children}\n"
|
67
|
-
# code << " #{var_name(:tbody)} << content_tag(:tr, :class => #{line_class}+' child') do\n"
|
68
|
-
# code << columns_to_cells(:children, table.children, record: child).dig(4)
|
69
|
-
# code << " end\n"
|
70
|
-
# code << " end\n"
|
71
|
-
# end
|
72
|
-
code << " end\n"
|
73
|
-
code << "else\n"
|
74
|
-
code << " #{var_name(:tbody)} << '<tr class=\"empty\"><td colspan=\"#{table.columns.size+1}\">' + ::I18n.translate('list.no_records') + '</td></tr>'\n"
|
75
|
-
code << "end\n"
|
76
|
-
|
77
|
-
code << "#{var_name(:tbody)} << '</tbody>'\n"
|
78
|
-
code << "return #{var_name(:tbody)}.html_safe if options[:only] == 'body' or options[:only] == 'tbody'\n"
|
79
|
-
|
80
|
-
code << "html = ''\n"
|
81
|
-
code << "html << '<div id=\"#{table.name}\" data-list-source=\"'+h(url_for(options.merge(:action => '#{generator.controller_method_name}')))+'\" class=\"active-list\""
|
82
|
-
if table.paginate?
|
83
|
-
code << " data-list-current-page=\"' + #{var_name(:page)}.to_s + '\" data-list-page-size=\"' + #{var_name(:limit)}.to_s + '\""
|
84
|
-
end
|
85
|
-
code << " data-list-sort-by=\"' + #{var_name(:params)}[:sort].to_s + '\" data-list-sort-dir=\"' + #{var_name(:params)}[:dir].to_s + '\""
|
86
|
-
code << ">'\n"
|
87
|
-
code << "html << '<table class=\"list\">'\n"
|
88
|
-
code << "html << (#{header})\n"
|
89
|
-
code << "if block_given?\n"
|
90
|
-
code << " html << '<tfoot>' + capture(" + table.columns.collect{|c| {name: c.name, id: c.id}}.inspect + ", &block).to_s + '</tfoot>'\n"
|
91
|
-
code << "end\n"
|
92
|
-
code << "html << #{var_name(:tbody)}\n"
|
93
|
-
code << "html << '</table>'\n"
|
94
|
-
code << "html << #{extras}\n" if extras
|
95
|
-
code << "html << '</div>'\n"
|
96
|
-
code << "return html.html_safe\n"
|
97
|
-
return code
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
def columns_to_cells(nature, options={})
|
103
|
-
code = ''
|
104
|
-
unless [:body, :children].include?(nature)
|
105
|
-
raise ArgumentError, "Nature is invalid"
|
106
|
-
end
|
107
|
-
children_mode = !!(nature == :children)
|
108
|
-
for column in table.columns
|
109
|
-
value_code = ""
|
110
|
-
record = options[:record] || 'record_of_the_death'
|
111
|
-
if column.is_a? ActiveList::Definition::EmptyColumn
|
112
|
-
value_code = 'nil'
|
113
|
-
elsif column.is_a? ActiveList::Definition::StatusColumn
|
114
|
-
|
115
|
-
value_code = column.datum_code(record, children_mode)
|
116
|
-
levels = %w(go caution stop)
|
117
|
-
lights = levels.collect do |light|
|
118
|
-
"content_tag(:span, '', :class => #{light.inspect})"
|
119
|
-
end.join(" + ")
|
120
|
-
# Expected value are :valid, :warning, :error
|
121
|
-
value_code = "content_tag(:span, #{lights}, :class => 'lights lights-' + (#{levels.inspect}.include?(#{value_code}.to_s) ? #{value_code}.to_s : 'undefined'))"
|
122
|
-
|
123
|
-
elsif column.is_a? ActiveList::Definition::DataColumn
|
124
|
-
if column.options[:children].is_a? FalseClass and children_mode
|
125
|
-
value_code = 'nil'
|
126
|
-
else
|
127
|
-
value_code = column.datum_code(record, children_mode)
|
128
|
-
if column.datatype == :boolean
|
129
|
-
value_code = "content_tag(:div, '', :class => 'checkbox-'+("+value_code.to_s+" ? 'true' : 'false'))"
|
130
|
-
elsif [:date, :datetime, :timestamp, :measure].include? column.datatype
|
131
|
-
value_code = "(#{value_code}.nil? ? '' : #{value_code}.l)"
|
132
|
-
elsif [:item].include? column.datatype
|
133
|
-
value_code = "(#{value_code}.nil? ? '' : #{value_code}.human_name)"
|
134
|
-
end
|
135
|
-
if !column.options[:currency].is_a?(FalseClass) and currency = column.options[:currency]
|
136
|
-
currency = currency[nature] if currency.is_a?(Hash)
|
137
|
-
currency = :currency if currency.is_a?(TrueClass)
|
138
|
-
# currency = "#{record}.#{currency}".c if currency.is_a?(Symbol)
|
139
|
-
currency = "#{column.record_expr(record)}.#{currency}".c if currency.is_a?(Symbol)
|
140
|
-
value_code = "(#{value_code}.nil? ? '' : #{value_code}.l(currency: #{currency.inspect}))"
|
141
|
-
elsif column.datatype == :decimal
|
142
|
-
value_code = "(#{value_code}.nil? ? '' : #{value_code}.l)"
|
143
|
-
elsif column.enumerize?
|
144
|
-
value_code = "(#{value_code}.nil? ? '' : #{value_code}.text)"
|
145
|
-
end
|
146
|
-
if column.options[:url] and nature == :body
|
147
|
-
column.options[:url] = {} unless column.options[:url].is_a?(Hash)
|
148
|
-
column.options[:url][:id] ||= (column.record_expr(record)+'.id').c
|
149
|
-
column.options[:url][:action] ||= :show
|
150
|
-
column.options[:url][:controller] ||= column.class_name.tableize.to_sym # (self.generator.collection? ? "RECORD.class.name.tableize".c : column.class_name.tableize.to_sym)
|
151
|
-
# column.options[:url][:controller] ||= "#{value_code}.class.name.tableize".c
|
152
|
-
url = column.options[:url].collect{|k, v| "#{k}: " + urlify(v, record)}.join(", ")
|
153
|
-
value_code = "(#{value_code}.blank? ? '' : link_to(#{value_code}.to_s, #{url}))"
|
154
|
-
elsif column.options[:mode]||column.label_method == :email
|
155
|
-
value_code = "(#{value_code}.blank? ? '' : mail_to(#{value_code}))"
|
156
|
-
elsif column.options[:mode]||column.label_method == :website
|
157
|
-
value_code = "(#{value_code}.blank? ? '' : link_to("+value_code+", "+value_code+"))"
|
158
|
-
elsif column.label_method == :color
|
159
|
-
value_code = "content_tag(:div, #{column.datum_code(record)}, style: 'background: #'+"+column.datum_code(record)+")"
|
160
|
-
elsif column.label_method.to_s.match(/(^|\_)currency$/) and column.datatype == :string
|
161
|
-
value_code = "(Nomen::Currencies[#{value_code}] ? Nomen::Currencies[#{value_code}].human_name : #{value_code})"
|
162
|
-
elsif column.label_method.to_s.match(/(^|\_)language$/) and column.datatype == :string
|
163
|
-
value_code = "(Nomen::Languages[#{value_code}] ? Nomen::Languages[#{value_code}].human_name : #{value_code})"
|
164
|
-
elsif column.label_method.to_s.match(/(^|\_)country$/) and column.datatype == :string
|
165
|
-
value_code = "(Nomen::Countries[#{value_code}] ? (image_tag('countries/' + #{value_code}.to_s + '.png') + ' ' + Nomen::Countries[#{value_code}].human_name).html_safe : #{value_code})"
|
166
|
-
else # if column.datatype == :string
|
167
|
-
value_code = "h(" + value_code + ".to_s)"
|
168
|
-
end
|
169
|
-
|
170
|
-
value_code = "if #{record}\n" + value_code.dig + "end" if column.is_a?(ActiveList::Definition::AssociationColumn)
|
171
|
-
end
|
172
|
-
elsif column.is_a?(ActiveList::Definition::CheckBoxColumn)
|
173
|
-
if nature == :body
|
174
|
-
form_name = column.form_name || "'#{table.name}[' + #{record}.id.to_s + '][#{column.name}]'".c
|
175
|
-
value = "nil"
|
176
|
-
if column.form_value
|
177
|
-
value = recordify(column.form_value, record)
|
178
|
-
else
|
179
|
-
value = 1
|
180
|
-
value_code << "hidden_field_tag(#{form_name.inspect}, 0, id: nil) + \n"
|
181
|
-
end
|
182
|
-
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}'
|
183
|
-
else
|
184
|
-
value_code << "nil"
|
185
|
-
end
|
186
|
-
elsif column.is_a?(ActiveList::Definition::TextFieldColumn)
|
187
|
-
form_name = column.form_name || "'#{table.name}[' + #{record}.id.to_s + '][#{column.name}]'".c
|
188
|
-
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}'
|
189
|
-
elsif column.is_a?(ActiveList::Definition::ActionColumn)
|
190
|
-
value_code = (nature == :body ? column.operation(record) : "nil")
|
191
|
-
else
|
192
|
-
value_code = "' ∅ '.html_safe"
|
193
|
-
end
|
194
|
-
code << "content_tag(:td, :class => \"#{column_classes(column)}\") do\n"
|
195
|
-
code << value_code.dig
|
196
|
-
code << "end +\n"
|
197
|
-
end
|
198
|
-
# if nature == :header
|
199
|
-
# code << "'<th class=\"spe\">#{menu_code}</th>'"
|
200
|
-
# else
|
201
|
-
# code << "content_tag(:td)"
|
202
|
-
# end
|
203
|
-
|
204
|
-
code << "content_tag(:td)"
|
205
|
-
return code.c
|
206
|
-
end
|
207
|
-
|
208
|
-
|
209
|
-
# Produces main menu code
|
210
|
-
def menu_code
|
211
|
-
menu = "<div class=\"list-menu\">"
|
212
|
-
menu << "<a class=\"list-menu-start\"><span class=\"icon\"></span><span class=\"text\">' + h(::I18n.translate('list.menu').gsub(/\'/,''')) + '</span></a>"
|
213
|
-
menu << "<ul>"
|
214
|
-
if table.paginate?
|
215
|
-
# Per page
|
216
|
-
list = [5, 10, 20, 50, 100, 200]
|
217
|
-
list << table.options[:per_page].to_i if table.options[:per_page].to_i > 0
|
218
|
-
list = list.uniq.sort
|
219
|
-
menu << "<li class=\"parent\">"
|
220
|
-
menu << "<a class=\"pages\"><span class=\"icon\"></span><span class=\"text\">' + ::I18n.translate('list.items_per_page').gsub(/\'/,''') + '</span></a><ul>"
|
221
|
-
for n in list
|
222
|
-
menu << "<li data-list-change-page-size=\"#{n}\" '+(#{var_name(:params)}[:per_page] == #{n} ? ' class=\"check\"' : '')+'><a><span class=\"icon\"></span><span class=\"text\">'+h(::I18n.translate('list.x_per_page', :count => #{n}))+'</span></a></li>"
|
223
|
-
end
|
224
|
-
menu << "</ul></li>"
|
225
|
-
end
|
226
|
-
|
227
|
-
# Column selector
|
228
|
-
menu << "<li class=\"parent\">"
|
229
|
-
menu << "<a class=\"columns\"><span class=\"icon\"></span><span class=\"text\">' + ::I18n.translate('list.columns').gsub(/\'/,''') + '</span></a><ul>"
|
230
|
-
for column in table.data_columns
|
231
|
-
menu << "<li data-list-toggle-column=\"#{column.name}\" class=\"'+(#{var_name(:params)}[:hidden_columns].include?(:#{column.name}) ? 'unchecked' : 'checked')+'\"><a><span class=\"icon\"></span><span class=\"text\">'+h(#{column.header_code})+'</span></a></li>"
|
232
|
-
end
|
233
|
-
menu << "</ul></li>"
|
234
|
-
|
235
|
-
# Separator
|
236
|
-
menu << "<li class=\"separator\"></li>"
|
237
|
-
# Exports
|
238
|
-
for format, exporter in ActiveList.exporters
|
239
|
-
menu << "<li class=\"export #{exporter.name}\">' + link_to(params.merge(:action => :#{generator.controller_method_name}, :sort => #{var_name(:params)}[:sort], :dir => #{var_name(:params)}[:dir], :format => '#{format}')) { '<span class=\"icon\"></span>'.html_safe + content_tag('span', ::I18n.translate('list.export_as', :exported => ::I18n.translate('list.export.formats.#{format}')).gsub(/\'/,'''), :class => 'text')} + '</li>"
|
240
|
-
end
|
241
|
-
menu << "</ul></div>"
|
242
|
-
return menu
|
243
|
-
end
|
244
|
-
|
245
|
-
# Produces the code to create the header line using top-end menu for columns
|
246
|
-
# and pagination management
|
247
|
-
def header_code
|
248
|
-
code = "'<thead><tr>"
|
249
|
-
for column in table.columns
|
250
|
-
code << "<th data-list-column=\"#{column.sort_id}\""
|
251
|
-
code << " data-list-column-cells=\"#{column.short_id}\""
|
252
|
-
code << " data-list-column-sort=\"'+(#{var_name(:params)}[:sort] != '#{column.sort_id}' ? 'asc' : #{var_name(:params)}[:dir] == 'asc' ? 'desc' : 'asc')+'\"" if column.sortable?
|
253
|
-
code << " class=\"#{column_classes(column, true, true)}\""
|
254
|
-
code << ">"
|
255
|
-
code << "<span class=\"text\">'+h(#{column.header_code})+'</span>"
|
256
|
-
code << "<span class=\"icon\"></span>"
|
257
|
-
code << "</th>"
|
258
|
-
end
|
259
|
-
code << "<th class=\"spe\">#{menu_code}</th>"
|
260
|
-
code << "</tr></thead>'"
|
261
|
-
return code
|
262
|
-
end
|
263
|
-
|
264
|
-
# Produces the code to create bottom menu and pagination
|
265
|
-
def extras_code
|
266
|
-
code, pagination = nil, ''
|
267
|
-
|
268
|
-
if table.paginate?
|
269
|
-
current_page = "#{var_name(:page)}"
|
270
|
-
last_page = "#{var_name(:last)}"
|
271
|
-
|
272
|
-
pagination << "<div class=\"pagination\">"
|
273
|
-
pagination << "<a href=\"#\" data-list-move-to-page=\"1\" class=\"first-page\"' + (#{current_page} != 1 ? '' : ' disabled=\"true\"') + '><i></i>' + ::I18n.translate('list.pagination.first') + '</a>"
|
274
|
-
pagination << "<a href=\"#\" data-list-move-to-page=\"' + (#{current_page} - 1).to_s + '\" class=\"previous-page\"' + (#{current_page} != 1 ? '' : ' disabled=\"true\"') + '><i></i>' + ::I18n.translate('list.pagination.previous') + '</a>"
|
275
|
-
|
276
|
-
x = '@@PAGE-NUMBER@@'
|
277
|
-
y = '@@PAGE-COUNT@@'
|
278
|
-
pagination << "<span class=\"paginator\">'+::I18n.translate('list.page_x_on_y', :default => '%{x} / %{y}', :x => '#{x}', :y => '#{y}').html_safe.gsub('#{x}', ('<input type=\"number\" size=\"4\" data-list-move-to-page=\"value\" value=\"'+#{var_name(:page)}.to_s+'\">').html_safe).gsub('#{y}', #{var_name(:last)}.to_s) + '</span>"
|
279
|
-
|
280
|
-
pagination << "<a href=\"#\" data-list-move-to-page=\"' + (#{current_page} + 1).to_s + '\" class=\"next-page\"' + (#{current_page} != #{last_page} ? '' : ' disabled=\"true\"') + '><i></i>' + ::I18n.translate('list.pagination.next')+'</a>"
|
281
|
-
pagination << "<a href=\"#\" data-list-move-to-page=\"' + (#{last_page}).to_s + '\" class=\"last-page\"' + (#{current_page} != #{last_page} ? '' : ' disabled=\"true\"') + '><i></i>' + ::I18n.translate('list.pagination.last')+'</a>"
|
282
|
-
|
283
|
-
pagination << "<span class=\"separator\"></span>"
|
284
|
-
|
285
|
-
pagination << "<span class=\"status\">'+::I18n.translate('list.pagination.showing_x_to_y_of_total', :x => (#{var_name(:offset)} + 1), :y => ((#{var_name(:last)} == #{var_name(:page)}) ? #{var_name(:count)} : #{var_name(:offset)}+#{var_name(:limit)}), :total => #{var_name(:count)})+'</span>"
|
286
|
-
pagination << "</div>"
|
287
|
-
|
288
|
-
code = "(#{var_name(:last)} > 1 ? '<div class=\"extras\">#{pagination}</div>' : '').html_safe"
|
289
|
-
end
|
290
|
-
|
291
|
-
return code
|
292
|
-
end
|
293
|
-
|
294
|
-
|
295
|
-
# # Not used
|
296
|
-
# def columns_definition_code
|
297
|
-
# code = table.columns.collect do |column|
|
298
|
-
# "<col id=\\\"#{column.unique_id}\\\" class=\\\"#{column_classes(column, true)}\\\" data-cells-class=\\\"#{column.short_id}\\\" href=\\\"\#\{url_for(:action => :#{generator.controller_method_name}, :column => #{column.id.to_s.inspect})\}\\\" />"
|
299
|
-
# end.join
|
300
|
-
# return "\"#{code}\""
|
301
|
-
# end
|
302
|
-
|
303
|
-
# Finds all default styles for column
|
304
|
-
def column_classes(column, without_id = false, without_interpolation = false)
|
305
|
-
classes, conds = [], []
|
306
|
-
conds << [:sor, "#{var_name(:params)}[:sort] == '#{column.sort_id}'".c] if column.sortable?
|
307
|
-
conds << [:hidden, "#{var_name(:params)}[:hidden_columns].include?(:#{column.name})".c] if column.is_a? ActiveList::Definition::DataColumn
|
308
|
-
classes << column.options[:class].to_s.strip unless column.options[:class].blank?
|
309
|
-
classes << column.short_id unless without_id
|
310
|
-
if column.is_a? ActiveList::Definition::ActionColumn
|
311
|
-
classes << :act
|
312
|
-
elsif column.is_a? ActiveList::Definition::StatusColumn
|
313
|
-
classes << :status
|
314
|
-
elsif column.is_a? ActiveList::Definition::DataColumn
|
315
|
-
classes << :col
|
316
|
-
classes << DATATYPE_ABBREVIATION[column.datatype]
|
317
|
-
classes << :url if column.options[:url].is_a?(Hash)
|
318
|
-
classes << column.label_method if [:code, :color].include? column.label_method.to_sym
|
319
|
-
if column.options[:mode] == :download
|
320
|
-
classes << :dld
|
321
|
-
elsif column.options[:mode]||column.label_method == :email
|
322
|
-
classes << :eml
|
323
|
-
elsif column.options[:mode]||column.label_method == :website
|
324
|
-
classes << :web
|
325
|
-
end
|
326
|
-
elsif column.is_a? ActiveList::Definition::TextFieldColumn
|
327
|
-
classes << :tfd
|
328
|
-
elsif column.is_a? ActiveList::Definition::CheckBoxColumn
|
329
|
-
classes << :chk
|
330
|
-
else
|
331
|
-
classes << :unk
|
332
|
-
end
|
333
|
-
html = classes.join(' ').strip
|
334
|
-
if conds.size > 0
|
335
|
-
if without_interpolation
|
336
|
-
html << "' + "
|
337
|
-
html << conds.collect do |c|
|
338
|
-
"(#{c[1]} ? ' #{c[0]}' : '')"
|
339
|
-
end.join(' + ')
|
340
|
-
html << " + '"
|
341
|
-
else
|
342
|
-
html << conds.collect do |c|
|
343
|
-
"\#\{' #{c[0]}' if #{c[1]}\}"
|
344
|
-
end.join
|
345
|
-
end
|
346
|
-
end
|
347
|
-
return html
|
348
|
-
end
|
349
|
-
|
350
|
-
|
351
|
-
end
|
352
|
-
|
353
|
-
|
354
|
-
end
|
355
|
-
|
356
|
-
end
|