lanes 0.5.6 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +6 -2
- data/client/lanes/Config.coffee +6 -5
- data/client/lanes/access/LoginDialog.cjsx +4 -2
- data/client/lanes/access/Roles.coffee +3 -0
- data/client/lanes/access/screens/user-management/Editor.cjsx +1 -1
- data/client/lanes/components/grid/Body.cjsx +4 -3
- data/client/lanes/components/grid/Grid.cjsx +4 -3
- data/client/lanes/components/grid/Header.cjsx +1 -1
- data/client/lanes/components/grid/PopOverMixin.cjsx +6 -6
- data/client/lanes/components/grid/Selections.cjsx +16 -6
- data/client/lanes/components/grid/Toolbar.cjsx +1 -1
- data/client/lanes/components/grid/styles.scss +21 -5
- data/client/lanes/components/modal/Modal.cjsx +18 -9
- data/client/lanes/components/record-finder/Clause.cjsx +1 -2
- data/client/lanes/components/record-finder/Dialog.cjsx +11 -3
- data/client/lanes/components/record-finder/RecordFinder.cjsx +14 -7
- data/client/lanes/components/record-finder/styles.scss +1 -0
- data/client/lanes/components/select-field/SelectField.cjsx +36 -10
- data/client/lanes/components/select-field/styles.scss +7 -0
- data/client/lanes/components/shared/Checkbox.cjsx +34 -0
- data/client/lanes/components/shared/DateTime.cjsx +3 -2
- data/client/lanes/components/shared/ErrorDisplay.cjsx +1 -1
- data/client/lanes/components/shared/FieldMixin.cjsx +26 -15
- data/client/lanes/components/shared/FieldSet.cjsx +1 -1
- data/client/lanes/components/shared/FieldWrapper.cjsx +2 -2
- data/client/lanes/components/shared/FormGroup.cjsx +2 -2
- data/client/lanes/components/shared/Icon.cjsx +31 -4
- data/client/lanes/components/shared/IconButton.cjsx +8 -0
- data/client/lanes/components/shared/ImageAsset.cjsx +8 -5
- data/client/lanes/components/shared/IndeterminateCheckbox.cjsx +19 -0
- data/client/lanes/components/shared/InputFieldMixin.cjsx +6 -0
- data/client/lanes/components/shared/JobProgress.cjsx +4 -3
- data/client/lanes/components/shared/NetworkActivityOverlay.cjsx +1 -1
- data/client/lanes/components/shared/ScreenWrapper.cjsx +1 -1
- data/client/lanes/components/shared/ToggleField.cjsx +2 -1
- data/client/lanes/components/shared/Tooltip.cjsx +10 -2
- data/client/lanes/components/shared/fields.scss +7 -2
- data/client/lanes/components/toolbar/RemoteChangeSets.cjsx +10 -7
- data/client/lanes/components/toolbar/SaveButton.cjsx +5 -4
- data/client/lanes/components/toolbar/Toolbar.cjsx +18 -19
- data/client/lanes/components/toolbar/changes-notification.scss +3 -1
- data/client/lanes/components/toolbar/styles.scss +6 -3
- data/client/lanes/lib/HotReload.coffee +1 -1
- data/client/lanes/lib/all.js +1 -1
- data/client/lanes/lib/dom.coffee +14 -1
- data/client/lanes/lib/format.coffee +3 -0
- data/client/lanes/lib/loader.coffee +0 -2
- data/client/lanes/lib/{dom-polyfills.coffee → polyfills.coffee} +3 -0
- data/client/lanes/lib/utilFunctions.coffee +5 -7
- data/client/lanes/models/Asset.coffee +33 -20
- data/client/lanes/models/AssociationMap.coffee +5 -6
- data/client/lanes/models/Base.coffee +5 -2
- data/client/lanes/models/Collection.coffee +23 -2
- data/client/lanes/models/PubSub.coffee +51 -13
- data/client/lanes/models/Query.coffee +53 -42
- data/client/lanes/models/State.coffee +5 -4
- data/client/lanes/models/Sync.coffee +5 -3
- data/client/lanes/models/index.js +1 -1
- data/client/lanes/models/mixins/TrackCollectionRemovals.coffee +17 -0
- data/client/lanes/models/query/ArrayResult.coffee +16 -17
- data/client/lanes/models/query/CollectionResult.coffee +4 -4
- data/client/lanes/react/Component.coffee +14 -13
- data/client/lanes/react/Root.cjsx +1 -1
- data/client/lanes/react/Screen.coffee +1 -0
- data/client/lanes/react/Viewport.coffee +52 -16
- data/client/lanes/react/mixins/Access.coffee +5 -0
- data/client/lanes/react/mixins/Data.coffee +52 -144
- data/client/lanes/react/mixins/MonitorSize.coffee +1 -1
- data/client/lanes/react/mixins/ReadEditingState.coffee +3 -0
- data/client/lanes/screens/Commands.coffee +1 -1
- data/client/lanes/screens/CommonComponents.cjsx +2 -2
- data/client/lanes/screens/Definitions.coffee +3 -1
- data/client/lanes/screens/SystemSettings.cjsx +13 -18
- data/client/lanes/screens/UserPreferences.cjsx +1 -1
- data/client/lanes/styles/fonts.scss +2 -3
- data/client/lanes/styles/global/styles.scss +2 -1
- data/client/lanes/testing/TestObjects.coffee +6 -2
- data/client/lanes/vendor/action_cable.js +590 -0
- data/client/lanes/vendor/development/calendar.js +56 -56
- data/client/lanes/vendor/development/commons.js +7819 -6690
- data/client/lanes/vendor/development/data.js +1877 -1455
- data/client/lanes/vendor/development/helpers.js +39 -82
- data/client/lanes/vendor/development/toggle.js +20 -20
- data/client/lanes/vendor/development/ui.js +14629 -14261
- data/client/lanes/vendor/development/widgets.js +3146 -2173
- data/client/lanes/vendor/index.js +1 -2
- data/client/lanes/vendor/production/calendar.js +56 -56
- data/client/lanes/vendor/production/commons.js +6352 -6185
- data/client/lanes/vendor/production/data.js +1871 -1456
- data/client/lanes/vendor/production/toggle.js +20 -20
- data/client/lanes/vendor/production/ui.js +14694 -14286
- data/client/lanes/vendor/production/widgets.js +3139 -2166
- data/client/lanes/vendor/standalone/index.js +5666 -4586
- data/client/lanes/vendor/styles/widgets.scss +5 -5
- data/client/lanes/workspace/Layout.cjsx +1 -10
- data/client/lanes/workspace/Navbar.cjsx +8 -13
- data/client/lanes/workspace/ScreenView.cjsx +3 -4
- data/client/lanes/workspace/ScreensMenu.cjsx +8 -19
- data/client/lanes/workspace/Tabs.cjsx +6 -14
- data/db/migrate/02_create_assets.rb +1 -3
- data/lanes.gemspec +16 -11
- data/lib/lanes/access/test_fixture_extensions.rb +6 -10
- data/lib/lanes/access/track_modifications.rb +24 -0
- data/lib/lanes/api/cable.rb +49 -0
- data/lib/lanes/api/controller_base.rb +52 -9
- data/lib/lanes/api/default_routes.rb +9 -0
- data/lib/lanes/api/generic_controller.rb +2 -9
- data/lib/lanes/api/handlers/asset.rb +5 -6
- data/lib/lanes/api/helper_methods.rb +3 -2
- data/lib/lanes/api/javascript_processor.rb +6 -5
- data/lib/lanes/api/pub_sub.rb +14 -32
- data/lib/lanes/api/request_wrapper.rb +1 -1
- data/lib/lanes/api/root.rb +4 -7
- data/lib/lanes/api/routing.rb +3 -3
- data/lib/lanes/api/sprockets_extension.rb +1 -1
- data/lib/lanes/api.rb +4 -0
- data/lib/lanes/asset.rb +25 -25
- data/lib/lanes/concerns/asset_uploader.rb +25 -47
- data/lib/lanes/concerns/export_scope.rb +5 -7
- data/lib/lanes/concerns/queries.rb +7 -3
- data/lib/lanes/concerns/set_attribute_data.rb +12 -6
- data/lib/lanes/configuration.rb +4 -7
- data/lib/lanes/db.rb +3 -1
- data/lib/lanes/guard_tasks.rb +2 -1
- data/lib/lanes/hot_reload_plugin.rb +2 -1
- data/lib/lanes/job.rb +0 -1
- data/lib/lanes/logger.rb +3 -3
- data/lib/lanes/model.rb +0 -3
- data/lib/lanes/spec_helper.rb +1 -1
- data/lib/lanes/system_settings.rb +8 -14
- data/lib/lanes/version.rb +1 -1
- data/npm-build/data.js +1 -0
- data/npm-build/package.json +21 -19
- data/npm-build/ui.js +3 -0
- data/npm-build/update-dayz +2 -2
- data/npm-build/update-model-bindings.js +5 -0
- data/spec/command-reference-files/initial/Gemfile +1 -1
- data/spec/command-reference-files/initial/config/database.yml +1 -0
- data/spec/command-reference-files/initial/config/lanes.rb +3 -3
- data/spec/command-reference-files/screen/spec/appy-app/screens/ready-set-go/ReadySetGoSpec.coffee +1 -1
- data/spec/lanes/components/grid/GridSpec.coffee +2 -2
- data/spec/lanes/components/grid/PopoverEditorSpec.coffee +11 -12
- data/spec/lanes/components/select-field/SelectFieldSpec.coffee +6 -4
- data/spec/lanes/components/shared/NetworkActivityOverlaySpec.coffee +1 -1
- data/spec/lanes/models/PubSubSpec.coffee +6 -8
- data/spec/lanes/models/QuerySpec.coffee +19 -0
- data/spec/lanes/react/mixins/DataSpec.coffee +18 -16
- data/spec/server/api/coffeescript_processor_spec.rb +1 -1
- data/spec/server/api/controller_base_spec.rb +77 -0
- data/spec/server/api/pub_sub_spec.rb +9 -0
- data/spec/server/asset_spec.rb +23 -18
- data/spec/server/concerns/export_scope_spec.rb +2 -1
- data/spec/server/concerns/exported_limits_spec.rb +14 -9
- data/spec/server/concerns/set_attribute_data_spec.rb +17 -0
- data/spec/server/spec_helper.rb +29 -11
- data/templates/config/database.yml +1 -0
- data/templates/spec/client/Screen.coffee +1 -1
- data/views/specs.erb +4 -1
- metadata +138 -89
- data/client/lanes/vendor/message-bus-ajax.js +0 -44
- data/client/lanes/vendor/message-bus.js +0 -414
@@ -1,4 +1,4 @@
|
|
1
|
-
/*
|
1
|
+
/* Normalize.css */
|
2
2
|
.rw-btn,
|
3
3
|
.rw-input {
|
4
4
|
color: inherit;
|
@@ -305,7 +305,7 @@ ul.rw-list.rw-list-grouped > li.rw-list-option,
|
|
305
305
|
border-bottom-left-radius: 4px;
|
306
306
|
border-top-left-radius: 4px;
|
307
307
|
}
|
308
|
-
.rw-rtl.rw-widget .rw-input {
|
308
|
+
.rw-rtl .rw-widget .rw-input {
|
309
309
|
border-bottom-left-radius: 0;
|
310
310
|
border-top-left-radius: 0;
|
311
311
|
border-bottom-right-radius: 4px;
|
@@ -314,7 +314,7 @@ ul.rw-list.rw-list-grouped > li.rw-list-option,
|
|
314
314
|
.rw-widget > .rw-select {
|
315
315
|
border-left: #ccc 1px solid;
|
316
316
|
}
|
317
|
-
.rw-
|
317
|
+
.rw-widget.rw-rtl > .rw-select {
|
318
318
|
border-right: #ccc 1px solid;
|
319
319
|
border-left: none;
|
320
320
|
}
|
@@ -401,8 +401,8 @@ ul.rw-list.rw-list-grouped > li.rw-list-option,
|
|
401
401
|
.rw-combobox input.rw-input,
|
402
402
|
.rw-datetimepicker input.rw-input,
|
403
403
|
.rw-numberpicker input.rw-input {
|
404
|
-
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0
|
405
|
-
box-shadow: inset 0 1px 1px rgba(0,0,0
|
404
|
+
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
405
|
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
406
406
|
}
|
407
407
|
.rw-combobox:active,
|
408
408
|
.rw-datetimepicker:active,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Lanes.Workspace.Layout extends Lanes.React.Component
|
2
2
|
|
3
|
-
|
3
|
+
modelBindings:
|
4
4
|
uistate: -> Lanes.Workspace.Extension.uistate
|
5
5
|
viewport: -> @context.viewport
|
6
6
|
|
@@ -17,15 +17,6 @@ class Lanes.Workspace.Layout extends Lanes.React.Component
|
|
17
17
|
|
18
18
|
componentWillMount: ->
|
19
19
|
@uistate.set(@props)
|
20
|
-
useBasename = Lanes.Vendor.BrowserHistory.useBasename
|
21
|
-
history = useBasename(Lanes.Vendor.BrowserHistory.createHistory)({
|
22
|
-
basename: Lanes.config.root_path
|
23
|
-
})
|
24
|
-
@historyStopListening = history.listen (location) ->
|
25
|
-
Lanes.Screens.Definitions.setBrowserLocation(location)
|
26
|
-
@setState({history})
|
27
|
-
|
28
|
-
componentWillUnmount: -> @historyStopListening()
|
29
20
|
|
30
21
|
render: ->
|
31
22
|
<div className="layout">
|
@@ -1,16 +1,12 @@
|
|
1
1
|
class Lanes.Workspace.Navbar extends Lanes.React.Component
|
2
|
-
|
2
|
+
modelBindings:
|
3
3
|
settings: -> Lanes.config.system_settings
|
4
4
|
|
5
|
-
propTypes:
|
6
|
-
history: React.PropTypes.shape(
|
7
|
-
push: React.PropTypes.func
|
8
|
-
).isRequired
|
9
|
-
|
10
5
|
contextTypes:
|
11
6
|
uistate: React.PropTypes.object.isRequired
|
12
7
|
|
13
|
-
switchMenu: ->
|
8
|
+
switchMenu: (ev) ->
|
9
|
+
ev.preventDefault()
|
14
10
|
@context.uistate.nextSidebarState()
|
15
11
|
|
16
12
|
classNames: ->
|
@@ -18,12 +14,11 @@ class Lanes.Workspace.Navbar extends Lanes.React.Component
|
|
18
14
|
"menu-hidden": !@model.screen_menu_shown
|
19
15
|
|
20
16
|
Logo: ->
|
21
|
-
if @settings.logo?.
|
22
|
-
|
17
|
+
if @settings.logo?.thumbnail_url
|
18
|
+
url = "//#{Lanes.config.api_host}#{@settings.logo.thumbnail_url}"
|
19
|
+
<img src={url} />
|
23
20
|
else
|
24
|
-
<span>
|
25
|
-
{Lanes.Extensions.controlling().title()}
|
26
|
-
</span>
|
21
|
+
<span>{Lanes.Extensions.controlling().title()}</span>
|
27
22
|
|
28
23
|
render: ->
|
29
24
|
|
@@ -37,5 +32,5 @@ class Lanes.Workspace.Navbar extends Lanes.React.Component
|
|
37
32
|
<i className="icon"></i>
|
38
33
|
</button>
|
39
34
|
</div>
|
40
|
-
<Lanes.Workspace.Tabs
|
35
|
+
<Lanes.Workspace.Tabs />
|
41
36
|
</div>
|
@@ -10,12 +10,12 @@ class Lanes.Workspace.ScreenView extends Lanes.React.Component
|
|
10
10
|
contextTypes:
|
11
11
|
uistate: React.PropTypes.object.isRequired
|
12
12
|
|
13
|
-
|
13
|
+
modelBindings:
|
14
14
|
displaying: -> Lanes.Screens.Definitions.displaying
|
15
15
|
allScreens: -> Lanes.Screens.Definitions.all
|
16
16
|
|
17
|
-
|
18
|
-
displaying: 'change:active
|
17
|
+
bindEvents:
|
18
|
+
displaying: 'add remove reset change:active'
|
19
19
|
allScreens: 'change:loading'
|
20
20
|
|
21
21
|
renderScreen: (screen) ->
|
@@ -34,7 +34,6 @@ class Lanes.Workspace.ScreenView extends Lanes.React.Component
|
|
34
34
|
</div>
|
35
35
|
|
36
36
|
render: ->
|
37
|
-
|
38
37
|
child = if @displaying.isEmpty() then <@BaseView /> else @displaying.map(@renderScreen)
|
39
38
|
<div className={"page-content #{@context.uistate.layout_size}"}>
|
40
39
|
{@renderLoading() if Lanes.Screens.Definitions.all.isLoading()}
|
@@ -1,12 +1,9 @@
|
|
1
1
|
class ScreenList extends Lanes.React.Component
|
2
|
-
propTypes:
|
3
|
-
history: React.PropTypes.shape(
|
4
|
-
push: React.PropTypes.func
|
5
|
-
).isRequired
|
6
2
|
|
7
|
-
activateScreen: ->
|
3
|
+
activateScreen: (ev) ->
|
4
|
+
ev.preventDefault()
|
8
5
|
@model.display().then (screen) =>
|
9
|
-
@
|
6
|
+
@context.viewport.history.push(screen.historyUrl())
|
10
7
|
|
11
8
|
render: ->
|
12
9
|
<li>
|
@@ -18,12 +15,8 @@ class ScreenList extends Lanes.React.Component
|
|
18
15
|
|
19
16
|
class ScreenGroup extends Lanes.React.Component
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
push: React.PropTypes.func
|
24
|
-
).isRequired
|
25
|
-
|
26
|
-
toggleActive: ->
|
18
|
+
toggleActive: (ev) ->
|
19
|
+
ev.preventDefault()
|
27
20
|
@model.active = !@model.active
|
28
21
|
undefined
|
29
22
|
|
@@ -41,18 +34,14 @@ class ScreenGroup extends Lanes.React.Component
|
|
41
34
|
|
42
35
|
class Lanes.Workspace.ScreensMenu extends Lanes.React.Component
|
43
36
|
|
44
|
-
|
45
|
-
history: React.PropTypes.shape(
|
46
|
-
push: React.PropTypes.func
|
47
|
-
).isRequired
|
48
|
-
|
49
|
-
dataObjects:
|
37
|
+
modelBindings:
|
50
38
|
user: -> Lanes.current_user
|
51
39
|
|
52
40
|
renderGroup: (group) ->
|
53
41
|
<ScreenGroup {...@props} model=group key=group.id />
|
54
42
|
|
55
|
-
logOut: ->
|
43
|
+
logOut: (ev) ->
|
44
|
+
ev.preventDefault()
|
56
45
|
Lanes.current_user.logout()
|
57
46
|
|
58
47
|
render: ->
|
@@ -1,20 +1,16 @@
|
|
1
1
|
class TabView extends Lanes.React.Component
|
2
2
|
|
3
|
-
|
3
|
+
setModelState: (nextState) ->
|
4
4
|
if @model.active
|
5
5
|
_.dom(document.head).qs('title').text = @model.title()
|
6
|
-
@
|
6
|
+
@context.viewport.history.replace(@model.historyUrl())
|
7
7
|
if Lanes.Screens.Definitions.displaying.length is 0
|
8
|
-
@
|
8
|
+
@context.viewport.history.push('/')
|
9
9
|
@setState(nextState)
|
10
10
|
|
11
|
-
propTypes:
|
12
|
-
history: React.PropTypes.shape(
|
13
|
-
push: React.PropTypes.func
|
14
|
-
).isRequired
|
15
|
-
|
16
11
|
activate: ->
|
17
|
-
@
|
12
|
+
@model.active = true
|
13
|
+
@context.viewport.history.push(@model.historyUrl())
|
18
14
|
null
|
19
15
|
|
20
16
|
close: -> @model.remove()
|
@@ -28,12 +24,8 @@ class TabView extends Lanes.React.Component
|
|
28
24
|
|
29
25
|
|
30
26
|
class Lanes.Workspace.Tabs extends Lanes.React.Component
|
31
|
-
propTypes:
|
32
|
-
history: React.PropTypes.shape(
|
33
|
-
push: React.PropTypes.func
|
34
|
-
).isRequired
|
35
27
|
|
36
|
-
|
28
|
+
modelBindings:
|
37
29
|
collection: -> Lanes.Screens.Definitions.displaying
|
38
30
|
|
39
31
|
render: ->
|
@@ -2,11 +2,9 @@ class CreateAssets < ActiveRecord::Migration
|
|
2
2
|
def change
|
3
3
|
|
4
4
|
create_table "assets" do |t|
|
5
|
-
t.string :file, null: false
|
6
|
-
|
7
5
|
t.references :owner, polymorphic: true, null: false
|
8
6
|
t.integer :order
|
9
|
-
t.jsonb :
|
7
|
+
t.jsonb :file_data, null: false, default: {}
|
10
8
|
end
|
11
9
|
|
12
10
|
add_index :assets, [:owner_id, :owner_type]
|
data/lanes.gemspec
CHANGED
@@ -24,37 +24,42 @@ Gem::Specification.new do |spec|
|
|
24
24
|
|
25
25
|
spec.required_ruby_version = ">= 2.0"
|
26
26
|
|
27
|
-
spec.add_dependency "activejob", "~>
|
28
|
-
spec.add_dependency "activerecord", "~>
|
27
|
+
spec.add_dependency "activejob", "~> 5.0"
|
28
|
+
spec.add_dependency "activerecord", "~> 5.0"
|
29
|
+
spec.add_dependency "actioncable", "~> 5.0"
|
30
|
+
|
31
|
+
spec.add_dependency "sinatra", "~> 2.0.0.beta2"
|
32
|
+
spec.add_dependency "rack", "~> 2.0"
|
33
|
+
spec.add_dependency "rack-protection", "~> 2.0.0.beta2"
|
34
|
+
|
35
|
+
spec.add_dependency "rack-cors", "~> 0.4"
|
36
|
+
spec.add_dependency "rack-test", "~> 0.6"
|
37
|
+
|
29
38
|
spec.add_dependency "bcrypt", "~> 3.1"
|
30
|
-
spec.add_dependency "
|
39
|
+
spec.add_dependency "shrine", "~> 2.4"
|
40
|
+
spec.add_dependency "image_processing", "~> 0.4"
|
31
41
|
spec.add_dependency "coffee-react", "~> 4.0"
|
32
42
|
spec.add_dependency "coffee-script", "~> 2.4"
|
33
43
|
spec.add_dependency "compass-import-once", "~> 1.0"
|
34
44
|
spec.add_dependency "execjs", "~> 2.6"
|
35
45
|
spec.add_dependency "fastimage", "~> 1.8.1"
|
36
46
|
spec.add_dependency "guard", "~> 2.13"
|
37
|
-
spec.add_dependency "guard-jasmine", "~> 2.
|
47
|
+
spec.add_dependency "guard-jasmine", "~> 2.1"
|
38
48
|
spec.add_dependency "guard-minitest", "~> 2.3"
|
39
49
|
spec.add_dependency "hashie", "~> 3.3"
|
40
50
|
spec.add_dependency "jasmine-core", "~> 2.0"
|
41
51
|
spec.add_dependency "jobba", "~> 1.4"
|
42
|
-
spec.add_dependency "message_bus", "2.0.0.beta.6"
|
43
52
|
spec.add_dependency "mini_magick", "~> 4.3.6"
|
44
53
|
spec.add_dependency "minitest-around", "~> 0.2"
|
45
54
|
spec.add_dependency "mocha", "~> 1.1"
|
46
55
|
spec.add_dependency "oj", "~> 2.1"
|
47
56
|
spec.add_dependency "pg", "~> 0.8"
|
48
|
-
spec.add_dependency "rack-cors", "~> 0.4"
|
49
|
-
spec.add_dependency "rack-protection", "~> 1.5"
|
50
|
-
spec.add_dependency "rack-test", "~> 0.6"
|
51
57
|
spec.add_dependency "rake", "~> 10.0"
|
52
58
|
spec.add_dependency "require_all", "~> 1.3"
|
53
59
|
spec.add_dependency "resque", "~> 1.25"
|
54
60
|
spec.add_dependency "sanitize", "~> 3.0"
|
55
61
|
spec.add_dependency "sass", "~> 3.4"
|
56
|
-
spec.add_dependency "
|
57
|
-
spec.add_dependency "sprockets", "~> 3.6"
|
62
|
+
spec.add_dependency "sprockets", "3.6.3"
|
58
63
|
spec.add_dependency "sprockets-helpers", "~> 1.2"
|
59
64
|
spec.add_dependency "thor", "~> 0.19"
|
60
65
|
spec.add_dependency "uglifier", "~> 2.7"
|
@@ -62,5 +67,5 @@ Gem::Specification.new do |spec|
|
|
62
67
|
spec.add_development_dependency "bundler", "~> 1.5"
|
63
68
|
spec.add_development_dependency "diffy", "~> 3.0"
|
64
69
|
spec.add_development_dependency "growl", "~> 1.0"
|
65
|
-
|
70
|
+
spec.add_development_dependency "shrine-memory", ">= 0.2.2"
|
66
71
|
end
|
@@ -1,20 +1,16 @@
|
|
1
1
|
module AccessFixtureTestPatches
|
2
|
-
extend ActiveSupport::Concern
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
|
-
def table_rows_with_custom_autoset_user_fields
|
9
|
-
results = table_rows_without_custom_autoset_user_fields
|
3
|
+
def table_rows
|
4
|
+
results = super
|
10
5
|
if model_class && model_class < ActiveRecord::Base && model_class.record_modifications
|
11
6
|
results[ table_name ].each do | row |
|
12
|
-
|
13
|
-
row['
|
7
|
+
# 135138680 is the 'admin' user
|
8
|
+
row['created_by_id'] ||= 135138680 if model_class.column_names.include?('created_by_id')
|
9
|
+
row['updated_by_id'] ||= 135138680 if model_class.column_names.include?('updated_by_id')
|
14
10
|
end
|
15
11
|
end
|
16
12
|
results
|
17
13
|
end
|
18
14
|
end
|
19
15
|
|
20
|
-
ActiveRecord::FixtureSet.
|
16
|
+
ActiveRecord::FixtureSet.prepend AccessFixtureTestPatches
|
@@ -16,6 +16,30 @@ module Lanes::Concerns
|
|
16
16
|
self.blacklist_attributes :created_at, :updated_at, :created_by_id, :updated_by_id
|
17
17
|
before_update :record_update_modifications
|
18
18
|
before_create :record_create_modifications
|
19
|
+
|
20
|
+
self.export_scope :with_user_logins
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
|
25
|
+
def with_user_logins
|
26
|
+
q = self; t = table_name
|
27
|
+
if current_scope.nil? || current_scope.select_values.exclude?("#{t}.*")
|
28
|
+
q = q.select("#{t}.*")
|
29
|
+
end
|
30
|
+
if self.column_names.include?('created_by_id')
|
31
|
+
q = q.select("created_by_user.login as created_by_login")
|
32
|
+
.joins("left join lanes_users as created_by_user on " \
|
33
|
+
"created_by_user.id = #{t}.created_by_id")
|
34
|
+
end
|
35
|
+
if self.column_names.include?('updated_by_id')
|
36
|
+
q = q.select("updated_by_user.login as updated_by_login")
|
37
|
+
.joins("left join lanes_users as updated_by_user on " \
|
38
|
+
"updated_by_user.id = #{t}.updated_by_id")
|
39
|
+
end
|
40
|
+
q
|
41
|
+
end
|
42
|
+
|
19
43
|
end
|
20
44
|
|
21
45
|
private
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'action_cable'
|
2
|
+
# require 'action_cable/subscription_adapter/postgresql'
|
3
|
+
|
4
|
+
module Lanes
|
5
|
+
module API
|
6
|
+
module Cable
|
7
|
+
mattr_reader :server
|
8
|
+
mattr_reader :config
|
9
|
+
|
10
|
+
|
11
|
+
class Channel < ActionCable::Channel::Base
|
12
|
+
end
|
13
|
+
|
14
|
+
class Connection < ActionCable::Connection::Base
|
15
|
+
identified_by :current_user
|
16
|
+
|
17
|
+
def connect
|
18
|
+
reject_unauthorized_connection unless
|
19
|
+
cookies['user_id'] &&
|
20
|
+
self.current_user = Lanes::User.where(id: cookies['user_id']).first
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
|
25
|
+
def cookies
|
26
|
+
request.session
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.configure
|
31
|
+
require_relative 'updates'
|
32
|
+
@@config = ActionCable::Server::Configuration.new
|
33
|
+
config.logger = Lanes.logger
|
34
|
+
config.cable = Lanes.config.cable
|
35
|
+
config.connection_class = -> { Connection }
|
36
|
+
config.allowed_request_origins = -> (host) {
|
37
|
+
host
|
38
|
+
}
|
39
|
+
|
40
|
+
ActionCable::Server::Base.config = config
|
41
|
+
@@server = ActionCable.server
|
42
|
+
Updates.relay!
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -33,39 +33,64 @@ module Lanes
|
|
33
33
|
|
34
34
|
protected
|
35
35
|
|
36
|
+
def perform_retrieval
|
37
|
+
query = build_query
|
38
|
+
query = add_scopes_to_query(query)
|
39
|
+
query = add_access_limits_to_query(query)
|
40
|
+
options = build_reply_options
|
41
|
+
if should_include_total_count?
|
42
|
+
options[:total_count] = count_query_records(query)
|
43
|
+
end
|
44
|
+
query = add_modifiers_to_query(query)
|
45
|
+
if params[:id]
|
46
|
+
query = query.first!
|
47
|
+
end
|
48
|
+
std_api_reply(:retrieve, query, options)
|
49
|
+
end
|
50
|
+
|
36
51
|
def perform_single_destroy
|
37
|
-
|
52
|
+
query = model.where(id: params[:id])
|
53
|
+
query = add_access_limits_to_query(query)
|
54
|
+
record = query.first!
|
38
55
|
record.destroy
|
39
56
|
std_api_reply(:destroy, record, {})
|
40
57
|
end
|
41
58
|
|
42
59
|
def perform_multiple_destroy
|
43
|
-
|
60
|
+
query = model.where( id: data.map{|rec|rec['id']} )
|
61
|
+
query = add_access_limits_to_query(query)
|
44
62
|
success = true
|
45
|
-
|
63
|
+
query.each do | record |
|
46
64
|
if user.can_delete?(record, record.id)
|
47
65
|
success = false unless record.destroy
|
48
66
|
end
|
49
67
|
end
|
50
68
|
options = build_reply_options.merge(success: success)
|
51
|
-
std_api_reply(:destroy,
|
69
|
+
std_api_reply(:destroy, query, options)
|
52
70
|
end
|
53
71
|
|
54
72
|
def perform_multiple_updates
|
55
|
-
|
73
|
+
|
74
|
+
query = model.where( id: data.map{|rec|rec['id']} )
|
75
|
+
query = add_access_limits_to_query(query)
|
76
|
+
|
56
77
|
success = true
|
57
|
-
|
78
|
+
query.each do | record |
|
58
79
|
record_data = data.detect{ |rd| rd['id'] == record.id }
|
80
|
+
next unless record_data
|
59
81
|
if user.can_write?(record, record.id)
|
60
82
|
record.set_attribute_data(record_data, user)
|
61
83
|
success = false unless record.save
|
62
84
|
end
|
63
85
|
end
|
64
86
|
options = build_reply_options.merge(success: success)
|
65
|
-
std_api_reply(:update,
|
87
|
+
std_api_reply(:update, query, options)
|
66
88
|
end
|
67
89
|
|
68
|
-
def perform_single_update
|
90
|
+
def perform_single_update
|
91
|
+
query = build_query
|
92
|
+
query = add_access_limits_to_query(query)
|
93
|
+
record = query.first!
|
69
94
|
record.set_attribute_data(data, user)
|
70
95
|
options = build_reply_options.merge(success: record.save)
|
71
96
|
std_api_reply(:update, record, options)
|
@@ -149,6 +174,14 @@ module Lanes
|
|
149
174
|
|
150
175
|
# query options
|
151
176
|
|
177
|
+
def add_access_limits_to_query(query)
|
178
|
+
if model.respond_to?(:access_limits_for_query)
|
179
|
+
query = model.access_limits_for_query(query, user, params)
|
180
|
+
else
|
181
|
+
query
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
152
185
|
def build_query(query = model.all)
|
153
186
|
if params[:id]
|
154
187
|
query = query.where(id: params[:id])
|
@@ -156,16 +189,26 @@ module Lanes
|
|
156
189
|
if params[:nested_attribute]
|
157
190
|
query = query.where(params[:nested_attribute])
|
158
191
|
end
|
192
|
+
query = add_access_limits_to_query(query)
|
193
|
+
|
159
194
|
if query_params.present?
|
160
195
|
query = add_params_to_query(query)
|
161
196
|
end
|
162
197
|
query
|
163
198
|
end
|
164
199
|
|
165
|
-
def
|
200
|
+
def count_query_records(query)
|
201
|
+
model.from('('+query.to_sql+') q').count
|
202
|
+
end
|
203
|
+
|
204
|
+
def add_scopes_to_query(query)
|
166
205
|
if query_scopes.present?
|
167
206
|
query = add_scope_to_query(query)
|
168
207
|
end
|
208
|
+
query
|
209
|
+
end
|
210
|
+
|
211
|
+
def add_modifiers_to_query(query)
|
169
212
|
query = query.limit(query_limit_size)
|
170
213
|
query = query.offset(query_offset.to_i) if query_offset.present?
|
171
214
|
if include_associations.any?
|
@@ -10,6 +10,15 @@ module Lanes
|
|
10
10
|
get Lanes.config.api_path + '/asset/*',
|
11
11
|
&API::Handlers::Asset.getter
|
12
12
|
|
13
|
+
get Lanes.config.api_path + '/ws' do
|
14
|
+
API::Cable.server.call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
post Lanes.config.api_path + '/dev-file-change.json' do
|
18
|
+
API::PubSub.publish("file-change", data)
|
19
|
+
"OK"
|
20
|
+
end
|
21
|
+
|
13
22
|
Extensions.each(reversed: true) do | ext |
|
14
23
|
ext.route(self)
|
15
24
|
end
|
@@ -5,14 +5,7 @@ module Lanes
|
|
5
5
|
class GenericController < ControllerBase
|
6
6
|
|
7
7
|
def show
|
8
|
-
|
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)
|
8
|
+
perform_retrieval
|
16
9
|
end
|
17
10
|
|
18
11
|
def create
|
@@ -23,7 +16,7 @@ module Lanes
|
|
23
16
|
|
24
17
|
def update
|
25
18
|
if params[:id]
|
26
|
-
perform_single_update
|
19
|
+
perform_single_update
|
27
20
|
elsif data.is_a?(Array)
|
28
21
|
perform_multiple_updates
|
29
22
|
end
|
@@ -4,8 +4,6 @@ module Lanes::API::Handlers
|
|
4
4
|
|
5
5
|
def self.saver
|
6
6
|
lambda do
|
7
|
-
Lanes.logger.debug "Saving File. Root=#{CarrierWave.root}"
|
8
|
-
|
9
7
|
path = "#{params['extension_id']}/#{params['owner_type']}"
|
10
8
|
model = path.underscore.camelize.constantize
|
11
9
|
|
@@ -17,7 +15,8 @@ module Lanes::API::Handlers
|
|
17
15
|
else
|
18
16
|
owner.send("build_#{params['owner_association']}")
|
19
17
|
end
|
20
|
-
|
18
|
+
|
19
|
+
asset.update(file: params['file'])
|
21
20
|
|
22
21
|
json_reply std_api_reply asset.new_record? ? :update : :create,
|
23
22
|
asset,
|
@@ -27,10 +26,10 @@ module Lanes::API::Handlers
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def self.getter
|
29
|
+
root = Lanes::Extensions.controlling
|
30
|
+
.root_path.join('public', 'files')
|
30
31
|
lambda do
|
31
|
-
|
32
|
-
# knows the filename has access and don't empose any further restrictions
|
33
|
-
send_file CarrierWave::Uploader::Base.root.call + '/' + params['splat'].first
|
32
|
+
- send_file(root.join( params['splat'].first ).to_s)
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
@@ -15,8 +15,9 @@ module Lanes
|
|
15
15
|
stylesheet_tag('lanes')
|
16
16
|
end
|
17
17
|
|
18
|
-
def client_bootstrap_data
|
19
|
-
Oj.dump(Extensions.client_bootstrap_data(self)
|
18
|
+
def client_bootstrap_data(mergedWith: {})
|
19
|
+
Oj.dump(Extensions.client_bootstrap_data(self)
|
20
|
+
.merge(mergedWith), mode: :compat)
|
20
21
|
end
|
21
22
|
|
22
23
|
def csrf_token
|
@@ -21,7 +21,7 @@ module Lanes
|
|
21
21
|
|
22
22
|
def get_js_aliases(ns)
|
23
23
|
ext = Extensions.for_identifier(ns)
|
24
|
-
aliases = ext ? ext.client_js_aliases : {}
|
24
|
+
aliases = ext ? ext.client_js_aliases || {} : {}
|
25
25
|
aliases.merge!({
|
26
26
|
'LC' => 'window.Lanes.Components',
|
27
27
|
'React' => 'window.Lanes.Vendor.React',
|
@@ -58,10 +58,11 @@ module Lanes
|
|
58
58
|
(aliases, definitions) = get_js_aliases(identifier)
|
59
59
|
ns, ns_file_ref, ns_ref, ns_name = get_wrapping_vars(identifier)
|
60
60
|
file="{namespace:#{ns_file_ref},extension:{name:'#{ns}',identifier:'#{identifier}'},path:#{path}}"
|
61
|
-
"(function(Lanes,#{ns_name}_,#{aliases},FILE,window,undefined)"\
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
"(function(Lanes,#{ns_name}_,#{aliases},FILE,window,undefined)" \
|
62
|
+
"{\n#{js}\n})" \
|
63
|
+
"((window.Lanes = (window.Lanes || {})),#{ns_ref}" \
|
64
|
+
"(window.Lanes.Vendor = (window.Lanes.Vendor || {})).ld," \
|
65
|
+
"#{definitions},#{file},window);"
|
65
66
|
end
|
66
67
|
|
67
68
|
end
|