lanes 0.1.9.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/Rakefile +1 -1
- data/client/lanes/Boot.cjsx +3 -3
- data/client/lanes/Config.coffee +38 -3
- data/client/lanes/access/Extension.coffee +1 -1
- data/client/lanes/access/LoginDialog.cjsx +57 -47
- data/client/lanes/access/Roles.coffee +2 -2
- data/client/lanes/access/User.coffee +4 -3
- data/client/lanes/access/screens/user-management/UserManagement.cjsx +12 -11
- data/client/lanes/components/calendar/Calendar.cjsx +16 -0
- data/client/lanes/components/calendar/index.js +3 -0
- data/client/lanes/components/calendar/styles.scss +3 -0
- data/client/lanes/components/grid/Body.cjsx +86 -0
- data/client/lanes/components/grid/CellStyles.coffee +20 -0
- data/client/lanes/components/grid/EditingMixin.cjsx +84 -24
- data/client/lanes/components/grid/Editor.cjsx +45 -0
- data/client/lanes/components/grid/Grid.cjsx +62 -104
- data/client/lanes/components/grid/Header.cjsx +35 -0
- data/client/lanes/components/grid/PopOverMixin.cjsx +19 -9
- data/client/lanes/components/grid/PopoverEditor.cjsx +7 -1
- data/client/lanes/components/grid/RowEditor.cjsx +1 -1
- data/client/lanes/components/grid/Selections.cjsx +39 -0
- data/client/lanes/components/grid/Toolbar.cjsx +24 -5
- data/client/lanes/components/grid/editors.scss +22 -50
- data/client/lanes/components/grid/index.js +0 -1
- data/client/lanes/components/grid/row-editor.scss +68 -0
- data/client/lanes/components/grid/styles.scss +79 -3
- data/client/lanes/components/modal/Modal.cjsx +64 -24
- data/client/lanes/components/modal/styles.scss +12 -0
- data/client/lanes/components/record-finder/Clause.cjsx +11 -4
- data/client/lanes/components/record-finder/Dialog.cjsx +23 -24
- data/client/lanes/components/record-finder/RecordFinder.cjsx +45 -14
- data/client/lanes/components/record-finder/styles.scss +9 -6
- data/client/lanes/components/select-field/SelectField.cjsx +108 -53
- data/client/lanes/components/select-field/styles.scss +19 -0
- data/client/lanes/components/shared/ControlLabel.cjsx +45 -0
- data/client/lanes/components/shared/DateTime.cjsx +48 -0
- data/client/lanes/components/shared/DisplayValue.cjsx +16 -0
- data/client/lanes/components/shared/FieldMixin.cjsx +54 -23
- data/client/lanes/components/shared/FieldSet.cjsx +12 -35
- data/client/lanes/components/shared/FieldWrapper.cjsx +13 -0
- data/client/lanes/components/shared/FormGroup.cjsx +37 -0
- data/client/lanes/components/shared/Icon.cjsx +20 -0
- data/client/lanes/components/shared/ImageSaver.cjsx +33 -0
- data/client/lanes/components/shared/Input.cjsx +19 -0
- data/client/lanes/components/shared/InputFieldMixin.cjsx +48 -0
- data/client/lanes/components/shared/JobProgress.cjsx +27 -0
- data/client/lanes/components/shared/NetworkActivityOverlay.cjsx +58 -0
- data/client/lanes/components/shared/NumberInput.cjsx +29 -0
- data/client/lanes/components/shared/ResizeSensor.cjsx +11 -0
- data/client/lanes/components/shared/ScreenWrapper.cjsx +13 -0
- data/client/lanes/components/shared/Throbber.cjsx +3 -0
- data/client/lanes/components/shared/ToggleField.cjsx +33 -0
- data/client/lanes/components/shared/Tooltip.cjsx +2 -2
- data/client/lanes/components/shared/fields.scss +75 -13
- data/client/lanes/components/shared/fieldset.scss +3 -5
- data/client/lanes/components/shared/image-saver.scss +38 -0
- data/client/lanes/components/shared/index.js +2 -0
- data/client/lanes/{styles/plugins → components/shared}/overlay.scss +17 -4
- data/client/lanes/components/shared/resize-sensor.scss +30 -0
- data/client/lanes/components/shared/styles.scss +13 -0
- data/client/lanes/components/shared/throbber.scss +53 -0
- data/client/lanes/components/toolbar/RemoteChangeSets.cjsx +21 -48
- data/client/lanes/components/toolbar/SaveButton.cjsx +24 -0
- data/client/lanes/components/toolbar/Toolbar.cjsx +24 -37
- data/client/lanes/components/toolbar/changes-notification.scss +10 -6
- data/client/lanes/components/toolbar/styles.scss +29 -9
- data/client/lanes/extension/Base.coffee +4 -5
- data/client/lanes/index.js +0 -1
- data/client/lanes/index.scss.erb +10 -1
- data/client/lanes/lib/HotReload.coffee +13 -15
- data/client/lanes/lib/MakeBaseClass.coffee +6 -1
- data/client/lanes/lib/development.coffee +2 -0
- data/client/lanes/lib/dom-polyfills.coffee +5 -0
- data/client/lanes/lib/dom.coffee +38 -9
- data/client/lanes/lib/format.coffee +11 -0
- data/client/lanes/lib/index.js.erb +2 -0
- data/client/lanes/lib/production.coffee +6 -0
- data/client/lanes/lib/utilFunctions.coffee +50 -15
- data/client/lanes/models/AssociationMap.coffee +122 -46
- data/client/lanes/models/AssociationProxy.coffee +147 -0
- data/client/lanes/models/Base.coffee +97 -85
- data/client/lanes/models/ChangeMonitor.coffee +7 -3
- data/client/lanes/models/ChangeSet.coffee +2 -2
- data/client/lanes/models/Collection.coffee +49 -6
- data/client/lanes/models/JobStatus.coffee +32 -0
- data/client/lanes/models/PubSub.coffee +7 -5
- data/client/lanes/models/Query.coffee +115 -34
- data/client/lanes/models/ServerCache.coffee +67 -52
- data/client/lanes/models/State.coffee +97 -0
- data/client/lanes/models/Sync.coffee +18 -13
- data/client/lanes/models/SystemSettings.coffee +0 -0
- data/client/lanes/models/index.js +1 -0
- data/client/lanes/models/mixins/FileSupport.coffee +60 -0
- data/client/lanes/models/mixins/HasCodeField.coffee +13 -6
- data/client/lanes/models/query/ArrayResult.coffee +188 -0
- data/client/lanes/models/query/CollectionResult.coffee +71 -0
- data/client/lanes/models/query/Result.coffee +9 -0
- data/client/lanes/react/Component.coffee +7 -3
- data/client/lanes/react/PubSub.coffee +7 -7
- data/client/lanes/react/Root.cjsx +1 -4
- data/client/lanes/react/Screen.coffee +1 -0
- data/client/lanes/react/TypeValidators.coffee +3 -3
- data/client/lanes/react/Viewport.coffee +41 -7
- data/client/lanes/react/index.js +0 -1
- data/client/lanes/react/mixins/Access.coffee +4 -1
- data/client/lanes/react/mixins/Data.coffee +40 -25
- data/client/lanes/react/mixins/FieldErrors.coffee +27 -0
- data/client/lanes/react/mixins/RelayEditingState.coffee +4 -0
- data/client/lanes/react/mixins/Screen.coffee +14 -0
- data/client/lanes/react/mixins/Viewport.coffee +9 -3
- data/client/lanes/screens/ChangeListener.coffee +3 -3
- data/client/lanes/screens/Commands.coffee +14 -7
- data/client/lanes/screens/CommonComponents.cjsx +20 -0
- data/client/lanes/screens/Definitions.coffee +64 -20
- data/client/lanes/screens/SystemSettings.cjsx +56 -0
- data/client/lanes/screens/UserPreferences.cjsx +38 -0
- data/client/lanes/screens/index.js +3 -0
- data/client/lanes/screens/styles.scss +2 -1
- data/client/lanes/styles/fonts.scss +1 -0
- data/client/lanes/styles/global.scss +2 -1
- data/client/lanes/styles/global/flexbox.scss +16 -0
- data/client/lanes/styles/global/styles.scss +1 -0
- data/client/lanes/styles/mixins/_dropdown.scss +21 -0
- data/client/lanes/styles/mixins/_flexbox.scss +394 -0
- data/client/lanes/styles/mixins/all.scss +2 -0
- data/client/lanes/styles/variables.scss +28 -0
- data/client/lanes/testing/BeforeEach.coffee +15 -14
- data/client/lanes/testing/Helpers.coffee +14 -5
- data/client/lanes/testing/TestObjects.coffee +10 -2
- data/client/lanes/testing/index.js +1 -0
- data/client/lanes/testing/jasmine-react.js +125 -0
- data/client/lanes/vendor/base.js +56049 -74987
- data/client/lanes/vendor/calendar.js +17301 -0
- data/client/lanes/vendor/calendar.scss +303 -0
- data/client/lanes/vendor/commons.js +14990 -15847
- data/client/lanes/vendor/development.js +4912 -1952
- data/client/lanes/vendor/grid.js +14246 -5551
- data/client/lanes/vendor/grid.scss +876 -335
- data/client/lanes/vendor/index.js +1 -0
- data/client/lanes/vendor/message-bus-ajax.js +44 -0
- data/client/lanes/vendor/message-bus.js +414 -0
- data/client/lanes/vendor/rw-widgets.eot +0 -0
- data/client/lanes/vendor/rw-widgets.svg +18 -0
- data/client/lanes/vendor/rw-widgets.ttf +0 -0
- data/client/lanes/vendor/rw-widgets.woff +0 -0
- data/client/lanes/vendor/toggle.js +345 -0
- data/client/lanes/vendor/toggle.scss +138 -0
- data/client/lanes/vendor/widgets.js +21245 -6839
- data/client/lanes/vendor/widgets.scss +83 -67
- data/client/lanes/workspace/Layout.cjsx +18 -8
- data/client/lanes/workspace/Modal.cjsx +47 -0
- data/client/lanes/workspace/Navbar.cjsx +16 -2
- data/client/lanes/workspace/ScreenView.cjsx +10 -3
- data/client/lanes/workspace/ScreensMenu.cjsx +23 -7
- data/client/lanes/workspace/Tabs.cjsx +55 -0
- data/client/lanes/workspace/UIState.coffee +7 -8
- data/client/lanes/workspace/index.js +2 -1
- data/client/lanes/workspace/mixin.coffee +11 -0
- data/client/lanes/workspace/mixins/UIState.coffee +8 -0
- data/client/lanes/workspace/mixins/index.js +3 -0
- data/client/lanes/workspace/styles.scss +2 -1
- data/client/lanes/workspace/styles/header.scss +23 -1
- data/client/lanes/workspace/styles/layout.scss +26 -24
- data/client/lanes/workspace/styles/screens.scss +0 -4
- data/client/lanes/workspace/styles/tabs.scss +3 -10
- data/config/routes.rb +10 -4
- data/config/screens.rb +25 -0
- data/db/migrate/01_create_system_settings.rb +10 -0
- data/docs/todo-example-part-1.md +18 -20
- data/lanes.gemspec +15 -6
- data/lib/lanes.rb +4 -2
- data/lib/lanes/access/config/routes.rb +5 -3
- data/lib/lanes/access/config/screens.rb +1 -0
- data/lib/lanes/access/db/migrate/20140615031600_create_lanes_users.rb +1 -1
- data/lib/lanes/access/user.rb +1 -1
- data/lib/lanes/api.rb +2 -1
- data/lib/lanes/api/controller.rb +32 -71
- data/lib/lanes/api/default_routes.rb +10 -8
- data/lib/lanes/api/formatted_reply.rb +53 -0
- data/lib/lanes/api/handlers/file.rb +26 -0
- data/lib/lanes/api/helper_methods.rb +29 -5
- data/lib/lanes/api/javascript_processor.rb +36 -17
- data/lib/lanes/api/pub_sub.rb +6 -9
- data/lib/lanes/api/request_wrapper.rb +1 -2
- data/lib/lanes/api/root.rb +11 -43
- data/lib/lanes/api/routing.rb +63 -0
- data/lib/lanes/api/sprockets_extension.rb +15 -7
- data/lib/lanes/api/updates.rb +1 -2
- data/lib/lanes/command.rb +0 -1
- data/lib/lanes/command/app.rb +6 -5
- data/lib/lanes/command/console.rb +1 -0
- data/lib/lanes/command/generate.rb +3 -0
- data/lib/lanes/command/generate_migration.rb +33 -0
- data/lib/lanes/command/generate_model.rb +4 -26
- data/lib/lanes/command/migration_support.rb +29 -0
- data/lib/lanes/command/update_model.rb +14 -5
- data/lib/lanes/concerns/all.rb +2 -0
- data/lib/lanes/concerns/api_path.rb +4 -2
- data/lib/lanes/concerns/association_extensions.rb +1 -1
- data/lib/lanes/concerns/attr_accessor_with_default.rb +3 -1
- data/lib/lanes/concerns/code_identifier.rb +1 -1
- data/lib/lanes/concerns/image_uploader.rb +42 -0
- data/lib/lanes/concerns/pub_sub.rb +0 -1
- data/lib/lanes/concerns/queries.rb +2 -2
- data/lib/lanes/concerns/set_attribute_data.rb +4 -13
- data/lib/lanes/concerns/sorting_expressions.rb +34 -0
- data/lib/lanes/configuration.rb +48 -9
- data/lib/lanes/extension.rb +16 -7
- data/lib/lanes/extension/definition.rb +8 -2
- data/lib/lanes/job.rb +78 -0
- data/lib/lanes/job/failure_logger.rb +33 -0
- data/lib/lanes/model.rb +4 -0
- data/lib/lanes/rake_tasks.rb +6 -0
- data/lib/lanes/redis.rb +13 -0
- data/lib/lanes/screen.rb +34 -18
- data/lib/lanes/system_settings.rb +66 -0
- data/lib/lanes/version.rb +1 -1
- data/lib/lanes/workspace/extension.rb +1 -1
- data/npm-build/base.js +10 -3
- data/npm-build/calendar.js +6 -0
- data/npm-build/development.js +4 -5
- data/npm-build/grid.js +3 -5
- data/npm-build/package.json +40 -29
- data/npm-build/react-toggle.js +5 -0
- data/npm-build/react-widgets.js +6 -0
- data/npm-build/update-dayz +14 -0
- data/npm-build/webpack.config.js +5 -2
- data/spec/command-reference-files/initial/Gemfile +1 -1
- data/spec/command-reference-files/initial/config/routes.rb +2 -0
- data/spec/command-reference-files/initial/lib/appy-app.rb +4 -0
- data/spec/command-reference-files/initial/lib/appy-app/extension.rb +2 -0
- data/spec/command-reference-files/initial/spec/server/{spec_helpers.rb → spec_helper.rb} +0 -0
- data/spec/command-reference-files/model/config/routes.rb +2 -0
- data/spec/command-reference-files/model/spec/server/test_test_spec.rb +1 -1
- data/spec/command-reference-files/screen/client/appy-app/screens/ready-set-go/ReadySetGo.cjsx +6 -4
- data/spec/command-reference-files/screen/client/appy-app/screens/ready-set-go/index.scss +4 -3
- data/spec/command-reference-files/screen/config/screens.rb +4 -2
- data/spec/command-reference-files/screen/spec/appy-app/screens/ready-set-go/ReadySetGoSpec.coffee +1 -1
- data/spec/fixtures/system_settings.yml +1 -0
- data/spec/lanes/components/grid/GridSpec.coffee +56 -31
- data/spec/lanes/components/grid/RowEditorSpec.coffee +96 -0
- data/spec/lanes/components/select-field/SelectFieldSpec.coffee +99 -0
- data/spec/lanes/components/shared/NetworkActivityOverlaySpec.coffee +34 -0
- data/spec/lanes/models/AssociationMapSpec.coffee +36 -2
- data/spec/lanes/models/AssociationProxySpec.coffee +77 -0
- data/spec/lanes/models/BaseSpec.coffee +37 -4
- data/spec/lanes/models/CollectionSpec.coffee +11 -17
- data/spec/lanes/models/PubSubSpec.coffee +1 -1
- data/spec/lanes/models/ServerCacheSpec.coffee +65 -0
- data/spec/server/api/coffeescript_processor_spec.rb +1 -1
- data/spec/server/concerns/pub_sub_spec.rb +9 -10
- data/spec/server/concerns/sorting_expressions_spec.rb +34 -0
- data/spec/server/configuration_spec.rb +3 -3
- data/spec/server/job_spec.rb +54 -0
- data/spec/server/spec_helper.rb +0 -5
- data/spec/server/system_settings_spec.rb +23 -0
- data/templates/client/screens/Screen.cjsx +6 -4
- data/templates/client/screens/styles.scss +4 -3
- data/templates/config/routes.rb +2 -0
- data/templates/config/screen.rb +4 -2
- data/templates/lib/namespace.rb +4 -0
- data/templates/lib/namespace/extension.rb +2 -0
- data/templates/spec/client/Screen.coffee +1 -1
- data/templates/spec/server/model_spec.rb +1 -1
- data/templates/spec/server/{spec_helpers.rb → spec_helper.rb} +0 -0
- data/views/lanes_root_view.erb +70 -0
- data/views/specs.erb +2 -2
- metadata +207 -68
- data/client/images/lanes/dataTables/Sorting icons.psd +0 -0
- data/client/images/lanes/dataTables/back_disabled.png +0 -0
- data/client/images/lanes/dataTables/back_enabled.png +0 -0
- data/client/images/lanes/dataTables/back_enabled_hover.png +0 -0
- data/client/images/lanes/dataTables/favicon.ico +0 -0
- data/client/images/lanes/dataTables/forward_disabled.png +0 -0
- data/client/images/lanes/dataTables/forward_enabled.png +0 -0
- data/client/images/lanes/dataTables/forward_enabled_hover.png +0 -0
- data/client/images/lanes/dataTables/loading-background.png +0 -0
- data/client/images/lanes/dataTables/sort_asc.png +0 -0
- data/client/images/lanes/dataTables/sort_asc_disabled.png +0 -0
- data/client/images/lanes/dataTables/sort_both.png +0 -0
- data/client/images/lanes/dataTables/sort_desc.png +0 -0
- data/client/images/lanes/dataTables/sort_desc_disabled.png +0 -0
- data/client/lanes/components/shared/Resize.cjsx +0 -152
- data/client/lanes/components/shared/TextArea.cjsx +0 -19
- data/client/lanes/components/shared/TextField.cjsx +0 -25
- data/client/lanes/models/Bootstrap.coffee +0 -5
- data/client/lanes/models/QueryResults.coffee +0 -93
- data/client/lanes/react/FormBindings.coffee +0 -103
- data/client/lanes/react/Router.cjsx +0 -18
- data/client/lanes/styles/dataTables.scss +0 -4
- data/client/lanes/styles/plugins/all.scss +0 -2
- data/client/lanes/styles/plugins/resize-sensor.scss +0 -24
- data/client/lanes/vendor/jquery-2.js +0 -9190
- data/client/lanes/vendor/jquery.tap.js +0 -401
- data/client/lanes/vendor/magicsuggest.js +0 -1565
- data/client/lanes/vendor/message-bus.coffee +0 -264
- data/client/lanes/workspace/ActiveScreenSwitcher.cjsx +0 -38
- data/client/lanes/workspace/styles/toolbar.scss +0 -4
- data/lib/lanes/api/eco.js +0 -516
- data/lib/lanes/api/sprockets_compressor.rb +0 -39
- data/spec/command-reference-files/model/lib/appy-app.rb +0 -11
- data/views/index.erb +0 -19
@@ -1,13 +1,15 @@
|
|
1
|
-
REACT_CACHE =
|
1
|
+
REACT_CACHE = Object.create(null)
|
2
2
|
|
3
3
|
Lanes.lib.HotReload =
|
4
4
|
|
5
|
-
|
6
|
-
return unless klass::FILE
|
5
|
+
remember: (klass) ->
|
6
|
+
return klass unless klass::FILE
|
7
7
|
path = klass::FILE.path.join("/") + ".js"
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
if REACT_CACHE[path]
|
9
|
+
return klass
|
10
|
+
else
|
11
|
+
REACT_CACHE[path] = Lanes.Vendor.ReactProxy(klass)
|
12
|
+
return REACT_CACHE[path].get()
|
11
13
|
|
12
14
|
replaceCss: (asset) ->
|
13
15
|
styles = document.head.querySelectorAll("link[rel='stylesheet'][href*='#{asset.path}']")
|
@@ -15,17 +17,13 @@ Lanes.lib.HotReload =
|
|
15
17
|
link.parentElement.removeChild(link)
|
16
18
|
|
17
19
|
replaceProps: (asset) ->
|
18
|
-
klass = Lanes.u.objectForPath(asset.path)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# else
|
24
|
-
# for klass in prev
|
20
|
+
klass = Lanes.u.objectForPath(asset.path)
|
21
|
+
if klass and REACT_CACHE[asset.path]
|
22
|
+
REACT_CACHE[asset.path].update(klass)
|
23
|
+
for viewport in Lanes.React.Viewport.all()
|
24
|
+
Lanes.Vendor.deepForceUpdate(viewport.reactRoot)
|
25
25
|
|
26
26
|
initiate: (assets) ->
|
27
|
-
console.log _.pluck(assets, 'path')
|
28
|
-
|
29
27
|
Lanes.lib.RequestAssets (_.pluck(assets, 'path'))...
|
30
28
|
.then (a) =>
|
31
29
|
for asset in assets
|
@@ -13,7 +13,12 @@ if Function::name == undefined && Object.defineProperty != undefined
|
|
13
13
|
mixinModules = (klass) ->
|
14
14
|
Lanes.lib.ModuleSupport.includeInto(klass)
|
15
15
|
if klass::mixins
|
16
|
-
|
16
|
+
for mixin in klass::mixins
|
17
|
+
if _.isString(mixin) and klass::FILE
|
18
|
+
part = _.classify(klass::FILE.path[1])
|
19
|
+
mixin = klass::FILE.namespace[part]?.Mixins[mixin] || Lanes[part]?.Mixins[mixin]
|
20
|
+
klass.include(mixin) if mixin
|
21
|
+
|
17
22
|
|
18
23
|
extendProperties = (parent, child) ->
|
19
24
|
child::extendedProperties = _.uniq(
|
data/client/lanes/lib/dom.coffee
CHANGED
@@ -3,20 +3,45 @@ class Lanes.lib.Dom
|
|
3
3
|
constructor: (el) ->
|
4
4
|
@el = el
|
5
5
|
|
6
|
-
qs: (selector) ->
|
6
|
+
qs: (selector, options = {}) ->
|
7
7
|
el = @el.querySelector(selector)
|
8
|
-
|
9
|
-
|
8
|
+
if not el and options.raise isnt false
|
9
|
+
throw new TypeError("Unable to find element for selector #{selector}")
|
10
|
+
new Lanes.lib.Dom(el || @el)
|
10
11
|
|
11
12
|
qsa: (selector) ->
|
12
13
|
@el.querySelectorAll(selector)
|
13
14
|
|
14
|
-
|
15
|
+
remove: ->
|
16
|
+
@el.parentElement.removeChild(@el)
|
17
|
+
|
18
|
+
focusAndSelect: ->
|
19
|
+
@el.select?()
|
20
|
+
@el.focus?()
|
21
|
+
|
22
|
+
closest: (selector) ->
|
23
|
+
# Traverse the DOM up with a while loop
|
24
|
+
el = @el
|
25
|
+
while el.nodeType isnt 9 and !el.matches(selector)
|
26
|
+
# Increment the loop to the parent node
|
27
|
+
el = el.parentNode
|
28
|
+
return null unless el
|
29
|
+
_.dom(el)
|
30
|
+
|
31
|
+
wrapArg = (fn) ->
|
15
32
|
return ->
|
16
33
|
fn(this.el, arguments...)
|
17
34
|
|
35
|
+
chain = (fn) ->
|
36
|
+
return ->
|
37
|
+
fn(this.el, arguments...)
|
38
|
+
return this
|
39
|
+
|
18
40
|
for name, func of Lanes.Vendor.dom
|
19
|
-
Lanes.lib.Dom::[name] =
|
41
|
+
Lanes.lib.Dom::[name] = if name.match(/^has/)
|
42
|
+
wrapArg
|
43
|
+
else
|
44
|
+
chain(func)
|
20
45
|
|
21
46
|
Object.defineProperties(Lanes.lib.Dom.prototype, {
|
22
47
|
|
@@ -37,11 +62,15 @@ Object.defineProperties(Lanes.lib.Dom.prototype, {
|
|
37
62
|
|
38
63
|
|
39
64
|
_.dom = (unknown, query) ->
|
40
|
-
el = if _.
|
65
|
+
el = if _.isBlank(unknown)
|
66
|
+
throw new TypeError("Selector / DOM node is not present")
|
67
|
+
else if _.isElement(unknown)
|
41
68
|
unknown
|
42
|
-
else if
|
43
|
-
|
44
|
-
else
|
69
|
+
else if unknown.isReactComponent
|
70
|
+
Lanes.Vendor.ReactDOM.findDOMNode(unknown)
|
71
|
+
else if unknown.nodeType is 9 # body tag
|
72
|
+
unknown
|
73
|
+
else if unknown
|
45
74
|
throw new TypeError("Unable to obtain dom reference to #{unknown}")
|
46
75
|
|
47
76
|
if query
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Lanes.u.format ||= {}
|
2
|
+
|
3
|
+
Lanes.u.format.shartDate = (d) ->
|
4
|
+
_.moment(d).format('L')
|
5
|
+
|
6
|
+
Lanes.u.format.shartDateTime = (d) ->
|
7
|
+
_.moment(d).format('lll')
|
8
|
+
|
9
|
+
Lanes.u.format.currency = (v) ->
|
10
|
+
v ||= '0'
|
11
|
+
_.sprintf('%0.2f', parseFloat(v)).replace(/\B(?=(\d{3})+\b)/g, ",")
|
@@ -11,18 +11,24 @@ Lanes.warn = (msg...) ->
|
|
11
11
|
else console.warn(msg...)
|
12
12
|
null
|
13
13
|
|
14
|
-
Lanes.log = (msg...) ->
|
15
|
-
return unless console
|
16
|
-
if msg[0] instanceof Error
|
17
|
-
console.warn(msg[0].stack)
|
18
|
-
else console.log(msg...)
|
19
|
-
null
|
20
|
-
|
21
14
|
distillTypes = (type, ns) ->
|
22
15
|
_.reduce( type.split( '.' ), ( ( memo, val ) -> return if memo then memo[ val ] else null ), ns )
|
23
16
|
|
24
17
|
Lanes.u = {
|
25
18
|
|
19
|
+
withReactContext: (newContext, fn) ->
|
20
|
+
previousContext = Lanes.Vendor.ReactContext.current
|
21
|
+
Lanes.Vendor.ReactContext.current = _.clone newContext
|
22
|
+
ret = fn()
|
23
|
+
Lanes.Vendor.ReactContext.current = previousContext
|
24
|
+
ret
|
25
|
+
|
26
|
+
makeComparatorUsing: (method) ->
|
27
|
+
(a, b) -> Lanes.u.comparator(a[method], b[method])
|
28
|
+
|
29
|
+
comparator: (a, b) ->
|
30
|
+
if a < b then 1 else if a > b then -1 else 0
|
31
|
+
|
26
32
|
objectForPath: (path) ->
|
27
33
|
parts = path.replace(/\.js$/, '').split('/')
|
28
34
|
last = null
|
@@ -52,6 +58,17 @@ Lanes.u = {
|
|
52
58
|
obj = _.reduce( parts, ( ( memo, val ) -> return if memo then memo[ val ] else null ), Lanes )
|
53
59
|
obj?[name]
|
54
60
|
|
61
|
+
isModel: (object) ->
|
62
|
+
_.isObject(object) and object.isProxy or object instanceof Lanes.Models.BasicModel
|
63
|
+
|
64
|
+
isCollection: (object) ->
|
65
|
+
object instanceof Lanes.Models.Collection ||
|
66
|
+
object instanceof Lanes.Models.BasicCollection ||
|
67
|
+
object instanceof Lanes.Models.SubCollection
|
68
|
+
|
69
|
+
isState: (object) ->
|
70
|
+
_.isObject(object) and object.isProxy or object instanceof Lanes.Models.State
|
71
|
+
|
55
72
|
# Can be called one of two ways:
|
56
73
|
# With ns being a string, which will attempt to deref it then deref name inside it
|
57
74
|
# or with ns being an object, which will dref name inside it
|
@@ -77,14 +94,12 @@ Lanes.u = {
|
|
77
94
|
else
|
78
95
|
method
|
79
96
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
return null unless el
|
97
|
+
invokeOrReturn: (func, scope = this) ->
|
98
|
+
if _.isFunction(func)
|
99
|
+
func.apply(scope)
|
100
|
+
else
|
101
|
+
func
|
86
102
|
|
87
|
-
return el
|
88
103
|
|
89
104
|
}
|
90
105
|
|
@@ -105,12 +120,17 @@ Lanes.u = {
|
|
105
120
|
lcDash = (char, match, index) ->
|
106
121
|
return ( if index == 0 then '' else '_' ) + char.toLowerCase()
|
107
122
|
|
123
|
+
originalTitleize = _.titleize
|
124
|
+
|
108
125
|
_.mixin({
|
109
126
|
dasherize: (str) ->
|
110
127
|
_.trim(str).replace(/([A-Z])/g, lcDash).replace(/[-_\s]+/g, '-').toLowerCase()
|
111
128
|
|
129
|
+
titleize: (str) ->
|
130
|
+
originalTitleize.call(_, _.humanize(str))
|
131
|
+
|
112
132
|
field2title: (field) ->
|
113
|
-
_.titleize
|
133
|
+
_.titleize field
|
114
134
|
|
115
135
|
toSentence: (words = [], comma = ', ', nd = ' and ') ->
|
116
136
|
last = words.pop()
|
@@ -121,5 +141,20 @@ _.mixin({
|
|
121
141
|
last
|
122
142
|
else
|
123
143
|
''
|
144
|
+
isPromise: (obj) ->
|
145
|
+
!!obj && (_.isObject(obj) || _.isFunction(obj)) && _.isFunction(obj.then)
|
146
|
+
|
147
|
+
isBlank: (value) ->
|
148
|
+
switch true
|
149
|
+
when _.isDate(value)
|
150
|
+
_.isNaN(value.getDate())
|
151
|
+
when _.isError(value), _.isNaN(value)
|
152
|
+
true
|
153
|
+
when _.isElement(value), _.isFunction(value), _.isBoolean(value), _.isRegExp(value)
|
154
|
+
false
|
155
|
+
when _.isNumber(value)
|
156
|
+
!value
|
157
|
+
else
|
158
|
+
_.isEmpty(value)
|
124
159
|
|
125
160
|
})
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# ------------------------------------------------------------------ #
|
2
2
|
# Handles Association definitions. #
|
3
3
|
# It creates a derived definition for each one #
|
4
|
-
#
|
4
|
+
# Note! An AssociationMap is created for each type of Model, and #
|
5
|
+
# is shared between all instances #
|
5
6
|
# ------------------------------------------------------------------ #
|
6
7
|
class Lanes.Models.AssocationMap
|
7
8
|
constructor: (@klass) ->
|
@@ -9,15 +10,38 @@ class Lanes.Models.AssocationMap
|
|
9
10
|
@definitions = @klass::associations
|
10
11
|
@definitions['created_by'] ||= { model: 'Lanes.Models.User', readOnly: true }
|
11
12
|
@definitions['updated_by'] ||= { model: 'Lanes.Models.User', readOnly: true }
|
13
|
+
@collections = Object.create(null)
|
14
|
+
@proxy = Object.create(null)
|
12
15
|
for name, options of @definitions
|
13
16
|
@klass::derived[name] = this.derivedDefinition(name, options)
|
14
17
|
|
18
|
+
# finds the correct class for association
|
15
19
|
getClassFor: (name) ->
|
16
20
|
definition = @definitions[name]
|
17
21
|
object = definition.model || definition.collection
|
18
22
|
Lanes.u.findObject(object, 'Models', @klass::FILE)
|
19
23
|
|
20
|
-
|
24
|
+
getProxyFor: (name) ->
|
25
|
+
@proxy[name] ||= (
|
26
|
+
Lanes.Models.AssocationProxy.construct( @getClassFor(name),
|
27
|
+
association_pk: @pk(name)
|
28
|
+
association_name: name
|
29
|
+
)
|
30
|
+
)
|
31
|
+
|
32
|
+
clear: (model) ->
|
33
|
+
for name, value of @proxy
|
34
|
+
Proxy = @getProxyFor(name)
|
35
|
+
model._cache[name] = new Proxy( this, this.getOptions(name, model) )
|
36
|
+
|
37
|
+
replace: (parent, name, model) ->
|
38
|
+
parent._cache[name] = model
|
39
|
+
model.parent = parent
|
40
|
+
parent.trigger("change", parent, {})
|
41
|
+
parent.trigger("change:#{name}", model, {})
|
42
|
+
|
43
|
+
getOptions: (name, model) ->
|
44
|
+
definition = @definitions[name]
|
21
45
|
options = { parent: model }
|
22
46
|
if definition.options
|
23
47
|
_.extend(options, Lanes.u.resultsFor(model, definition.options))
|
@@ -25,35 +49,47 @@ class Lanes.Models.AssocationMap
|
|
25
49
|
|
26
50
|
# will be called in the scope of the parent model
|
27
51
|
createModel: (association, name, definition, fk, pk, target_class) ->
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
this._cache[name]
|
52
|
+
if definition.autoCreate
|
53
|
+
target_class ||= association.getClassFor(name)
|
54
|
+
options = association.getOptions(name, this)
|
55
|
+
model_id = this.get(pk)
|
56
|
+
if model_id && model_id == this._cache[name]?.id
|
57
|
+
this._cache[name]
|
58
|
+
else
|
59
|
+
new target_class(options)
|
33
60
|
else
|
34
|
-
|
35
|
-
|
36
|
-
# returns a collection for the given association.
|
37
|
-
collectionFor: (name) ->
|
38
|
-
klass = @getClassFor(name)
|
39
|
-
if klass::isModel
|
40
|
-
klass.Collection
|
41
|
-
else
|
42
|
-
klass
|
43
|
-
|
61
|
+
Proxy = association.getProxyFor(name)
|
62
|
+
new Proxy( association, association.getOptions(name, @) )
|
44
63
|
|
45
64
|
# will be called in the scope of the parent model
|
46
65
|
createCollection: (association, name, definition, fk, pk, target_class) ->
|
47
66
|
target_class ||= association.getClassFor(name)
|
48
|
-
options = association.getOptions(name,
|
67
|
+
options = association.getOptions(name, this)
|
49
68
|
options.filter ||= {}
|
50
69
|
options.filter[fk] = this.get(pk)
|
70
|
+
options.inverse =
|
71
|
+
name: definition.inverse
|
72
|
+
without: name
|
51
73
|
|
52
|
-
if target_class::isCollection
|
74
|
+
if true == target_class::isCollection
|
53
75
|
new target_class(options.models || [], options)
|
54
76
|
else
|
55
77
|
options.model = target_class
|
56
|
-
new Lanes.Models.AssociationCollection(options.
|
78
|
+
new Lanes.Models.AssociationCollection(options.models || [], options)
|
79
|
+
|
80
|
+
# returns a collection for the given association.
|
81
|
+
collectionFor: (name, model, options = {}) ->
|
82
|
+
options = _.extend({}, this.getOptions(name, model), options)
|
83
|
+
@collections[name] ||= (
|
84
|
+
Klass = @getClassFor(name)
|
85
|
+
if true == Klass::isModel
|
86
|
+
new Lanes.Models.AssociationCollection(options.models || [],
|
87
|
+
_.extend({}, options, model: Klass)
|
88
|
+
)
|
89
|
+
else
|
90
|
+
new Klass(options.models || [], options)
|
91
|
+
)
|
92
|
+
|
57
93
|
# returns the definition for the derived property
|
58
94
|
derivedDefinition: (name, definition) ->
|
59
95
|
defaultCreator = if definition.model then this.createModel else this.createCollection
|
@@ -62,58 +98,98 @@ class Lanes.Models.AssocationMap
|
|
62
98
|
-> definition.default.apply(this, args) || defaultCreator.apply(this, args)
|
63
99
|
else
|
64
100
|
defaultCreator
|
65
|
-
{
|
66
|
-
|
101
|
+
{ fn: _.partial(createFn, args...) }
|
67
102
|
|
68
103
|
# Sets the assocations for "model"
|
69
|
-
set: (model, data) ->
|
70
|
-
this._set(model, data, 'set')
|
104
|
+
set: (model, data, options) ->
|
105
|
+
this._set(model, data, options, 'set')
|
71
106
|
for name, value of data
|
72
|
-
if @
|
107
|
+
if @exists(name) && Lanes.u.isModel(value) && !value.isNew()
|
73
108
|
model[@pk(name)] = if value then value.getId() else null
|
74
109
|
|
75
|
-
setFromServer: (model, data) ->
|
76
|
-
this._set(model, data, 'setFromServer')
|
110
|
+
setFromServer: (model, data, options) ->
|
111
|
+
this._set(model, data, options, 'setFromServer')
|
77
112
|
|
78
|
-
|
113
|
+
onIdChange: (model) ->
|
114
|
+
for name, def of @definitions
|
115
|
+
if def.collection and @isCreated(model, name) and model[name]?.associationFilter
|
116
|
+
model[name]?.associationFilter[ @fk(name) ] = model[ @pk(name) ]
|
117
|
+
|
118
|
+
_set: (model, data, options, fn_name) ->
|
79
119
|
for name, value of data
|
80
|
-
|
120
|
+
# we're done if we're not setting the association to anything
|
121
|
+
# and it's not yet created
|
122
|
+
continue if not @exists(name) or
|
123
|
+
(_.isEmpty(value) and not @isCreated(model, name))
|
124
|
+
|
81
125
|
association = model[name]
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
126
|
+
|
127
|
+
if association.isProxy and Lanes.u.isModel(value) and not value.isProxy
|
128
|
+
association.replaceWithModel(value, association_name: name)
|
129
|
+
|
130
|
+
else if Lanes.u.isModel(association)
|
131
|
+
continue if association is value
|
132
|
+
|
133
|
+
if !value
|
134
|
+
association.clear()
|
135
|
+
else
|
136
|
+
model.set(this.pk(name), value.id, options) if value.id
|
137
|
+
if Lanes.u.isModel(value)
|
138
|
+
@replace(model, name, value)
|
139
|
+
else
|
140
|
+
association[fn_name]( value )
|
141
|
+
|
142
|
+
if options?.silent isnt true and not association.isProxy
|
143
|
+
model.trigger("change:#{name}", value, {})
|
144
|
+
else
|
145
|
+
if value then association[fn_name]( value, options ) else association.clear()
|
91
146
|
|
92
147
|
pk: (name) ->
|
93
148
|
def = @definitions[name]
|
94
|
-
return null unless name
|
95
|
-
def
|
149
|
+
return null unless name and def
|
150
|
+
_.result(def, 'pk', ( if def.model then "#{name}_id" else "id" ) )
|
96
151
|
|
97
152
|
fk: (name) ->
|
98
153
|
def = @definitions[name]
|
99
|
-
return null unless name
|
100
|
-
def
|
154
|
+
return null unless name and def
|
155
|
+
_.result(def, 'fk', ( if def.model then "id" else "#{name}_id" ) )
|
101
156
|
|
102
157
|
# returns the data from all assocations for saving
|
103
158
|
dataForSave: (model, options) ->
|
104
159
|
ret = {}
|
105
160
|
options.saveDepth = ( if options.saveDepth then options.saveDepth + 1 else 1 )
|
106
161
|
return ret if options.saveDepth > 5
|
107
|
-
for name,
|
108
|
-
|
162
|
+
for name, def_options of @definitions when @isCreated(model, name)
|
163
|
+
continue if def_options.readOnly or
|
164
|
+
(options.onlyAssociations and not _.include(options.onlyAssociations, name))
|
109
165
|
assoc = model[name]
|
110
|
-
ret[name] = assoc.dataForSave(
|
166
|
+
ret[name] = assoc.dataForSave(
|
167
|
+
_.extend({}, options, def_options)
|
168
|
+
) if _.result(assoc, 'isDirty')
|
169
|
+
ret
|
170
|
+
|
171
|
+
serialize: (model, options = {depth: 1}) ->
|
172
|
+
ret = {}
|
173
|
+
options.depth ||= 1
|
174
|
+
return ret if options.depth > 5
|
175
|
+
for name, opts of @definitions
|
176
|
+
if @isCreated(model, name) and name isnt 'parent'
|
177
|
+
ret[name] = model[name].serialize(options)
|
111
178
|
ret
|
112
179
|
|
113
180
|
# return a list of assocations from "name" that are not loaded
|
114
181
|
nonLoaded: (model, names) ->
|
115
182
|
list = []
|
116
183
|
for name in names
|
117
|
-
if
|
184
|
+
if @exists(name) &&
|
185
|
+
(Lanes.u.isCollection(model[name]) ||
|
186
|
+
model[name].isProxy ||
|
187
|
+
model[name].isNew())
|
118
188
|
list.push(name)
|
119
189
|
list
|
190
|
+
|
191
|
+
exists: (name) ->
|
192
|
+
_.has(@definitions, name)
|
193
|
+
|
194
|
+
isCreated: (model, name) ->
|
195
|
+
!!(@exists(name) and model._cache[name])
|