Product error handling
This commit is contained in:
@@ -86,7 +86,7 @@ group :development do
|
||||
#gem 'pry-remote'
|
||||
gem 'quiet_assets'
|
||||
gem 'letter_opener'
|
||||
gem 'thin'
|
||||
# gem 'thin'
|
||||
gem 'faye'
|
||||
gem 'capistrano', '~> 3.0', require: false
|
||||
gem 'capistrano-rvm', '~> 0.1', require: false
|
||||
|
||||
@@ -155,7 +155,6 @@ GEM
|
||||
mime-types (~> 1.15)
|
||||
multi_json (~> 1.0)
|
||||
rest-client (~> 1.6.1)
|
||||
daemons (1.1.9)
|
||||
debug_inspector (0.0.2)
|
||||
diff-lcs (1.2.5)
|
||||
docile (1.1.5)
|
||||
@@ -408,10 +407,6 @@ GEM
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
temple (0.6.10)
|
||||
thin (1.6.3)
|
||||
daemons (~> 1.0, >= 1.0.9)
|
||||
eventmachine (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
thor (0.19.1)
|
||||
thread_safe (0.3.4)
|
||||
tilt (1.4.1)
|
||||
@@ -487,7 +482,6 @@ DEPENDENCIES
|
||||
slim-rails
|
||||
spring
|
||||
spring-commands-rspec
|
||||
thin
|
||||
turnip
|
||||
uglifier (>= 1.0.3)
|
||||
web-console (~> 2.0.0.beta3)
|
||||
|
||||
@@ -1,9 +1,24 @@
|
||||
App.MenuProductComponent = Ember.Component.extend
|
||||
editMode: false
|
||||
code_filter: ''
|
||||
showProduct: (-> !@get('code_filter') or (@get('product.code') || "").match(@get('code_filter'))).property('code_filter')
|
||||
code_filter_display: (->
|
||||
return new Ember.Handlebars.SafeString(' ') unless code = @get('product.code')
|
||||
return code unless filter = @get('code_filter')
|
||||
index = code.indexOf(filter)
|
||||
if index >= 0
|
||||
pre_code = code.substring(0,index)
|
||||
highlight = code.substring(index,index + filter.length)
|
||||
post_code = code.substring(index + filter.length)
|
||||
new Ember.Handlebars.SafeString("#{pre_code}<span class='highlight'>#{highlight}</span>#{post_code}")
|
||||
else
|
||||
code
|
||||
).property('code_filter')
|
||||
actions:
|
||||
makeEditable: -> @set('editMode', true)
|
||||
save: ->
|
||||
@get('product').save() if @get('product.isDirty')
|
||||
if @get('product.isDirty')
|
||||
@get('product').save().then((-> true), (-> true))
|
||||
@set 'editMode', false
|
||||
destroyProduct: (product)->
|
||||
if product.get('isNew')
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
App.MenuController = Ember.ObjectController.extend
|
||||
needs: ['application']
|
||||
product_code_filter: ''
|
||||
product_categories: (-> @store.all('product_category')).property()
|
||||
sorted_product_categories: (-> @get('product_categories').sortBy('position')).property('product_categories.@each', 'product_categories.@each.position')
|
||||
product_code_filter_placeholder: t('product.code_filter.placeholder')
|
||||
actions:
|
||||
editProductCategory: (product_category)->
|
||||
@modal 'product_category_edit',
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
Ember.Handlebars.helper 'errors', (errors, params..., options)->
|
||||
return "" unless errors and errors.length
|
||||
result = ""
|
||||
model_name = options.hash.includeAttribute
|
||||
for error in errors
|
||||
if model_name
|
||||
attribute = ttry("attributes.#{model_name}.#{error.attribute}")
|
||||
message = "#{attribute} #{error.message}"
|
||||
else
|
||||
message = error.message
|
||||
result += "<div class='error'>#{message}</div>"
|
||||
new Ember.Handlebars.SafeString(result)
|
||||
@@ -1,8 +1,8 @@
|
||||
App.ApplicationSerializer = DS.ActiveModelSerializer
|
||||
|
||||
App.ApplicationStore = DS.Store.extend
|
||||
adapter: DS.RESTAdapter.extend
|
||||
adapter: DS.ActiveModelAdapter.extend
|
||||
namespace: 'supplier'
|
||||
# user underscored paths
|
||||
pathForType: (type)->
|
||||
Ember.String.pluralize(Ember.String.decamelize(type))
|
||||
## user underscored paths
|
||||
#pathForType: (type)->
|
||||
#Ember.String.pluralize(Ember.String.decamelize(type))
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
.row.menu-product-container
|
||||
if editMode
|
||||
.small-3.columns= input value=product.name
|
||||
.small-3.columns= edit-currency value=product.price validatePresence=true
|
||||
.small-3.columns
|
||||
= input value=product.name
|
||||
= errors product.errors.name
|
||||
.small-3.columns
|
||||
= edit-currency value=product.price validatePresence=true
|
||||
= errors product.errors.price
|
||||
.small-3.columns= input value=product.code
|
||||
.small-3.columns
|
||||
a.destroy-product-action{action "destroyProduct" product}: span
|
||||
a.save-product-action{action "save"}: span
|
||||
else
|
||||
.small-3.columns: span= product.name
|
||||
.small-3.columns= currency product.price
|
||||
.small-3.columns: span= product.code_or_empty
|
||||
.small-3.columns: span.fa.fa-edit{action "makeEditable"}
|
||||
if showProduct
|
||||
.small-3.columns
|
||||
span= product.name
|
||||
= errors product.errors.name includeAttribute="product"
|
||||
.small-3.columns
|
||||
= currency product.price
|
||||
= errors product.errors.price includeAttribute="product"
|
||||
.small-3.columns: span= code_filter_display
|
||||
.small-3.columns: span.fa.fa-edit{action "makeEditable"}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.products-menu-filters-container
|
||||
= input value=product_code_filter type="search" placeholder=product_code_filter_placeholder
|
||||
h2 Menu
|
||||
each product_category in sorted_product_categories
|
||||
.row.product_category-container: .small-12.columns
|
||||
@@ -8,7 +10,7 @@ each product_category in sorted_product_categories
|
||||
a.edit-product-category-button{action "editProductCategory" product_category} href="#"
|
||||
a.add-product-product-category-button{action "addProduct" product_category} href="#": span
|
||||
each product in product_category.sorted_products
|
||||
= menu-product product=product
|
||||
= menu-product product=product code_filter=product_code_filter
|
||||
.row
|
||||
.small-12.columns
|
||||
a.button{action "newProductCategory"} href="#" = t 'product_category.new_button'
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.form-label.half=t 'attributes.product_category.name'
|
||||
.form-field.half= input valueBinding="model.name"
|
||||
.row
|
||||
.small-6.columns
|
||||
.small-12.medium-6.columns
|
||||
unless model.supplier.week_starts_on_monday
|
||||
.form-row
|
||||
.form-label.half= t 'date.day_name.sunday'
|
||||
@@ -29,7 +29,7 @@
|
||||
.form-row
|
||||
.form-label.half= t 'date.day_name.sunday'
|
||||
.form-field.half= view "boolean-switch" valueBinding=model.active_on_sunday
|
||||
.small-6.columns
|
||||
.small-12.medium-6.columns
|
||||
.row
|
||||
.small-12.columns.text-center= view 'boolean-button' value=model.full_day reverse=true text_path="product_category.modal.active_between.top"
|
||||
unless model.full_day
|
||||
|
||||
@@ -9,13 +9,14 @@ each product_category in product_categories
|
||||
a{action "moveBelow" product_category} href="#"
|
||||
span.title= product_category.name
|
||||
span.availability= product_category.availability_text
|
||||
hr
|
||||
h4=t 'product_category.modal.move.products.title'
|
||||
hr
|
||||
ul.sortable
|
||||
each product in model.sorted_products
|
||||
li.sortable-item-container data-sortable-id=product.id
|
||||
span.handle
|
||||
span= product.name
|
||||
if model.products
|
||||
hr
|
||||
h4=t 'product_category.modal.move.products.title'
|
||||
hr
|
||||
ul.sortable
|
||||
each product in model.sorted_products
|
||||
li.sortable-item-container data-sortable-id=product.id
|
||||
span.handle
|
||||
span= product.name
|
||||
hr
|
||||
button.modal-close{action "close"}=t 'section.add_tables.modal.close_button'
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
//= require_self
|
||||
|
||||
var Qstorage = localStorage;
|
||||
|
||||
$.extend($translations.en, <%= I18n.t('supplier', locale: :en).to_json %>);
|
||||
$.extend($translations.nl, <%= I18n.t('supplier', locale: :nl).to_json %>);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
jQuery ->
|
||||
$('#product-category-list').sortable
|
||||
axis: 'y'
|
||||
handle: '.handle'
|
||||
update: ->
|
||||
$.post($(this).data('update-url'), $(this).sortable('serialize'))
|
||||
#jQuery ->
|
||||
#$('#product-category-list').sortable
|
||||
#axis: 'y'
|
||||
#handle: '.handle'
|
||||
#update: ->
|
||||
#$.post($(this).data('update-url'), $(this).sortable('serialize'))
|
||||
|
||||
@@ -32,9 +32,10 @@
|
||||
#translatable = undefined
|
||||
#isafety = undefined
|
||||
#replacable = undefined
|
||||
locale = Qstorage.getItem('locale') || 'en'
|
||||
parts = path.split(".")
|
||||
#accessor = "$translations.#{$locale}[\"#{parts.join("\"][\"")}\"]"
|
||||
result = $translations[$locale]
|
||||
result = $translations[locale]
|
||||
try
|
||||
result = result[part] for part in parts
|
||||
catch err
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
.modal
|
||||
margin: 10px auto
|
||||
width: 600px
|
||||
max-width: 100%
|
||||
background-color: #fff
|
||||
padding: 1em
|
||||
max-height: calc(100% - 20px)
|
||||
overflow-y: scroll
|
||||
z-index: 6524
|
||||
.modal-close
|
||||
+button($bg: #ddd)
|
||||
.modal-confirm
|
||||
@@ -29,6 +31,7 @@
|
||||
top: 0
|
||||
left: 0
|
||||
background-color: rgba(0, 0, 0, 0.5)
|
||||
z-index: 6522
|
||||
|
||||
.flush--top
|
||||
margin-top: 0
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
//DEPRICATED
|
||||
.row.product_category-container
|
||||
margin-bottom: 15px
|
||||
|
||||
.products-menu-filters-container
|
||||
float: right
|
||||
width: 200px
|
||||
|
||||
.product_category-header
|
||||
border-top: 1px solid #ccc
|
||||
border-bottom: 1px solid #ccc
|
||||
@@ -40,6 +45,9 @@
|
||||
color: rgb(39, 6, 121)
|
||||
|
||||
.menu-product-container
|
||||
.highlight
|
||||
text-decoration: underline
|
||||
font-weight: bold
|
||||
.destroy-product-action
|
||||
color: $alert-color
|
||||
margin-right: 12px
|
||||
@@ -47,6 +55,10 @@
|
||||
@extend .fa
|
||||
@extend .fa-lg
|
||||
@extend .fa-trash
|
||||
.error
|
||||
color: $alert-color
|
||||
input
|
||||
margin-bottom: 0
|
||||
.save-product-action
|
||||
color: $success-color
|
||||
span
|
||||
|
||||
@@ -52,7 +52,7 @@ module Suppliers
|
||||
format.json { render json: @product, status: :created }
|
||||
else
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @product.errors, status: :unprocessable_entity }
|
||||
format.json { render json: {errors: @product.errors}, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -68,7 +68,7 @@ module Suppliers
|
||||
format.json { render json: @product }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @product.errors, status: :unprocessable_entity }
|
||||
format.json { render json: {errors: @product.errors}, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
module ProductDecorator
|
||||
|
||||
def category_links(options = {})
|
||||
product_categories = [product_category].compact # changed from habtm to belongs_to
|
||||
if namespace = options[:namespace]
|
||||
product_categories.map{|pc| link_to pc.name, [namespace, pc]}.join(', ').html_safe
|
||||
else
|
||||
|
||||
@@ -19,7 +19,7 @@ class Product
|
||||
|
||||
validates :name, presence: true
|
||||
validates :supplier_id, presence: true
|
||||
validates :price, presence: true, numericality: true
|
||||
validates :price, numericality: {greater_than: 0}
|
||||
view :by_supplier_id_and_id, key: [:supplier_id, :_id]
|
||||
|
||||
#after_save :persist_product_category_ids
|
||||
|
||||
@@ -163,6 +163,8 @@ en:
|
||||
product:
|
||||
new: 'New ${model.product|downcase}'
|
||||
destroy_confirmation: Are you sure you want to delete ${models.product|downcase} %{name}
|
||||
code_filter:
|
||||
placeholder: Filter ${models.product|downcase} ${attributes.product.code|downcase}
|
||||
preview:
|
||||
header: 'Select moment to preview products'
|
||||
description: 'Products visible to customers at chosen moment:'
|
||||
|
||||
@@ -166,6 +166,8 @@ nl:
|
||||
product:
|
||||
new: 'Nieuw ${model.product|downcase}'
|
||||
destroy_confirmation: Weet je zeker dat je ${models.product|downcase} %{name} wilt verwijderen
|
||||
code_filter:
|
||||
placeholder: Filter ${models.product|downcase} ${attributes.product.code|downcase}
|
||||
preview:
|
||||
header: 'Selecteer tijdstip voor voorbeeld'
|
||||
description: 'Producten op gekozen tijdstip:'
|
||||
|
||||
Reference in New Issue
Block a user