diff --git a/.gitignore b/.gitignore index 13e841c4..2f615afe 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ # git config --global core.excludesfile ~/.gitignore_global # Ignore bundler config -/.bundle +.bundle # Ignore the default SQLite database. /db/*.sqlite3 diff --git a/Gemfile b/Gemfile index a8591749..c3bf5dfd 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'rails', '4.2.0.rc2' +gem 'rails', '4.2.0' gem 'rack-cors', :require => 'rack/cors' # Bundle edge Rails instead: @@ -20,12 +20,12 @@ group :assets do gem 'ember-source', '1.8.1'#, github: 'emberjs/ember.js', require: 'ember/source' gem 'ember-rails' gem 'ember_script-rails', github: 'ghempton/ember-script-rails' - gem 'sass-rails', '5.0.0.beta1' + gem 'sass-rails', '~> 5.0.0' gem 'coffee-rails' #, '~> 3.2.1' #gem 'twitter-bootstrap-rails' # Only for mobile assets precompile, not used in this project - gem 'bootstrap-sass', '~>2.3' - gem 'bourbon', '4.0.2' + #gem 'bootstrap-sass', '~>2.3' + gem 'bourbon' #, '4.0.2' #gem 'compass-rails' gem 'js-routes' gem "font-awesome-rails" @@ -35,7 +35,9 @@ group :assets do #gem 'therubyracer', :platforms => :ruby gem 'uglifier', '>= 1.0.3' + #gem "emblem-source", github: "machty/emblem.js" gem 'emblem-rails' + gem 'ember-validations-rails' gem 'foundation-rails' #, github: 'bterkuile/foundation-rails' #gem 'mustache' #, :require => 'mustache/railtie' @@ -96,7 +98,6 @@ group :development do gem 'spring' gem 'spring-commands-rspec' gem 'web-console', '~> 2.0.0' - end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 7f7a5268..bde5f57c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: git://github.com/bterkuile/cmtool.git - revision: 323e68bcad3b21cd580d3aff5771d99a805fc985 + revision: e2f8459960eb4eff12365c6ebd60278d79eaab8f specs: cmtool (1.0.0) bourbon @@ -28,7 +28,7 @@ GIT GIT remote: git://github.com/bterkuile/simply_stored.git - revision: 8f00644f7a8e82dba057c01f86dbb8bc3154d5d8 + revision: 652caf8c2cfe4f828477f8b76d0cd201851cd53d specs: simply_stored (1.0.0) activesupport @@ -59,60 +59,58 @@ GIT GEM remote: https://rubygems.org/ specs: - actionmailer (4.2.0.rc2) - actionpack (= 4.2.0.rc2) - actionview (= 4.2.0.rc2) - activejob (= 4.2.0.rc2) + actionmailer (4.2.0) + actionpack (= 4.2.0) + actionview (= 4.2.0) + activejob (= 4.2.0) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.0.rc2) - actionview (= 4.2.0.rc2) - activesupport (= 4.2.0.rc2) - rack (~> 1.6.0.beta2) + actionpack (4.2.0) + actionview (= 4.2.0) + activesupport (= 4.2.0) + rack (~> 1.6.0) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.1) - actionview (4.2.0.rc2) - activesupport (= 4.2.0.rc2) + actionview (4.2.0) + activesupport (= 4.2.0) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.1) - active_decorator (0.3.4) + active_decorator (0.4.0) active_model_serializers (0.9.0) activemodel (>= 3.2) - activejob (4.2.0.rc2) - activesupport (= 4.2.0.rc2) + activejob (4.2.0) + activesupport (= 4.2.0) globalid (>= 0.3.0) - activemodel (4.2.0.rc2) - activesupport (= 4.2.0.rc2) + activemodel (4.2.0) + activesupport (= 4.2.0) builder (~> 3.1) - activerecord (4.2.0.rc2) - activemodel (= 4.2.0.rc2) - activesupport (= 4.2.0.rc2) + activerecord (4.2.0) + activemodel (= 4.2.0) + activesupport (= 4.2.0) arel (~> 6.0) - activesupport (4.2.0.rc2) - i18n (>= 0.7.0.beta1, < 0.8) + activesupport (4.2.0) + i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) - thread_safe (~> 0.1) + thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - addressable (2.3.6) + addressable (2.3.7) arel (6.0.0) - barber (0.5.0) + barber (0.6.0) ember-source execjs handlebars-source (>= 1.0.0.rc.4) - barber-emblem (0.1.1) + barber-emblem (0.1.2) barber (>= 0.4.1) emblem-source - bcrypt (3.1.9) + bcrypt (3.1.10) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) - bootstrap-sass (2.3.2.2) - sass (~> 3.2) - bourbon (4.0.2) - sass (~> 3.3) + bourbon (4.2.0) + sass (~> 3.4) thor builder (3.2.2) capistrano (3.3.5) @@ -120,7 +118,7 @@ GEM i18n rake (>= 10.0.0) sshkit (~> 1.3) - capistrano-bundler (1.1.3) + capistrano-bundler (1.1.4) capistrano (~> 3.1) sshkit (~> 1.2) capistrano-local-precompile (0.0.2) @@ -138,7 +136,7 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) - capybara-screenshot (1.0.3) + capybara-screenshot (1.0.5) capybara (>= 1.0, < 3) colored launchy @@ -155,7 +153,7 @@ GEM coffee-script (2.3.0) coffee-script-source execjs - coffee-script-source (1.8.0) + coffee-script-source (1.9.0) colored (1.2) colorize (0.7.5) cookiejar (0.3.2) @@ -178,80 +176,82 @@ GEM eventmachine (>= 1.0.0.beta.4) email_validator (1.5.0) activemodel - ember-data-source (1.0.0.beta.12) - ember-source - ember-rails (0.15.1) + ember-data-source (1.0.0.beta.14.1) + ember-source (~> 1.8) + ember-rails (0.16.3) active_model_serializers - barber (>= 0.4.1) + barber (>= 0.6.0) ember-data-source (>= 1.0.0.beta.5) ember-source (>= 1.1.0) execjs (>= 1.2) - handlebars-source (> 1.0.0) + handlebars-source (> 1.0.0, < 3) jquery-rails (>= 1.0.17) railties (>= 3.1) ember-source (1.8.1) handlebars-source (~> 1.0) + ember-validations-rails (1.0.0) + railties ember_script (0.0.5) ember_script-source (>= 0.0.2) execjs tilt ember_script-source (0.0.14) - emblem-rails (0.2.1) + emblem-rails (0.2.2) barber-emblem (~> 0.1.1) ember-rails (>= 0.14.0) - emblem-source (0.3.17) + emblem-source (0.3.18) erubis (2.7.0) - eventmachine (1.0.4) - execjs (2.2.2) + eventmachine (1.0.7) + execjs (2.3.0) factory_girl (4.5.0) activesupport (>= 3.0.0) factory_girl_rails (4.5.0) factory_girl (~> 4.5.0) railties (>= 3.0.0) - faraday (0.9.0) + faraday (0.9.1) multipart-post (>= 1.2, < 3) - faye (1.0.3) + faye (1.1.0) cookiejar (>= 0.3.0) em-http-request (>= 0.3.0) eventmachine (>= 0.12.0) - faye-websocket (>= 0.7.0) + faye-websocket (>= 0.9.1) multi_json (>= 1.0.0) rack (>= 1.0.0) - websocket-driver (>= 0.3.0) + websocket-driver (>= 0.5.1) faye-websocket (0.9.2) eventmachine (>= 0.12.0) websocket-driver (>= 0.5.1) ffi (1.9.6) - font-awesome-rails (4.2.0.0) + font-awesome-rails (4.3.0.0) railties (>= 3.2, < 5.0) - foundation-rails (5.5.0.0) + foundation-rails (5.5.1.0) railties (>= 3.1.0) - sass (>= 3.2.0, < 3.4) + sass (>= 3.3.0, < 3.5) fuubar (2.0.0) rspec (~> 3.0) ruby-progressbar (~> 1.4) gherkin (2.12.2) multi_json (~> 1.3) - globalid (0.3.0) + globalid (0.3.3) activesupport (>= 4.1.0) handlebars-source (1.3.0) - hashie (3.3.2) + hashie (3.4.0) hike (1.2.3) http_parser.rb (0.6.0) i18n (0.7.0) iso_country_codes (0.6.1) - jquery-rails (4.0.1) + jquery-rails (4.0.3) rails-dom-testing (~> 1.0) - railties (>= 4.2.0.beta) + railties (>= 4.2.0) thor (>= 0.14, < 2.0) jquery-ui-rails (5.0.3) railties (>= 3.2.16) - js-routes (0.9.9) + js-routes (1.0.0) railties (>= 3.2) sprockets-rails json (1.8.2) - jwt (1.2.0) - kaminari (0.16.1) + jwt (1.2.1) + kaminari (0.16.3) actionpack (>= 3.0.0) activesupport (>= 3.0.0) launchy (2.4.3) @@ -264,7 +264,7 @@ GEM mime-types (>= 1.16, < 3) method_source (0.8.2) mime-types (1.25.1) - mini_magick (4.0.1) + mini_magick (4.0.4) mini_portile (0.6.2) minitest (5.5.1) multi_json (1.10.1) @@ -272,8 +272,8 @@ GEM multipart-post (2.0.0) net-scp (1.2.1) net-ssh (>= 2.6.5) - net-ssh (2.9.1) - nokogiri (1.6.5) + net-ssh (2.9.2) + nokogiri (1.6.6.2) mini_portile (~> 0.6.0) oauth2 (1.0.0) faraday (>= 0.8, < 0.10) @@ -304,24 +304,24 @@ GEM coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) - pry-rails (0.3.2) + pry-rails (0.3.3) pry (>= 0.9.10) - quiet_assets (1.0.3) + quiet_assets (1.1.0) railties (>= 3.1, < 5.0) rack (1.6.0) - rack-cors (0.3.0) + rack-cors (0.3.1) rack-test (0.6.3) rack (>= 1.0) - rails (4.2.0.rc2) - actionmailer (= 4.2.0.rc2) - actionpack (= 4.2.0.rc2) - actionview (= 4.2.0.rc2) - activejob (= 4.2.0.rc2) - activemodel (= 4.2.0.rc2) - activerecord (= 4.2.0.rc2) - activesupport (= 4.2.0.rc2) + rails (4.2.0) + actionmailer (= 4.2.0) + actionpack (= 4.2.0) + actionview (= 4.2.0) + activejob (= 4.2.0) + activemodel (= 4.2.0) + activerecord (= 4.2.0) + activesupport (= 4.2.0) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.0.rc2) + railties (= 4.2.0) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) @@ -331,52 +331,53 @@ GEM rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.1) loofah (~> 2.0) - railties (4.2.0.rc2) - actionpack (= 4.2.0.rc2) - activesupport (= 4.2.0.rc2) + railties (4.2.0) + actionpack (= 4.2.0) + activesupport (= 4.2.0) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rake (10.4.2) rdoc (4.2.0) - json (~> 1.4) - responders (2.0.2) - railties (>= 4.2.0.alpha, < 5) + responders (2.1.0) + railties (>= 4.2.0, < 5) rest-client (1.6.8) mime-types (~> 1.16) rdoc (>= 2.4.2) rqrcode (0.4.2) - rspec (3.1.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-core (3.1.7) - rspec-support (~> 3.1.0) - rspec-expectations (3.1.2) + rspec (3.2.0) + rspec-core (~> 3.2.0) + rspec-expectations (~> 3.2.0) + rspec-mocks (~> 3.2.0) + rspec-core (3.2.0) + rspec-support (~> 3.2.0) + rspec-expectations (3.2.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.1.0) + rspec-support (~> 3.2.0) rspec-its (1.1.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.1.3) - rspec-support (~> 3.1.0) - rspec-rails (3.1.0) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-support (~> 3.1.0) - rspec-support (3.1.2) + rspec-mocks (3.2.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.2.0) + rspec-rails (3.2.0) + actionpack (>= 3.0, <= 4.2) + activesupport (>= 3.0, <= 4.2) + railties (>= 3.0, <= 4.2) + rspec-core (~> 3.2.0) + rspec-expectations (~> 3.2.0) + rspec-mocks (~> 3.2.0) + rspec-support (~> 3.2.0) + rspec-support (3.2.1) ruby-progressbar (1.7.1) - rubyzip (1.1.6) + rubyzip (1.1.7) safe_yaml (1.0.4) - sass (3.3.14) - sass-rails (5.0.0.beta1) + sass (3.4.11) + sass-rails (5.0.1) railties (>= 4.0.0, < 5.0) - sass (~> 3.2) - sprockets (~> 2.12) + sass (~> 3.1) + sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) + tilt (~> 1.1) selenium-webdriver (2.44.0) childprocess (~> 0.5) multi_json (~> 1.0) @@ -387,7 +388,7 @@ GEM multi_json (~> 1.0) simplecov-html (~> 0.8.0) simplecov-html (0.8.0) - slim (3.0.1) + slim (3.0.2) temple (~> 0.7.3) tilt (>= 1.3.3, < 2.1) slim-rails (3.0.1) @@ -397,7 +398,7 @@ GEM railties (>= 3.1, < 5.0) slim (~> 3.0) slop (3.6.0) - spring (1.2.0) + spring (1.3.1) spring-commands-rspec (1.0.4) spring (>= 0.9.1) sprockets (2.12.3) @@ -405,7 +406,7 @@ GEM multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.2.2) + sprockets-rails (2.2.4) actionpack (>= 3.0) activesupport (>= 3.0) sprockets (>= 2.8, < 4.0) @@ -424,7 +425,7 @@ GEM rspec (>= 2.14.0, < 4.0) tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (2.6.0) + uglifier (2.7.0) execjs (>= 0.3.0) json (>= 1.8.0) warden (1.2.3) @@ -450,8 +451,7 @@ PLATFORMS DEPENDENCIES active_decorator active_model_serializers (= 0.9.0) - bootstrap-sass (~> 2.3) - bourbon (= 4.0.2) + bourbon capistrano (~> 3.0) capistrano-local-precompile capistrano-rails (~> 1.1) @@ -464,6 +464,7 @@ DEPENDENCIES devise_simply_stored! ember-rails ember-source (= 1.8.1) + ember-validations-rails ember_script-rails! emblem-rails factory_girl_rails @@ -485,11 +486,11 @@ DEPENDENCIES pry-rails quiet_assets rack-cors - rails (= 4.2.0.rc2) + rails (= 4.2.0) rqrcode rspec-its rspec-rails - sass-rails (= 5.0.0.beta1) + sass-rails (~> 5.0.0) selenium-webdriver simplecov simply_stored! diff --git a/Models.dia b/Models.dia index c29c1de7..ec9c700c 100644 Binary files a/Models.dia and b/Models.dia differ diff --git a/app/assets/javascripts/supplier/app/application.js.coffee b/app/assets/javascripts/supplier/app/application.js.coffee index 67d71ab7..d6e29874 100644 --- a/app/assets/javascripts/supplier/app/application.js.coffee +++ b/app/assets/javascripts/supplier/app/application.js.coffee @@ -2,12 +2,13 @@ #= require handlebars #= require ember #= require ember-data + #= require ember-validations #= require_directory ./modifications #= require shared-ember-helpers/all #= require ./app #= require ./controllers/modals/base_controller #= require ion.sound #= require_tree . -@$assets_path = '/assets/'; +@$assets_path = '/assets/' @EmberENV = {FEATURES: {'query-params-new': true}} @$days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'] diff --git a/app/assets/javascripts/supplier/app/components/menu_product_component.js.coffee b/app/assets/javascripts/supplier/app/components/menu_product_component.js.coffee index 52de3720..10abad03 100644 --- a/app/assets/javascripts/supplier/app/components/menu_product_component.js.coffee +++ b/app/assets/javascripts/supplier/app/components/menu_product_component.js.coffee @@ -25,8 +25,7 @@ App.MenuProductComponent = Ember.Component.extend save: -> return unless @get('product.isValid') if @get('product.isDirty') - @get('product').save().then((-> true), (-> true)) - @set 'editMode', false + @get('product').save().then((=> @set 'editMode', false), (-> true)) destroyProduct: (product)-> if product.get('isNew') product.deleteRecord() diff --git a/app/assets/javascripts/supplier/app/controllers/application_controller.js.coffee b/app/assets/javascripts/supplier/app/controllers/application_controller.js.coffee index 98ba449d..f80058ce 100644 --- a/app/assets/javascripts/supplier/app/controllers/application_controller.js.coffee +++ b/app/assets/javascripts/supplier/app/controllers/application_controller.js.coffee @@ -24,3 +24,7 @@ App.ApplicationController = Ember.Controller.extend markSupplierOpen: -> return unless supplier = @get('supplier') supplier.open_the_place() + showSupplierStatusInfo: -> + @modal 'supplier_status_info', + model: @get('supplier') + title_path: 'supplier_status_info.title' diff --git a/app/assets/javascripts/supplier/app/controllers/employees_index_controller.js.coffee b/app/assets/javascripts/supplier/app/controllers/employees_index_controller.js.coffee new file mode 100644 index 00000000..b4b0e3a5 --- /dev/null +++ b/app/assets/javascripts/supplier/app/controllers/employees_index_controller.js.coffee @@ -0,0 +1,16 @@ +App.EmployeesIndexController = Ember.ArrayController.extend + employees: (-> @get('model').sortBy('name')).property('model.@each.name') + actions: + newEmployee: -> + employee = @store.createRecord('employee') + @modal 'employee_edit', + model: employee + close: -> employee.deleteRecord() + editEmployee: (employee)-> + @modal 'employee_edit', + model: employee + close: -> employee.rollback() + destroyEmployee: (employee)-> + @modal 'confirm', + title: t('employee.destroy.modal.title', employee.serialize()) + ok: -> employee.destroyRecord() diff --git a/app/assets/javascripts/supplier/app/controllers/menu_controller.js.coffee b/app/assets/javascripts/supplier/app/controllers/menu_controller.js.coffee index bacc30ca..713c5714 100644 --- a/app/assets/javascripts/supplier/app/controllers/menu_controller.js.coffee +++ b/app/assets/javascripts/supplier/app/controllers/menu_controller.js.coffee @@ -3,7 +3,7 @@ App.MenuController = Ember.ObjectController.extend product_code_filter: '' product_categories: (-> @store.all('product_category')).property() filter: null - sorted_product_categories: (-> + sorted_product_categories: (-> list = @get('product_categories') if filter_day = @get('filter.day') list = list.filterBy "active_on_#{filter_day}" diff --git a/app/assets/javascripts/supplier/app/controllers/modals/base_controller.js.coffee b/app/assets/javascripts/supplier/app/controllers/modals/base_controller.js.coffee index dbc06fac..9472580f 100644 --- a/app/assets/javascripts/supplier/app/controllers/modals/base_controller.js.coffee +++ b/app/assets/javascripts/supplier/app/controllers/modals/base_controller.js.coffee @@ -7,14 +7,15 @@ translation_params = {} if model = @get('model') translation_params = model.serialize() if model.serialize - return new Ember.Handlebars.SafeString(tspan(@title_path, translation_params)) if @title_path + + return tspan(@title_path, translation_params).htmlSafe() if @title_path # return translated title_path if directly set by options - return new Ember.Handlebars.SafeString(tspan(@get('modal_options.title_path'), translation_params)) if @get('modal_options.title_path') + return tspan(@get('modal_options.title_path'), translation_params).htmlSafe() if @get('modal_options.title_path') # infer title path based on controller name App.modals.AddSectionController => add_section underscored = `this.constructor.toString().substr(11).replace(/Controller$/, '').underscore()` # find translated title or humanize the controller name if convention_translation = ttry("modal.#{underscored}.title", translation_params) - new Ember.Handlebars.SafeString(tspan(@get("modal.#{underscored}.title"), translation_params)) + tspan(@get("modal.#{underscored}.title"), translation_params).htmlSafe() else underscored.capitalize().replace(/_/, ' ') ).property('model.id') @@ -35,8 +36,9 @@ @send 'closeModal' unless @preventClose confirm: -> @send('ok') save: -> - @get('model').save() - @send 'closeModal' unless @preventClose + if @get('model.isValid') + @get('model').save().then((=> @send 'closeModal' ), (-> true)) + #@send 'closeModal' unless @preventClose destroy: -> @modal 'confirm', title_path: @get('modal_options.destroy_text_path') || 'general.destroy.text' diff --git a/app/assets/javascripts/supplier/app/controllers/modals/section_arrange_tables_controller.js.coffee b/app/assets/javascripts/supplier/app/controllers/modals/section_arrange_tables_controller.js.coffee index cd2ce74d..977b3623 100644 --- a/app/assets/javascripts/supplier/app/controllers/modals/section_arrange_tables_controller.js.coffee +++ b/app/assets/javascripts/supplier/app/controllers/modals/section_arrange_tables_controller.js.coffee @@ -1,35 +1,50 @@ App.modals.SectionArrangeTablesController = App.modals.BaseController.extend + title_path: 'section.arrange_tables.modal.title' arrange_type: 'distributed' # can be distributed, by_row or by_column row_count: 2 column_count: 2 + alert_message: '' #isDistributed: ~> @arrange_type is 'distributed' #isByRow: ~> @arrange_type is 'by_row' #isByColumn: ~> @arrange_type is 'by_column' isDistributed: (->@get('arrange_type') is 'distributed').property('arrange_type') isByRow: (->@get('arrange_type') is 'by_row').property('arrange_type') isByColumn: (->@get('arrange_type') is 'by_column').property('arrange_type') + canArrangeTables: (-> + unless parseFloat(@get('model.width')) > 0 and parseFloat(@get('model.height')) > 0 + @set 'alert_message', t('section.arrange_tables.modal.cannot_arrange') + return false + @set 'alert_message', '' + true + ).property('model.width', 'model.height') actions: arrangeTables: -> + return unless @isValid() Ember.$.post Routes.arrange_tables_suppliers_section_path(@get('model.id')), option: @get('arrange_type') row_count: @get('row_count') column_count: @get('column_count') , (result,state,xhr)=> - #@store.pushPayload 'table', result @store.pushPayload result @send 'close' - - ##TODO remove followin code if Ember pushPayload is working - ##properly with associations - #section_id = @get('model.id') - #tables_that_should_be_in_section = @store.all('table').filter((t)->t.get('section.id') == section_id) - #current_table_ids = @get('model.tables').mapProperty('id') - #for table in tables_that_should_be_in_section.toArray() - #@get('model.tables').pushObject(table) unless table.get('id') in current_table_ids - ##TODO it still does not work for the second client side action, - ##soo the good old reload for now for the failing case - #window.location.reload() if result.tables.length != tables_that_should_be_in_section.toArray().length return - makeDistributed: -> @set 'arrange_type', 'distributed' - makeByRow: -> @set 'arrange_type', 'by_row' - makeByColumn: -> @set 'arrange_type', 'by_column' + makeDistributed: -> + @set 'arrange_type', 'distributed' + @set 'alert_message', '' + makeByRow: -> + @set 'arrange_type', 'by_row' + @set 'alert_message', '' + makeByColumn: -> + @set 'arrange_type', 'by_column' + @set 'alert_message', '' + isValid: -> + switch @get('arrange_type') + when 'by_row' + if parseInt(@get('row_count')) < 1 + @set 'alert_message', "Must at least be 1" + return false + when 'by_column' + if parseInt(@get('column_count')) < 1 + @set 'alert_message', "Must at least be 1" + return false + true diff --git a/app/assets/javascripts/supplier/app/controllers/section_controller.js.coffee b/app/assets/javascripts/supplier/app/controllers/section_controller.js.coffee index feee3264..1db748cc 100644 --- a/app/assets/javascripts/supplier/app/controllers/section_controller.js.coffee +++ b/app/assets/javascripts/supplier/app/controllers/section_controller.js.coffee @@ -6,6 +6,9 @@ App.SectionController = Ember.ObjectController.extend finishEditable: -> @set('editmode', false) @get('model').save() + rollbackEditable: -> + @get('model').rollback() + @set('editmode', false) addSection: -> @modal 'add_section', model: @get('model') addTables: -> @modal 'section_add_tables', model: @get('model') arrangeTables: -> @modal 'section_arrange_tables', model: @get('model') diff --git a/app/assets/javascripts/supplier/app/helpers/errors.js.coffee b/app/assets/javascripts/supplier/app/helpers/errors.js.coffee index d505270d..44afebc8 100644 --- a/app/assets/javascripts/supplier/app/helpers/errors.js.coffee +++ b/app/assets/javascripts/supplier/app/helpers/errors.js.coffee @@ -3,10 +3,13 @@ Ember.Handlebars.helper 'errors', (errors, params..., options)-> result = "" model_name = options.hash.includeAttribute for error in errors - if model_name - attribute = ttry("attributes.#{model_name}.#{error.attribute}") - message = "#{attribute} #{error.message}" + if typeof error is "string" + message = error else - message = error.message + if model_name + attribute = ttry("attributes.#{model_name}.#{error.attribute}") + message = "#{attribute} #{error.message}" + else + message = error.message result += "
#{message}
" - new Ember.Handlebars.SafeString(result) + result.htmlSafe() diff --git a/app/assets/javascripts/supplier/app/models/employee.js.coffee b/app/assets/javascripts/supplier/app/models/employee.js.coffee new file mode 100644 index 00000000..3fb785bb --- /dev/null +++ b/app/assets/javascripts/supplier/app/models/employee.js.coffee @@ -0,0 +1,8 @@ +attr = DS.attr +App.Employee= DS.Model.extend Ember.Validations.Mixin, + name: attr 'string' + email: attr 'string' + + validations: + name: + presence: true diff --git a/app/assets/javascripts/supplier/app/models/product.js.coffee b/app/assets/javascripts/supplier/app/models/product.js.coffee index 4fb40202..87dd0add 100644 --- a/app/assets/javascripts/supplier/app/models/product.js.coffee +++ b/app/assets/javascripts/supplier/app/models/product.js.coffee @@ -17,7 +17,7 @@ App.Product = DS.Model.extend image ).property('image') - isValid: (-> + isValid: (-> return false unless price = @get('price') return false unless "#{price}".match(/^[+-]?\d+(\.?\d?\d)?$/) true diff --git a/app/assets/javascripts/supplier/app/router.js.coffee b/app/assets/javascripts/supplier/app/router.js.coffee index 017526bb..1b439f15 100644 --- a/app/assets/javascripts/supplier/app/router.js.coffee +++ b/app/assets/javascripts/supplier/app/router.js.coffee @@ -12,6 +12,8 @@ App.Router.map -> @resource 'table', path: ':table_id' @resource 'lists', -> @resource 'list', path: ':list_id' + @resource 'employees', -> + @resource 'employee', path: ':employee_id' @route 'orders_display' # chromecast etc @route 'menu' @route 'settings' diff --git a/app/assets/javascripts/supplier/app/routes/employees_route.js.coffee b/app/assets/javascripts/supplier/app/routes/employees_route.js.coffee new file mode 100644 index 00000000..a386c344 --- /dev/null +++ b/app/assets/javascripts/supplier/app/routes/employees_route.js.coffee @@ -0,0 +1,2 @@ +App.EmployeesRoute = Ember.Route.extend + model: -> @store.find 'employee' diff --git a/app/assets/javascripts/supplier/app/templates/application.emblem b/app/assets/javascripts/supplier/app/templates/application.emblem index 3927fda7..421438f1 100644 --- a/app/assets/javascripts/supplier/app/templates/application.emblem +++ b/app/assets/javascripts/supplier/app/templates/application.emblem @@ -1,4 +1,5 @@ = partial "global/top_menu" += partial "global/side_menu" .main-section= outlet = view flash_message = outlet modal diff --git a/app/assets/javascripts/supplier/app/templates/employees.emblem b/app/assets/javascripts/supplier/app/templates/employees.emblem new file mode 100644 index 00000000..26191258 --- /dev/null +++ b/app/assets/javascripts/supplier/app/templates/employees.emblem @@ -0,0 +1 @@ += outlet diff --git a/app/assets/javascripts/supplier/app/templates/employees/index.emblem b/app/assets/javascripts/supplier/app/templates/employees/index.emblem new file mode 100644 index 00000000..ca88805f --- /dev/null +++ b/app/assets/javascripts/supplier/app/templates/employees/index.emblem @@ -0,0 +1,21 @@ +.row: .small-12.columns + h1=t 'models.plural.employee' + if employees + table.table + thead + tr + th.name=t 'attributes.employee.name' + th.email=t 'attributes.employee.email' + th.actions=t 'helpers.actions.title' + tbody + each employee in employees + tr + td: link-to 'employee' employee: span= employee.name + td.email + = employee.email + = errors employee.errors.email + td.actions + a.table-edit{ action 'editEmployee' employee }: span + a.table-destroy{ action 'destroyEmployee' employee }: span + .form-actions + a.form-action-new.new-employee-button{action "newEmployee"}= t 'employee.new_button' diff --git a/app/assets/javascripts/supplier/app/templates/global/_side_menu.emblem b/app/assets/javascripts/supplier/app/templates/global/_side_menu.emblem new file mode 100644 index 00000000..600eb0ac --- /dev/null +++ b/app/assets/javascripts/supplier/app/templates/global/_side_menu.emblem @@ -0,0 +1,16 @@ +aside.side-menu + ul + li.title: h3 Menu + li.supplier-name= supplier.name + if supplier.open + li: a.supplier-close-shop{action "markSupplierClosed"}= t 'supplier.close_for_orders' + else + li: a.supplier-open-shop{action "markSupplierOpen"}= t 'supplier.open_for_orders' + li + =link-to 'settings' class="supplier-settings-link" + span.settings-icon + span= t 'supplier.settings' + li class="supplier-sign-out-link" + a{action "signOut"} + span.sign-out-icon + = t 'supplier.sign_out' diff --git a/app/assets/javascripts/supplier/app/templates/global/_top_menu.emblem b/app/assets/javascripts/supplier/app/templates/global/_top_menu.emblem index 02531814..6bcdaf19 100644 --- a/app/assets/javascripts/supplier/app/templates/global/_top_menu.emblem +++ b/app/assets/javascripts/supplier/app/templates/global/_top_menu.emblem @@ -13,7 +13,9 @@ header.top-menu = t 'models.plural.table' = link-to "lists" class="top-menu-lists" = t 'models.plural.list' - .extra-info + = link-to "employees" class="top-menu-employees" + = t 'models.plural.employee' + .extra-info{action "showSupplierStatusInfo"} .supplier-info-row .counter.supplier-orders-placed-count span.supplier-orders-placed-count-number= supplier.orders_placed_count @@ -22,14 +24,3 @@ header.top-menu .counter.supplier-orders-in-process-count span.supplier-orders-in-process-count-number= supplier.orders_in_process_count span.orders-in-process-count-icon -aside.side-menu - ul - li.title: h3 Menu - li.supplier-name= supplier.name - if supplier.open - li: a.supplier-close-shop{action "markSupplierClosed"}= t 'supplier.close_for_orders' - else - li: a.supplier-open-shop{action "markSupplierOpen"}= t 'supplier.open_for_orders' - = link-to "settings" class="supplier-settings-link" - = t 'supplier.settings' - li class="supplier-sign-out-link": a{action "signOut"}= t 'supplier.sign_out' diff --git a/app/assets/javascripts/supplier/app/templates/modals/employee_edit.emblem b/app/assets/javascripts/supplier/app/templates/modals/employee_edit.emblem new file mode 100644 index 00000000..a4857cd9 --- /dev/null +++ b/app/assets/javascripts/supplier/app/templates/modals/employee_edit.emblem @@ -0,0 +1,14 @@ +p=t 'employee.edit.modal.body_header' +.form-row.name + .form-label=t 'attributes.employee.name' + .form-field + = input valueBinding="model.name" + = errors model.errors.name +.form-row.name + .form-label=t 'attributes.employee.email' + .form-field + = input type="email" valueBinding="model.email" + = errors model.errors.email +hr +button.modal-close{action "close"}=t 'section.add_employees.modal.close_button' +button.modal-confirm.right{action "save"}=t 'section.add_employees.modal.add_button' diff --git a/app/assets/javascripts/supplier/app/templates/modals/section_arrange_tables.emblem b/app/assets/javascripts/supplier/app/templates/modals/section_arrange_tables.emblem index da4dd4c9..88e36791 100644 --- a/app/assets/javascripts/supplier/app/templates/modals/section_arrange_tables.emblem +++ b/app/assets/javascripts/supplier/app/templates/modals/section_arrange_tables.emblem @@ -1,52 +1,30 @@ -.modal-alert== alert_message p=t 'section.arrange_tables.modal.body_header' -.arrange-type-buttons - if isDistributed - span.arrange-tables-current-type.distributed=t 'section.arrange_tables.modal.distributed.title' - else - button.arrange-tables-type-button.distributed{action "makeDistributed"}=t 'section.arrange_tables.modal.distributed.title' - if isByRow - span.arrange-tables-current-type.by_row=t 'section.arrange_tables.modal.by_row.title' - else - button.arrange-tables-type-button.by_row{action "makeByRow"}=t 'section.arrange_tables.modal.by_row.title' - if isByColumn - span.arrange-tables-current-type.by_column=t 'section.arrange_tables.modal.by_column.title' - else - button.arrange-tables-type-button.by_column{action "makeByColumn"}=t 'section.arrange_tables.modal.by_column.title' -.arrange-content - if isDistributed - ==t 'section.arrange_tables.modal.distributed.explanation' - if isByRow - ==t 'section.arrange_tables.modal.by_row.before_field' - App.NumberField valueBinding="row_count" - ==t 'section.arrange_tables.modal.by_row.after_field' - if isByColumn - ==t 'section.arrange_tables.modal.by_column.before_field' - App.NumberField valueBinding="column_count" - ==t 'section.arrange_tables.modal.by_column.after_field' +if canArrangeTables + .arrange-type-buttons + if isDistributed + span.arrange-tables-current-type.distributed=t 'section.arrange_tables.modal.distributed.title' + else + button.arrange-tables-type-button.distributed{action "makeDistributed"}=t 'section.arrange_tables.modal.distributed.title' + if isByRow + span.arrange-tables-current-type.by_row=t 'section.arrange_tables.modal.by_row.title' + else + button.arrange-tables-type-button.by_row{action "makeByRow"}=t 'section.arrange_tables.modal.by_row.title' + if isByColumn + span.arrange-tables-current-type.by_column=t 'section.arrange_tables.modal.by_column.title' + else + button.arrange-tables-type-button.by_column{action "makeByColumn"}=t 'section.arrange_tables.modal.by_column.title' + .arrange-content + if isDistributed + ==t 'section.arrange_tables.modal.distributed.explanation' + if isByRow + =t 'section.arrange_tables.modal.by_row.before_field' + App.NumberField valueBinding="row_count" + =t 'section.arrange_tables.modal.by_row.after_field' + if isByColumn + =t 'section.arrange_tables.modal.by_column.before_field' + App.NumberField valueBinding="column_count" + =t 'section.arrange_tables.modal.by_column.after_field' hr button.modal-close{action "close"}=t 'section.arrange_tables.modal.close_button' -button.modal-confirm.right{action "arrangeTables"}=t 'section.arrange_tables.modal.arrange_button' - - - /form.form-horizontal - .control-group - label.control-label for='arrange-tables-distributed' data-t='section.arrange_tables.modal.distributed' = t('supplier.section.arrange_tables.modal.distributed') - .controls - input#arrange-tables-distributed type="radio" name="arrange-table-option" checked=true value="distributed" - .control-group - label.control-label for='arrange-tables-by_row' data-t='section.arrange_tables.modal.by_row' = t('supplier.section.arrange_tables.modal.by_row') - .controls - input#arrange-tables-by_row type="radio" name="arrange-table-option" value="by_row" - label for="arrange-tables-by-row-count" data-t='section.arrange_tables.modal.by_row_count' = t('supplier.section.arrange_tables.modal.by_row_count') - input.input-mini#arrange-tables-by-row-count type="text" value=0 - ' - span data-t='models.plural.table' - .control-group - label.control-label for='arrange-tables-by_column' data-t='section.arrange_tables.modal.by_column' = t('supplier.section.arrange_tables.modal.by_column') - .controls - input#arrange-tables-by_column type="radio" name="arrange-table-option" value="by_column" - label for="arrange-tables-by-column-count" data-t='section.arrange_tables.modal.by_column_count' = t('supplier.section.arrange_tables.modal.by_column_count') - input.input-mini#arrange-tables-by-column-count type="text" value=0 - ' - span data-t='models.plural.table' +if canArrangeTables + button.modal-confirm.right{action "arrangeTables"}=t 'section.arrange_tables.modal.arrange_button' diff --git a/app/assets/javascripts/supplier/app/templates/modals/supplier_status_info.emblem b/app/assets/javascripts/supplier/app/templates/modals/supplier_status_info.emblem new file mode 100644 index 00000000..c038af13 --- /dev/null +++ b/app/assets/javascripts/supplier/app/templates/modals/supplier_status_info.emblem @@ -0,0 +1,13 @@ +p== t 'supplier_status_info.header' +.row: .small-12.columns + .counter.supplier-orders-placed-count + = model.orders_placed_count + span.orders-placed-count-icon + = t 'supplier_status_info.orders_placed_count_explanation' count=model.orders_placed_count +.row: .small-12.columns + .counter.supplier-orders-in-process-count + = model.orders_in_process_count + span.orders-in-process-count-icon + = t 'supplier_status_info.orders_in_process_count_explanation' count=model.orders_in_process_count +hr +button.modal-confirm.right{action "close"}= t 'supplier_status_info.close' diff --git a/app/assets/javascripts/supplier/app/templates/section.emblem b/app/assets/javascripts/supplier/app/templates/section.emblem index f37c509b..e7160bb7 100644 --- a/app/assets/javascripts/supplier/app/templates/section.emblem +++ b/app/assets/javascripts/supplier/app/templates/section.emblem @@ -4,33 +4,18 @@ = view "section-tab-header" context=section a.add-section{action "addSection"}: span .section-manage-tables.pull-right + App.DropdownLink title="Action" + ul + li: a{action "addTables"}: span.section-add-tables-icon=t 'section.add_tables.button_label' + li: a{action "arrangeTables"}: span.section-arrange-tables-icon=t 'section.arrange_tables.modal.title' + li: a href="{{route 'qr_codes_suppliers_tables_path' section_id=id}}" target="_blank": span.qr-icon=t 'table.print_qr_codes' + li: a.section-destroy{action "destroySection"}: span.section-remove-icon=t 'helpers.links.destroy' if editmode - /.btn-group - /a.btn.dropdown-toggle data-toggle="dropdown" href="#section-background" - span Background - span.caret - ul#section-background.dropdown-menu - each texture in textures - li - a{ action "setTexture" texture }= texture - /a.tiny.button.dropdown.section-actions-menu-header href="#" data-dropdown="section-action-list" Action - /button.btn.dropdown-toggle data-toggle="dropdown" - span Action - span.caret - App.DropdownLink title="Action" - ul - li - a{action "addTables"}: span.section-add-tables-icon=t 'section.add_tables.button_label' - li - a{action "arrangeTables"}: span.section-arrange-tables-icon=t 'section.arrange_tables.modal.title' - li - a href="{{route 'qr_codes_suppliers_tables_path' section_id=id}}": span.table-qr-codes=t 'tables.qr_codes.link' - li - a.section-destroy{action "destroySection"}: span.section-remove-icon=t 'helpers.links.destroy' = input type="text" valueBinding="title" class="section-edit-title-field" App.NumberField valueBinding="width" class="dimension section-edit-width-field" span.fa.fa-lg.fa-times App.NumberField valueBinding="height" class="dimension section-edit-height-field" + a.section-rollback-button{ action "rollbackEditable" }: span a.section-normal-mode-button{ action "finishEditable" }: span else a.section-edit-mode-button{ action "makeEditable" }: span diff --git a/app/assets/javascripts/supplier/app/templates/sections/index.emblem b/app/assets/javascripts/supplier/app/templates/sections/index.emblem index 3e5eec0a..5a232e3f 100644 --- a/app/assets/javascripts/supplier/app/templates/sections/index.emblem +++ b/app/assets/javascripts/supplier/app/templates/sections/index.emblem @@ -32,8 +32,7 @@ /td.timestamp=time list.created_at td.actions a.section-dashboard-orders{action showDashboardOrders section}: span - a.table-qr-codes{path qr_codes_suppliers_tables section_id=section.id} - span + a.table-qr-codes{path qr_codes_suppliers_tables section_id=section.id} target="_blank": span.qr-icon else .row: .small-12.columns .panel=t 'section.none_found' diff --git a/app/assets/javascripts/supplier/app/templates/settings.emblem b/app/assets/javascripts/supplier/app/templates/settings.emblem index e62a9eff..d56c0d25 100644 --- a/app/assets/javascripts/supplier/app/templates/settings.emblem +++ b/app/assets/javascripts/supplier/app/templates/settings.emblem @@ -1,4 +1,4 @@ -h2=t 'settings.title' +.row: .small-12.columns: h2=t 'settings.title' .form-row .form-label: label=t 'attributes.supplier.name' .form-field: Ember.TextField valueBinding="controller.model.name" classNames="supplier-name" diff --git a/app/assets/javascripts/supplier/app/templates/tables/index.emblem b/app/assets/javascripts/supplier/app/templates/tables/index.emblem index c35b62bb..37f3039c 100644 --- a/app/assets/javascripts/supplier/app/templates/tables/index.emblem +++ b/app/assets/javascripts/supplier/app/templates/tables/index.emblem @@ -6,7 +6,7 @@ tr th=t 'attributes.table.number' th.link=t 'models.section' - th.timestamp= t 'attributes.table.created_at' + /th.timestamp= t 'attributes.table.created_at' th.actions=t 'helpers.actions.title' tbody each table in tables @@ -16,8 +16,13 @@ if table.section = link-to 'section' table.section = table.section.title - td.numeric=time table.created_at + /td.timestamp=time table.created_at td.actions a.table-edit{ action 'editTable' table }: span a.table-destroy{ action 'destroyTable' table }: span - a.button.new-table-button{action "newTable"}= t 'table.new_button' + .form-actions + a.form-action-new.new-table-button{action "newTable"}= t 'table.new_button' + if tables + a.table-qr-codes{path qr_codes_suppliers_tables} target="_blank" + span.qr-icon + = t 'table.print_qr_codes' diff --git a/app/assets/javascripts/supplier/app/views/form_elements/boolean_button_view.js.coffee b/app/assets/javascripts/supplier/app/views/form_elements/boolean_button_view.js.coffee index f3909859..52c08c78 100644 --- a/app/assets/javascripts/supplier/app/views/form_elements/boolean_button_view.js.coffee +++ b/app/assets/javascripts/supplier/app/views/form_elements/boolean_button_view.js.coffee @@ -3,7 +3,7 @@ App.BooleanButtonView = Ember.View.extend href: '#' classNames: "button" # templateName: "form_elements/boolean_switch" - template: Ember.Handlebars.compile "{{view.text}}" + #template: Ember.Handlebars.compile "{{view.text}}" classNameBindings: ['rounded:round', 'active:active:disabled'] text: Ember.computed 'text_path', -> diff --git a/app/assets/javascripts/supplier/app/views/side_menu_item.js.coffee b/app/assets/javascripts/supplier/app/views/side_menu_item.js.coffee new file mode 100644 index 00000000..c1f27970 --- /dev/null +++ b/app/assets/javascripts/supplier/app/views/side_menu_item.js.coffee @@ -0,0 +1,14 @@ +App.SideMenuItemView = Ember.View.extend + classNames: 'menu-list-item' + classNameBindings: ['active'] + click: -> + if @route_param + @get('controller').transitionToRoute(@route, @route_param) + else + @get('controller').transitionToRoute(@route) + active: (-> + if @get('controller.currentPath') == @route then 'active' else '' + ).property('controller.currentPath') + init: -> + @templateName = "side_menu/#{@route}" + @_super() diff --git a/app/assets/javascripts/translations.js.coffee.erb b/app/assets/javascripts/translations.js.coffee.erb index ffc3d14d..ce800d50 100644 --- a/app/assets/javascripts/translations.js.coffee.erb +++ b/app/assets/javascripts/translations.js.coffee.erb @@ -81,7 +81,7 @@ selector = $( selector || document) selector.find(".locale-select").show() selector.find(".locale-select-" + locale).hide() - moment.lang locale + moment.locale locale if selector selector.find("[data-t]").each -> $(this).html t($(this).data("t"), $(this).data("tAttributes")) diff --git a/app/assets/javascripts/user/app/controllers/application_controller.js.coffee b/app/assets/javascripts/user/app/controllers/application_controller.js.coffee index 5cd1df0e..1eb15657 100644 --- a/app/assets/javascripts/user/app/controllers/application_controller.js.coffee +++ b/app/assets/javascripts/user/app/controllers/application_controller.js.coffee @@ -21,6 +21,7 @@ App.ApplicationController = Ember.Controller.extend @set 'notice', '' ).observes('currentPath') events: + notify: (notification) -> @set 'notice', notification.message list_helped: -> @set 'list.needs_help', false list_needs_help: -> @set 'list.needs_help', true # incoming from other users list_is_paid: -> @set 'list.needs_payment', false diff --git a/app/assets/javascripts/user/app/templates/application.emblem b/app/assets/javascripts/user/app/templates/application.emblem index 2260d326..09a67c83 100644 --- a/app/assets/javascripts/user/app/templates/application.emblem +++ b/app/assets/javascripts/user/app/templates/application.emblem @@ -1,74 +1,5 @@ -.top-menu - .top-menu-bar - .menu-content - section.main-buttons - if list.id - link-to 'index' class="top-menu-logo with-list" - = image_tag 'user/logo-small.png' - = view "menu-item" route="active_list" - = view "menu-item" route="table" route_param=list.table.id - = view "menu-item-list-needs-help" - = view "menu-item-list-needs-payment" - else - link-to 'index' class="top-menu-logo without-list" - = image_tag 'user/logo-small.png' - = view "menu-item-scan-qr" - = view "menu-item-product-orders" - if list - .extra-info{action "showSupplierStatusInfo"} - .supplier-info-row - / .supplier-name= list.supplier.name - .table-number - |#  - = list.table.number - .supplier-info-row - .counter.supplier-orders-placed-count - = list.supplier.orders_placed_count - span.orders-placed-count-icon - .supplier-info-row - .counter.supplier-orders-in-process-count - = list.supplier.orders_in_process_count - span.orders-in-process-count-icon -.side-menu - .toggle-side-menu: span - ul - li.title: h3 Menu - li - = link-to 'index' - span Home - li - a{action "scanQr" bubbles=false} - span.scan-qr-icon - span Scan QR - if list.id - li - =link-to 'table' list.table.id class="side-menu-list-products" - span.fa.fa-cutlery - span.fa.fa-glass - = t 'list_products.title' - li - =link-to 'active_list' class="side-menu-active-list" - span.active-list-icon - span= t 'active_list.title' - if list.join_requests - li - =link-to 'join_requests' - span= t 'models.plural.join_request' - li - =link-to 'lists' class="side-menu-lists" - span= t 'models.plural.list' - li - =link-to 'settings' - span.settings-icon - span= t 'settings.title' - li - =link-to 'about' class="side-menu-about" - span.about-mozo-icon - span=t 'about.title' - li.hide - a{action "openDebugger"} - span.fa.fa-wrench.fa-lg - span Debugger += partial "global/top_menu" += partial "global/side_menu" .main-section .main-section-content if notice diff --git a/app/assets/javascripts/user/app/templates/global/_side_menu.emblem b/app/assets/javascripts/user/app/templates/global/_side_menu.emblem new file mode 100644 index 00000000..971da8bb --- /dev/null +++ b/app/assets/javascripts/user/app/templates/global/_side_menu.emblem @@ -0,0 +1,40 @@ +.side-menu + .toggle-side-menu: span + ul + li.title: h3 Menu + li + = link-to 'index' + span Home + li + a{action "scanQr" bubbles=false} + span.scan-qr-icon + span Scan QR + if list.id + li + =link-to 'table' list.table.id class="side-menu-list-products" + span.fa.fa-cutlery + span.fa.fa-glass + = t 'list_products.title' + li + =link-to 'active_list' class="side-menu-active-list" + span.active-list-icon + span= t 'active_list.title' + if list.join_requests + li + =link-to 'join_requests' + span= t 'models.plural.join_request' + li + =link-to 'lists' class="side-menu-lists" + span= t 'models.plural.list' + li + =link-to 'settings' + span.settings-icon + span= t 'settings.title' + li + =link-to 'about' class="side-menu-about" + span.about-mozo-icon + span=t 'about.title' + li.hide + a{action "openDebugger"} + span.fa.fa-wrench.fa-lg + span Debugger diff --git a/app/assets/javascripts/user/app/templates/global/_top_menu.emblem b/app/assets/javascripts/user/app/templates/global/_top_menu.emblem new file mode 100644 index 00000000..7ed1ead7 --- /dev/null +++ b/app/assets/javascripts/user/app/templates/global/_top_menu.emblem @@ -0,0 +1,31 @@ +.top-menu + .top-menu-bar + .menu-content + section.main-buttons + if list.id + link-to 'index' class="top-menu-logo with-list" + = image_tag 'user/logo-small.png' + = view "menu-item" route="active_list" + = view "menu-item" route="table" route_param=list.table.id + = view "menu-item-list-needs-help" + = view "menu-item-list-needs-payment" + else + link-to 'index' class="top-menu-logo without-list" + = image_tag 'user/logo-small.png' + = view "menu-item-scan-qr" + = view "menu-item-product-orders" + if list + .extra-info{action "showSupplierStatusInfo"} + .supplier-info-row + / .supplier-name= list.supplier.name + .table-number + |#  + = list.table.number + .supplier-info-row + .counter.supplier-orders-placed-count + = list.supplier.orders_placed_count + span.orders-placed-count-icon + .supplier-info-row + .counter.supplier-orders-in-process-count + = list.supplier.orders_in_process_count + span.orders-in-process-count-icon diff --git a/app/assets/stylesheets/supplier/foundation1/_form_actions.css.sass b/app/assets/stylesheets/supplier/foundation1/_form_actions.css.sass index 878cab0d..8ff1a78c 100644 --- a/app/assets/stylesheets/supplier/foundation1/_form_actions.css.sass +++ b/app/assets/stylesheets/supplier/foundation1/_form_actions.css.sass @@ -7,7 +7,7 @@ +button($bg: $button-index-color, $padding: $button-sml) margin-right: $button-margin &.form-action-new - +button($bg: $button-new-color, $padding: $button-sml) + +button($padding: $button-sml) margin-right: $button-margin &.form-action-edit +button($bg: $button-edit-color, $padding: $button-sml) diff --git a/app/assets/stylesheets/supplier/foundation1/_foundation_and_overrides.css.sass b/app/assets/stylesheets/supplier/foundation1/_foundation_and_overrides.css.sass index ddaf5f54..2eb43aaa 100644 --- a/app/assets/stylesheets/supplier/foundation1/_foundation_and_overrides.css.sass +++ b/app/assets/stylesheets/supplier/foundation1/_foundation_and_overrides.css.sass @@ -1258,8 +1258,8 @@ $alert-color: #ee3e41 $button-margin: rem-calc(10) $button-qr-code-color: #555 $button-index-color: $secondary-color -$button-new-color: #afa -$button-edit-color: #ffa -$button-destroy-color: #faa +$button-new-color: $primary-color +$button-edit-color: $warning-color +$button-destroy-color: $alert-color $button-submit-color: $primary-color $button-cancel-color: $secondary-color diff --git a/app/assets/stylesheets/supplier/foundation1/_qsections.css.sass b/app/assets/stylesheets/supplier/foundation1/_qsections.css.sass index 3523e35d..49060c69 100644 --- a/app/assets/stylesheets/supplier/foundation1/_qsections.css.sass +++ b/app/assets/stylesheets/supplier/foundation1/_qsections.css.sass @@ -1,20 +1,21 @@ .section-edit-mode-button - +button - margin: 0 - padding: 2px + margin-left: 5px span @extend .fa @extend .fa-lg @extend .fa-edit .section-normal-mode-button - +button - margin: 0 - padding: 2px - margin-left: 8px + margin-left: 5px span @extend .fa @extend .fa-lg @extend .fa-save +.section-rollback-button + margin-left: 5px + span + @extend .fa + @extend .fa-lg + @extend .fa-undo .arrange-tables-type-button +button($bg: $secondary-color, $padding: $button-tny) .arrange-tables-current-type @@ -31,7 +32,7 @@ .section-manage-tables .dropdown-container margin-right: 10px - $icon-right-margin: 8px + $icon-right-margin: 12px ul list-style: none margin: 0 @@ -44,7 +45,7 @@ padding: 4px 7px &:hover background-color: #ddd - span.table-qr-codes + span.qr-icon margin-right: $icon-right-margin .section-destroy color: $alert-color diff --git a/app/assets/stylesheets/supplier/foundation1/components/_forms.css.sass b/app/assets/stylesheets/supplier/foundation1/components/_forms.css.sass index f6ad23bc..ea786eec 100644 --- a/app/assets/stylesheets/supplier/foundation1/components/_forms.css.sass +++ b/app/assets/stylesheets/supplier/foundation1/components/_forms.css.sass @@ -25,6 +25,8 @@ +grid-column($columns: 9, $last-column:true) &.half +grid-column(6) + .error + color: $alert-color &.form-actions padding-top: 12px body diff --git a/app/assets/stylesheets/supplier/foundation1/components/_menu_side.css.sass b/app/assets/stylesheets/supplier/foundation1/components/_menu_side.css.sass index deeaee0e..43ce7f31 100644 --- a/app/assets/stylesheets/supplier/foundation1/components/_menu_side.css.sass +++ b/app/assets/stylesheets/supplier/foundation1/components/_menu_side.css.sass @@ -20,6 +20,15 @@ aside.side-menu .title border-bottom: 1px solid #aaa margin-bottom: 4px + .settings-icon + margin-right: 18px + @extend .fa, .fa-gears + .about-mozo-icon + margin-right: 18px + @extend .fa, .fa-info-circle + .sign-out-icon + margin-right: 18px + @extend .fa, .fa-caret-square-o-left .supplier-close-shop +alert($bg: $alert-color, $radius: true) padding: 3px diff --git a/app/assets/stylesheets/supplier/foundation1/components/_tables.css.sass b/app/assets/stylesheets/supplier/foundation1/components/_tables.css.sass index 010e7531..aa655803 100644 --- a/app/assets/stylesheets/supplier/foundation1/components/_tables.css.sass +++ b/app/assets/stylesheets/supplier/foundation1/components/_tables.css.sass @@ -16,26 +16,29 @@ table text-align: right &.date text-align: right + .error + display: inline-block + padding-left: 5px + color: $alert-color + a.table-qr-codes + +button-icon-only .table-edit +button($bg: $secondary-color) +button-icon-only span @extend .fa @extend .fa-pencil -a.table-qr-codes - +button($bg: $secondary-color) - +button-icon-only - span - @extend .fa - @extend .fa-qrcode -span.table-qr-codes +span.qr-icon @extend .fa @extend .fa-qrcode + + span + padding-left: 7px +a.table-qr-codes + +button($bg: $secondary-color, $padding: $button-sml) .table-destroy +button($bg: $secondary-color) +button-icon-only color: $warning-color - margin-left: 8px span @extend .fa diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index ff2aee60..0d82ea3c 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -1,4 +1,4 @@ - class DashboardController < ApplicationController +class DashboardController < ApplicationController layout 'theme1' before_action :allow_all_origins, only: :error_report @@ -13,6 +13,10 @@ render nothing: true end + def scan + + end + def close_window render layout: false end diff --git a/app/controllers/suppliers/employees_controller.rb b/app/controllers/suppliers/employees_controller.rb new file mode 100644 index 00000000..43fa287a --- /dev/null +++ b/app/controllers/suppliers/employees_controller.rb @@ -0,0 +1,65 @@ +module Suppliers + class EmployeesController < Suppliers::ApplicationController + + # GET /employees + # GET /employees.json + def index + @employees = current_supplier.employees + render json: @employees, each_serializer: Suppliers::EmployeeSerializer + end + + # GET /employees/1 + # GET /employees/1.json + def show + @employee = Employee.find(params[:id]) + render json: @employee, serializer: Suppliers::EmployeeSerializer + end + + # POST /employees + # POST /employees.json + def create + @employee = Employee.new(employee_params) + @employee.supplier = current_supplier + + respond_to do |format| + if @employee.save + render json: @employee, serializer: Suppliers::EmployeeSerializer, status: :created + else + render json: {errors: @employee.errors}, status: :unprocessable_entity + end + end + end + + # PUT /employees/1 + # PUT /employees/1.json + def update + @employee = Employee.find(params[:id]) + render json: {}, status: 404 unless @employee.supplier_id == current_supplier.id + respond_to do |format| + if @employee.update_attributes(employee_params) + format.json { head :no_content } + else + format.json { render json: {errors: @employee.errors}, status: :unprocessable_entity } + end + end + end + + # DELETE /employees/1 + # DELETE /employees/1.json + def destroy + @employee = Employee.find(params[:id]) + render json: {}, status: :forbidden unless @employee.supplier_id == current_supplier.id + @employee.destroy + + respond_to do |format| + format.json { head :no_content } + end + end + + private + + def employee_params + params.require(:employee).permit(:name, :email) + end + end +end diff --git a/app/models/employee.rb b/app/models/employee.rb index fe1db8b0..52068228 100644 --- a/app/models/employee.rb +++ b/app/models/employee.rb @@ -1,8 +1,14 @@ class Employee include SimplyStored::Couch + include ActiveModel::SerializerSupport devise :database_authenticatable, :recoverable, :rememberable, :trackable #, :omniauthable, :omniauth_providers => [:facebook] #, :token_authenticatable , :registerable + property :name + property :email + view :by_email, key: :email + + validates :email, email: true belongs_to :supplier has_many :orders has_and_belongs_to_many :lists, storing_keys: false diff --git a/app/models/list.rb b/app/models/list.rb index 007a5dd0..5cb85323 100644 --- a/app/models/list.rb +++ b/app/models/list.rb @@ -52,6 +52,14 @@ class List } }], reduce_function: '_sum' + view :active_users_view, type: :custom, map_function: %[function(doc){ + if(doc.ruby_class == 'List' && doc.state == 'active'){ + doc.user_ids && doc.user_ids.forEach(function(uid){ + emit([doc.supplier_id, uid], 1); + }) + } + }], reduce_function: '_sum' + view :for_user_view, type: :custom, map_function: %|function(doc){ if(doc.ruby_class == 'List' && doc.user_ids && doc.user_ids.length){ doc.user_ids.forEach(function(uid){ diff --git a/app/serializers/suppliers/employee_serializer.rb b/app/serializers/suppliers/employee_serializer.rb new file mode 100644 index 00000000..d85da47f --- /dev/null +++ b/app/serializers/suppliers/employee_serializer.rb @@ -0,0 +1,6 @@ +class Suppliers::EmployeeSerializer < Qwaiter::Serializer + self.root = :employee + embed :ids, include: true + attributes :supplier_id, :name, :email + has_many :orders +end diff --git a/config/deploy.rb b/config/deploy.rb index 2f66e856..9b54df0c 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -60,7 +60,21 @@ namespace :deploy do end end - after :publishing, :restart + task :update_remote_cache do + on roles(:app), in: :sequence, wait: 5 do + within shared_path.join('cached-copy') do + execute :git, :pull + end + end + end + + task :build_drb_counter do + + end + + after :publishing, :restart do + update_remote_cache + end after :restart, :clear_cache do on roles(:web), in: :groups, limit: 3, wait: 10 do diff --git a/config/locales/models.en.yml b/config/locales/models.en.yml index 3d344d00..c29098e6 100644 --- a/config/locales/models.en.yml +++ b/config/locales/models.en.yml @@ -11,6 +11,7 @@ en: section: Section join_request: Join request user_feedback: User feedback + employee: Employee plural: user: Users supplier: Restaurants @@ -22,6 +23,7 @@ en: section: Sections join_request: Join requests user_feedback: User feedbacks + employee: Employees attributes: product_category: name: Name diff --git a/config/locales/models.nl.yml b/config/locales/models.nl.yml index ec02a883..ad33dd04 100644 --- a/config/locales/models.nl.yml +++ b/config/locales/models.nl.yml @@ -10,6 +10,7 @@ nl: product_category: Product categorie section: Afdeling join_request: Deelname verzoek + employee: Werknemer plural: user: Gebruikers supplier: Restaurants @@ -20,6 +21,7 @@ nl: product_category: Product categorieen section: Afdelingen join_request: Deelname verzoeken + employee: Werknemers attributes: product_category: name: Naam diff --git a/config/locales/supplier.en.yml b/config/locales/supplier.en.yml index 23152575..eaf980de 100644 --- a/config/locales/supplier.en.yml +++ b/config/locales/supplier.en.yml @@ -19,11 +19,6 @@ en: no_lists: No active lists active_orders: no_orders: No active orders - messages: - could_not_arrange_tables: 'The tables could not be arranged' - could_not_arrange_tables_distributed: 'The tables could not be arranged. Does the ${models.section|downcase} have a width and a height?' - could_not_arrange_tables_by_row: 'The tables could not be arranged. Does the ${models.section|downcase} have a width and a height?' - could_not_arrange_tables_by_column: 'The tables could not be arranged. Does the ${models.section|downcase} have a width and a height?' top_menu: menu: Menu active_lists: @@ -39,11 +34,8 @@ en: settings: Settings sign_out: Sign out table_number: Table - tables: - qr_codes: - link: Print Qr codes sheet - has_no_section: "Not placed" table: + print_qr_codes: Print Qr codes destroy: modal: title: Are you sure you want to delete ${models.table} %{number} @@ -122,6 +114,7 @@ en: after_field: ' ${models.plural.table}' close_button: Close arrange_button: Distribute + cannot_arrange: 'The tables could not be arranged. Does the ${models.section|downcase} have a width and a height?' settings: title: Settings save: Save settings @@ -183,3 +176,17 @@ en: modal: info: close: OK + supplier_status_info: + title: "%{name} info" + header: The icons at the top right corner contain information about the current orders + orders_placed_count_explanation: "  means that there are %{count} orders placed and not yet processing or finished" + orders_in_process_count_explanation: "  means that there are %{count} orders currently processing" + close: Got it + employee: + new_button: 'Add ${models.employee}' + destroy: + modal: + title: 'Delete ${models.employee} %{name}?' + edit: + modal: + body_header: '' diff --git a/config/locales/supplier.nl.yml b/config/locales/supplier.nl.yml index e5711338..62c408eb 100644 --- a/config/locales/supplier.nl.yml +++ b/config/locales/supplier.nl.yml @@ -18,11 +18,6 @@ nl: no_lists: Geen actieve ${models.plural.list} active_orders: no_orders: Geen actieve ${models.plural.order} - messages: - could_not_arrange_tables: 'De ${models.plural.table} konden niet worden gepositioneerd' - could_not_arrange_tables_distributed: 'De ${models.plural.table} konden niet worden gepositioneerd. Heeft de ${models.section|downcase} een hoogte en breedte?' - could_not_arrange_tables_by_row: 'De ${models.plural.table} konden niet worden gepositioneerd. Heeft de ${models.section|downcase} een hoogte en breedte?' - could_not_arrange_tables_by_column: 'De ${models.plural.table} konden niet worden gepositioneerd. Heeft de ${models.section|downcase} een hoogte en breedte?' top_menu: menu: Menu active_lists: @@ -38,11 +33,8 @@ nl: settings: Instellingen sign_out: Afmelden table_number: Tafel - tables: - qr_codes: - link: Print Qr codes - has_no_section: "Niet geplaatst" table: + print_qr_codes: Print Qr codes destroy: modal: title: Weet je zeker dat je ${models.table} %{number} wilt verwijderen @@ -121,6 +113,7 @@ nl: after_field: ' ${models.plural.table}' close_button: Sluiten arrange_button: Positioneer + cannot_arrange: 'De ${models.plural.table} konden niet worden gepositioneerd. Heeft de ${models.section|downcase} een hoogte en breedte?' settings: title: Instellingen save: Instellingen opslaan @@ -186,3 +179,14 @@ nl: modal: info: close: OK + supplier_status_info: + title: "%{name} info" + header: The icons at the top right corner contain information about the current orders + orders_placed_count_explanation: "  means that there are %{count} orders placed and not yet processing or finished" + orders_in_process_count_explanation: "  means that there are %{count} orders currently processing" + close: Got it + employee: + new_button: '${models.employee} toevoegen' + destroy: + modal: + title: '${models.employee} %{name} verwijderen?' diff --git a/config/routes.rb b/config/routes.rb index a698dfc3..b2d77ea5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -87,7 +87,7 @@ Qwaiter::Application.routes.draw do #get '/bars-restaurants' => 'dashboard#bars_restaurants', as: :bars_restaurants #get '/clients' => 'dashboard#clients' #get '/contact' => 'dashboard#contact' - get '/s' => redirect('/scan'), as: :scan + get '/s' => 'dashboard#scan', as: :scan # DEVELOPMENT ONLY get '/qr' => 'dashboard#qr' @@ -128,6 +128,8 @@ Qwaiter::Application.routes.draw do get :qr_codes end end + + resources :employees resources :products do collection do get :preview_products diff --git a/drb_counter/Dockerfile b/drb_counter/Dockerfile new file mode 100644 index 00000000..ee43ddf2 --- /dev/null +++ b/drb_counter/Dockerfile @@ -0,0 +1,28 @@ +FROM ruby:2.2.0 + +# throw errors if Gemfile has been modified since Gemfile.lock +RUN bundle config --global frozen 1 + +RUN mkdir -p /usr/src/app + +WORKDIR /usr/src/app + +# Test +#RUN apt-get update && apt-get install -y qt5-default libqt5webkit5-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* +# Standard +#RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/* +#RUN apt-get update && apt-get install -y mysql-client postgresql-client sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/* +# Specific +#RUN apt-get update && apt-get install -y dos2unix --no-install-recommends && rm -rf /var/lib/apt/lists/* + +COPY Gemfile /usr/src/app/ +COPY Gemfile.lock /usr/src/app/ +#COPY vendor/cache /usr/src/app/vendor/cache +#RUN bundle install --local +RUN rm -rf /usr/src/app/.bundle +RUN bundle install + +COPY . /usr/src/app + +EXPOSE 9022 +ENTRYPOINT ["ruby", "drb_counter.rb"] diff --git a/drb_counter/Gemfile b/drb_counter/Gemfile new file mode 100644 index 00000000..0ef2abef --- /dev/null +++ b/drb_counter/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem "couchrest" +gem "pry" diff --git a/drb_counter/Gemfile.lock b/drb_counter/Gemfile.lock new file mode 100644 index 00000000..3cd7ec73 --- /dev/null +++ b/drb_counter/Gemfile.lock @@ -0,0 +1,196 @@ +GEM + remote: https://rubygems.org/ + specs: + coderay (1.1.0) + couchrest (1.2.0) + mime-types (~> 1.15) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + multi_json (~> 1.0) + rest-client (~> 1.6.1) + method_source (0.8.2) + mime-types (1.25.1) + multi_json (1.10.1) + pry (0.10.1) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + rdoc (4.2.0) + rest-client (1.6.8) + mime-types (~> 1.16) + rdoc (>= 2.4.2) + slop (3.6.0) + +PLATFORMS + ruby + +DEPENDENCIES + couchrest + pry diff --git a/drb_counter/couchdb_design.yml b/drb_counter/couchdb_design.yml new file mode 100644 index 00000000..7bb546a2 --- /dev/null +++ b/drb_counter/couchdb_design.yml @@ -0,0 +1,8 @@ +views: + by_supplier_id_and_state: + map: | + function(doc) { + if(doc.ruby_class && doc.ruby_class == 'Order') emit([doc['supplier_id'], doc['state']], 1); + } + reduce: _sum +language: "javascript" diff --git a/bin/drb_counter.rb b/drb_counter/drb_counter.rb similarity index 61% rename from bin/drb_counter.rb rename to drb_counter/drb_counter.rb index 6225babd..84edb967 100755 --- a/bin/drb_counter.rb +++ b/drb_counter/drb_counter.rb @@ -1,6 +1,8 @@ #!/usr/bin/env ruby # Make drb server require 'rubygems' +require 'drb' +require 'pry' #require File.expand_path('../lib/in_memory_q_counter', File.dirname(__FILE__)) # This is a non thread safe replacement for the # couchbase counter mechanism since every test needs @@ -16,14 +18,18 @@ class InMemoryQCounter end def get(key, options = {}) - store[key] + value = store[key] + debug "Get key #{key} (#{value})" + value end def set(key, value) + debug "Set key #{key} to #{value}" store[key] = value end def incr(key, options = {}) + debug "Increment key #{key}" # store[key] ||= options[:initial].to_i # store[key] += 1 if store[key] @@ -34,6 +40,7 @@ class InMemoryQCounter end def decr(key, options = {}) + debug "Decrement key #{key}" # store[key] ||= options[:initial].to_i # store[key] -= 1 if store[key] @@ -44,22 +51,45 @@ class InMemoryQCounter end def flush + debug "Flushing store" store.clear end + def debug(message) + puts message + end + def reload_stats! require 'yaml' require 'couchrest' require 'pry' - binding.pry - couch_settings_path = File.join(ENV['MOZO_PATH'], 'config/couchdb.yml') + couch_settings_path = 'config/couchdb.yml' puts "Couch settings path: #{couch_settings_path}" puts "Environment: #{environment.inspect}" couch_settings = YAML.load_file(couch_settings_path)[environment] database = couch_settings['database'] db = CouchRest.database(database) - view_result = db.view("_design/order/_view/by_supplier_id_and_state", reduce: true, group_level: 2) + design_doc = "_design/order_counter" + view_path = File.join design_doc, "_view/by_supplier_id_and_state" + tries = 0 + begin + view_result = db.view(view_path, reduce: true, group: true, group_level: 2) + rescue RestClient::ResourceNotFound => e + puts "Database view #{view_path} not found" + design_doc_path = File.expand_path('../couchdb_design.yml', __FILE__) + doc = YAML.load_file design_doc_path + doc['_id'] = design_doc + db.save_doc(doc) + if tries < 3 + tries += 1 + retry + else + raise e + end + # view not available, initialize as zero + end counts = view_result ? view_result['rows'] : nil + puts "Initialize with: #{counts.to_yaml}" if counts counts.each do |count_spec| supplier_id, order_state = count_spec['key'] @@ -70,17 +100,11 @@ class InMemoryQCounter end end end - rescue RestClient::ResourceNotFound - # view not available, initialize as zero rescue => e raise e end end -require 'drb' -require 'daemons' drb_port = 9022 -Daemons.run_proc('DRBcounter', dir_mode: :normal, dir: File.expand_path("#{File.dirname(__FILE__)}/../tmp/pids")) do - environment = (%w[production staging development test] & ARGV).first - DRb.start_service "druby://:#{drb_port}", InMemoryQCounter.new(reload_stats: true, environment: environment) - DRb.thread.join -end +environment = (%w[production staging development test] & ARGV).first || 'development' +DRb.start_service "druby://:#{drb_port}", InMemoryQCounter.new(reload_stats: true, environment: environment) +DRb.thread.join diff --git a/faye/Dockerfile b/faye/Dockerfile new file mode 100644 index 00000000..f2b3dcbf --- /dev/null +++ b/faye/Dockerfile @@ -0,0 +1,29 @@ +FROM ruby:2.2.0 + +# throw errors if Gemfile has been modified since Gemfile.lock +RUN bundle config --global frozen 1 + +RUN mkdir -p /usr/src/app + +WORKDIR /usr/src/app +RUN apt-get update +# Test +#RUN apt-get update && apt-get install -y qt5-default libqt5webkit5-dev --no-install-recommends && rm -rf /var/lib/apt/lists/* +# Standard +#RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/* +#RUN apt-get update && apt-get install -y mysql-client postgresql-client sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/* +# Specific +#RUN apt-get update && apt-get install -y dos2unix --no-install-recommends && rm -rf /var/lib/apt/lists/* + +COPY Gemfile /usr/src/app/ +COPY Gemfile.lock /usr/src/app/ +#COPY vendor/cache /usr/src/app/vendor/cache +#RUN bundle install --local +RUN rm -rf /usr/src/app/.bundle +RUN bundle install + +COPY . /usr/src/app +ENV FAYE_PORT=9296 +EXPOSE $FAYE_PORT +CMD thin start -R config.ru -p $FAYE_PORT + diff --git a/faye/Gemfile b/faye/Gemfile new file mode 100644 index 00000000..9be00b22 --- /dev/null +++ b/faye/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gem "faye" +gem "thin" +gem "pry" diff --git a/faye/Gemfile.lock b/faye/Gemfile.lock new file mode 100644 index 00000000..23235c76 --- /dev/null +++ b/faye/Gemfile.lock @@ -0,0 +1,51 @@ +GEM + remote: https://rubygems.org/ + specs: + addressable (2.3.7) + coderay (1.1.0) + cookiejar (0.3.2) + daemons (1.1.9) + em-http-request (1.1.2) + addressable (>= 2.3.4) + cookiejar + em-socksify (>= 0.3) + eventmachine (>= 1.0.3) + http_parser.rb (>= 0.6.0) + em-socksify (0.3.0) + eventmachine (>= 1.0.0.beta.4) + eventmachine (1.0.7) + faye (1.1.0) + cookiejar (>= 0.3.0) + em-http-request (>= 0.3.0) + eventmachine (>= 0.12.0) + faye-websocket (>= 0.9.1) + multi_json (>= 1.0.0) + rack (>= 1.0.0) + websocket-driver (>= 0.5.1) + faye-websocket (0.9.2) + eventmachine (>= 0.12.0) + websocket-driver (>= 0.5.1) + http_parser.rb (0.6.0) + method_source (0.8.2) + multi_json (1.10.1) + pry (0.10.1) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + rack (1.6.0) + slop (3.6.0) + thin (1.6.3) + daemons (~> 1.0, >= 1.0.9) + eventmachine (~> 1.0) + rack (~> 1.0) + websocket-driver (0.5.1) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.1) + +PLATFORMS + ruby + +DEPENDENCIES + faye + pry + thin diff --git a/fig.yml b/fig.yml index 463e1fca..cfaa69df 100644 --- a/fig.yml +++ b/fig.yml @@ -6,14 +6,19 @@ db: - 5984 net: host counters: - image: ruby:2.2 -web: - build: . - #command: bundle exec unicorn -p 3000 -c ./config/unicorn.rb - command: rails s + build: drb_counter + net: host volumes: - - .:/usr/src/app - ports: - - "3000:3000" - #links: - # #- db + - config:/usr/src/app/config + command: development +faye: + build: faye + net: host +#web: + #build: . + #command: bundle exec unicorn -p 3000 -c ./config/unicorn.rb + #command: rails s + #volumes: + #- .:/usr/src/app + #ports: + #- "3000:3000" diff --git a/mdocker b/mdocker new file mode 100755 index 00000000..d83b54ea --- /dev/null +++ b/mdocker @@ -0,0 +1,51 @@ +#!/usr/bin/env ruby +require 'pry' +require 'yaml' +require 'active_support/all' + +shared_dir = Pathname.new File.expand_path('../../', __FILE__) +app_dir = Pathname.new File.expand_path('../', __FILE__) +class Runner + def execute(cmd) + puts "Running: #{cmd}" + `#{cmd}` + end +end + +runner = Runner.new + +prefix = "mozo_" +containers = YAML.load <<-YML.strip_heredoc + drb_counter: + directory: drb_counter + volumes: + - #{app_dir.join('config')}:config + ports: + - 9022 + arguments: + - production + faye: + directory: faye + ports: + - 9296 +YML +container_names = containers.keys.map{|c| [prefix, c].join } +#container_name_list = container_names.join(' ') + +#REBUILD +containers.each do |name, settings| + runner.execute "docker build -t #{prefix}#{name} #{settings['directory']}" +end + +running_containers = runner.execute("docker ps -q #{container_names.map{|cname| "-f name=#{cname}" }.join(' ')}").to_s.strip.split(/\s+/) +runner.execute("docker stop #{running_containers.join(' ')}") if running_containers.any? + +existing_containers = runner.execute("docker ps -a -q #{container_names.map{|cname| "-f name=#{cname}" }.join(' ')}").to_s.strip.split(/\s+/) +runner.execute("docker rm #{existing_containers.join(' ')}") if existing_containers.any? + +# RUN THE CONTAINERS +containers.each do |name, settings| + volumes = Array.wrap(settings['volumes']).map{|v| "-v #{v}"}.join(' ') + arguments = Array.wrap(settings['arguments']).join(' ') + runner.execute "docker run -d --net=host --restart=always #{volumes} --name=#{prefix}#{name} #{prefix}#{name} #{arguments}" +end diff --git a/wip.md b/wip.md index 54a180d6..e0e6e300 100644 --- a/wip.md +++ b/wip.md @@ -23,7 +23,8 @@ User - product variants - remove active orders on list close - fix ajaxError duplicity -- rename "I am signed in as a user" to "there is a signed in user" +- rename "I am signed in as a user" to "there is a signed in user" in + the specs Bugs ----