Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Rapid development of enterprise web apps with Netzke

Rapid development of enterprise web apps with Netzke

RubyKaigi 2013, Tokyo: http://rubykaigi.org/2013/talk/S34

Max Gorin

June 01, 2013
Tweet

More Decks by Max Gorin

Other Decks in Technology

Transcript

  1. Max Gorin author and maintainer of Netzke on Rails since

    2007 nomad since 2008 Dvorak, vim, geekery, speaking, mountains
  2. Challenges hundreds of data models very comlpex views monstrous monolitic

    client side decoupled client and server code lack of best practices
  3. Modular GUI development old proven concept used for building complex

    apps does Rails cooperate? and Cells lack of consistent front-end lack of pre-built components
  4. Duplication class Contacts < Netzke::Basepack::Grid def configure(c) super c.model =

    "Contact" end end class Carriers < Netzke::Basepack::Grid def configure(c) super c.model = "Carrier" end end class PackingTypes < Netzke::Basepack::Grid def configure(c) super c.model = "PackingType" end end
  5. Better class GridBase < Netzke::Basepack::Grid def configure(c) super c.model =

    self.class.name.singularize end end # Now: class Contacts < GridBase end class Carriers < GridBase end class PackingTypes < GridBase end # etc
  6. Shared changes class GridBase < Netzke::Basepack::Grid # hide the created_at

    and updated_at columns column :created_at do |c| c.excluded = true end column :updated_at do |c| c.excluded = true end def configure(c) super c.model = self.class.name.singularize end end
  7. Testing code structure floralogic/ spec/ mocha/ fixtures/ orders/ grid.rb <--

    fixtures for Orders::Grid specs orders/ grid.js.coffee <-- Orders::Grid specs support/ ... <-- various helpers in CoffeeScript mocha_spec.rb <-- runs all specs from mocha/
  8. Fixtures seller1 = FactoryGirl.create :seller, short_name: 'One' seller2 = FactoryGirl.create

    :seller, short_name: 'Two' cargo1 = FactoryGirl.create :cargo_type, name: 'CARGO ONE' cargo2 = FactoryGirl.create :cargo_type, name: 'CARGO TWO' FactoryGirl.create :order, seller: seller1, cargo_type: cargo1 FactoryGirl.create :order, seller: seller1, cargo_type: cargo2 FactoryGirl.create :order, seller: seller2, cargo_type: cargo1 # ...
  9. Mocha specs describe 'Orders::Grid', -> it 'searches by seller', (done)

    -> wait -> expect(gridCount('Orders')).to.eql 5 select 'One', from: combo('seller_id') wait -> expect(gridCount('Orders')).to.eql 3 select 'Two', from: combo('seller_id') wait -> expect(gridCount('Orders')).to.eql 2 done()
  10. ShipmentsAndOrders: nesting class ShipmentsAndOrders < Netzke::Base js_configure do |c| c.layout

    = :border end component :shipments do |c| c.klass = Shipments::Grid c.region = :center end component :orders do |c| c.klass = Orders::Grid c.region = :south c.height = 300 end def configure(c) super c.items = [:shipments, :orders] end end
  11. Client-side code initComponent: function(){ this.callParent(); var shipments = this.netzkeGetComponent('shipments'), orders

    = this.netzkeGetComponent('orders'); shipments.on('itemclick', function(view, record){ // call endpoint this.serverSelectShipment(record.get('id')); orders.getStore().load(); }, this); }
  12. Select shipment at server class ShipmentsAndOrders < Netzke::Base endpoint :server_select_shipment

    do |id, this| # dept: authorization component_session[:selected_shipment_id] = id end component :orders do |c| c.klass = Orders::Grid c.shipment_id = component_session[:selected_shipment_id] c.region = :south c.height = 300 end # ... end
  13. Orders::Grid module Orders class Grid < GridBase def configure(c) super

    c.model = "Order" if c.shipment_id c.scope = { shipment_id: c.shipment_id } c.strong_default_attrs = { shipment_id: c.shipment_id } end end # ... end end
  14. Notes on composability nesting components is easy by doing it

    we get new components nested doesn't always mean visible we can show components on demand however...
  15. Dynamic loading client side onManageAttachments: function(){ var row = this.getSelectionModel().selected.first();

    if (row) { this.netzkeLoadComponent('attachment_window', { clientConfig: { id: row.get('id') }, callback: function(w){ w.show(); } }); } }
  16. Powerful techniques reusability ✓ extensibility (OOP) ✓ modular development ✓

    composability ✓ dynamic loading ✓ JS encapsulation
  17. Final notes Netzke component != data grid use Netkze Core

    to build any reusable GUI element that needs to talk to the server forms, trees, dynamic layouts with persistence, photo galeries, charts, etc
  18. "If I had to develop a webapp like that, I

    would try your framework." -- Matz