Default column visibility can be set per user using ColumnPreferences model

This commit is contained in:
Rob Harrington
2016-05-04 11:33:14 +10:00
parent 3647b17110
commit 1d8719b474
39 changed files with 406 additions and 95 deletions

View File

@@ -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 = ""

View File

@@ -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()

View File

@@ -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?

View File

@@ -0,0 +1,4 @@
angular.module("admin.dropdown").controller "ColumnsDropdownCtrl", ($scope, Columns) ->
$scope.columns = Columns.columns
$scope.toggle = Columns.toggleColumn
$scope.saveColumnPreferences = Columns.savePreferences

View File

@@ -0,0 +1,6 @@
angular.module("admin.dropdown").directive 'columnsDropdown', ->
restrict: 'E'
templateUrl: 'admin/columns_dropdown.html'
controller: 'ColumnsDropdownCtrl'
scope:
action: '@'

View File

@@ -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

View File

@@ -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"

View File

@@ -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)

View File

@@ -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")

View File

@@ -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 = ''

View File

@@ -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)"} }

View 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

View File

@@ -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}

View 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

View File

@@ -0,0 +1,5 @@
class ColumnPreferenceSet < ModelSet
def initialize(collection, attributes={})
super(ColumnPreference, collection, attributes, nil, nil )
end
end

View File

@@ -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)

View File

@@ -0,0 +1,3 @@
class Api::Admin::ColumnPreferenceSerializer < ActiveModel::Serializer
attributes :id, :user_id, :action_name, :column_name, :name, :visible
end

View File

@@ -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 &nbsp;
= 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" }

View File

@@ -6,7 +6,7 @@
.six.columns &nbsp;
-# = render 'admin/shared/bulk_actions_dropdown'
.three.columns &nbsp;
= 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" }

View File

@@ -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 }

View File

@@ -1,7 +0,0 @@
.ofn-drop-down.right#columns-dropdown
%span{ :class => 'icon-reorder' }= "&nbsp; #{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 }}

View File

@@ -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}" }

View File

@@ -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'

View File

@@ -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 &nbsp;
= 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" }

View File

@@ -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}" }

View File

@@ -2,3 +2,4 @@
= admin_inject_taxons
= admin_inject_tax_categories
= admin_inject_spree_api_key
= admin_inject_column_preferences

View File

@@ -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

View 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

View File

@@ -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

View 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

View 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

View File

@@ -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_) ->

View File

@@ -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

View File

@@ -5,6 +5,10 @@ describe "EnterprisesCtrl", ->
beforeEach ->
module('admin.enterprises')
module ($provide) ->
$provide.value 'columns', []
null
inject ($controller, $rootScope, _Enterprises_) ->
scope = $rootScope
Enterprises = _Enterprises_

View File

@@ -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_

View File

@@ -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", ->

View File

@@ -4,6 +4,9 @@ describe "LineItemsCtrl", ->
beforeEach ->
module "admin.lineItems"
module ($provide) ->
$provide.value 'columns', []
null
jasmine.addMatchers
toDeepEqual: (util, customEqualityTesters) ->

View File

@@ -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_) ->

View 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