the_grid 1.1.3 → 1.1.4
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.
- checksums.yaml +8 -8
- data/lib/the_grid/api/command.rb +8 -0
- data/lib/the_grid/api.rb +1 -1
- data/lib/the_grid/builder/context.rb +6 -0
- data/lib/the_grid/builder/csv.rb +28 -28
- data/lib/the_grid/builder/json.rb +10 -26
- data/lib/the_grid/builder.rb +32 -1
- data/lib/the_grid/version.rb +1 -1
- data/lib/the_grid.rb +0 -3
- data/spec/builder/context_spec.rb +5 -0
- data/spec/builder/csv_spec.rb +19 -13
- data/spec/builder/json_spec.rb +10 -9
- data/spec/builder/view_builder_helper.rb +13 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YTM1YzE1MmUxNzZjZTZlNjIyYjNkNjhhYWNiNmY4YWQ2ZGU4YjAzMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NTkyN2FmNTZlMWUxZWM0NDI4YmVkNTYzMjMyODdkYWE5MGVlOWE1Yg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDkyYzc4ZDQ4NjM3YWU3OTNjZDQ2YzQzZTNkYzU1NWJjY2IyYTYzMjQ2ZmEy
|
10
|
+
YjI3YmIyYmM5MzRjZTJkNjE5NDU0YWM1YzFhZTQ5NjljNjdkMGU3NmFlNTlk
|
11
|
+
ZDQyMmEzMjk2ZTkxN2QwM2YxMDIwYmEwM2Q3NzVlNTZhNTEzY2E=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZTM1YzgyZTYwZjI4MDU2MjUwODRhMDFlNDM0ZGIxNGU3YzI1YjdiZWE0OTE5
|
14
|
+
Nzk1MTc2MGViZDEzN2VhNTFlYjg3NGU1MDg5N2E3MTFhODRkMjc0MTQzODJl
|
15
|
+
ODA0ZDMwZDQwMWI4Nzc4NGE4ZGFjNmYwMWI4ODdiODE2MDJlMzA=
|
data/lib/the_grid/api/command.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
module TheGrid
|
2
2
|
class Api::Command
|
3
3
|
|
4
|
+
autoload :BatchRemove, 'the_grid/api/command/batch_remove'
|
5
|
+
autoload :BatchUpdate, 'the_grid/api/command/batch_update'
|
6
|
+
autoload :Filter, 'the_grid/api/command/filter'
|
7
|
+
autoload :Paginate, 'the_grid/api/command/paginate'
|
8
|
+
autoload :Search, 'the_grid/api/command/search'
|
9
|
+
autoload :Sort, 'the_grid/api/command/sort'
|
10
|
+
|
11
|
+
|
4
12
|
def self.find(cmd)
|
5
13
|
@@commands ||= {}
|
6
14
|
@@commands[cmd] ||= build(cmd)
|
data/lib/the_grid/api.rb
CHANGED
@@ -48,6 +48,12 @@ module TheGrid
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
+
def column_titles
|
52
|
+
self.options[:titles] ||= columns.flat_map do |name, options|
|
53
|
+
options[:as].kind_of?(self.class) ? options[:as].column_titles : options.fetch(:title, name.to_s.titleize)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
51
57
|
def assemble(records)
|
52
58
|
records.map{ |record| assemble_row_for(record) }
|
53
59
|
end
|
data/lib/the_grid/builder/csv.rb
CHANGED
@@ -1,49 +1,49 @@
|
|
1
1
|
require 'csv'
|
2
2
|
|
3
3
|
module TheGrid
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module Builder::Csv
|
5
|
+
extend self, Builder::Base
|
7
6
|
BATCH_SIZE = 1000
|
8
7
|
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def assemble_with(params)
|
15
|
-
options = params.merge context.params
|
16
|
-
api.compose!(options.merge :per_page => BATCH_SIZE) if api.relation.respond_to?(:connection)
|
17
|
-
generate_csv_with(options)
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def generate_csv_with(options)
|
8
|
+
def build(context, options)
|
9
|
+
records, params = options.values_at(:for, :with)
|
10
|
+
options.merge! :per_page => BATCH_SIZE if records.respond_to?(:connection)
|
11
|
+
api = compose(records, options)
|
23
12
|
CSV.generate do |csv|
|
24
|
-
csv <<
|
25
|
-
api.relation.
|
13
|
+
csv << context.column_titles
|
14
|
+
api.relation.respond_to?(:connection) ? put(context, :to => csv, :with => api) : put_this(context, :to => csv, :with => records)
|
26
15
|
end
|
27
16
|
end
|
28
17
|
|
29
|
-
|
30
|
-
put_records_to(csv, api.relation)
|
31
|
-
end
|
18
|
+
private
|
32
19
|
|
33
|
-
def
|
20
|
+
def put(context, options)
|
21
|
+
api, csv = options.values_at(:with, :to)
|
34
22
|
pages = api.options[:max_page]
|
35
23
|
(1..pages).each do |page|
|
36
24
|
relation = api.run_command!(:paginate, :page => page, :per_page => BATCH_SIZE, :size => pages * BATCH_SIZE)
|
37
|
-
|
25
|
+
put_this(context, :to => csv, :with => relation)
|
38
26
|
end
|
39
27
|
end
|
40
28
|
|
41
|
-
def
|
42
|
-
context.assemble(
|
29
|
+
def put_this(context, options)
|
30
|
+
context.assemble(options[:with]).each do |row|
|
31
|
+
flatten(row).each{ |row| options[:to] << row }
|
32
|
+
end
|
43
33
|
end
|
44
34
|
|
45
|
-
def
|
46
|
-
|
35
|
+
def flatten(row)
|
36
|
+
# TODO: optimize it
|
37
|
+
row_values, row_nested_values = [], []
|
38
|
+
row.each do |field, value|
|
39
|
+
if value.kind_of?(Array)
|
40
|
+
row_nested_values += value.flat_map{ |r| flatten(r) }
|
41
|
+
else
|
42
|
+
row_values << value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
return [ row_values ] if row_nested_values.empty?
|
46
|
+
row_nested_values.each{ |nested_values| nested_values.unshift(*row_values) }
|
47
47
|
end
|
48
48
|
|
49
49
|
end
|
@@ -1,38 +1,22 @@
|
|
1
1
|
module TheGrid
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
module Builder::Json
|
3
|
+
extend self, Builder::Base
|
4
|
+
mattr_accessor :prettify_json
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
@context = context
|
9
|
-
end
|
10
|
-
|
11
|
-
def assemble_with(params)
|
12
|
-
options = params.merge context.params
|
13
|
-
api.compose!(options)
|
14
|
-
stringify as_json_with(options)
|
15
|
-
rescue ArgumentError => error
|
16
|
-
stringify as_json_message('error', error.message)
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def stringify(json_hash)
|
22
|
-
self.class.prettify_json ? JSON.pretty_generate(json_hash) : json_hash.to_json
|
23
|
-
end
|
24
|
-
|
25
|
-
def as_json_with(options)
|
6
|
+
def build(context, params)
|
7
|
+
api, options = compose(params[:for], params[:with]), params[:with]
|
26
8
|
json = {:max_page => api.options[:max_page], :items => context.assemble(api.relation)}
|
27
9
|
if options[:with_meta]
|
28
10
|
json[:meta] = context.options.except(:delegate, :search_over)
|
29
11
|
json[:columns] = columns_as_array(context.visible_columns)
|
30
12
|
end
|
31
|
-
json
|
13
|
+
stringify json
|
32
14
|
end
|
33
15
|
|
34
|
-
|
35
|
-
|
16
|
+
private
|
17
|
+
|
18
|
+
def stringify(json_hash)
|
19
|
+
self.prettify_json ? JSON.pretty_generate(json_hash) : json_hash.to_json
|
36
20
|
end
|
37
21
|
|
38
22
|
def columns_as_array(columns)
|
data/lib/the_grid/builder.rb
CHANGED
@@ -2,6 +2,10 @@ module TheGrid
|
|
2
2
|
class Builder
|
3
3
|
private_class_method :new
|
4
4
|
|
5
|
+
autoload :Context, 'the_grid/builder/context'
|
6
|
+
autoload :Csv, 'the_grid/builder/csv'
|
7
|
+
autoload :Json, 'the_grid/builder/json'
|
8
|
+
|
5
9
|
def self.call(template)
|
6
10
|
source = if template.source.empty?
|
7
11
|
File.read(template.identifier)
|
@@ -37,7 +41,7 @@ module TheGrid
|
|
37
41
|
|
38
42
|
def grid_for(relation, options = {}, &block)
|
39
43
|
context = Context.new(options.merge(:scope => @_scope), &block)
|
40
|
-
@_view_type.
|
44
|
+
@_view_type.assemble(context, :on => relation, :with => @_scope.params)
|
41
45
|
end
|
42
46
|
|
43
47
|
def method_missing(name, *args, &block)
|
@@ -55,5 +59,32 @@ module TheGrid
|
|
55
59
|
vars.each{ |name| instance_variable_set(name.to_sym, object.instance_variable_get(name)) }
|
56
60
|
end
|
57
61
|
|
62
|
+
|
63
|
+
module Base
|
64
|
+
|
65
|
+
def compose(records, params)
|
66
|
+
api = ::TheGrid::Api.new(records)
|
67
|
+
api.compose!(params)
|
68
|
+
api
|
69
|
+
end
|
70
|
+
|
71
|
+
def assemble(context, options)
|
72
|
+
options.assert_valid_keys(:on, :with)
|
73
|
+
params = options[:with].merge context.params
|
74
|
+
build(context, :for => options[:on], :with => params)
|
75
|
+
rescue ArgumentError => error
|
76
|
+
stringify :status => 'error', :message => error.message
|
77
|
+
end
|
78
|
+
|
79
|
+
def stringify(data)
|
80
|
+
data.inspect
|
81
|
+
end
|
82
|
+
|
83
|
+
def build
|
84
|
+
raise NotImplementedError
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
58
89
|
end
|
59
90
|
end
|
data/lib/the_grid/version.rb
CHANGED
data/lib/the_grid.rb
CHANGED
@@ -3,9 +3,6 @@ require 'the_grid/api'
|
|
3
3
|
require 'the_grid/api/command'
|
4
4
|
require 'the_grid/builder'
|
5
5
|
require 'the_grid/config'
|
6
|
-
Dir.chdir(File.dirname(__FILE__)) do
|
7
|
-
Dir['the_grid/builder/**/*.rb', 'the_grid/api/command/**/*.rb'].each{ |f| require f }
|
8
|
-
end
|
9
6
|
|
10
7
|
module TheGrid
|
11
8
|
def self.configure
|
@@ -88,6 +88,11 @@ describe TheGrid::Builder::Context do
|
|
88
88
|
context = build_context{ scope_for(:articles, :as => :children, &dsl) }
|
89
89
|
context.columns[:children][:as].should be_kind_of subject
|
90
90
|
end
|
91
|
+
|
92
|
+
it "returns titles for columns from attributes" do
|
93
|
+
context = build_context{ column(:id, :title => "Name") }
|
94
|
+
context.column_titles.should eql %w{Name}
|
95
|
+
end
|
91
96
|
end
|
92
97
|
|
93
98
|
context "when collects visible columns" do
|
data/spec/builder/csv_spec.rb
CHANGED
@@ -2,30 +2,32 @@ require 'spec_helper'
|
|
2
2
|
require_relative 'view_builder_helper'
|
3
3
|
|
4
4
|
describe TheGrid::Builder::Csv do
|
5
|
-
subject{ TheGrid::Builder::Csv
|
5
|
+
subject{ TheGrid::Builder::Csv }
|
6
6
|
|
7
7
|
include_examples "for Grid View Builder"
|
8
|
-
before(:each) { subject.api.stub(:compose!) }
|
9
|
-
before(:each) { subject.api.options[:max_page] = 1 }
|
10
8
|
|
11
|
-
let(:
|
12
|
-
let(:
|
13
|
-
let(:
|
14
|
-
let(:params) {{ :cmd => [:sort], :field => :name, :order => :desc, :per_page => subject.
|
9
|
+
let(:api_options) {{ :max_page => 1 }}
|
10
|
+
let(:context) { build_context }
|
11
|
+
let(:relation) { double(:connection => double.as_null_object).as_null_object }
|
12
|
+
let(:params) {{ :cmd => [:sort], :field => :name, :order => :desc, :per_page => subject.const_get("BATCH_SIZE") }}
|
15
13
|
|
16
14
|
it "generates expected csv string" do
|
17
|
-
subject.
|
15
|
+
subject.assemble(context, :on => relation, :with => params).should eql generate_csv(records, context.column_titles)
|
18
16
|
end
|
19
17
|
|
20
18
|
it "uses titleized column names if titles are not specified" do
|
21
|
-
|
22
|
-
|
23
|
-
subject.assemble_with(params).should eql generate_csv(records, titles)
|
19
|
+
context.stub(:options => {})
|
20
|
+
subject.assemble(context, :on => relation, :with => params).should eql generate_csv(records, context.column_titles)
|
24
21
|
end
|
25
22
|
|
26
23
|
it "generates csv records in batches" do
|
27
|
-
|
28
|
-
subject.
|
24
|
+
TheGrid::Api.any_instance.should_receive(:run_command!).with(:paginate, :page => 1, :per_page => params[:per_page], :size => api_options[:max_page] * params[:per_page])
|
25
|
+
subject.assemble(context, :on => relation, :with => params)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "generates csv with nested data" do
|
29
|
+
context.stub(:assemble => [ record.merge(:children => [ child_record(1), child_record(2) ]) ])
|
30
|
+
subject.assemble(context, :on => relation, :with => params).should eql generate_csv(2.times.map{ |i| record.merge child_record(i + 1) }, context.column_titles)
|
29
31
|
end
|
30
32
|
|
31
33
|
|
@@ -42,6 +44,10 @@ describe TheGrid::Builder::Csv do
|
|
42
44
|
column :name
|
43
45
|
column :status
|
44
46
|
column :text
|
47
|
+
|
48
|
+
scope_for :children do
|
49
|
+
column :name
|
50
|
+
end
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
data/spec/builder/json_spec.rb
CHANGED
@@ -2,22 +2,23 @@ require 'spec_helper'
|
|
2
2
|
require_relative 'view_builder_helper'
|
3
3
|
|
4
4
|
describe TheGrid::Builder::Json do
|
5
|
-
subject{ TheGrid::Builder::Json
|
5
|
+
subject{ TheGrid::Builder::Json }
|
6
6
|
|
7
7
|
include_examples "for Grid View Builder"
|
8
|
-
before(:each) { subject.api.stub(:compose!){ subject.api.options[:max_page] = 25 } }
|
9
8
|
|
9
|
+
let(:context) { build_context }
|
10
10
|
let(:records) {[ 1, 2, 3, 4 ]}
|
11
11
|
let(:params) {{ :cmd => [:sort], :field => :name, :order => :desc }}
|
12
12
|
|
13
|
-
let(:meta) {{ "meta" => {"api_key" =>
|
14
|
-
let(:columns) {
|
15
|
-
let(:json_schema) {{ "max_page" => 25, "items" =>
|
16
|
-
let(:assembled_result) { JSON.parse(subject.
|
13
|
+
let(:meta) {{ "meta" => {"api_key" => context.options[:api_key]}, "columns" => columns }}
|
14
|
+
let(:columns) { context.visible_columns.stringify_keys.map{ |n, o| o.merge "name" => n } }
|
15
|
+
let(:json_schema) {{ "max_page" => 25, "items" => context.assemble(records) }}
|
16
|
+
let(:assembled_result) { JSON.parse(subject.assemble(context, :on => Object.new, :with => params)) }
|
17
|
+
|
17
18
|
|
18
19
|
it "merges params with context options" do
|
19
|
-
|
20
|
-
subject.
|
20
|
+
TheGrid::Api.any_instance.should_receive(:compose!).with(params.merge context.options)
|
21
|
+
subject.assemble(context, :on => Object.new, :with => params)
|
21
22
|
end
|
22
23
|
|
23
24
|
it "generates json with meta information" do
|
@@ -30,7 +31,7 @@ describe TheGrid::Builder::Json do
|
|
30
31
|
end
|
31
32
|
|
32
33
|
it "generates json notification when get wrong argument" do
|
33
|
-
|
34
|
+
TheGrid::Api.any_instance.stub(:compose!) { raise ArgumentError, "my message" }
|
34
35
|
assembled_result.should eql "status" => "error", "message" => "my message"
|
35
36
|
end
|
36
37
|
|
@@ -1,10 +1,18 @@
|
|
1
1
|
shared_examples "for Grid View Builder" do
|
2
|
-
before(:each) {
|
2
|
+
before(:each) { context.stub(:assemble => records) }
|
3
|
+
before(:each) { TheGrid::Api.any_instance.stub(:compose!) }
|
4
|
+
before(:each) { TheGrid::Api.any_instance.stub(:options => api_options) }
|
3
5
|
|
4
|
-
|
6
|
+
let(:records) {[ record, record, record ]}
|
7
|
+
let(:api_options){{ :max_page => 25 }}
|
5
8
|
|
6
|
-
it
|
7
|
-
|
8
|
-
|
9
|
+
it { should respond_to(:assemble) }
|
10
|
+
|
11
|
+
def child_record(id)
|
12
|
+
{ :child_id => id, :child_name => "Child Name #{id}" }
|
13
|
+
end
|
14
|
+
|
15
|
+
def record(id = nil)
|
16
|
+
{ :id => id || 1, :name => "Name #{id}", :status => "Active", :text => "Text" }
|
9
17
|
end
|
10
18
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: the_grid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergiy Stotskiy
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|