Merge branch 'master' into redesign

This commit is contained in:
Rohan Mitchell
2015-06-16 16:57:09 +10:00
19 changed files with 145 additions and 143 deletions

View File

@@ -1,14 +1,11 @@
angular.module("admin.enterprises").controller "EnterpriseIndexRowCtrl", ($scope) ->
$scope.statusText = ->
issueCount = (issue for issue in $scope.enterprise.issues when !issue.resolved).length
if issueCount > 0
$scope.statusClass = "issue"
$scope.status = ->
if $scope.enterprise.issues.length > 0
"issue"
else if $scope.enterprise.warnings.length > 0
"warning"
else
warningCount = (warning for warning in $scope.enterprise.warnings when !warning.resolved).length
if warningCount > 0
$scope.statusClass = "warning"
else
$scope.statusClass = "ok"
"ok"
$scope.producerText = ->
@@ -42,7 +39,6 @@ angular.module("admin.enterprises").controller "EnterpriseIndexRowCtrl", ($scope
$scope.updateRowText = ->
$scope.producer = $scope.producerText()
$scope.package = $scope.packageText()
$scope.status = $scope.statusText()
$scope.producerError = ($scope.producer == "Choose")
$scope.packageError = ($scope.package == "Choose")

View File

@@ -1,3 +1,3 @@
angular.module("admin.enterprises").controller 'indexStatusPanelCtrl', ($scope, $filter) ->
$scope.issues = $filter('filter')($scope.object.issues, {resolved: false })
$scope.warnings = $filter('filter')($scope.object.warnings, {resolved: false})
$scope.issues = $scope.object.issues
$scope.warnings = $scope.object.warnings

View File

@@ -1,7 +1,7 @@
angular.module("admin.indexUtils").directive "panelToggle", ->
restrict: "C"
transclude: true
template: '<div ng-transclude></div><i class=\'icon-chevron-down\'"></i>'
template: '<div ng-transclude></div><i class=\'icon-chevron\'></i>'
require: "^panelToggleRow"
scope:
name: "@"

View File

@@ -22,17 +22,11 @@ Darkswarm.directive "filterSelector", (FilterSelectorsService)->
.map (selector)->
selector.object.id
# This can be called from a parent scope
# when data has been loaded, in order to pass
# selectors up
scope.$on 'loadFilterSelectors', ->
scope.allSelectors = scope.selectors() if attr.allSelectors?
scope.$watchCollection "selectors()", (newValue, oldValue) ->
scope.allSelectors = scope.selectors() if attr.allSelectors?
scope.$watchCollection "objects()", (newValue, oldValue) ->
scope.allSelectors = scope.buildSelectors()
# Build a list of selectors
scope.selectors = ->
scope.buildSelectors = ->
# Generate a selector for each object.
# NOTE: THESE ARE MEMOIZED to stop new selectors from being created constantly, otherwise function always returns non-identical results
# This means the $digest cycle can never close and times out

View File

@@ -1,5 +1,5 @@
.row.enterprise_status_panel{ ng: { controller: 'indexStatusPanelCtrl' } }
.alpha.sixteen.columns
.alpha.omega.sixteen.columns
%h4.status-ok.text-center{ ng: { show: "issues.length == 0 && warnings.length == 0" } }
%i.icon-ok-sign
@@ -21,7 +21,7 @@
%td.resolve
%div{ ng: { bind: { html: "issue.link" } } }
%tr{ ng: { repeat: "warning in warnings"} }
%td.severity.text-center
%td.severity
%i.icon-warning-sign.warning
%td.description
%span{ bo: { bind: "warning.description" } }

View File

@@ -1,4 +1,4 @@
%div{bindonce:true, style: "display: inline-block" }
%ul{ bindonce: true }
%active-selector{ ng: { repeat: "selector in allSelectors", show: "ifDefined(selector.fits, true)" } }
%render-svg{path: "{{selector.object.icon}}", ng: { if: "selector.object.icon"} }
%span{"bo-text" => "selector.object.name"}

View File

@@ -9,12 +9,10 @@
%br
.filter-shopfront.taxon-selectors.inline-block
%ul
%filter-selector{ objects: "[product] | taxonsOf" }
%filter-selector{ objects: "[product] | taxonsOf" }
.filter-shopfront.property-selectors.inline-block
%ul
%filter-selector{ objects: "[product] | propertiesWithValuesOf" }
%filter-selector{ objects: "[product] | propertiesWithValuesOf" }
%div{"ng-if" => "product.description"}
%hr

View File

@@ -1,8 +1,8 @@
%ul
-# In order for the single-line-selector scope to have access to the available selectors,
%filter-selector{objects: "objects()", "active-selectors" => "activeSelectors", "all-selectors" => "allSelectors" }
-# In order for the single-line-selector scope to have access to the available selectors,
%filter-selector{objects: "objects()", "active-selectors" => "activeSelectors", "all-selectors" => "allSelectors" }
%li.more{ ng: { show: "overFlowSelectors().length > 0 || fitting" } }
%ul{ ng: { if: "overFlowSelectors().length > 0 || fitting" } }
%li.more
%a.dropdown{ data: { dropdown: "{{ 'show-more-' + selectorName }}" }, ng: { class: "{active: selectedOverFlowSelectors().length > 0}" } }
%span
+ {{ overFlowSelectors().length }} more

View File

@@ -96,6 +96,8 @@
}
td.severity {
text-align: center;
i {
font-size: 1.5rem;

View File

@@ -9,11 +9,12 @@ tr.panel-toggle-row {
position: relative;
i {
i.icon-chevron::before {
font-size: 1.2rem;
content: "\f078";
}
&::before {
&.error::before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
@@ -24,23 +25,14 @@ tr.panel-toggle-row {
right: 5px;
font-size: 2rem;
-webkit-font-smoothing: antialiased;
}
&.error::before {
content: "\f071";
color: #da5354;
}
&.status {
i.status::before {
font-family: FontAwesome;
font-weight: normal;
font-style: normal;
display: inline-block;
text-decoration: inherit;
i.icon-status::before {
font-size: 1.5rem;
opacity: 0.5;
-webkit-font-smoothing: antialiased;
}
i.issue::before {
@@ -59,16 +51,6 @@ tr.panel-toggle-row {
}
}
&.selected {
background-color: #ffffff;
border-left: 2px solid #444444;
border-right: 2px solid #444444;
border-top: 2px solid #444444;
* {
color: #1b3c56;
}
}
&:hover {
cursor: pointer;
background-color: #d0e2f6;
@@ -76,7 +58,7 @@ tr.panel-toggle-row {
color: #1b3c56;
}
i.status::before {
i.icon-status::before {
opacity: 1.0;
}
}
@@ -87,10 +69,27 @@ tr.panel-toggle-row {
border-bottom: 2px solid #444444;
&.selected {
background-color: #ffffff;
border-left: 2px solid #444444;
border-right: 2px solid #444444;
border-top: 2px solid #444444;
border-bottom: none;
&:hover {
background-color: #ffffff;
}
* {
color: #1b3c56;
}
i.icon-status::before {
opacity: 1.0;
}
i.icon-chevron::before {
content: "\f077";
}
}
}
}
@@ -120,10 +119,6 @@ tr.panel-row {
.column.alpha, .columns.alpha {
padding-left: 20px;
&.sixteen {
padding-right: 20px;
}
}
.column.omega, .columns.omega {

View File

@@ -92,24 +92,23 @@
span.filter-label
opacity: 0.75
.filter-shopfront.taxon-selectors, .filter-shopfront.property-selectors
background: transparent
single-line-selectors
overflow-x: hidden
white-space: nowrap
.f-dropdown
overflow-x: auto
white-space: normal
ul
margin: 0
ul, ul li
list-style: none
.filter-shopfront
&.taxon-selectors, &.property-selectors
background: transparent
single-line-selectors
overflow-x: hidden
white-space: nowrap
.f-dropdown
overflow-x: auto
white-space: normal
ul
margin: 0
display: inline-block
ul, ul li
list-style: none
// Shopfront taxons
&.taxon-selectors

View File

@@ -32,6 +32,12 @@ class EnterpriseRelationship < ActiveRecord::Base
relationships = EnterpriseRelationship.includes(:child, :parent)
relatives = {}
Enterprise.all.each do |e|
relatives[e.id] ||= { distributors: Set.new, producers: Set.new }
relatives[e.id][:producers] << e.id if e.is_primary_producer
relatives[e.id][:distributors] << e.id if e.is_distributor
end
relationships.each do |r|
relatives[r.parent_id] ||= {distributors: Set.new, producers: Set.new}
relatives[r.child_id] ||= {distributors: Set.new, producers: Set.new}

View File

@@ -23,32 +23,34 @@ class Api::Admin::IndexEnterpriseSerializer < ActiveModel::Serializer
end
def issues
[
{
resolved: shipping_methods_ok?,
description: "#{object.name} currently has no shipping methods.",
link: "<a class='button fullwidth' href='#{spree.new_admin_shipping_method_path}'>Create New</a>"
},
{
resolved: payment_methods_ok?,
description: "#{object.name} currently has no payment methods.",
link: "<a class='button fullwidth' href='#{spree.new_admin_payment_method_path}'>Create New</a>"
},
{
resolved: object.confirmed?,
description: "Email confirmation is pending. We've sent a confirmation email to #{object.email}.",
link: "<a class='button fullwidth' href='#{enterprise_confirmation_path(enterprise: { id: object.id, email: object.email } )}' method='post'>Resend Email</a>"
}
]
issues = []
issues << {
description: "#{object.name} currently has no shipping methods.",
link: "<a class='button fullwidth' href='#{spree.new_admin_shipping_method_path}'>Create New</a>"
} unless shipping_methods_ok?
issues << {
description: "#{object.name} currently has no payment methods.",
link: "<a class='button fullwidth' href='#{spree.new_admin_payment_method_path}'>Create New</a>"
} unless payment_methods_ok?
issues << {
description: "Email confirmation is pending. We've sent a confirmation email to #{object.email}.",
link: "<a class='button fullwidth' href='#{enterprise_confirmation_path(enterprise: { id: object.id, email: object.email } )}' method='post'>Resend Email</a>"
} unless object.confirmed?
issues
end
def warnings
[
{
resolved: object.visible,
description: "#{object.name} is not visible and so cannot be found on the map or in searches",
link: "<a class='button fullwidth' href='#{edit_admin_enterprise_path(object)}'>Edit</a>"
}
]
warnings = []
warnings << {
description: "#{object.name} is not visible and so cannot be found on the map or in searches",
link: "<a class='button fullwidth' href='#{edit_admin_enterprise_path(object)}'>Edit</a>"
} unless object.visible
warnings
end
end

View File

@@ -89,12 +89,12 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
def producers
relatives = options[:data].relatives[object.id]
relatives ? ids_to_objs(relatives[:producers]) : []
ids_to_objs(relatives.andand[:producers])
end
def hubs
relatives = options[:data].relatives[object.id]
relatives ? ids_to_objs(relatives[:distributors]) : []
ids_to_objs(relatives.andand[:distributors])
end
# Map svg icons.
@@ -139,6 +139,7 @@ class Api::CachedEnterpriseSerializer < ActiveModel::Serializer
private
def ids_to_objs(ids)
ids.andand.map { |id| {id: id} }
return [] if ids.blank?
ids.map { |id| {id: id} }
end
end

View File

@@ -50,8 +50,8 @@
%h5{ ng: { bind: "producer" } }
%td.package.panel-toggle.text-center{ ng: { show: 'columns.package.visible', class: "{error: packageError}" }, name: "package" }
%h5{ ng: { bind: "package" } }
%td.status.panel-toggle.text-center{ ng: { show: 'columns.status.visible' }, bo: { class: "statusClass" }, name: "status" }
%i.status{ bo: { class: "status" } }
%td.status.panel-toggle.text-center{ ng: { show: 'columns.status.visible' }, name: "status" }
%i.icon-status{ bo: { class: "status" } }
%td.manage{ ng: { show: 'columns.manage.visible' } }
%a.button.fullwidth{ bo: { href: 'enterprise.edit_path' } }
Manage

View File

@@ -1,22 +1,21 @@
.row
-# = render partial: 'shared/components/filter_controls'
.small-12.medium-6.columns &nbsp;
= render partial: 'shared/components/filter_controls'
-# .small-12.medium-6.columns &nbsp;
= render partial: 'shared/components/show_profiles'
-# .row.animate-show{"ng-show" => "filtersActive"}
-# .small-12.columns
-# .row.filter-box
-# .small-12.large-9.columns
-# %h5.tdhead
-# .light Filter by
-# Type
-# %ul.small-block-grid-2.medium-block-grid-4.large-block-grid-5
-# %filter-selector{objects: "Enterprises.hubs | searchEnterprises:query | taxonsOf", "active-selectors" => "activeTaxons"}
-# .small-12.large-3.columns
-# %h5.tdhead
-# .light Filter by
-# Delivery
-# %ul.small-block-grid-2.medium-block-grid-4.large-block-grid-2
-# %shipping-type-selector{results: "shippingTypes"}
-#
-# = render partial: 'shared/components/filter_box'
.row.animate-show{"ng-show" => "filtersActive"}
.small-12.columns
.row.filter-box
.small-12.large-9.columns
%h5.tdhead
.light Filter by
Type
%filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-5{ objects: "Enterprises.hubs | searchEnterprises:query | taxonsOf", "active-selectors" => "activeTaxons" }
.small-12.large-3.columns
%h5.tdhead
.light Filter by
Delivery
%ul.small-block-grid-2.medium-block-grid-4.large-block-grid-2
%shipping-type-selector{results: "shippingTypes"}
= render partial: 'shared/components/filter_box'

View File

@@ -1,15 +1,14 @@
-# .row
-# = render partial: 'shared/components/filter_controls'
-# .small-12.medium-6.columns.text-right
-# &nbsp;
-#
-# .row.animate-show{"ng-show" => "filtersActive"}
-# .small-12.columns
-# .row.filter-box
-# .small-12.columns
-# %h5.tdhead
-# .light Filter by
-# Type
-# %ul.small-block-grid-2.medium-block-grid-4.large-block-grid-6
-# %filter-selector{objects: "Enterprises.producers | searchEnterprises:query | taxonsOf", "active-selectors" => "activeTaxons"}
-# = render partial: 'shared/components/filter_box'
.row
= render partial: 'shared/components/filter_controls'
.small-12.medium-6.columns.text-right
&nbsp;
.row.animate-show{"ng-show" => "filtersActive"}
.small-12.columns
.row.filter-box
.small-12.columns
%h5.tdhead
.light Filter by
Type
%filter-selector.small-block-grid-2.medium-block-grid-4.large-block-grid-6{objects: "Enterprises.producers | searchEnterprises:query | taxonsOf", "active-selectors" => "activeTaxons"}
= render partial: 'shared/components/filter_box'

View File

@@ -12,6 +12,11 @@ module OpenFoodNetwork
it "only loads activated relatives" do
subject.relatives[enterprise.id][:producers].should_not include producer_inactive.id
end
it "loads self where appropiate" do
subject.relatives[producer.id][:producers].should include producer.id
subject.relatives[enterprise.id][:distributors].should include enterprise.id
end
end
end
end

View File

@@ -72,14 +72,20 @@ describe EnterpriseRelationship do
describe "finding relatives" do
let(:e1) { create(:supplier_enterprise) }
let(:e2) { create(:supplier_enterprise, sells: 'any') }
let(:e2) { create(:distributor_enterprise) }
let!(:er) { create(:enterprise_relationship, parent: e1, child: e2) }
let(:er_reverse) { create(:enterprise_relationship, parent: e2, child: e1) }
it "includes self where appropriate" do
EnterpriseRelationship.relatives[e2.id][:distributors].should include e2.id
EnterpriseRelationship.relatives[e2.id][:producers].should_not include e2.id
end
it "categorises enterprises into distributors and producers" do
e2.update_attribute :is_primary_producer, true
EnterpriseRelationship.relatives.should ==
{e1.id => {distributors: Set.new([e2.id]), producers: Set.new([e2.id])},
e2.id => {distributors: Set.new([]), producers: Set.new([e1.id])}}
{e1.id => {distributors: Set.new([e2.id]), producers: Set.new([e1.id, e2.id])},
e2.id => {distributors: Set.new([e2.id]), producers: Set.new([e2.id, e1.id])}}
end
it "finds inactive enterprises by default" do