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
@@ -59,22 +59,12 @@ class Page
|
|
59
59
|
|
60
60
|
modelAt: (index, options) ->
|
61
61
|
row = @_rowAt(index)
|
62
|
-
@
|
63
|
-
id = @idForRow(row)
|
64
|
-
if _.isBlank(id)
|
65
|
-
@_rowToModel(row)
|
66
|
-
else
|
67
|
-
@modelCache[id] ||= @_rowToModel(row)
|
62
|
+
@_rowToModel(row)
|
68
63
|
|
69
64
|
saveModelChanges: (model, index) ->
|
70
65
|
row = @_rowAt(index)
|
71
|
-
@modelCache[ @idForRow(row)] = model
|
72
|
-
data = model.serialize()
|
73
66
|
for field, i in @result.query.fields.models
|
74
|
-
row[field.fetchIndex] =
|
75
|
-
|
76
|
-
idForRow: (row) ->
|
77
|
-
row[@result.query.idIndex]
|
67
|
+
row[field.fetchIndex] = model[field.id]
|
78
68
|
|
79
69
|
addBlankRow: (index) ->
|
80
70
|
model = new @result.query.model
|
@@ -127,7 +117,7 @@ class Lanes.Models.Query.ArrayResult extends Lanes.Models.Query.Result
|
|
127
117
|
eachRow: (fn) ->
|
128
118
|
for i in [0...@length]
|
129
119
|
row = @rowAt(i)
|
130
|
-
fn(row, row[@xDataColumn], i)
|
120
|
+
return i if 'break' is fn(row, row[@xDataColumn], i)
|
131
121
|
|
132
122
|
map: (fn) ->
|
133
123
|
rows = []
|
@@ -135,6 +125,12 @@ class Lanes.Models.Query.ArrayResult extends Lanes.Models.Query.Result
|
|
135
125
|
rows.push fn(row, xd, i)
|
136
126
|
rows
|
137
127
|
|
128
|
+
findById: (id) ->
|
129
|
+
@eachRow (row, xd, i) =>
|
130
|
+
return 'break' if id is @idForRow(row)
|
131
|
+
|
132
|
+
idForRow: (row) ->
|
133
|
+
row[@query.idIndex]
|
138
134
|
|
139
135
|
filteredRows: (fn) ->
|
140
136
|
found = []
|
@@ -146,7 +142,10 @@ class Lanes.Models.Query.ArrayResult extends Lanes.Models.Query.Result
|
|
146
142
|
@pageForIndex(index).modelAt(index)
|
147
143
|
|
148
144
|
saveModelChanges: (model, index) ->
|
145
|
+
if _.isUndefined(index)
|
146
|
+
index = @findById( model.getId() )
|
149
147
|
@pageForIndex(index).saveModelChanges(model, index)
|
148
|
+
@query.markModified()
|
150
149
|
|
151
150
|
removeRow: (index = 0) ->
|
152
151
|
@total -= 1
|
@@ -184,8 +183,8 @@ class Lanes.Models.Query.ArrayResult extends Lanes.Models.Query.Result
|
|
184
183
|
rowRepresentation: (rowNum) ->
|
185
184
|
@pageForIndex(rowNum).rowAt(rowNum)
|
186
185
|
|
187
|
-
valueForField: (
|
188
|
-
|
186
|
+
valueForField: (row, field) ->
|
187
|
+
if field.fetchIndex? then row[ field.fetchIndex ] else undefined
|
189
188
|
|
190
189
|
_updateSort: ->
|
191
190
|
fn = @sortingFunction()
|
@@ -194,11 +193,11 @@ class Lanes.Models.Query.ArrayResult extends Lanes.Models.Query.Result
|
|
194
193
|
rows = if @query.sortAscending then rows.reverse() else rows
|
195
194
|
page = new Page(0, @, rows: rows)
|
196
195
|
@pages = [page]
|
197
|
-
@query.
|
196
|
+
@query.markModified()
|
198
197
|
@
|
199
198
|
else
|
200
199
|
@reload().then =>
|
201
|
-
@query.
|
200
|
+
@query.markModified()
|
202
201
|
@
|
203
202
|
|
204
203
|
Object.defineProperty Lanes.Models.Query.ArrayResult.prototype, 'length',
|
@@ -5,7 +5,7 @@ class Lanes.Models.Query.CollectionResult extends Lanes.Models.Query.Result
|
|
5
5
|
@query.trigger('change', @query)
|
6
6
|
)
|
7
7
|
@collection.on('sort', =>
|
8
|
-
@query.
|
8
|
+
@query.markModified()
|
9
9
|
)
|
10
10
|
|
11
11
|
this
|
@@ -28,7 +28,7 @@ class Lanes.Models.Query.CollectionResult extends Lanes.Models.Query.Result
|
|
28
28
|
|
29
29
|
@collection.remove(old)
|
30
30
|
@collection.add(model, at:index)
|
31
|
-
@query.
|
31
|
+
@query.markModified()
|
32
32
|
|
33
33
|
addBlankRow: (index) ->
|
34
34
|
@collection.add({}, at: index)
|
@@ -49,8 +49,8 @@ class Lanes.Models.Query.CollectionResult extends Lanes.Models.Query.Result
|
|
49
49
|
rowRepresentation: (rowNum) ->
|
50
50
|
@modelAt(rowNum)
|
51
51
|
|
52
|
-
valueForField: (
|
53
|
-
|
52
|
+
valueForField: (model, field) ->
|
53
|
+
model[field.id]
|
54
54
|
|
55
55
|
fieldToSortValue:
|
56
56
|
any: (v) -> v
|
@@ -1,20 +1,21 @@
|
|
1
|
-
createHelper = (component, name) ->
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
1
|
+
# createHelper = (component, name) ->
|
2
|
+
# unless component.prototype[name]
|
3
|
+
# Object.defineProperty(component.prototype, name,
|
4
|
+
# configurable: true, enumerable: true
|
5
|
+
# get: -> @data?.states[name]
|
6
|
+
# set: (val) ->
|
7
|
+
# @data?.rebind("#{name}": val)
|
8
|
+
# )
|
9
9
|
|
10
|
-
extendComponent = (component) ->
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
# extendComponent = (component) ->
|
11
|
+
# names = _.keys(component.prototype.dataObjects).concat(['collection', 'model'])
|
12
|
+
# for name in _.uniq(names)
|
13
|
+
# createHelper(component, name)
|
14
14
|
|
15
15
|
Lanes.React.Component = {
|
16
16
|
|
17
17
|
defaultMixins: [
|
18
|
+
Lanes.Vendor.ReactModelMixin
|
18
19
|
Lanes.React.Mixins.Data
|
19
20
|
Lanes.React.Mixins.Viewport
|
20
21
|
Lanes.React.Mixins.Component
|
@@ -24,7 +25,7 @@ Lanes.React.Component = {
|
|
24
25
|
klass::mixins ||= []
|
25
26
|
klass::mixins = _.uniq(klass::mixins.concat(mixins))
|
26
27
|
comp = React.createClass(klass.prototype)
|
27
|
-
extendComponent(comp)
|
28
|
+
# extendComponent(comp)
|
28
29
|
return Lanes.lib.HotReload?.remember(comp) or comp
|
29
30
|
}
|
30
31
|
|
@@ -1,4 +1,7 @@
|
|
1
1
|
ALL_INSTANCES = []
|
2
|
+
class FakeHistory
|
3
|
+
push: Lanes.emptyFn
|
4
|
+
replace: Lanes.emptyFn
|
2
5
|
|
3
6
|
class Lanes.React.Viewport extends Lanes.Models.State
|
4
7
|
|
@@ -6,17 +9,20 @@ class Lanes.React.Viewport extends Lanes.Models.State
|
|
6
9
|
@displayError: (msg) -> _.first(ALL_INSTANCES)?.displayError(msg)
|
7
10
|
|
8
11
|
session:
|
9
|
-
width:
|
10
|
-
height:
|
11
|
-
el:
|
12
|
-
selector:
|
13
|
-
domRoot:
|
14
|
-
reactRoot:
|
15
|
-
lanes:
|
16
|
-
modalProps:
|
12
|
+
width: 'number'
|
13
|
+
height: 'number'
|
14
|
+
el: 'element'
|
15
|
+
selector: 'string'
|
16
|
+
domRoot: 'element'
|
17
|
+
reactRoot: 'object'
|
18
|
+
lanes: 'element'
|
19
|
+
modalProps: 'object'
|
17
20
|
pubSubDisabled: 'boolean'
|
18
|
-
rootComponent:
|
19
|
-
rootProps:
|
21
|
+
rootComponent: 'any'
|
22
|
+
rootProps: 'object'
|
23
|
+
rootElement: 'object'
|
24
|
+
history: 'object'
|
25
|
+
useHistory: {type: 'boolean', default: true}
|
20
26
|
|
21
27
|
constructor: ->
|
22
28
|
super
|
@@ -27,6 +33,7 @@ class Lanes.React.Viewport extends Lanes.Models.State
|
|
27
33
|
Lanes.fatal("Root selector #{@selector} not found") unless @domRoot
|
28
34
|
_.dom(@domRoot).html = "<div class='lanes'/>"
|
29
35
|
this.lanes = @domRoot.querySelector('.lanes')
|
36
|
+
|
30
37
|
Lanes.lib.ResizeSensor(@domRoot, _.debounce( =>
|
31
38
|
@_updateDimensions()
|
32
39
|
, 250))
|
@@ -41,10 +48,39 @@ class Lanes.React.Viewport extends Lanes.Models.State
|
|
41
48
|
|
42
49
|
onBoot: ->
|
43
50
|
prev = _.dom(this.domRoot.previousElementSibling)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
51
|
+
if @useHistory
|
52
|
+
@initializeHistory()
|
53
|
+
else
|
54
|
+
@history = new FakeHistory
|
55
|
+
if prev.hasClass('loading')
|
56
|
+
prev.addClass('complete')
|
57
|
+
_.delay(->
|
58
|
+
prev.remove()
|
59
|
+
, 100)
|
60
|
+
|
61
|
+
initializeHistory: ->
|
62
|
+
useBasename = Lanes.Vendor.BrowserHistory.useBasename
|
63
|
+
|
64
|
+
@history = useBasename(Lanes.Vendor.BrowserHistory.createHistory)({
|
65
|
+
basename: Lanes.config.root_path
|
66
|
+
})
|
67
|
+
@_historyStopListening = @history.listen (location) ->
|
68
|
+
Lanes.Screens.Definitions.setBrowserLocation(location)
|
69
|
+
|
70
|
+
Lanes.Screens.Definitions.setBrowserLocation(
|
71
|
+
@history.getCurrentLocation()
|
72
|
+
)
|
73
|
+
|
74
|
+
Lanes.Screens.Definitions.displaying.on('change:active', (screen) =>
|
75
|
+
if screen.active
|
76
|
+
@history.replace(screen.historyUrl())
|
77
|
+
if Lanes.Screens.Definitions.displaying.length is 0
|
78
|
+
@history.push('/')
|
79
|
+
)
|
80
|
+
|
81
|
+
close: ->
|
82
|
+
@hideModal()
|
83
|
+
@_historyStopListening?()
|
48
84
|
|
49
85
|
_updateDimensions: ->
|
50
86
|
this.set
|
@@ -70,7 +106,7 @@ class Lanes.React.Viewport extends Lanes.Models.State
|
|
70
106
|
component = cntrl?.rootComponent?(this) ||
|
71
107
|
Lanes.React.Root.DefaultComponentNotFound
|
72
108
|
)
|
73
|
-
|
109
|
+
@rootElement = React.createElement(Lanes.React.Root, {viewport: @},
|
74
110
|
React.createElement(component, _.extend(@rootProps, extension: cntrl))
|
75
111
|
)
|
76
|
-
@reactRoot = Lanes.Vendor.ReactDOM.render(
|
112
|
+
@reactRoot = Lanes.Vendor.ReactDOM.render(@rootElement, @lanes)
|
@@ -17,6 +17,11 @@ Lanes.React.Mixins.Access = {
|
|
17
17
|
componentDidMount: ->
|
18
18
|
calculateAccess(this, @props)
|
19
19
|
|
20
|
+
propTypes:
|
21
|
+
writable: React.PropTypes.bool
|
22
|
+
readable: React.PropTypes.bool
|
23
|
+
readonly: React.PropTypes.bool
|
24
|
+
|
20
25
|
componentWillReceiveProps: (newProps) ->
|
21
26
|
calculateAccess(this, newProps)
|
22
27
|
|
@@ -1,157 +1,65 @@
|
|
1
|
-
|
2
|
-
# https://github.com/magalhas/backbone-react-component/blob/master/lib/component.js
|
3
|
-
|
4
|
-
# Mixing `Backbone.Events` into `Wrapper.prototype`
|
5
|
-
# Binds models and collections to a `React.Component`. It mixes `Backbone.Events`.
|
6
|
-
|
7
|
-
class DataWrapper
|
8
|
-
|
9
|
-
constructor: (@component, initialState = {}) ->
|
10
|
-
# Object to store data state (not the component state)
|
11
|
-
@states = {}
|
12
|
-
@rebind(_.clone(initialState), silent: true)
|
13
|
-
|
14
|
-
rebind: (objects, options = {}) ->
|
15
|
-
customEvents = _.result(@component, 'bindDataEvents', {})
|
16
|
-
@_rebindAttr(name, state, customEvents[name], options) for name, state of objects when state isnt false
|
17
|
-
|
18
|
-
_rebindAttr: (name, state, ev, options) ->
|
19
|
-
unless state
|
20
|
-
Lanes.warn "#{name} is not set on #{@componentName()}"
|
21
|
-
return
|
22
|
-
|
23
|
-
prevState = @states[name]
|
24
|
-
|
25
|
-
# onto next if the object is the same
|
26
|
-
return if prevState == state
|
27
|
-
|
28
|
-
@states[name] = state
|
29
|
-
|
30
|
-
this.bindEvents(name, state, ev)
|
31
|
-
|
32
|
-
if Lanes.u.isModel(state)
|
33
|
-
@listenToNetworkEvents(state) if @component.listenNetworkEvents
|
34
|
-
if @isStateUsingPubsub(name, state)
|
35
|
-
if !prevState? or prevState.getId() != state.getId()
|
36
|
-
Lanes.Models.PubSub.remove(prevState) if prevState
|
37
|
-
unless false == state.pubsub
|
38
|
-
if state.isNew()
|
39
|
-
state.once "change:#{state.idAttribute}", -> Lanes.Models.PubSub.add(state)
|
40
|
-
else
|
41
|
-
Lanes.Models.PubSub.add(state)
|
42
|
-
@listenTo(state, 'remote-update', @onPubSubChangeSet)
|
43
|
-
this.setComponentState({}) unless options.silent
|
44
|
-
|
45
|
-
listenToNetworkEvents: (state) ->
|
46
|
-
@listenTo(state, 'error', @onError)
|
47
|
-
.listenTo(state, 'request', @onRequest)
|
48
|
-
.listenTo(state, 'load sync', @onSync)
|
49
|
-
|
50
|
-
onPubSubChangeSet: (model, cs) ->
|
51
|
-
screen = @component.context?.screen || @component.getChildContext?()?.screen
|
52
|
-
screen?.onPubSubChangeSet?(model, cs)
|
53
|
-
|
54
|
-
componentName: ->
|
55
|
-
@component.constructor.displayName
|
56
|
-
|
57
|
-
onProxyReplace: (name, model) ->
|
58
|
-
@states[name] = model
|
59
|
-
@setComponentState(name, model)
|
60
|
-
|
61
|
-
bindEvents: (name, state, events) ->
|
62
|
-
if state.isProxy
|
63
|
-
@listenTo(state, 'proxyreplace', _.partial(@onProxyReplace, name))
|
64
|
-
if !events
|
65
|
-
if state.isState or state.isProxy
|
66
|
-
events ||= 'change'
|
67
|
-
else if Lanes.u.isCollection(state)
|
68
|
-
events ||= 'add remove change sort reset'
|
69
|
-
else
|
70
|
-
Lanes.warn "Unable to listen to unknown type #{name}"
|
71
|
-
|
72
|
-
@listenTo(state, events, _.partial(@setComponentState, name, state))
|
1
|
+
class NetworkEventListener
|
73
2
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
3
|
+
constructor: (component) -> @component = component
|
4
|
+
|
5
|
+
bindEvents: (events, model) ->
|
6
|
+
model.on('error', @onError, @)
|
7
|
+
.on('request', @onRequest, @)
|
8
|
+
.on('load sync', @onSync, @)
|
9
|
+
|
10
|
+
unBindEvents: (events, model) ->
|
11
|
+
model.off(null, null, @)
|
81
12
|
|
82
|
-
|
83
|
-
|
13
|
+
setState: (state, options) ->
|
14
|
+
return if options?.silent
|
15
|
+
fn = @component.setNetworkActivity or @component.setState
|
16
|
+
fn.call(@component, state)
|
17
|
+
|
18
|
+
onError: (modelOrCollection, options) ->
|
19
|
+
@setState(
|
20
|
+
isRequesting: false
|
21
|
+
hasError: modelOrCollection?.errorMessage or true
|
22
|
+
errors: modelOrCollection.errors
|
23
|
+
)
|
84
24
|
|
85
25
|
onRequest: (modelOrCollection, type, options) ->
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
isInvalid: false
|
26
|
+
@setState(
|
27
|
+
isRequesting: true
|
28
|
+
hasError: false
|
29
|
+
errors: []
|
30
|
+
)
|
92
31
|
|
93
32
|
onSync: (modelOrCollection, res, options = {}) ->
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
state = if _.isObject(key) then key else {"#{key}": value}
|
100
|
-
if _.isFunction(@component.setDataState)
|
101
|
-
@component.setDataState(state, args...)
|
102
|
-
else
|
103
|
-
@component.setState(state)
|
104
|
-
true
|
105
|
-
|
106
|
-
isStateUsingPubsub: (name, state) ->
|
107
|
-
_.result(state, 'registerforPubSub') isnt false and
|
108
|
-
not (false == @component.pubsub or false == @component.pubsub?[name])
|
109
|
-
|
110
|
-
destroy: (state, events, fn) ->
|
111
|
-
for name, state of @states when @isStateUsingPubsub(name, state)
|
112
|
-
Lanes.Models.PubSub.remove(state) if Lanes.u.isModel(state)
|
113
|
-
this.stopListening()
|
114
|
-
delete @component.data
|
115
|
-
|
116
|
-
|
117
|
-
Lanes.Vendor.Events.createEmitter(DataWrapper.prototype)
|
118
|
-
#_.extend(DataWrapper.prototype, Lanes.Vendor.BBEvents)
|
119
|
-
|
120
|
-
readDataObjects = (comp, newProps) ->
|
121
|
-
bound = _.clone _.result(comp, 'dataObjects') || {}
|
122
|
-
bound.model ||= 'props' if comp.props.model
|
123
|
-
bound.collection ||= 'props' if comp.props.collection
|
124
|
-
_.mapValues(bound, (value, name) ->
|
125
|
-
if _.isFunction(value)
|
126
|
-
if _.isEmpty(comp.data?.states[name]) then value.call(comp) else false
|
127
|
-
else if 'props' == value then newProps?[name] or comp.props[name]
|
128
|
-
else value
|
129
|
-
)
|
33
|
+
@setState(isRequesting: false)
|
34
|
+
|
35
|
+
getNetworkListener = (component) ->
|
36
|
+
return unless _.result(component, 'listenNetworkEvents') is true
|
37
|
+
component._networkEventsListener ||= new NetworkEventListener(component)
|
130
38
|
|
131
39
|
Lanes.React.Mixins.Data = {
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
@
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
if
|
147
|
-
|
40
|
+
|
41
|
+
onModelUnbind: (model, name) ->
|
42
|
+
Lanes.Models.PubSub.remove(model)
|
43
|
+
getNetworkListener(@)?.unBindEvents(@modelBindings, model)
|
44
|
+
|
45
|
+
onModelBind: (model, name) ->
|
46
|
+
model = this[name]
|
47
|
+
return unless Lanes.u.isModel(model)
|
48
|
+
|
49
|
+
getNetworkListener(@)?.bindEvents(@modelBindings, @[name])
|
50
|
+
|
51
|
+
return if _.result(model, 'registerForPubSub') is false or
|
52
|
+
_.result(@, 'registerForPubSub') is false
|
53
|
+
|
54
|
+
if model.isNew()
|
55
|
+
model.once "change:#{model.idAttribute}", -> Lanes.Models.PubSub.add(model)
|
148
56
|
else
|
149
|
-
|
57
|
+
Lanes.Models.PubSub.add(model)
|
150
58
|
|
151
|
-
|
152
|
-
|
59
|
+
this.modelBindings.listenTo(model, 'remote-update', (model, cs) =>
|
60
|
+
screen = @context?.screen || @getChildContext?()?.screen
|
61
|
+
screen?.onPubSubChangeSet?(model, cs)
|
62
|
+
)
|
153
63
|
|
154
|
-
stopListening: (state, events, fn) ->
|
155
|
-
@data.stopListening(state, events, fn)
|
156
64
|
|
157
65
|
}
|
@@ -7,5 +7,5 @@ Lanes.React.Mixins.MonitorSize = {
|
|
7
7
|
|
8
8
|
componentDidMount: ->
|
9
9
|
if @context.viewport
|
10
|
-
@
|
10
|
+
@modelBindings.listenTo(@context.viewport, 'change:height change:width', @_updateViewportSize)
|
11
11
|
}
|
@@ -13,7 +13,7 @@ class Lanes.Screens.Commands extends Lanes.Models.State
|
|
13
13
|
|
14
14
|
setModel: (model) ->
|
15
15
|
@options.modelWillRebind?(model)
|
16
|
-
@screen.
|
16
|
+
@screen.modelBindings.reset({"#{@options.modelName}": model})
|
17
17
|
@screen.setModelUrl?(model)
|
18
18
|
@options.modelDidRebind?(model)
|
19
19
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class Lanes.Screens.CommonComponents extends Lanes.React.Component
|
2
2
|
|
3
3
|
propTypes:
|
4
|
-
commands: React.PropTypes.
|
4
|
+
commands: React.PropTypes.object.isRequired
|
5
5
|
errors: React.PropTypes.bool
|
6
6
|
networkActivity: React.PropTypes.bool
|
7
7
|
toolbarProps: React.PropTypes.object
|
@@ -13,7 +13,7 @@ class Lanes.Screens.CommonComponents extends Lanes.React.Component
|
|
13
13
|
<div>
|
14
14
|
{unless @networkActivity is false
|
15
15
|
<LC.NetworkActivityOverlay model={model} {...@props} /> }
|
16
|
-
<LC.Toolbar {...@props} {...@props.toolbarProps}>
|
16
|
+
<LC.Toolbar {...@props} {...@props.toolbarProps} model={model}>
|
17
17
|
{@props.children}
|
18
18
|
</LC.Toolbar>
|
19
19
|
{<LC.ErrorDisplay model={model} {...@props} /> unless @errors is false}
|
@@ -64,7 +64,9 @@ class ScreenDefinition extends Lanes.Models.BasicModel
|
|
64
64
|
@url_prefix
|
65
65
|
else
|
66
66
|
"#{@extension.toLowerCase()}/screens"
|
67
|
-
@assets.map (asset) ->
|
67
|
+
@assets.map (asset) ->
|
68
|
+
"//#{Lanes.config.api_host}" +
|
69
|
+
"#{Lanes.config.assets_path_prefix}/#{prefix}/#{asset}"
|
68
70
|
|
69
71
|
extension_path:
|
70
72
|
deps: ['extension', 'model'], fn: ->
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Lanes.Screens.SystemSettings extends Lanes.React.Screen
|
2
2
|
|
3
|
-
|
3
|
+
modelBindings:
|
4
4
|
config: -> Lanes.config.system_settings
|
5
5
|
|
6
6
|
getInitialState: ->
|
@@ -15,7 +15,7 @@ class Lanes.Screens.SystemSettings extends Lanes.React.Screen
|
|
15
15
|
dir = @config.settings.lanes.storage_dir
|
16
16
|
<LC.FieldWrapper
|
17
17
|
model={@config} displayComponent={<span />}
|
18
|
-
label='Store Directory' sm=9
|
18
|
+
label='Store Directory' sm=9 value={dir}>
|
19
19
|
<input type="text" className='value form-control'
|
20
20
|
placeholder="Directory to store files" value={dir}
|
21
21
|
onChange={_.partial(@onChange, 'storage_dir')} />
|
@@ -45,24 +45,19 @@ class Lanes.Screens.SystemSettings extends Lanes.React.Screen
|
|
45
45
|
|
46
46
|
<LC.ScreenWrapper identifier="system-settings">
|
47
47
|
<BS.Nav bsStyle="pills" className="lanes-toolbar">
|
48
|
-
<BS.
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
<BS.NavItem>
|
49
|
+
<BS.Button componentClass="button"
|
50
|
+
onClick={@saveConfig}
|
51
|
+
className="save control"
|
52
|
+
>
|
53
|
+
<LC.Icon type="cloud-upload" />Save
|
54
|
+
</BS.Button>
|
55
|
+
</BS.NavItem>
|
52
56
|
</BS.Nav>
|
53
|
-
|
54
|
-
<BS.Row>
|
55
|
-
<LC.FieldWrapper
|
56
|
-
model={@config} displayComponent={<span />}
|
57
|
-
label='File Storage' sm=3 {...@props} value={storage}>
|
58
|
-
<Lanes.Vendor.ReactWidgets.DropdownList
|
59
|
-
data={choices} value={storage} onChange={_.partial(@onChange, 'storage')} />
|
60
|
-
</LC.FieldWrapper>
|
61
|
-
{if storage is 'file' then @renderFileOptions() else @renderFogOptions()}
|
62
|
-
</BS.Row>
|
63
57
|
<BS.Row>
|
64
|
-
<LC.ImageAsset sm=4 model={@config} name='logo'
|
58
|
+
<LC.ImageAsset sm=4 model={@config} name='logo'
|
59
|
+
label='Logo' size='thumb' />
|
65
60
|
</BS.Row>
|
66
61
|
{for id, Ext of Lanes.Extensions.instances when Ext.getSettingsElement
|
67
|
-
Ext.getSettingsElement(ref: id, key: id, settings: @config.settings[id])}
|
62
|
+
Ext.getSettingsElement(ref: id, key: id, settings: @config.settings[id] || {})}
|
68
63
|
</LC.ScreenWrapper>
|
@@ -4,10 +4,9 @@ $lanes-icon-font: 'FontAwesome';
|
|
4
4
|
|
5
5
|
@import "./fonts/font-awesome";
|
6
6
|
|
7
|
-
button, a.btn {
|
8
|
-
.icon {
|
7
|
+
button, a.btn, [role=button] {
|
8
|
+
.icon:not(.flush) {
|
9
9
|
margin-right: 0.5em;
|
10
|
-
&.flush { margin-right: 0; }
|
11
10
|
}
|
12
11
|
&.icon:before{
|
13
12
|
font-family: $lanes-icon-font;
|