Modify implementation of how data tables define cells

* We want a clean, clear, but flexible interface for using data tables
  * We want the model to define our cell
  * We want to be informative to the user if they do not define the cell
This commit is contained in:
David Larrabee
2015-04-04 08:16:00 -04:00
parent 847ef63128
commit 7eb232675f
4 changed files with 55 additions and 67 deletions

View File

@@ -1,2 +1,10 @@
class Contributer < CDQManagedObject
def cell
{
cell_class: ContributerCell,
properties: {
name: name
}
}
end
end

View File

@@ -2,10 +2,7 @@ class ContributerScreen < PM::DataTableScreen
title "RedPotion Contributers"
refreshable
stylesheet ContributerScreenStylesheet
cell model: Contributer, scope: :all, template: {
name: :name,
cell_class: ContributerCell
}
model Contributer
def on_load
end

View File

@@ -1,12 +1,17 @@
module ProMotion
class DataTableScreen < TableScreen
class << self
def model(value, scope=nil)
if value.method_defined?(:cell)
@data_model = value
@data_scope = scope || :all
else
raise "#{value} must define the cell method"
end
end
def self.cell(cell)
@cell = cell
end
def self.cell_properties
@cell
def data_model; @data_model; end
def data_scope; @data_scope; end
end
def table_data
@@ -15,47 +20,20 @@ module ProMotion
}]
end
def cell_properties
self.class.cell_properties
end
def cell_data
return [] if cell_properties.nil?
return [] if data_model.nil?
data_model.send(data_scope).collect do |c|
if c.respond_to?(:cell)
c.cell
else
{
cell_class: cell_class,
properties: properties.inject({}) do |hash, element|
hash[element.first] = c.send(element.last)
hash
end
}
end
end
data_model.send(data_scope).collect(&:cell)
end
private
def properties
@properties ||= cell_properties[:template].reject do |k,v|
k == :cell_class
end unless cell_properties[:template].nil?
end
def cell_class
@cell_class ||= cell_properties[:template].nil? ? nil : cell_properties[:template][:cell_class]
end
def data_model
@data_model ||= cell_properties[:model]
self.class.data_model
end
def data_scope
@data_scope ||= cell_properties[:scope] || :all
self.class.data_scope
end
end
end

View File

@@ -18,6 +18,15 @@ describe 'DataTableScreen' do
new('one')
]
end
def cell
{
cell_class: TestCell,
properties: {
name: self.name
}
}
end
end
class TestCell
def on_load
@@ -31,17 +40,7 @@ describe 'DataTableScreen' do
end
class TestDataTableScreen < ProMotion::DataTableScreen
cell model: TestModel, scope: :starts_with_o, template: {
name: :name,
cell_class: TestCell
}
end
it 'should set the cell_properties value when we call DataTableScreen.cell' do
TestDataTableScreen.new.cell_properties[:model].should.equal(TestModel)
TestDataTableScreen.new.cell_properties[:scope].should.equal(:starts_with_o)
TestDataTableScreen.new.cell_properties[:template][:cell_class].should.equal(TestCell)
TestDataTableScreen.new.cell_properties[:template][:name].should.equal(:name)
model TestModel, :starts_with_o
end
it 'should return items that can be used to build cells from cell_data' do
@@ -50,29 +49,35 @@ describe 'DataTableScreen' do
end
it 'should default the scope to all, if its not included in the cell definition' do
TestDataTableScreen.cell(model: TestModel, template: {
name: :name,
cell_class: TestCell
})
class TestDataTableScreen < ProMotion::DataTableScreen
model TestModel
end
TestDataTableScreen.new.cell_data.count.should.equal(2)
TestDataTableScreen.new.cell_data[0][:properties][:name].should.equal('one')
TestDataTableScreen.new.cell_data[1][:properties][:name].should.equal('two')
end
it 'should use a the cell method in the model when specified' do
class TestModel
def cell
{
cell_class: TestCell,
properties: {
name: 'one',
}
}
describe ".model" do
it "should query the model that was provided to the screen" do
TestDataTableScreen.model TestModel
TestDataTableScreen.data_model.should.equal(TestModel)
TestDataTableScreen.new.cell_data.count.should.equal(2)
end
it "should require the model provided defines the cell method" do
class MissingCellMethod; end
should.raise(RuntimeError) do
TestDataTableScreen.model MissingCellMethod
end
end
TestDataTableScreen.cell(model: TestModel)
TestDataTableScreen.new.cell_data.count.should.equal(2)
TestDataTableScreen.new.cell_data[0][:properties][:name].should.equal('one')
it "should accept an optional scope" do
TestDataTableScreen.model TestModel, :starts_with_o
TestDataTableScreen.data_scope.should.equal(:starts_with_o)
TestDataTableScreen.new.cell_data.count.should.equal(1)
TestDataTableScreen.new.cell_data[0][:properties][:name].should.equal('one')
end
end
end