diff --git a/front-api/app.rb b/front-api/app.rb index 696a71b..3e0dc31 100644 --- a/front-api/app.rb +++ b/front-api/app.rb @@ -16,6 +16,7 @@ before do headers 'Access-Control-Allow-Origin' => 'http://localhost:3001', 'Access-Control-Allow-Methods' => ['OPTIONS', 'GET', 'POST','PUT'], 'Access-Control-Allow-Headers' => 'Origin, X-Requested-With, Content-Type, Accept', + 'Access-Control-Expose-Headers' => 'X-Total-Count', 'Access-Control-Allow-Credentials' => 'true' request.body.rewind diff --git a/front-api/controllers/common_for_controllers.rb b/front-api/controllers/common_for_controllers.rb index f1374f3..547af54 100644 --- a/front-api/controllers/common_for_controllers.rb +++ b/front-api/controllers/common_for_controllers.rb @@ -3,6 +3,10 @@ def get_querystring_hash() Rack::Utils.parse_nested_query(request.query_string) end +def add_total_count_header(total) + response.headers['X-Total-Count'] = total +end + # converts list of parameters to array of integers def mass_to_i(*id_strings) id_strings.map(&:to_i) diff --git a/front-api/controllers/item.rb b/front-api/controllers/item.rb index ec3a6d1..fb88f2a 100644 --- a/front-api/controllers/item.rb +++ b/front-api/controllers/item.rb @@ -21,7 +21,7 @@ end def filter_by_traits(items) get_querystring_hash.each do |k,v| - items = items.where(["traits ->> '#{k}' = '#{v}'"]) + items = items.where(["traits ->> ? = ?", k, v]) end items end @@ -54,9 +54,12 @@ get '/item/category/:category_id/offset/:offset/limit/:limit' do |category_id_s, input_invalid = offset_and_limit_invalid?(offset,limit) or category_id <= 0 return [].to_json if input_invalid + all_in_cat = filter_by_traits(Item.all_in_category(category_id)) items = Item.best_selling_in_category(category_id, offset,limit) items = filter_by_traits(items) + add_total_count_header(all_in_cat.count) + prepare_items_for_mass_display(items) end diff --git a/front-api/models/item.rb b/front-api/models/item.rb index dab0a8c..25a6904 100644 --- a/front-api/models/item.rb +++ b/front-api/models/item.rb @@ -10,7 +10,13 @@ class Item < ActiveRecord::Base # TODO: change "best selling" algorithm when get some data - currently it's only sorted by earnings scope :best_selling, -> (offset, limit) { where(:on_display => true).order("(list_price - current_input_price) DESC").limit(limit).offset(offset) } + scope :best_selling_in_sub_category, -> (sub_category_id, offset, limit) { best_selling(offset, limit).where(sub_category_id: sub_category_id) } + scope :best_selling_in_category, -> (category_id, offset, limit) { best_selling(offset, limit).joins( sub_category: [:category] ).where(["category_id = ?", category_id]) } + scope :best_selling_in_section, -> (section_id, offset, limit) { best_selling(offset, limit).joins( sub_category: [category: [ :section ]] ).where( ["section_id = ?", section_id] ) } + + scope :all_in_category, -> (category_id) { where(on_display: true).joins( sub_category: [:category]).where(["category_id = ?", category_id]) } + end diff --git a/front-api/models/sub_category.rb b/front-api/models/sub_category.rb index 9d779fe..9a4a9af 100644 --- a/front-api/models/sub_category.rb +++ b/front-api/models/sub_category.rb @@ -1,6 +1,7 @@ class SubCategory < ActiveRecord::Base belongs_to :category has_many :filter_criterias, as: :owner + has_many :items end diff --git a/front-ui/app/actions/itemActions.js b/front-ui/app/actions/itemActions.js index 3a892a6..d26e254 100644 --- a/front-ui/app/actions/itemActions.js +++ b/front-ui/app/actions/itemActions.js @@ -4,11 +4,13 @@ var ItemConstants = require('../constants/itemConstants'); // Define action methods var ItemActions = { - loadByCategory: function(categoryId, query) { + loadByCategory: function(categoryId, offset, limit, query) { AppDispatcher.handleAction({ actionType: ItemConstants.LOAD_BY_CATEGORY, categoryId : categoryId, - query : query + query : query, + offset : offset, + limit: limit }); }, diff --git a/front-ui/app/actions/navigationActions.js b/front-ui/app/actions/navigationActions.js index fc7325d..6a92e3c 100644 --- a/front-ui/app/actions/navigationActions.js +++ b/front-ui/app/actions/navigationActions.js @@ -21,20 +21,30 @@ var NavigationActions = { }); }, - goToCategory: function(category,section, query) { + goToCategory: function(category,section, query, offset, limit) { var url ='/sekcija/' + section.get('name') +'/kategorija/'+ category.get('id') + '/' + category.get('name'); var q = ''; + var qp = []; + if(query) { - var qp = []; for(var key in query) { - if (query.hasOwnProperty(key)) { + + if (key !== 'offset' && key !== 'limit' && query.hasOwnProperty(key)) { qp.push(key + '=' + query[key]); } } - if (qp.length > 0) { - q = '?' + qp.join('&'); - } + } + if (offset !== undefined) { + qp.push('offset='+offset); + } + + if (limit !== undefined) { + qp.push('limit='+limit); + } + + if (qp.length > 0) { + q = '?' + qp.join('&'); } AppDispatcher.handleAction({ actionType: NavigationConstants.CHANGE_URL, diff --git a/front-ui/app/components/browsing/byCategory.js b/front-ui/app/components/browsing/byCategory.js index e99081d..2125f05 100644 --- a/front-ui/app/components/browsing/byCategory.js +++ b/front-ui/app/components/browsing/byCategory.js @@ -19,7 +19,8 @@ var ByCategory = React.createClass({ return { category: category, items: items, - filter :{} + filter :{}, + pagination: {} }; }, filter: {}, @@ -30,16 +31,24 @@ var ByCategory = React.createClass({ var category = this.state.category; this.filter[fc.field_name] = fcv.filter_value; - NavigationActions.goToCategory(category, section, this.filter); + NavigationActions.goToCategory(category, section, this.filter, 0, this.state.pagination.limit); }, removeAppliedFilter: function(name) { delete this.filter[name]; var section = new Section(this.state.category.get('section')); var category = this.state.category; - NavigationActions.goToCategory(category, section, this.filter); + NavigationActions.goToCategory(category, section, this.filter, 0, this.state.pagination.limit); + + }, + changePage: function(page) { + var section = new Section(this.state.category.get('section')); + var category = this.state.category; + + NavigationActions.goToCategory(category, section, this.filter, parseInt(page) * this.state.pagination.limit, this.state.pagination.limit); }, render: function() { var self = this; + return (