lanes 0.5.0 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/client/fonts/fontawesome-webfont.woff +0 -0
  3. data/client/fonts/fontawesome-webfont.woff2 +0 -0
  4. data/client/lanes/Boot.cjsx +1 -6
  5. data/client/lanes/components/grid/Body.cjsx +14 -1
  6. data/client/lanes/components/grid/Grid.cjsx +20 -19
  7. data/client/lanes/components/grid/Toolbar.cjsx +7 -4
  8. data/client/lanes/components/grid/editors.scss +1 -1
  9. data/client/lanes/components/grid/styles.scss +16 -5
  10. data/client/lanes/components/modal/Modal.cjsx +9 -11
  11. data/client/lanes/components/record-finder/RecordFinder.cjsx +2 -2
  12. data/client/lanes/components/record-finder/styles.scss +7 -5
  13. data/client/lanes/components/shared/FormGroup.cjsx +1 -1
  14. data/client/lanes/components/shared/Icon.cjsx +3 -2
  15. data/client/lanes/components/shared/Input.cjsx +1 -0
  16. data/client/lanes/components/shared/PanelHeader.cjsx +8 -0
  17. data/client/lanes/components/shared/fields.scss +5 -4
  18. data/client/lanes/components/shared/styles.scss +18 -0
  19. data/client/lanes/index.js +0 -1
  20. data/client/lanes/{plugins → lib}/ResizeSensor.js +0 -0
  21. data/client/lanes/lib/all.js +13 -0
  22. data/client/lanes/lib/dom.coffee +1 -1
  23. data/client/lanes/lib/format.coffee +2 -2
  24. data/client/lanes/lib/index.js.erb +1 -13
  25. data/client/lanes/lib/loader.coffee +2 -2
  26. data/client/lanes/lib/utilFunctions.coffee +12 -0
  27. data/client/lanes/models/AssociationMap.coffee +27 -18
  28. data/client/lanes/models/Base.coffee +12 -4
  29. data/client/lanes/models/Collection.coffee +5 -3
  30. data/client/lanes/models/PubSub.coffee +1 -1
  31. data/client/lanes/models/Query.coffee +0 -1
  32. data/client/lanes/models/State.coffee +5 -1
  33. data/client/lanes/models/Sync.coffee +5 -9
  34. data/client/lanes/models/query/ArrayResult.coffee +27 -7
  35. data/client/lanes/models/query/Result.coffee +2 -0
  36. data/client/lanes/react/Component.coffee +3 -3
  37. data/client/lanes/react/Viewport.coffee +17 -5
  38. data/client/lanes/react/mixins/Access.coffee +2 -2
  39. data/client/lanes/react/mixins/FieldErrors.coffee +3 -3
  40. data/client/lanes/remote/BaseClasses.coffee +0 -0
  41. data/client/lanes/remote/api.coffee +8 -0
  42. data/client/lanes/styles/fonts/_icons.scss +139 -2
  43. data/client/lanes/styles/fonts/_variables.scss +142 -4
  44. data/client/lanes/styles/global/mixins.scss +5 -0
  45. data/client/lanes/styles/global/styles.scss +5 -2
  46. data/client/lanes/styles/global.scss +1 -0
  47. data/client/lanes/vendor/base.js.erb +4 -2
  48. data/client/lanes/vendor/development/calendar.js +65 -65
  49. data/client/lanes/vendor/development/commons.js +34530 -34719
  50. data/client/lanes/vendor/development/data.js +30832 -0
  51. data/client/lanes/vendor/development/helpers.js +26 -26
  52. data/client/lanes/vendor/development/toggle.js +19 -19
  53. data/client/lanes/vendor/development/ui.js +22568 -0
  54. data/client/lanes/vendor/development/widgets.js +362 -362
  55. data/client/lanes/vendor/production/calendar.js +65 -65
  56. data/client/lanes/vendor/production/commons.js +34360 -34549
  57. data/client/lanes/vendor/production/data.js +30829 -0
  58. data/client/lanes/vendor/production/toggle.js +19 -19
  59. data/client/lanes/vendor/production/ui.js +22564 -0
  60. data/client/lanes/vendor/production/widgets.js +362 -362
  61. data/client/lanes/vendor/{production/base.js → standalone/index.js} +43836 -53602
  62. data/client/lanes/workspace/Modal.cjsx +1 -1
  63. data/client/lanes/workspace/styles/header.scss +1 -0
  64. data/client/lanes/workspace/styles/layout.scss +12 -0
  65. data/lanes.gemspec +1 -0
  66. data/lib/lanes/access/authentication_provider.rb +4 -3
  67. data/lib/lanes/api/coffeescript_processor.rb +9 -3
  68. data/lib/lanes/api/{controller.rb → controller_base.rb} +3 -35
  69. data/lib/lanes/api/formatted_reply.rb +2 -2
  70. data/lib/lanes/api/generic_controller.rb +42 -0
  71. data/lib/lanes/api/helper_methods.rb +1 -1
  72. data/lib/lanes/api/null_authentication_provider.rb +3 -0
  73. data/lib/lanes/api/request_wrapper.rb +32 -18
  74. data/lib/lanes/api/root.rb +25 -3
  75. data/lib/lanes/api/routing.rb +41 -22
  76. data/lib/lanes/api/sprockets_extension.rb +3 -1
  77. data/lib/lanes/api.rb +2 -1
  78. data/lib/lanes/configuration.rb +0 -1
  79. data/lib/lanes/extension/definition.rb +5 -1
  80. data/lib/lanes/hot_reload_plugin.rb +0 -1
  81. data/lib/lanes/version.rb +1 -1
  82. data/npm-build/build +3 -0
  83. data/npm-build/{base.js → data.js} +16 -16
  84. data/npm-build/package.json +3 -1
  85. data/npm-build/standalone.js +4 -0
  86. data/npm-build/ui.js +8 -0
  87. data/npm-build/webpack-standalone.config.js +16 -0
  88. data/npm-build/webpack.config.js +4 -3
  89. data/templates/config/lanes.rb +3 -3
  90. metadata +34 -10
  91. data/client/lanes/lib/noConflict.coffee +0 -15
  92. data/client/lanes/plugins/index.js +0 -1
  93. data/client/lanes/vendor/development/base.js +0 -61239
