Many supplier features and style upgrades and fixes

This commit is contained in:
2015-10-06 16:08:00 +02:00
parent b7a5b3b750
commit 2df5b290ef
50 changed files with 225 additions and 474 deletions
@@ -1,7 +1,7 @@
App.ButtonRemoveListNeedsPaymentComponent = Ember.Component.extend
tagName: 'button'
layoutName: 'components/button/remove-list-needs-payment'
classNames: ['remove_list_needs_payment']
classNames: ['remove-list-needs-payment-button']
classNameBindings: ['content.needs_payment:show:hide']
click: ->
@get('content').invoke 'remove_needs_payment'
@@ -0,0 +1,6 @@
App.ButtonShowListComponent = Ember.Component.extend
tagName: 'button'
layoutName: 'components/button/show-list'
classNames: ['show-list-button']
click: ->
@get('targetObject.targetObject').transitionToRoute('list', @get('content'))
@@ -1,8 +1,5 @@
App.DashboardActiveListComponent = Ember.Component.extend
tagName: 'tr'
classNames: ['row']
layoutName: 'dashboard/active-list'
classNameBindings: ['classIdentifier']
classIdentifier: Ember.computed 'list.id', -> "list-row-#{@get('list.id')}"
actions:
showList: (list)->
@get('targetObject').transitionToRoute 'list', list
@@ -1,5 +1,5 @@
App.DashboardActiveOrderComponent = Ember.Component.extend
tagName: 'tr'
classNames: ['row']
layoutName: 'dashboard/active-order'
classNameBindings: ['order.active:active', 'order.delivered:delivered', 'classIdentifier']
classIdentifier: Ember.computed 'order.id', -> "order-row-#{@get('order.id')}"
@@ -28,6 +28,7 @@ App.MySelectComponent = Ember.Component.extend
@$('select:first').prop('selectedIndex', index)
actions:
showDebugger: -> debugger
change: ->
selectedIndex = @$('select:first').get(0).selectedIndex
@@ -17,5 +17,6 @@ App.SelectMinuteOfDayComponent = Ember.Component.extend
@set 'value', 60*hour + parseInt(value)
value
get: ->
number = Math.floor @get('value')%60
return "00" unless value = @get('value')
number = Math.floor value%60
"0#{number}".substr(-2,2)
@@ -0,0 +1,7 @@
App.UsersButtonsComponent = Ember.Component.extend
classNames: ['users-buttons']
actions:
userClick: (user)->
@modal 'user_info',
title_path: 'modal.user_info.title'
model: user
@@ -1,20 +1,18 @@
App.ListsIndexController = Ember.Controller.extend
loading: true
date: (new Date()).toISOString().substr(0,10) # 2015-11-02
dateChanged: (->
return unless date = @get('date')
@set 'loading', true
lists = if @get('date') then @store.findAll('list', date: @get('date')) else @store.findAll('list')
lists.then => @set('loading', false)
@set 'model', lists
@store.query 'list', date: date
.then => @set('loading', false)
).observes('date')
lists: (->
return @store.peekAll('list') unless date = @get('date')
@store.filter('list', (l)->
return false unless list_date = l.get('created_at')
list_date = list_date.toISOString().substring(0,10) if typeof(list_date) is 'object'
list_date == date
)
).property('date')
lists: Ember.computed 'date', ->
return @store.peekAll('list') unless selected_date = @get('date')
@store.peekAll('list').filter (list)->
return false unless list_creation_date = list.get('created_at')
list_creation_date = list_creation_date.toISOString().substring(0,10) if typeof(list_creation_date) is 'object'
selected_date is list_creation_date
sorted_lists: (->
sorted_lists: Ember.computed 'lists.[]', ->
@get('lists').sortBy('created_at').reverseObjects()
).property('lists.[]')
@@ -1,4 +1,4 @@
App.ListsIndexRoute = Ember.Route.extend
#model: -> @store.findAll 'list'
setupController: (controller, model)->
controller.set 'date', (new Date()).toISOString().substr(0,10) unless controller.get('date')
#App.ListsIndexRoute = Ember.Route.extend
# #model: -> @store.findAll 'list'
# setupController: (controller, model)->
# controller.set 'date', (new Date()).toISOString().substr(0,10) unless controller.get('date')
@@ -0,0 +1 @@
span.fa.fa-list.fa-2x
@@ -0,0 +1,5 @@
if user
a.user-avatar-button{action "userClick" user}= user.avatar_tag
else
each users as |user|
a.user-avatar-button{action "userClick" user}= user.avatar_tag
@@ -1,17 +1,16 @@
td.user-info.show-for-large-up
each list.users as |user|
= user.avatar_tag
td.status-icons
if list.needs_help
span.icon.needs-help
if list.needs_payment
|
span.icon.needs-payment
td.numeric.table_number= table-number-with-info list=list
td.section_title: link-to 'section' list.table.section.id: span=list.table.section.title
td.currency.total_list_amount=currency list.total
td.actions
= button-mark-list-helped content=list
= button-remove-list-needs-payment content=list
= button-close-list content=list
button.show-list.button{action "showList" list}: span
.small-12.columns
= users-buttons users=list.users
.status-icons
if list.needs_help
span.icon.needs-help
if list.needs_payment
span.icon.needs-payment
span.table-number= table-number list.table.number
= link-to 'section' list.table.section class="link-to-section"
span=list.table.section.title
span.currency=currency list.total
.actions
= button-mark-list-helped content=list
= button-remove-list-needs-payment content=list
= button-close-list content=list
= button-show-list content=list
@@ -1,13 +1,15 @@
td.user-info.show-for-large-up= order.user.avatar_tag
td.status-icons
if order.active
span.active-order
td= order.display
td.numeric.table_number= table-number-with-info list=order.list
td.section_title= link-to 'section' order.list.table.section.id: span=order.list.table.section.title
td.currency=currency order.total
td.time= time order.created_at format="HH:mm"
td.actions
= button-mark-order-active order=order
= button-mark-order-delivered order=order
= button-mark-order-cancelled order=order
.small-12.columns
= users-buttons users=order.list.users
.status-icons
if order.active
span.active-order
span.order-display= order.display
span.table-number= table-number order.list.table.number
= link-to 'section' order.list.table.section class="link-to-section"
span=order.list.table.section.title
span.currency=currency order.total
span.time= time order.created_at format="HH:mm"
.actions
= button-mark-order-active order=order
= button-mark-order-delivered order=order
= button-mark-order-cancelled order=order
@@ -1,4 +1,4 @@
.row.select-minute-of-day
.small-5.columns= my-select content=hours_list selection=hour identity=false
.small-5.columns.hour-of-day= my-select content=hours_list selection=hour identity=false
.small-1.columns: span
.small-5.columns.end= my-select content=minutes_list selection=minute identity=false
.small-5.columns.end.minute-of-hour= my-select content=minutes_list selection=minute identity=false
@@ -17,18 +17,9 @@
else
h3=t 'dashboard.active_lists.no_lists'
if show_lists_table
table.active-lists-table.table
thead
tr
th.user-info.show-for-large-up
th.status-icons
th.numeric=t 'table_number'
th=t 'models.section'
th.currency=t 'active_lists.price'
th.actions
tbody
each active_lists as |list|
= dashboard-active-list list=list
.active-lists-table
each active_lists as |list|
= dashboard-active-list list=list
.page-header
if active_orders.length
h3.dashboard-orders-header{action "toggleDashboardOrders"}
@@ -41,17 +32,6 @@
else
h3= t 'dashboard.active_orders.no_orders'
if show_orders_table
table.active-orders-table.table
thead
tr
th.user-info.show-for-large-up
th.status-icons
th=t 'models.order'
th.numeric=t 'table_number'
th=t 'models.section'
th.currency=t 'active_orders.price'
th.time
th.actions
tbody
each active_orders as |order|
= dashboard-active-order order=order
.active-orders-table
each active_orders as |order|
= dashboard-active-order order=order
@@ -21,9 +21,7 @@ if list.active
.display-field
= button-mark-list-helped content=list
= button-close-list content=list
.user-info-container
each list.users as |user|
= user.avatar_tag
= users-buttons users=list.users
if list.sorted_orders
.list-orders-container
each list.sorted_orders as |order|
@@ -1,7 +1,5 @@
h4=t 'modal.change_list_table.subtitle' current_table_number=model.table.number
.user-info-container
each model.users as |user|
= user.avatar_tag
= users-buttons users=model.users
each sections as |section|
h3= section.title
ul.change-list-table-section-tables
@@ -31,11 +31,11 @@
.form-field.half= boolean-switch value=model.active_on_sunday
.small-12.medium-6.columns
.row
.small-12.columns.text-center= boolean-button value=model.full_day reverse=true text_path="product_category.modal.active_between.top"
.small-12.columns.text-center= boolean-button value=model.full_day reverse=true text_path="product_category.modal.active_between.top" class="toggle-full-day-button"
unless model.full_day
.row
.small-12.columns= select-minute-of-day value=model.start_from
.small-12.columns.select-start_from= select-minute-of-day value=model.start_from
.row
.small-12.columns.text-center= t 'product_category.modal.active_between.middle'
.row
.small-12.columns= select-minute-of-day value=model.end_on
.small-12.columns.select-end_on= select-minute-of-day value=model.end_on
@@ -0,0 +1,9 @@
.form-row
.form-label  
.form-value= model.avatar_tag
.form-row
.form-label= t 'attributes.user.name'
.form-value= model.name
.form-row
.form-label= t 'user.number_of_lists_at_supplier'
.form-value 1
@@ -12,9 +12,7 @@ table.table
tbody
each orders as |order|
tr
td
each order.list.users as |user|
= user.avatar_tag
td= users-buttons users=order.list.users
td.status-icons
if order.active
span.active-order.fa.fa-check.fa-lg
@@ -20,5 +20,4 @@ if table.active_list
=currency table.active_list.total
/.table-action-row
a{action "editTable" table}: span.fa.fa-lg.fa-wrench
each table.active_list.users as |user|
= user.avatar_tag
= users-buttons users=table.active_list.users
@@ -22,7 +22,6 @@ var Qstorage = localStorage;
$.extend($translations.en, <%= I18n.t('supplier', locale: :en).to_json %>);
$.extend($translations.nl, <%= I18n.t('supplier', locale: :nl).to_json %>);
String.prototype.capitalize = function() { return this.charAt(0).toUpperCase() + this.slice(1); }
window.time_zones = <%= ActiveSupport::TimeZone.all.map{|tz| {name: tz.name, formatted: "GMT#{tz.formatted_offset} #{tz.name}"}}.to_json.html_safe %>;
@@ -16,10 +16,6 @@ td.boolean
.boolean-false
@extend .fa, .fa-lg, .fa-minus
.change-list-table-button
+button($bg: $warning-color, $padding: $button-tny)
margin: 0
margin-bottom: 8px
.change-list-table-section-tables
list-style: none
+clearfix
@@ -1,3 +1,4 @@
// spin-rotate is currently used when clicked on a section-element in a section view
.spin-rotate
+animation(spinRotate 2s)
+keyframes(spinRotate)
@@ -1,3 +1,42 @@
.button-text
// Only icons for now
display: none
.mark-list-as-helped-button
+button-icon-only
vertical-align: middle
padding-left: 8px //do not ask me why, just looks
padding-right: 2px //do not ask me why, just looks
margin-right: $button-spacing
span
@extend .fa, .fa-2x, .fa-bell-slash-o
.mark-order-active-button
+button-icon-only
margin-right: 0.6em
.mark-order-delivered-button
+button-icon-only
.show-list-button
+button-icon-only
vertical-align: middle
margin-left: $button-spacing
.mark-order-cancelled-button
+button($bg: $alert-color)
+button-icon-only
margin-left: $button-spacing
span
@extend .fa
@extend .fa-2x
@extend .fa-times
.change-list-table-button
+button($bg: $warning-color, $padding: $button-tny)
margin: 0
margin-bottom: 8px
.close-list-button
+button-icon-only
vertical-align: middle
.remove-list-needs-payment-button
+button-icon-only
vertical-align: middle
padding-left: 8px //do not ask me why, just looks
padding-right: 2px //do not ask me why, just looks
margin-right: $button-spacing
@@ -1,21 +0,0 @@
.mark-list-as-helped-button
+button-icon-only
vertical-align: top
padding-left: 8px //do not ask me why, just looks
padding-right: 2px //do not ask me why, just looks
margin-right: $button-spacing
span
@extend .fa, .fa-2x, .fa-bell-slash-o
.mark-order-active-button
+button-icon-only
margin-right: 0.6em
.mark-order-delivered-button
+button-icon-only
.mark-order-cancelled-button
+button($bg: $alert-color)
+button-icon-only
margin-left: $button-spacing
span
@extend .fa
@extend .fa-2x
@extend .fa-times
@@ -18,23 +18,41 @@
min-width: 124px
select
width: calc(100% - 30px)
.active-lists-table
width: 100%
.show-list
+button-icon-only
margin-left: $button-spacing
span
@extend .fa
@extend .fa-2x
@extend .fa-list
.remove_list_needs_payment
+button-icon-only
vertical-align: top
padding-left: 8px //do not ask me why, just looks
padding-right: 2px //do not ask me why, just looks
margin-right: $button-spacing
.close-list-button
+button-icon-only
= active-list-div($float: left, $padding: 4px)
line-height: 50px
float: $float
display: inline-block
vertical-align: middle
padding-left: $padding
padding-right: $padding
.active-lists-table, .active-orders-table
.row
border-bottom: 1px solid #777
background-color: white
padding: 5px
.users-buttons
float: left
.status-icons
font-size: 1.5rem
+active-list-div
.needs-payment
margin-left: 7px
.order-display
+active-list-div
.table-number
+active-list-div
.link-to-section
+active-list-div
.currency
+active-list-div
font-weight: bold
.actions
+active-list-div(right)
button
vertical-align: middle
.time
+active-list-div(right)
.active-orders-table
width: 100%
.go-to-orders-list
+1 -9
View File
@@ -91,15 +91,6 @@ private
end
end
def check_active_list_state
if current_user.try(:active_list_id)
unless active_list.active?
current_user.list_is_closed!
redirect_to user_root_path, alert: t('messages.the_list_has_been_closed', list: List.model_name.human)
end
end
end
def active_list
return nil unless current_user.try(:active_list_id).present?
@active_list ||= List.find(current_user.active_list_id)
@@ -113,6 +104,7 @@ private
{ok: false, message: message}.merge(options).to_json
end
alias json_alert js_alert
def js_notice(*args)
options = args.extract_options!
message = args.first || ''
-190
View File
@@ -1,209 +1,19 @@
class UserController < Users::ApplicationController
before_action :allow_all_origins
layout 'user/foundation'
#layout 'phone'
alias :list :active_list
def index
handle_message_params
end
# POST /user/create_list {table_id: 1234}
#DEPRICATED, see order_selected_products, this one now handles list creation as well
#def create_list
#render nothing: true and return unless current_user.present?
#@table = Table.find(params[:table_id])
#if @table.occupied?
#respond_to do |format|
#format.html { redirect_to user_root_path, alert: t('messages.table_is_occupied') }
#format.json { render json: json_alert('messages.table_is_occupied')}
#end
#else
#if @list = List.from_table( @table, current_user )
#end
#respond_to do |format|
#format.html { redirect_to user_list_products_path }
#format.json { render json: json_notice('messages.new_list_created')}
#end
#end
#end
# GET /suppliers/1/product_list
# GET /suppliers/1/product_list.json
def list_products
respond_to do |format|
format.html do
redirect_to(user_root_path(message: 'the_list_has_been_closed')) and return unless list
@supplier = list.supplier
handle_message_params
end
format.json do
unless list
render json: {not_present: true} and return
end
@supplier = list.supplier
h = ProductCategory.for_user(current_user, table: list.table, list: list, supplier: @supplier) # list is performance parameter
render json: h
#products = list.supplier.products
#product_categories = list.supplier.product_categories
#other = product_categories.find(&:other?) || (product_categories << ProductCategory.other).last # Container for non categorized products
#product_categories.sort_by!{|p| p.product_category.try(:position) || 90000}
#h = {table_number: list.table_number, supplier_name: @supplier.name}
#h[:categories] = product_categories.map{|pc| {pc.name => pc.product_ids.map{|p| p.as_json}}}
#){|h, p| n = p.product_category.try(:name) || 'other'; h[n] ||= []; h[n] << p; h}
#render json: h
end
end
end
def list_products_for_table
respond_to do |format|
format.html do
end
format.json do
render json: json_alert('messages.table_not_found') and return unless params[:table_id].present?
@table = Table.find(params[:table_id])
h = ProductCategory.for_user(current_user, table: @table)
render json: h
end
end
end
# POST /user/check_table_join_status.json table_id:12345
def check_table_join_status
render json: json_alert('messages.table_not_found') and return unless params[:table_id].present?
@table = Table.find(params[:table_id])
if @list = @table.active_list
if @list.user_ids.include?(current_user.id)
render json: {approved: true}
elsif @list.join_request_user_ids.include?(current_user.id)
render json: {waiting: true}
else
render json: {rejected: true}
end
else
render json: {rejected: true}
end
end
# GET /user/current_list.json
# Information about the currently active list
# This information includes detailed order information
def active_list
respond_to do |format|
format.html do
redirect_to(user_root_path, alert: t('messages.there_is_no_list_active')) and return unless list.present?
end
format.json do
render json: js_alert(t('messages.the_list_has_been_closed')) and return unless list.present?
render json: list.with_orders_and_join_requests_and_supplier_info_as_json
end
end
end
# GET /user/list_info.json
# Information about the currently active list
# Fast version to verify wether the is is still currently active
# for handle_active_list
def list_info
respond_to do |format|
format.json do
if list.present?
if !list.try(:active?)
current_user.list_is_closed!
render json: json_response(list_active: false)
return
else
render json: json_response(list.serialized_with_status_join_requests_and_supplier_counters)
end
else
render json: json_response(not_present: true)
end
end
end
end
def feedback
user_feedback = UserFeedback.create(user_id: current_user.id, content: params[:feedback].to_s)
Notifier.user_feedback(user_feedback.id).deliver_later
render json: {}
end
##
# Displays the closed lists of the user
# GET /user/list_history
#def list_history
#respond_to do |format|
#format.html {}
#format.json do
#@lists = List.for_user(current_user, page: params[:page], per_page: params[:per_page].presence || 14)
#@lists.include_relation(:supplier)
#render json: @lists.inject(lists: [], current_page: @lists.current_page, num_pages: @lists.num_pages, total_count: @lists.total_count){|h, l| h[:lists] << l.as_json.merge(supplier_name: l.supplier.name); h}
#end
#end
#end
##
# Displays a closed list of the user
# GET /user/list_history/:list_id
#def history_list
#respond_to do |format|
#format.html do
#end
#format.json do
#@list = List.find(params[:list_id])
#render json: json_alert('messages.illegal_history_list_attempt') and return unless @list.user_ids.include?(current_user.id)
#if params[:list_closed].present? && current_user.active_list_id == @list.id
#current_user.list_is_closed!
#flash.now[:notice] = t('messages.the_list_has_been_closed', list: List.model_name.human)
#end
#render json: @list.with_orders_as_json.merge(supplier_name: @list.supplier.name)
#end
#end
#end
# POST /user/order_selected_products.json
#def order_selected_products
#if list.present?
#@list = list
#else
#render json: json_alert('messages.table_not_found') and return unless params[:table_id].present?
#@table = Table.find(params[:table_id])
#if @table.occupied?
#render json: json_alert('messages.table_is_occupied', location: :join_occupied_table, location_params: {table_id: @table.id})
#else
#if @list = List.from_table( @table, current_user )
#else
##TODO handle second list creation for user
#end
#end
#end
#respond_to do |format|
#format.html do
#redirect_to(user_root_path, alert: t('messages.cannot_order_on_non_active_list')) and return unless @list.active?
#@list.place_order products: params[:products], user: current_user
#redirect_to user_root_path, notice: t('messages.order_is_placed')
#end
#format.json do
#render json: json_alert('messages.cannot_order_on_non_active_list') and return unless @list.active?
## Todo, better document and uniform this
#@list.place_order products: (params[:order] || params[:products]), user: current_user
#render json: json_notice('messages.order_is_placed', location: :active_list)
#end
#end
#end
def obtain_token
redirect_to user_omniauth_authorize_path(params[:provider].presence || 'facebook') and return unless current_user.present?
# redirect_to case platform
# when 'android' then "file:///android_asset/user/index.html?user_id=#{current_user.id}&auth_token=#{current_user.authentication_token}"
# when
# else user_root_path(user_id: current_user.id, auth_token: current_user.authentication_token)
# end
# return
respond_to do |format|
format.html { render layout: 'user/obtain_token' }
format.json do
@@ -12,7 +12,6 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
if @user.persisted?
flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => @user.provider.to_s.capitalize
sign_in @user
#redirect_to user_root_path, :event => :authentication, :current_user => @user # infinite loop
redirect_to user_obtain_token_path, :event => :authentication, :current_user => @user
else
session["devise.facebook_data"] = request.env["omniauth.auth"]
+1 -1
View File
@@ -83,7 +83,7 @@ class User
# This is the user name as it is shown to the supplier
def supplier_name
auth_data['info']['name'] rescue I18n.t('supplier.unknown_user_name')
auth_data['info']['name'] rescue I18n.t('supplier.user.unknown_name')
end
# This is the user name as it is shown to other users
-36
View File
@@ -1,36 +0,0 @@
= top_bar title: 'active_list.title' do
.pull-right
.supplier-info-row
.table-number
.supplier-name
.supplier-info-row
.counter.supplier-orders-placed-count
.counter.supplier-orders-in-process-count
.action-buttons
= link_to content_tag(:span, t('helpers.links.place_order')), user_list_products_path, class: ['user-top-button'], id: 'place-order-on-list'
span#list-needs-payment-button.user-top-button
span
span#list-needs-help-button.user-top-button
span
.well
table#active-list-table.table
thead
tr
th data-t="models.order" = Order.model_name.human
th.currency data-t="attributes.product.price" = Product.human_attribute_name(:price)
tbody
tr
td colspan=2 = slider_image
tfoot
tr
td
td.currency
strong.list-total-amount
script#active-list-order-template[type="text/html"]= mustache_template 'active_list_order'
- content_for :footer do
javascript:
jQuery(function(){
Quser.load_active_list();
Quser.watch_events();
//setInterval( "Quser.load_active_list()", 7500);
})
-31
View File
@@ -1,31 +0,0 @@
= top_bar title: 'history_list.title' do
.pull-right
.table-number
.supplier-name
table.table.table-condensed
tbody
tr
td.key data-t="attributes.list.created_at" = List.human_attribute_name(:created_at)
td.value.list-created-at
tr
td.key data-t="attributes.list.closed_at" = List.human_attribute_name(:closed_at)
td.value.list-closed-at
tr
td.key data-t="models.supplier" = Supplier.model_name.human
td.value.supplier-name
.well
table#history-list-table.table.list-table
thead
tr
th data-t="models.order" = Order.model_name.human
th.currency data-t="attributes.product.price" = Product.human_attribute_name(:price)
tbody
tr
td colspan=2 = slider_image
tfoot
tr
td
td.currency
strong.list-total-amount
script#active-list-order-template[type="text/html"]= render 'active_list_order.mustache'
- onload_javascript "Quser.load_history_list()"
@@ -1,10 +0,0 @@
.page-header
h4 data-t="join_request.requestor.title" = t('user.join_occupied_table.title')
.form-actions
= link_to t('user.join_occupied_table.back'), user_root_path, class: :btn, data: {t: 'join_request.requestor.go_back'}
'
button.btn.btn-primary.show-menu-button onclick="Quser.show_table_products()" data-t='join_request.requestor.show_the_products'= t('user.join_occupied_table.show_the_products')
'
button.btn.btn-warning.join-table-button onClick="Quser.join_occupied_table()" data-t='join_request.requestor.join_this_table'= t('user.join_occupied_table.join_this_table')
#join-occupied-table-progress-container
- onload_javascript 'Quser.watch_events()'
-6
View File
@@ -1,6 +0,0 @@
= top_bar title: 'list_history.title' do
span
nav.pagination
ul#list-history-container
script#list-history-template[type="text/html"]= mustache_template 'list_history'
- onload_javascript "Qstorage.page = 1; Quser.load_list_history()"
@@ -1,18 +0,0 @@
= top_bar title: 'show_products.title' do
.pull-right
.supplier-info-row
.table-number
.supplier-name
.supplier-info-row
.counter.supplier-orders-placed-count
.counter.supplier-orders-in-process-count
.well
table#products-table.table.table-hover
tbody
tr
td= slider_image
#active-order-container
script#products-category-template[type="text/html"]= mustache_template 'products_category'
script#products-category-for-order-template[type="text/html"]= mustache_template 'products_category_for_order'
script#active-order-template[type="text/html"]= mustache_template 'active_order'
- onload_javascript 'Quser.load_table_products()'