mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-27 06:05:19 +00:00
Default column visibility can be set per user using ColumnPreferences model
This commit is contained in:
@@ -18,19 +18,19 @@ angular.module("ofn.admin").controller "AdminOrderMgmtCtrl", [
|
||||
$scope.selectedUnitsVariant = {};
|
||||
$scope.sharedResource = false
|
||||
$scope.columns = Columns.setColumns
|
||||
order_no: { name: t("bom_no"), visible: false }
|
||||
full_name: { name: t("name"), visible: true }
|
||||
email: { name: t("email"), visible: false }
|
||||
phone: { name: t("phone"), visible: false }
|
||||
order_date: { name: t("bom_date"), visible: true }
|
||||
producer: { name: t("producer"), visible: true }
|
||||
order_cycle: { name: t("bom_cycle"), visible: false }
|
||||
hub: { name: t("bom_hub"), visible: false }
|
||||
variant: { name: t("bom_variant"), visible: true }
|
||||
quantity: { name: t("bom_quantity"), visible: true }
|
||||
max: { name: t("bom_max"), visible: true }
|
||||
final_weight_volume: { name: t("bom_final_weigth_volume"), visible: false }
|
||||
price: { name: t("price"), visible: false }
|
||||
order_no: { name: t("bom_no"), visible: false }
|
||||
full_name: { name: t("name"), visible: true }
|
||||
email: { name: t("email"), visible: false }
|
||||
phone: { name: t("phone"), visible: false }
|
||||
order_date: { name: t("bom_date"), visible: true }
|
||||
producer: { name: t("producer"), visible: true }
|
||||
order_cycle: { name: t("bom_cycle"), visible: false }
|
||||
hub: { name: t("bom_hub"), visible: false }
|
||||
variant: { name: t("bom_variant"), visible: true }
|
||||
quantity: { name: t("bom_quantity"), visible: true }
|
||||
max: { name: t("bom_max"), visible: true }
|
||||
final_weight_volume: { name: t("bom_final_weigth_volume"), visible: false }
|
||||
price: { name: t("price"), visible: false }
|
||||
$scope.initialise = ->
|
||||
$scope.initialiseVariables()
|
||||
authorise_api_reponse = ""
|
||||
|
||||
@@ -3,18 +3,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
|
||||
$scope.StatusMessage = StatusMessage
|
||||
|
||||
$scope.columns = Columns.setColumns
|
||||
producer: {name: t("products_producer"), visible: true}
|
||||
sku: {name: t("products_sku"), visible: false}
|
||||
name: {name: t("products_name"), visible: true}
|
||||
unit: {name: t("products_unit"), visible: true}
|
||||
price: {name: t("products_price"), visible: true}
|
||||
on_hand: {name: t("products_on_hand"), visible: true}
|
||||
on_demand: {name: t("products_on_demand"), visible: false}
|
||||
category: {name: t("products_category"), visible: false}
|
||||
tax_category: {name: t("products_tax_category"), visible: false}
|
||||
inherits_properties: {name: t("products_inherits_properties"), visible: false}
|
||||
available_on: {name: t("products_available_on"), visible: false}
|
||||
$scope.columns = Columns.columns
|
||||
|
||||
$scope.variant_unit_options = VariantUnitManager.variantUnitOptions()
|
||||
|
||||
|
||||
@@ -6,11 +6,7 @@ angular.module("admin.customers").controller "customersCtrl", ($scope, $q, Custo
|
||||
$scope.add = Customers.add
|
||||
$scope.deleteCustomer = Customers.remove
|
||||
$scope.customerLimit = 20
|
||||
|
||||
$scope.columns = Columns.setColumns
|
||||
email: { name: "Email", visible: true }
|
||||
code: { name: "Code", visible: true }
|
||||
tags: { name: "Tags", visible: true }
|
||||
$scope.columns = Columns.columns
|
||||
|
||||
$scope.$watch "CurrentShop.shop", ->
|
||||
if $scope.CurrentShop.shop.id?
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
angular.module("admin.dropdown").controller "ColumnsDropdownCtrl", ($scope, Columns) ->
|
||||
$scope.columns = Columns.columns
|
||||
$scope.toggle = Columns.toggleColumn
|
||||
$scope.saveColumnPreferences = Columns.savePreferences
|
||||
@@ -0,0 +1,6 @@
|
||||
angular.module("admin.dropdown").directive 'columnsDropdown', ->
|
||||
restrict: 'E'
|
||||
templateUrl: 'admin/columns_dropdown.html'
|
||||
controller: 'ColumnsDropdownCtrl'
|
||||
scope:
|
||||
action: '@'
|
||||
@@ -5,9 +5,4 @@ angular.module("admin.enterprises").controller 'enterprisesCtrl', ($scope, $q, E
|
||||
$q.all(requests).then ->
|
||||
$scope.loaded = true
|
||||
|
||||
$scope.columns = Columns.setColumns
|
||||
name: { name: "Name", visible: true }
|
||||
producer: { name: "Producer", visible: true }
|
||||
package: { name: "Package", visible: true }
|
||||
status: { name: "Status", visible: true }
|
||||
manage: { name: "Manage", visible: true }
|
||||
$scope.columns = Columns.columns
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
angular.module("admin.indexUtils").directive "toggleColumn", (Columns) ->
|
||||
link: (scope, element, attrs) ->
|
||||
element.addClass "selected" if scope.column.visible
|
||||
|
||||
element.click "click", ->
|
||||
scope.$apply ->
|
||||
Columns.toggleColumn(scope.column)
|
||||
element.toggleClass "selected"
|
||||
@@ -1,13 +1,14 @@
|
||||
angular.module("admin.indexUtils").factory 'Columns', ($rootScope) ->
|
||||
angular.module("admin.indexUtils").factory 'Columns', ($rootScope, $http, columns) ->
|
||||
new class Columns
|
||||
columns: {}
|
||||
visibleCount: 0
|
||||
saving: false
|
||||
|
||||
setColumns: (columns) =>
|
||||
constructor: ->
|
||||
@columns = {}
|
||||
@columns[name] = column for name, column of columns
|
||||
for column in columns
|
||||
@columns[column.column_name] = column
|
||||
@calculateVisibleCount()
|
||||
@columns
|
||||
|
||||
toggleColumn: (column) =>
|
||||
column.visible = !column.visible
|
||||
@@ -16,3 +17,11 @@ angular.module("admin.indexUtils").factory 'Columns', ($rootScope) ->
|
||||
calculateVisibleCount: =>
|
||||
@visibleCount = (column for name, column of @columns when column.visible).length
|
||||
$rootScope.$broadcast "columnCount:changed", @visibleCount
|
||||
|
||||
savePreferences: (action_name) ->
|
||||
$http
|
||||
method: "PUT"
|
||||
url: "/admin/column_preferences/bulk_update"
|
||||
data:
|
||||
action_name: action_name
|
||||
column_preferences: (preference for column_name, preference of @columns)
|
||||
|
||||
@@ -9,20 +9,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout,
|
||||
$scope.selectedUnitsProduct = {}
|
||||
$scope.selectedUnitsVariant = {}
|
||||
$scope.sharedResource = false
|
||||
$scope.columns = Columns.setColumns
|
||||
order_no: { name: t("bom_no"), visible: false }
|
||||
full_name: { name: t("name"), visible: true }
|
||||
email: { name: t("email"), visible: false }
|
||||
phone: { name: t("phone"), visible: false }
|
||||
order_date: { name: t("bom_date"), visible: true }
|
||||
producer: { name: t("producer"), visible: true }
|
||||
order_cycle: { name: t("bom_cycle"), visible: false }
|
||||
hub: { name: t("bom_hub"), visible: false }
|
||||
variant: { name: t("bom_variant"), visible: true }
|
||||
quantity: { name: t("bom_quantity"), visible: true }
|
||||
max: { name: t("bom_max"), visible: true }
|
||||
final_weight_volume: { name: t("bom_final_weigth_volume"), visible: false }
|
||||
price: { name: t("price"), visible: false }
|
||||
$scope.columns = Columns.columns
|
||||
|
||||
$scope.confirmRefresh = ->
|
||||
LineItems.allSaved() || confirm(t "unsaved_changes_warning")
|
||||
|
||||
@@ -19,19 +19,10 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl",
|
||||
hidden: { name: "Hidden Products", visible: false }
|
||||
new: { name: "New Products", visible: false }
|
||||
|
||||
$scope.columns = Columns.setColumns
|
||||
producer: { name: "Producer", visible: true }
|
||||
product: { name: "Product", visible: true }
|
||||
sku: { name: "SKU", visible: false }
|
||||
price: { name: "Price", visible: true }
|
||||
on_hand: { name: "On Hand", visible: true }
|
||||
on_demand: { name: "On Demand", visible: false }
|
||||
reset: { name: "Reset Stock Level", visible: false }
|
||||
inheritance: { name: "Inheritance", visible: false }
|
||||
visibility: { name: "Hide", visible: false }
|
||||
|
||||
$scope.bulkActions = [ name: "Reset Stock Levels To Defaults", callback: 'resetStock' ]
|
||||
|
||||
$scope.columns = Columns.columns
|
||||
|
||||
$scope.resetSelectFilters = ->
|
||||
$scope.producerFilter = 0
|
||||
$scope.query = ''
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
.ofn-drop-down.right#columns-dropdown{ ng: { controller: 'ColumnsDropdownCtrl' } }
|
||||
%span{ :class => 'icon-reorder' }= " #{t('admin.columns')}".html_safe
|
||||
%span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
|
||||
%div.menu{ 'ng-show' => "expanded" }
|
||||
%div.menu_item{ ng: { repeat: "column in columns", click: "toggle(column)", class: "{selected: column.visible}" } }
|
||||
%span.check
|
||||
%span.name {{column.name }}
|
||||
%hr
|
||||
%div.menu_item.text-center
|
||||
%input.fullwidth.red{ type: "button", value: 'Save As Default', ng: { click: "saveColumnPreferences(action)"} }
|
||||
38
app/controllers/admin/column_preferences_controller.rb
Normal file
38
app/controllers/admin/column_preferences_controller.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
module Admin
|
||||
class ColumnPreferencesController < ResourceController
|
||||
before_filter :load_collection, only: [:bulk_update]
|
||||
|
||||
respond_to :json
|
||||
|
||||
def bulk_update
|
||||
@cp_set.collection.each { |cp| authorize! :bulk_update, cp }
|
||||
|
||||
if @cp_set.save
|
||||
# Return saved VOs with IDs
|
||||
render json: @cp_set.collection, each_serializer: Api::Admin::ColumnPreferenceSerializer
|
||||
else
|
||||
if @cp_set.errors.present?
|
||||
render json: { errors: @cp_set.errors }, status: 400
|
||||
else
|
||||
render nothing: true, status: 500
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_collection
|
||||
collection_hash = Hash[params[:column_preferences].each_with_index.map { |cp, i| [i, cp] }]
|
||||
collection_hash.reject!{ |i, cp| cp[:action_name] != params[:action_name] }
|
||||
@cp_set = ColumnPreferenceSet.new @column_preferences, collection_attributes: collection_hash
|
||||
end
|
||||
|
||||
def collection
|
||||
ColumnPreference.where(user_id: spree_current_user, action_name: params[:action_name])
|
||||
end
|
||||
|
||||
def collection_actions
|
||||
[:bulk_update]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -47,13 +47,18 @@ module Admin
|
||||
admin_inject_json_ams_array opts[:module], "inventoryItems", @inventory_items, Api::Admin::InventoryItemSerializer
|
||||
end
|
||||
|
||||
def admin_inject_column_preferences(opts={module: 'ofn.admin'})
|
||||
column_preferences = ColumnPreference.for(spree_current_user, "#{controller_name}_#{action_name}")
|
||||
admin_inject_json_ams_array opts[:module], "columns", column_preferences, Api::Admin::ColumnPreferenceSerializer
|
||||
end
|
||||
|
||||
def admin_inject_enterprise_permissions
|
||||
permissions =
|
||||
{can_manage_shipping_methods: can?(:manage_shipping_methods, @enterprise),
|
||||
can_manage_payment_methods: can?(:manage_payment_methods, @enterprise),
|
||||
can_manage_enterprise_fees: can?(:manage_enterprise_fees, @enterprise)}
|
||||
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: "admin.enterprises", name: "enterprisePermissions", json: permissions.to_json}
|
||||
admin_inject_json "admin.enterprises", "enterprisePermissions", permissions
|
||||
end
|
||||
|
||||
def admin_inject_hub_permissions
|
||||
@@ -96,6 +101,11 @@ module Admin
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: 'admin.indexUtils', name: 'SpreeApiKey', json: "'#{@spree_api_key.to_s}'"}
|
||||
end
|
||||
|
||||
def admin_inject_json(ngModule, name, data)
|
||||
json = data.to_json
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: ngModule, name: name, json: json}
|
||||
end
|
||||
|
||||
def admin_inject_json_ams(ngModule, name, data, serializer, opts = {})
|
||||
json = serializer.new(data, scope: spree_current_user).to_json
|
||||
render partial: "admin/json/injection_ams", locals: {ngModule: ngModule, name: name, json: json}
|
||||
|
||||
46
app/models/column_preference.rb
Normal file
46
app/models/column_preference.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
require 'open_food_network/column_preference_defaults'
|
||||
|
||||
class ColumnPreference < ActiveRecord::Base
|
||||
extend OpenFoodNetwork::ColumnPreferenceDefaults
|
||||
|
||||
# These are the attributes used to identify a preference
|
||||
attr_accessible :user_id, :action_name, :column_name
|
||||
|
||||
# These are attributes that need to be mass assignable
|
||||
attr_accessible :name, :visible
|
||||
|
||||
# Non-persisted attributes that only have one
|
||||
# setting (ie. the default) for a given column
|
||||
attr_accessor :name
|
||||
|
||||
belongs_to :user, class_name: "Spree::User"
|
||||
|
||||
validates :action_name, presence: true, inclusion: { in: proc { known_actions } }
|
||||
validates :column_name, presence: true, inclusion: { in: proc { |p| valid_columns_for(p.action_name) } }
|
||||
|
||||
def self.for(user, action_name)
|
||||
stored_preferences = where(user_id: user.id, action_name: action_name)
|
||||
default_preferences = send("#{action_name}_columns")
|
||||
default_preferences.each_with_object([]) do |(column_name, default_attributes), preferences|
|
||||
stored_preference = stored_preferences.find_by_column_name(column_name)
|
||||
if stored_preference
|
||||
stored_preference.assign_attributes(default_attributes.select{ |k,v| stored_preference[k].nil? })
|
||||
preferences << stored_preference
|
||||
else
|
||||
attributes = default_attributes.merge(user_id: user.id, action_name: action_name, column_name: column_name)
|
||||
preferences << ColumnPreference.new(attributes)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.valid_columns_for(action_name)
|
||||
send("#{action_name}_columns").keys.map(&:to_s)
|
||||
end
|
||||
|
||||
def self.known_actions
|
||||
OpenFoodNetwork::ColumnPreferenceDefaults.private_instance_methods
|
||||
.select{|m| m.to_s.end_with?("_columns")}.map{ |m| m.to_s.sub /_columns$/, ''}
|
||||
end
|
||||
end
|
||||
5
app/models/column_preference_set.rb
Normal file
5
app/models/column_preference_set.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class ColumnPreferenceSet < ModelSet
|
||||
def initialize(collection, attributes={})
|
||||
super(ColumnPreference, collection, attributes, nil, nil )
|
||||
end
|
||||
end
|
||||
@@ -101,6 +101,10 @@ class AbilityDecorator
|
||||
can [:print], Spree::Order do |order|
|
||||
order.user == user
|
||||
end
|
||||
|
||||
can [:admin, :bulk_update], ColumnPreference do |column_preference|
|
||||
column_preference.user == user
|
||||
end
|
||||
end
|
||||
|
||||
def add_product_management_abilities(user)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
class Api::Admin::ColumnPreferenceSerializer < ActiveModel::Serializer
|
||||
attributes :id, :user_id, :action_name, :column_name, :name, :visible
|
||||
end
|
||||
@@ -10,6 +10,7 @@
|
||||
%a.button.icon-plus#new-customer{ href: "#", "new-customer-dialog" => true }
|
||||
= t('admin.customers.index.new_customer')
|
||||
|
||||
= admin_inject_column_preferences module: 'admin.customers'
|
||||
= admin_inject_shops
|
||||
|
||||
%div{ ng: { controller: 'customersCtrl' } }
|
||||
@@ -26,7 +27,7 @@
|
||||
.five.columns.alpha
|
||||
%input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' }
|
||||
.eight.columns
|
||||
= render 'admin/shared/columns_dropdown'
|
||||
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
|
||||
.row{ 'ng-if' => 'CurrentShop.shop.id && RequestMonitor.loading' }
|
||||
.sixteen.columns.alpha#loading
|
||||
%img.spinner{ src: "/assets/spinning-circles.svg" }
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
.six.columns
|
||||
-# = render 'admin/shared/bulk_actions_dropdown'
|
||||
.three.columns
|
||||
= render 'admin/shared/columns_dropdown'
|
||||
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
|
||||
.row{ 'ng-if' => '!loaded' }
|
||||
.sixteen.columns.alpha#loading
|
||||
%img.spinner{ src: "/assets/spinning-circles.svg" }
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
= button_link_to "New Enterprise", main_app.new_admin_enterprise_path, :icon => 'icon-plus', :id => 'admin_new_enterprise_link'
|
||||
|
||||
= admin_inject_monthly_bill_description
|
||||
= admin_inject_column_preferences module: 'admin.enterprises'
|
||||
|
||||
= render 'admin/shared/enterprises_sub_menu'
|
||||
|
||||
= render :partial => 'spree/shared/error_messages', :locals => { :target => @enterprise_set }
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
.ofn-drop-down.right#columns-dropdown
|
||||
%span{ :class => 'icon-reorder' }= " #{t('admin.columns')}".html_safe
|
||||
%span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" }
|
||||
%div.menu{ 'ng-show' => "expanded" }
|
||||
%div.menu_item{ ng: { repeat: "column in columns" }, toggle: { column: true } }
|
||||
%span.check
|
||||
%span.name {{column.name }}
|
||||
@@ -12,4 +12,4 @@
|
||||
%i.icon-chevron-left
|
||||
Back to my inventory
|
||||
.four.columns.omega{ng: { show: 'views.inventory.visible' } }
|
||||
= render 'admin/shared/columns_dropdown'
|
||||
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
= admin_inject_hubs module: 'admin.variantOverrides'
|
||||
= admin_inject_hub_permissions
|
||||
= admin_inject_producers module: 'admin.variantOverrides'
|
||||
= admin_inject_column_preferences module: 'admin.variantOverrides'
|
||||
= admin_inject_variant_overrides
|
||||
= admin_inject_inventory_items module: 'admin.variantOverrides'
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
= render :partial => 'spree/admin/shared/order_sub_menu'
|
||||
|
||||
= admin_inject_column_preferences module: 'admin.lineItems'
|
||||
|
||||
%div{ ng: { controller: 'LineItemsCtrl' } }
|
||||
%save-bar{ dirty: "bulk_order_form.$dirty", persist: "false" }
|
||||
%input.red{ type: "button", value: "Save Changes", ng: { click: "submit()", disabled: "!bulk_order_form.$dirty" } }
|
||||
@@ -97,7 +99,7 @@
|
||||
%input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' }
|
||||
= render 'admin/shared/bulk_actions_dropdown'
|
||||
%div.seven.columns
|
||||
= render 'admin/shared/columns_dropdown'
|
||||
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
|
||||
|
||||
%div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' }
|
||||
%img.spinner{ src: "/assets/spinning-circles.svg" }
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
%input.four.columns.alpha{ :type => 'button', :value => 'Save Changes', 'ng-click' => 'submitProducts()'}
|
||||
.nine.columns
|
||||
= render 'spree/admin/shared/status_message'
|
||||
= render 'admin/shared/columns_dropdown'
|
||||
%columns-dropdown{ action: "#{controller_name}_#{action_name}" }
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
= admin_inject_taxons
|
||||
= admin_inject_tax_categories
|
||||
= admin_inject_spree_api_key
|
||||
= admin_inject_column_preferences
|
||||
|
||||
@@ -135,6 +135,10 @@ Openfoodnetwork::Application.routes.draw do
|
||||
resource :cache_settings
|
||||
|
||||
resource :account, only: [:show], controller: 'account'
|
||||
|
||||
resources :column_preferences, only: [], format: :json do
|
||||
put :bulk_update, on: :collection
|
||||
end
|
||||
end
|
||||
|
||||
namespace :api do
|
||||
|
||||
13
db/migrate/20160116024333_create_column_preferences.rb
Normal file
13
db/migrate/20160116024333_create_column_preferences.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class CreateColumnPreferences < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :column_preferences do |t|
|
||||
t.references :user, null: false, index: true
|
||||
t.string :action_name, null: false, index: true
|
||||
t.string :column_name, null: false
|
||||
t.boolean :visible, null: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
add_index :column_preferences, [:user_id, :action_name, :column_name], unique: true, name: 'index_column_prefs_on_user_id_and_action_name_and_column_name'
|
||||
end
|
||||
end
|
||||
13
db/schema.rb
13
db/schema.rb
@@ -176,6 +176,17 @@ ActiveRecord::Schema.define(:version => 20160401043927) do
|
||||
add_index "cms_snippets", ["site_id", "identifier"], :name => "index_cms_snippets_on_site_id_and_identifier", :unique => true
|
||||
add_index "cms_snippets", ["site_id", "position"], :name => "index_cms_snippets_on_site_id_and_position"
|
||||
|
||||
create_table "column_preferences", :force => true do |t|
|
||||
t.integer "user_id", :null => false
|
||||
t.string "action_name", :null => false
|
||||
t.string "column_name", :null => false
|
||||
t.boolean "visible", :null => false
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "column_preferences", ["user_id", "action_name", "column_name"], :name => "index_column_prefs_on_user_id_and_action_name_and_column_name", :unique => true
|
||||
|
||||
create_table "coordinator_fees", :force => true do |t|
|
||||
t.integer "order_cycle_id"
|
||||
t.integer "enterprise_fee_id"
|
||||
@@ -683,9 +694,9 @@ ActiveRecord::Schema.define(:version => 20160401043927) do
|
||||
t.string "email"
|
||||
t.text "special_instructions"
|
||||
t.integer "distributor_id"
|
||||
t.integer "order_cycle_id"
|
||||
t.string "currency"
|
||||
t.string "last_ip_address"
|
||||
t.integer "order_cycle_id"
|
||||
t.integer "cart_id"
|
||||
t.integer "customer_id"
|
||||
end
|
||||
|
||||
77
lib/open_food_network/column_preference_defaults.rb
Normal file
77
lib/open_food_network/column_preference_defaults.rb
Normal file
@@ -0,0 +1,77 @@
|
||||
module OpenFoodNetwork
|
||||
module ColumnPreferenceDefaults
|
||||
|
||||
private
|
||||
|
||||
# NOTE: These methods define valid column names (via hash keys)
|
||||
# as well as default values for column attributes (eg. visiblity)
|
||||
# Default values can be overridden by storing a different value
|
||||
# for a given user, action_name and column_name
|
||||
|
||||
def variant_overrides_index_columns
|
||||
{
|
||||
producer: { name: "Producer", visible: true },
|
||||
product: { name: "Product", visible: true },
|
||||
sku: { name: "SKU", visible: false },
|
||||
price: { name: "Price", visible: true },
|
||||
on_hand: { name: "On Hand", visible: true },
|
||||
on_demand: { name: "On Demand", visible: false },
|
||||
reset: { name: "Reset Stock Level", visible: false },
|
||||
inheritance: { name: "Inheritance", visible: false },
|
||||
visibility: { name: "Hide", visible: false }
|
||||
}
|
||||
end
|
||||
|
||||
def customers_index_columns
|
||||
{
|
||||
email: { name: "Email", visible: true },
|
||||
code: { name: "Code", visible: true },
|
||||
tags: { name: "Tags", visible: true }
|
||||
}
|
||||
end
|
||||
|
||||
def orders_bulk_management_columns
|
||||
{
|
||||
order_no: { name: t("bom_no"), visible: false },
|
||||
full_name: { name: t("name"), visible: true },
|
||||
email: { name: t("email"), visible: false },
|
||||
phone: { name: t("phone"), visible: false },
|
||||
order_date: { name: t("bom_date"), visible: true },
|
||||
producer: { name: t("producer"), visible: true },
|
||||
order_cycle: { name: t("bom_cycle"), visible: false },
|
||||
hub: { name: t("bom_hub"), visible: false },
|
||||
variant: { name: t("bom_variant"), visible: true },
|
||||
quantity: { name: t("bom_quantity"), visible: true },
|
||||
max: { name: t("bom_max"), visible: true },
|
||||
final_weight_volume: { name: t("bom_final_weigth_volume"), visible: false },
|
||||
price: { name: t("price"), visible: false }
|
||||
}
|
||||
end
|
||||
|
||||
def products_bulk_edit_columns
|
||||
{
|
||||
producer: { name: t("products_producer"), visible: true },
|
||||
sku: { name: t("products_sku"), visible: false },
|
||||
name: { name: t("products_name"), visible: true },
|
||||
unit: { name: t("products_unit"), visible: true },
|
||||
price: { name: t("products_price"), visible: true },
|
||||
on_hand: { name: t("products_on_hand"), visible: true },
|
||||
on_demand: { name: t("products_on_demand"), visible: false },
|
||||
category: { name: t("products_category"), visible: false },
|
||||
tax_category: { name: t("products_tax_category"), visible: false },
|
||||
inherits_properties: { name: t("products_inherits_properties"), visible: false },
|
||||
available_on: { name: t("products_available_on"), visible: false }
|
||||
}
|
||||
end
|
||||
|
||||
def enterprises_index_columns
|
||||
{
|
||||
name: { name: "Name", visible: true },
|
||||
producer: { name: "Producer", visible: true },
|
||||
package: { name: "Package", visible: true },
|
||||
status: { name: "Status", visible: true },
|
||||
manage: { name: "Manage", visible: true }
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
44
spec/controllers/admin/column_preferences_controller_spec.rb
Normal file
44
spec/controllers/admin/column_preferences_controller_spec.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Admin::ColumnPreferencesController, type: :controller do
|
||||
include AuthenticationWorkflow
|
||||
|
||||
|
||||
describe "bulk_update" do
|
||||
let!(:user1) { create(:user) }
|
||||
let!(:user2) { create(:user) }
|
||||
let!(:enterprise) { create(:enterprise, owner: user1, users: [user1, user2]) }
|
||||
|
||||
context "json" do
|
||||
let!(:column_preference) { ColumnPreference.create(user_id: user1.id, action_name: 'enterprises_index', column_name: "name", visible: true) }
|
||||
|
||||
let(:column_preference_params) { [
|
||||
{ id: column_preference.id, user_id: user1.id, action_name: "enterprises_index", column_name: 'name', visible: false },
|
||||
{ id: nil, user_id: user1.id, action_name: "enterprises_index", column_name: 'producer', visible: true },
|
||||
{ id: nil, user_id: user1.id, action_name: "enterprises_index", column_name: 'status', visible: true }
|
||||
] }
|
||||
|
||||
context "where I don't own the preferences submitted" do
|
||||
before do
|
||||
allow(controller).to receive(:spree_current_user) { user2 }
|
||||
end
|
||||
|
||||
it "prevents me from updating the column preferences" do
|
||||
spree_put :bulk_update, format: :json, action_name: "enterprises_index", column_preferences: column_preference_params
|
||||
expect(ColumnPreference.count).to be 1
|
||||
end
|
||||
end
|
||||
|
||||
context "where I own the preferences submitted" do
|
||||
before do
|
||||
allow(controller).to receive(:spree_current_user) { user1 }
|
||||
end
|
||||
|
||||
it "allows me to update the column preferences" do
|
||||
spree_put :bulk_update, format: :json, action_name: "enterprises_index", column_preferences: column_preference_params
|
||||
expect(ColumnPreference.where(user_id: user1.id, action_name: 'enterprises_index').count).to be 3
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -20,6 +20,7 @@ describe "VariantOverridesCtrl", ->
|
||||
$provide.value 'variantOverrides', variantOverrides
|
||||
$provide.value 'dirtyVariantOverrides', dirtyVariantOverrides
|
||||
$provide.value 'inventoryItems', inventoryItems
|
||||
$provide.value 'columns', []
|
||||
null
|
||||
|
||||
inject ($controller, _VariantOverrides_, _DirtyVariantOverrides_, _StatusMessage_) ->
|
||||
|
||||
@@ -4,6 +4,10 @@ describe "CustomersCtrl", ->
|
||||
|
||||
beforeEach ->
|
||||
module('admin.customers')
|
||||
module ($provide) ->
|
||||
$provide.value 'columns', []
|
||||
null
|
||||
|
||||
inject ($controller, $rootScope, _CustomerResource_, $httpBackend) ->
|
||||
scope = $rootScope
|
||||
http = $httpBackend
|
||||
|
||||
@@ -5,6 +5,10 @@ describe "EnterprisesCtrl", ->
|
||||
|
||||
beforeEach ->
|
||||
module('admin.enterprises')
|
||||
module ($provide) ->
|
||||
$provide.value 'columns', []
|
||||
null
|
||||
|
||||
inject ($controller, $rootScope, _Enterprises_) ->
|
||||
scope = $rootScope
|
||||
Enterprises = _Enterprises_
|
||||
|
||||
@@ -5,6 +5,9 @@ describe "PanelRow directive", ->
|
||||
|
||||
beforeEach ->
|
||||
module 'admin.indexUtils'
|
||||
module ($provide) ->
|
||||
$provide.value 'columns', []
|
||||
null
|
||||
|
||||
beforeEach inject ($rootScope, $compile, $injector, $templateCache, _Panels_) ->
|
||||
Panels = _Panels_
|
||||
|
||||
@@ -3,19 +3,21 @@ describe "Columns service", ->
|
||||
|
||||
beforeEach ->
|
||||
module 'admin.indexUtils'
|
||||
|
||||
module ($provide) ->
|
||||
$provide.value 'columns', [
|
||||
{ column_name: 'col1', visible: true }
|
||||
{ column_name: 'col2', visible: false }
|
||||
]
|
||||
null
|
||||
inject (_Columns_) ->
|
||||
Columns = _Columns_
|
||||
|
||||
describe "setting columns", ->
|
||||
describe "initialising columns", ->
|
||||
it "sets resets @columns and copies each column of the provided object across", ->
|
||||
Columns.setColumns({ name: { visible: true } })
|
||||
expect(Columns.columns).toEqual { name: { visible: true } }
|
||||
expect(Columns.columns).toEqual { col1: { column_name: 'col1', visible: true }, col2: { column_name: 'col2', visible: false } }
|
||||
|
||||
it "calls calculateVisibleCount", ->
|
||||
spyOn(Columns, "calculateVisibleCount")
|
||||
Columns.setColumns({ name: { visible: true } })
|
||||
expect(Columns.calculateVisibleCount).toHaveBeenCalled()
|
||||
it "updates visibleCount", ->
|
||||
expect(Columns.visibleCount).toBe 1
|
||||
|
||||
describe "toggling a column", ->
|
||||
it "switches the visibility of the given column", ->
|
||||
|
||||
@@ -4,6 +4,9 @@ describe "LineItemsCtrl", ->
|
||||
|
||||
beforeEach ->
|
||||
module "admin.lineItems"
|
||||
module ($provide) ->
|
||||
$provide.value 'columns', []
|
||||
null
|
||||
|
||||
jasmine.addMatchers
|
||||
toDeepEqual: (util, customEqualityTesters) ->
|
||||
|
||||
@@ -241,6 +241,7 @@ describe "AdminProductEditCtrl", ->
|
||||
$provide.value "taxons", []
|
||||
$provide.value "tax_categories", []
|
||||
$provide.value 'SpreeApiKey', 'API_KEY'
|
||||
$provide.value 'columns', []
|
||||
null
|
||||
|
||||
beforeEach inject((_$controller_, _$timeout_, $rootScope, _$httpBackend_, _BulkProducts_, _DirtyProducts_, _DisplayProperties_) ->
|
||||
|
||||
59
spec/models/column_preference_spec.rb
Normal file
59
spec/models/column_preference_spec.rb
Normal file
@@ -0,0 +1,59 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe ColumnPreference, type: :model do
|
||||
describe "finding stored preferences for a user and action" do
|
||||
before do
|
||||
allow(ColumnPreference).to receive(:known_actions) { ['some_action'] }
|
||||
allow(ColumnPreference).to receive(:valid_columns_for) { ['col1', 'col2', 'col3'] }
|
||||
end
|
||||
|
||||
let(:user) { create(:user) }
|
||||
let!(:col1_pref) { ColumnPreference.create(user_id: user.id, action_name: 'some_action', column_name: 'col1', visible: true) }
|
||||
let!(:col2_pref) { ColumnPreference.create(user_id: user.id, action_name: 'some_action', column_name: 'col2', visible: false) }
|
||||
let(:defaults) { {
|
||||
col1: { name: "col1", visible: false },
|
||||
col2: { name: "col2", visible: true },
|
||||
col3: { name: "col3", visible: false },
|
||||
} }
|
||||
|
||||
context "when the user has preferences stored for the given action" do
|
||||
before do
|
||||
allow(ColumnPreference).to receive(:some_action_columns) { defaults }
|
||||
end
|
||||
|
||||
let(:preferences) { ColumnPreference.for(user, :some_action)}
|
||||
|
||||
it "builds an entry for each column listed in the defaults" do
|
||||
expect(preferences.count).to eq 3
|
||||
end
|
||||
|
||||
it "uses values from stored preferences where present" do
|
||||
expect(preferences).to include col1_pref, col2_pref
|
||||
end
|
||||
|
||||
it "uses defaults where no stored preference exists" do
|
||||
default_pref = preferences.last
|
||||
expect(default_pref).to be_a_new ColumnPreference
|
||||
expect(default_pref.visible).to be false # As per default
|
||||
end
|
||||
end
|
||||
|
||||
context "where the user does not have preferences stored for the given action" do
|
||||
before do
|
||||
allow(ColumnPreference).to receive(:some_action_columns) { defaults }
|
||||
end
|
||||
|
||||
let(:preferences) { ColumnPreference.for(create(:user), :some_action)}
|
||||
|
||||
it "builds an entry for each column listed in the defaults" do
|
||||
expect(preferences.count).to eq 3
|
||||
end
|
||||
|
||||
it "uses defaults where no stored preference exists" do
|
||||
expect(preferences.all?(&:new_record?)).to be true
|
||||
expect(preferences.map(&:column_name)).to eq [:col1, :col2, :col3]
|
||||
expect(preferences.map(&:visible)).to eq [false, true, false]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user