@@ -35,7 +35,7 @@ class Lanes.Workspace.Dialog extends Lanes.React.Component
35
35
 
36
36
  classes = _.classnames('layout-dialog', @props.className)
37
37
 
38
- <BS.Modal.Dialog>
38
+ <BS.Modal.Dialog className={classes}>
39
39
  <BS.Modal.Header>
40
40
  <BS.Modal.Title>{@props.title}</BS.Modal.Title>
41
41
  </BS.Modal.Header>
@@ -2,6 +2,7 @@
2
2
  @extend .navbar;
3
3
  @extend .navbar-inverse;
4
4
  @extend .navbar-fixed-top;
5
+ @include hidden-print;
5
6
  z-index: 20;
6
7
  height: $workspace-header-height;
7
8
  border-radius: 0;
@@ -7,6 +7,8 @@
7
7
 
8
8
  .page-container {
9
9
  height: calc(100% - #{$workspace-header-height});
10
+ @media print { height: 100%; }
11
+
10
12
  .screens-menu {
11
13
  width: 240px;
12
14
  z-index: 20;
@@ -21,10 +23,18 @@
21
23
  overflow-x: hidden;
22
24
  position: relative;
23
25
  top: 50px;
26
+ @media print { top: 0; }
24
27
  transition: all 0.15s ease-in-out 0s;
25
28
  margin-left: 240px;
29
+
26
30
  padding: 0 0 20px 0;
27
31
  height: 100%;
32
+
33
+ @media print {
34
+ margin-left: 0;
35
+ height: initial;
36
+ }
37
+
28
38
  .screen {
29
39
  height: 100%;
30
40
  display: none;
@@ -37,6 +47,7 @@
37
47
 
38
48
  .screens-menu {
39
49
  background-color: $navbar-inverse-bg;
50
+ @include hidden-print;
40
51
  .navigation {
41
52
  border-bottom: 1px solid $navbar-inverse-border;
42
53
  list-style: none outside none;
@@ -203,6 +214,7 @@
203
214
 
204
215
  .page-content {
205
216
  margin-left: 60px;
217
+ @media print { margin-left: 0; }
206
218
  }
207
219
  }
208
220
 
data/lanes.gemspec CHANGED
@@ -45,6 +45,7 @@ Gem::Specification.new do |spec|
45
45
  spec.add_dependency "mocha", "~> 1.1"
46
46
  spec.add_dependency "oj", "~> 2.1"
47
47
  spec.add_dependency "pg", "~> 0.8"
48
+ spec.add_dependency "rack-cors", "~> 0.4"
48
49
  spec.add_dependency "rack-protection", "~> 1.5"
49
50
  spec.add_dependency "rack-test", "~> 0.6"
50
51
  spec.add_dependency "rake", "~> 10.0"
@@ -32,7 +32,8 @@ module Lanes
32
32
  end
33
33
  end
34
34
 
35
- def allowed_access_to?(klass)
35
+ def allowed_access_to?(klass, options = {})
36
+ return true if options[:public] == true and current_user.nil?
36
37
  return false if current_user.nil?
37
38
  case request.request_method
38
39
  when 'GET'
@@ -56,8 +57,8 @@ module Lanes
56
57
  end
57
58
  end
58
59
 
59
- def wrap_model_access(model, req)
60
- if allowed_access_to?(model)
60
+ def wrap_model_access(model, req, options = {})
61
+ if allowed_access_to?(model, options)
61
62
  ::Lanes::User.scoped_to(current_user) do | user |
62
63
  yield
63
64
  end
@@ -60,14 +60,14 @@ module Lanes
60
60
  attr_reader :contents
61
61
 
62
62
  CONSTRUCTOR = /constructor\s*:/
63
-
64
63
  EXTENDING_CLASS_DEFINITION = /^\s*class\s+([\w|\.]+)\s+extends\s+([\w|\.]+)\s*?(\n|\#)/
64
+ REACT_CLASS_MATCH = /\.(React|Screens|Components|Views)\./
65
65
 
66
66
  def cleaned
67
67
  @contents = data.dup
68
68
  data.scan(EXTENDING_CLASS_DEFINITION) do |match|
69
69
  (name, extends) = match
70
- cc = if extends =~ /\.(React|Screens|Components)\./
70
+ cc = if extends =~ REACT_CLASS_MATCH
71
71
  ReactCoffeeClass.new(name, extends, contents)
72
72
  else
73
73
  CoffeeClass.new(name, extends, contents)
@@ -80,7 +80,13 @@ module Lanes
80
80
 
81
81
 
82
82
  def evaluate(scope, locals, &block)
83
- wrap_js scope, ::CoffeeScript.compile(cleaned, bare: true)
83
+ begin
84
+ wrap_js scope, ::CoffeeScript.compile(cleaned, bare: true)
85
+ rescue => e
86
+ Lanes.logger.warn e
87
+ Lanes.logger.warn cleaned
88
+ raise e
89
+ end
84
90
  end
85
91
  end
86
92
 
@@ -19,7 +19,7 @@ module Lanes
19
19
  # The parameters are deliberately shortened so they can be used in
20
20
  # query parameters without blowing the URL up to an unacceptable length
21
21
 
22
- class Controller
22
+ class ControllerBase
23
23
 
24
24
  attr_reader :model, :user, :params, :data
25
25
  include FormattedReply
@@ -31,39 +31,6 @@ module Lanes
31
31
  @data = data
32
32
  end
33
33
 
34
- def perform_retrieval
35
- query = build_query
36
- options = build_reply_options
37
- query = add_modifiers_to_query(query)
38
- options[:total_count] = query.dup.unscope(:select).count if should_include_total_count?
39
- if params[:id]
40
- query = query.first!
41
- end
42
- std_api_reply(:retrieve, query, options)
43
- end
44
-
45
- def perform_creation
46
- record = model.from_attribute_data(data, user)
47
- options = build_reply_options.merge(success: record.save)
48
- std_api_reply(:create, record, options)
49
- end
50
-
51
- def perform_update
52
- if params[:id]
53
- perform_single_update( build_query.first! )
54
- elsif data.is_a?(Array)
55
- perform_multiple_updates
56
- end
57
- end
58
-
59
- def perform_destroy
60
- if params[:id]
61
- perform_single_destroy
62
- elsif data.is_a?(Array)
63
- perform_multiple_destroy
64
- end
65
- end
66
-
67
34
  protected
68
35
 
69
36
  def perform_single_destroy
@@ -279,13 +246,14 @@ module Lanes
279
246
  when 'like' then field.matches( value )
280
247
  when 'ne' then field.not_eq(value)
281
248
  when 'lt' then field.lt(value)
282
- when ( op=='in' && value=~/.*:.*/ ) then field.in( Range.new( *value.split(':') ) )
249
+ when 'in' then field.in( Range.new( *value ) )
283
250
  when 'gt' then field.gt(value)
284
251
  else
285
252
  value =~ /%/ ? field.matches( value ) : field.eq( value )
286
253
  end
287
254
  end
288
255
 
256
+
289
257
  end
290
258
  end
291
259
  end
@@ -5,7 +5,7 @@ module Lanes
5
5
  # constructs a Hash with success, messages, and data keys and
6
6
  # populates them appropriately
7
7
 
8
- def std_api_reply(type, data, options)
8
+ def std_api_reply(type, data, options = {})
9
9
  json = { success: options[:success].nil? ? true : options[:success] }
10
10
  if data.is_a?(ActiveRecord::Base)
11
11
  record_active_record_errors(data, json)
@@ -15,7 +15,7 @@ module Lanes
15
15
  end
16
16
  json.merge(
17
17
  message: options[:messsage] || json_status_str(data, type.to_s.capitalize, json[:success]),
18
- data: json[:success] ? records_for_reply(data, type, options) : []
18
+ data: json[:success] ? records_for_reply(data, type, options) : []
19
19
  )
20
20
  end
21
21
 
@@ -0,0 +1,42 @@
1
+ module Lanes
2
+ module API
3
+
4
+
5
+ class GenericController < ControllerBase
6
+
7
+ def show
8
+ query = build_query
9
+ options = build_reply_options
10
+ options[:total_count] = query.dup.unscope(:select).count if should_include_total_count?
11
+ query = add_modifiers_to_query(query)
12
+ if params[:id]
13
+ query = query.first!
14
+ end
15
+ std_api_reply(:retrieve, query, options)
16
+ end
17
+
18
+ def create
19
+ record = model.from_attribute_data(data, user)
20
+ options = build_reply_options.merge(success: record.save)
21
+ std_api_reply(:create, record, options)
22
+ end
23
+
24
+ def update
25
+ if params[:id]
26
+ perform_single_update( build_query.first! )
27
+ elsif data.is_a?(Array)
28
+ perform_multiple_updates
29
+ end
30
+ end
31
+
32
+ def destroy
33
+ if params[:id]
34
+ perform_single_destroy
35
+ elsif data.is_a?(Array)
36
+ perform_multiple_destroy
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -33,7 +33,7 @@ module Lanes
33
33
  success: false,
34
34
  errors: { exception: request.env['sinatra.error'].message },
35
35
  message: request.env['sinatra.error'].message
36
- })
36
+ }, mode: :compat)
37
37
  end
38
38
 
39
39
  def data
@@ -27,6 +27,9 @@ module Lanes
27
27
  def wrap_reply(model, req)
28
28
  yield
29
29
  end
30
+ def wrap_model_access(model, req, options)
31
+ yield
32
+ end
30
33
 
31
34
  end
32
35
  end
@@ -6,49 +6,59 @@ module Lanes
6
6
 
7
7
  def get(*args)
8
8
  make_handler(*args) do |controller|
9
- controller.perform_retrieval
9
+ controller.show
10
10
  end
11
11
  end
12
12
 
13
13
  def post(*args)
14
14
  make_handler(*args) do |controller|
15
- controller.perform_creation
15
+ controller.create
16
16
  end
17
17
  end
18
18
 
19
19
  def update(*args)
20
20
  make_handler(*args) do |controller|
21
- controller.perform_update
21
+ controller.update
22
22
  end
23
23
  end
24
24
 
25
25
  def delete(*args)
26
26
  make_handler(*args) do |controller|
27
- controller.perform_destroy
27
+ controller.destroy
28
28
  end
29
29
  end
30
30
 
31
- def make_handler(model, controller, parent_attribute = nil)
31
+ # @!visibility private
32
+ def make_handler(model, controller, options = {})
32
33
  lambda do
33
34
  authentication = Lanes::API::AuthenticationProvider.new(request)
34
- authentication.wrap_model_access(model, self) do
35
- if parent_attribute
36
- params[:nested_attribute] = Hash[ parent_attribute,
35
+ authentication.wrap_model_access(model, self, options) do
36
+ if options[:parent_attribute]
37
+ params[:nested_attribute] = Hash[ options[:parent_attribute],
37
38
  params[parent_attribute] ]
38
39
  end
39
- wrap_reply(with_transaction: !request.get?) do
40
+ wrap_reply(options.merge(with_transaction: !request.get?)) do
40
41
  yield controller.new(model, authentication, params, data)
41
42
  end
42
43
  end
43
44
  end
44
45
  end
45
46
 
46
- def with_authenticated_user(role:nil, with_transaction:true)
47
+
48
+ # Ensure request is performed with a logged in user. The provided block will be called
49
+ # with |user, request|
50
+ #
51
+ # @param [options] options for additional checks
52
+ # @option options [String] :role A role name that the user must have
53
+ # @option opts [Boolean] :with_transaction rollback DB transaction if exceptions occur
54
+ #
55
+ def with_authenticated_user(options = {with_transaction: true})
56
+ role = options[:role]
47
57
  lambda do
48
58
  authentication = Lanes::API::AuthenticationProvider.new(request)
49
59
  user = authentication.current_user
50
60
  if user and ( role.nil? or user.roles.include?(role) )
51
- wrap_reply(with_transaction: with_transaction) do
61
+ wrap_reply(options) do
52
62
  yield authentication.current_user, self
53
63
  end
54
64
  else
@@ -58,15 +68,14 @@ module Lanes
58
68
  end
59
69
  end
60
70
 
61
- def log_request
62
- Lanes.logger.info "UserID: #{session['user_id']}, Params: #{request.params}"
63
- Lanes.logger.debug JSON.pretty_generate(data) unless Lanes.env.production? or data.nil?
64
- end
65
-
66
- def wrap_reply(with_transaction:true)
71
+ # Wraps a HTTP request in an optional DB transaction and converts yeilded data to JSON
72
+ #
73
+ # @param [options] options for additional checks
74
+ # @option opts [Boolean] :with_transaction rollback DB transaction if exceptions occur
75
+ def wrap_reply(options = {with_transaction: true})
67
76
  response = { success: false, message: "No response was generated" }
68
77
  log_request
69
- if with_transaction
78
+ if options[:with_transaction]
70
79
  Lanes::Model.transaction do
71
80
  response = yield
72
81
  # This is quite possibly a horrible idea.
@@ -84,6 +93,11 @@ module Lanes
84
93
  json_reply response
85
94
  end
86
95
 
96
+ # Logs UserID and params for a request. In non-production, the JSON payload is also logged
97
+ def log_request
98
+ Lanes.logger.info "UserID: #{session['user_id']}, Params: #{request.params}"
99
+ Lanes.logger.debug JSON.pretty_generate(data) unless Lanes.env.production? or data.nil?
100
+ end
87
101
  end
88
102
 
89
103
 
@@ -1,14 +1,15 @@
1
1
  require 'sinatra'
2
2
  require 'oj'
3
3
  require 'rack/protection'
4
+ require 'rack/cors'
4
5
  require_relative 'sprockets_extension'
5
6
  require_relative 'helper_methods'
6
7
  require_relative 'pub_sub'
7
8
 
8
-
9
9
  module Lanes
10
10
  module API
11
11
  class Root < Sinatra::Application
12
+ CORS_PATHS = {}
12
13
 
13
14
  Lanes.config.get(:environment) do | env |
14
15
  set :environment, env
@@ -40,11 +41,32 @@ module Lanes
40
41
  unless API.const_defined?(:AuthenticationProvider)
41
42
  require "lanes/api/null_authentication_provider"
42
43
  end
43
- use Rack::Protection #, :skip=>['GET:/'], :raise => true
44
-
45
44
  Lanes::Configuration.apply
46
45
  end
47
46
 
47
+ configure do
48
+ cors_resources = []
49
+
50
+ if API::Root::CORS_PATHS.any?
51
+ use Rack::Cors, debug: !Lanes.env.production? do
52
+
53
+ API::Root::CORS_PATHS.each do | path, options |
54
+ allow do
55
+ cors_resources.push Rack::Cors::Resource.new('', path)
56
+ origins options[:origins]
57
+ resource path, :methods => options[:methods], :headers => :any
58
+ end
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+ use Rack::Protection, allow_if: -> (env) {
65
+ path = env['PATH_INFO']
66
+ cors_resources.any?{|r| r.matches_path?(path) }
67
+ }
68
+
69
+ end
48
70
  end
49
71
  end
50
72
  end
@@ -16,47 +16,66 @@ module Lanes
16
16
  end
17
17
 
18
18
  [:get, :post, :put, :patch, :delete].each do | method_name |
19
- define_method(method_name) do | path, options = {}, &block |
20
- API::Root.send(method_name, make_path(path), options, &block)
19
+ define_method(method_name) do | path_suffix, options = {}, &block |
20
+ API::Root.send(method_name, make_path(path_suffix), options, &block)
21
21
  end
22
22
  end
23
23
 
24
+ def enable_cors(path_suffix, options = {origins: '*', methods: [:get]})
25
+ puts path_suffix
26
+ puts options
27
+ API::Root::CORS_PATHS[make_path(path_suffix)] = options
28
+ end
29
+
24
30
  def resources(model, options = {})
25
31
  path = options[:path] || model.api_path
26
- controller = options[:controller] || Lanes::API::Controller
27
- parent_attribute = false
32
+ controller = options[:controller] || Lanes::API::GenericController
33
+ format = options[:format] || '.json'
28
34
  if options[:under]
29
- parent_attribute = options[:parent_attribute] || options[:under].underscore.singularize+'_id'
35
+ options[:parent_attribute] = options[:under].underscore.singularize+'_id'
30
36
  end
31
37
 
32
- prefix = parent_attribute ? parent_attribute + '/' : ''
38
+ prefix = options[:parent_attribute] ? options[:parent_attribute] + '/' : ''
39
+
40
+ configured_routes = Hash.new{|hsh, key| hsh[key] = []}
33
41
 
34
- # index
35
- if controller.method_defined?(:perform_retrieval)
36
- get "#{prefix}#{path}/?:id?.json",
37
- &RequestWrapper.get(model, controller, parent_attribute)
42
+ bind = lambda{ |method, route, wrapper_method = method|
43
+ route = route + format
44
+ configured_routes[route].push(method)
45
+ self.send( method, route,
46
+ &RequestWrapper.send(wrapper_method, model, controller, options) )
47
+ }
48
+
49
+ # show
50
+ if controller.method_defined?(:show)
51
+ bind[:get, "#{prefix}#{path}/?:id?"]
38
52
  end
39
53
 
40
54
  # create
41
- if controller.method_defined?(:perform_creation)
42
- post "#{prefix}#{path}.json",
43
- &RequestWrapper.post(model, controller, parent_attribute)
55
+ if controller.method_defined?(:create)
56
+ bind[:post, "#{prefix}#{path}"]
44
57
  end
45
58
 
46
59
  unless options[:immutable]
47
60
 
48
61
  # update
49
- if controller.method_defined?(:perform_update)
50
- patch "#{prefix}#{path}/?:id?.json",
51
- &RequestWrapper.update(model, controller, parent_attribute)
52
- put "#{prefix}#{path}/?:id?.json",
53
- &RequestWrapper.update(model, controller, parent_attribute)
62
+ if controller.method_defined?(:update)
63
+ bind[:patch, "#{prefix}#{path}/?:id?", :update]
64
+ bind[:put, "#{prefix}#{path}/?:id?", :update]
54
65
  end
55
66
 
56
- if controller.method_defined?(:perform_destroy) and not options[:indestructible]
57
- # destroy
58
- delete "#{prefix}#{path}/?:id?.json",
59
- &RequestWrapper.delete(model, controller, parent_attribute)
67
+ # destroy
68
+ if controller.method_defined?(:destroy) and not options[:indestructible]
69
+ bind[:delete, "#{prefix}#{path}/?:id?"]
70
+ end
71
+
72
+ end
73
+
74
+ if options[:cors]
75
+ cors = options[:cors].is_a?(Hash) ? otions[:cors] : {origins: options[:cors]}
76
+
77
+ configured_routes.each do | route, methods |
78
+ enable_cors route, cors.merge(methods: methods)
60
79
  end
61
80
 
62
81
  end
@@ -23,7 +23,7 @@ module Lanes
23
23
  manifest.compile('lanes/vendor.js', 'lanes.js', 'lanes.css')
24
24
  Extensions.each do |ext|
25
25
  ext.each_static_asset do | asset |
26
- manifest.compile( asset.to_s )
26
+ manifest.compile( asset.to_s )
27
27
  end
28
28
  end
29
29
  Screen.each do | screen |
@@ -80,6 +80,8 @@ module Lanes
80
80
  end
81
81
  end
82
82
 
83
+ Root::CORS_PATHS['/assets/*'] = {origins: '*', methods: [:get]}
84
+
83
85
  app.configure :test, :development do
84
86
  app.get "#{Lanes.config.assets_path_prefix}/*" do |path|
85
87
  env_sprockets = request.env.dup
data/lib/lanes/api.rb CHANGED
@@ -2,7 +2,8 @@ require_relative '../lanes'
2
2
  require_relative 'api/request_wrapper'
3
3
  require_relative 'api/error_formatter'
4
4
  require_relative 'api/formatted_reply'
5
- require_relative 'api/controller'
5
+ require_relative 'api/controller_base'
6
+ require_relative 'api/generic_controller'
6
7
  require_relative 'api/root'
7
8
 
8
9
  Lanes.config.get(:environment) do
@@ -57,7 +57,6 @@ module Lanes
57
57
  config.namespace = "#{identifier}::jobba"
58
58
  end
59
59
 
60
-
61
60
  Resque.redis.namespace = "#{identifier}::resque"
62
61
  Resque.redis = Lanes.config.redis
63
62
  MessageBus.redis_config = Lanes.config.redis
@@ -63,6 +63,10 @@ module Lanes
63
63
  [ root_path.join('client') ]
64
64
  end
65
65
 
66
+ def standard_client_path
67
+ root_path.join('client', identifier )
68
+ end
69
+
66
70
  def static_paths
67
71
  client_paths.each_with_object(Array.new) do |path, result|
68
72
  Lanes.config.static_asset_types.each do | prefix |
@@ -74,7 +78,7 @@ module Lanes
74
78
  def each_static_asset
75
79
  static_paths.each do | path |
76
80
  path.find.each do | entry |
77
- yield entry if entry.file?
81
+ yield entry.relative_path_from(path) if entry.file?
78
82
  end
79
83
  end
80
84
  end
@@ -36,7 +36,6 @@ module ::Guard
36
36
  body = paths.map do | file |
37
37
  asset_to_json(file)
38
38
  end
39
- p body
40
39
  post.body = Oj.dump(body)
41
40
  http = Net::HTTP.new(@uri.host, @uri.port)
42
41
  http.request(post)
data/lib/lanes/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Lanes
2
2
 
3
- VERSION = "0.5.0"
3
+ VERSION = "0.5.5"
4
4
 
5
5
  end
data/npm-build/build CHANGED
@@ -7,3 +7,6 @@ BUILD_ENV=development webpack --progress
7
7
 
8
8
  echo Building production
9
9
  BUILD_ENV=production webpack --progress --optimize-dedupe
10
+
11
+ echo Building standalone
12
+ BUILD_ENV=production webpack --config webpack-standalone.config.js --progress --optimize-dedupe
@@ -1,29 +1,31 @@
1
+ var previousLanes = global.Lanes;
2
+
1
3
  var Lanes = ( global.Lanes || (global.Lanes = {}) );
4
+
5
+ Lanes.noConflict = function(){
6
+ global.Lanes = previousLanes;
7
+ return Lanes;
8
+ };
9
+
2
10
  Lanes.Vendor = ( Lanes.Vendor || {} );
11
+ Lanes.Vendor.xhr = require('xhr');
12
+ Lanes.Vendor.ld = require('lodash');
3
13
 
4
14
  Lanes.Vendor.Ampersand = ( Lanes.Ampersand || {} );
5
15
  Lanes.Vendor.Ampersand.State = require("ampersand-state");
6
- Lanes.Vendor.React = require("react");
7
- Lanes.Vendor.ReactDOM = require("react-dom");
8
16
 
9
- Lanes.Vendor.Ampersand.SubCollection = require("ampersand-subcollection");
17
+ Lanes.Vendor.Ampersand.SubCollection = require("ampersand-filtered-subcollection");
10
18
  Lanes.Vendor.Ampersand.RestCollection = require("ampersand-rest-collection");
11
19
  Lanes.Vendor.Ampersand.LDCollection = require('ampersand-collection-lodash-mixin');
12
20
  Lanes.Vendor.Ampersand.Collection = require("ampersand-collection");
13
21
  Lanes.Vendor.Events = require('ampersand-events');
14
- Lanes.Vendor.ReactBootstrap = require("react-bootstrap");
15
- Lanes.Vendor.BrowserHistory = require("history");
16
- Lanes.Vendor.Moment = require("moment");
17
- Lanes.Vendor.RSVP = require('rsvp');
18
- Lanes.Vendor.xhr = require('xhr');
19
- Lanes.Vendor.ComponentResize = require('react-component-resizable');
20
- Lanes.Vendor.List = require('react-list')
21
- Lanes.Vendor.Overlay = require('react-overlays');
22
- Lanes.log = require('loglevel');
23
- Lanes.Vendor.ld = require('lodash');
24
- var spf = require('sprintf-js');
25
22
 
23
+ Lanes.log = require('loglevel');
24
+ Lanes.Vendor.dom = require('ampersand-dom');
25
+ Lanes.Vendor.Moment = require("moment");
26
+ Lanes.Vendor.RSVP = require('rsvp');
26
27
 
28
+ var spf = require('sprintf-js');
27
29
 
28
30
  Lanes.Vendor.ld.mixin(require('lodash-inflection'));
29
31
 
@@ -42,5 +44,3 @@ Lanes.Vendor.ld.mixin({
42
44
  sprintf : spf.sprintf,
43
45
  vsprintf : spf.vsprintf
44
46
  });
45
-
46
- Lanes.Vendor.dom = require('ampersand-dom');