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
@@ -6,20 +6,24 @@
|
|
6
6
|
class Lanes.Models.ChangeMonitor
|
7
7
|
constructor: (model) ->
|
8
8
|
model.on('change', this.onChange, this)
|
9
|
+
@_unsaved = {}
|
9
10
|
|
10
11
|
onChange: (record, options) ->
|
11
12
|
attrs = record.changedAttributes()
|
12
13
|
return if _.isEmpty(attrs)
|
14
|
+
if attrs[record.idAttribute] and record.associations
|
15
|
+
record.associations.onIdChange(record)
|
13
16
|
if attrs.isDirty == false
|
14
|
-
|
17
|
+
@_unsaved = {}
|
15
18
|
else
|
16
|
-
@_unsaved ||= {}
|
17
19
|
this.recordChanges(record, _.keys(attrs))
|
18
20
|
|
21
|
+
reset: ->
|
22
|
+
@_unsaved = {}
|
19
23
|
|
20
24
|
recordChanges: (record, names) ->
|
21
25
|
# console.log "Change: #{names}"
|
22
|
-
#console.log record.getAttributes(props:true, session: true)
|
26
|
+
# console.log record.getAttributes(props:true, session: true)
|
23
27
|
for name in names
|
24
28
|
if name != record.idAttribute && record._definition[name] && !record._definition[name].session
|
25
29
|
record.isDirty = true
|
@@ -11,7 +11,7 @@ class Lanes.Models.ChangeSet extends Lanes.Models.Base
|
|
11
11
|
|
12
12
|
derived:
|
13
13
|
record: { deps: ['collection'], fn: -> @collection.parent }
|
14
|
-
record_name: { deps: ['record'], fn: -> _.field2title @record.
|
14
|
+
record_name: { deps: ['record'], fn: -> _.field2title @record.modelTypeIdentifier() }
|
15
15
|
fields: { deps: ['update'], fn: -> _.keys(@update) }
|
16
16
|
displayed_fields: { deps:['fields'], fn: -> _.without(@fields, 'updated_by_id', 'updated_at') }
|
17
17
|
displayed_changes:
|
@@ -23,7 +23,7 @@ class Lanes.Models.ChangeSet extends Lanes.Models.Base
|
|
23
23
|
value: ->
|
24
24
|
set = {}
|
25
25
|
for field, change of @update
|
26
|
-
set[field] = change
|
26
|
+
set[field] = if _.isArray(change) then _.last(change) else change
|
27
27
|
set
|
28
28
|
|
29
29
|
class ChangeSetCollection extends Lanes.Models.BasicCollection
|
@@ -1,5 +1,5 @@
|
|
1
1
|
CommonMethods = {
|
2
|
-
findIndexWhere: (attrs)->
|
2
|
+
findIndexWhere: (attrs) ->
|
3
3
|
found = -1
|
4
4
|
for index, model of @models
|
5
5
|
found = parseInt(index)
|
@@ -10,6 +10,14 @@ CommonMethods = {
|
|
10
10
|
break if found != -1
|
11
11
|
found
|
12
12
|
|
13
|
+
pick: (keys...) ->
|
14
|
+
_.map(@models, _.partialRight(_.pick, keys...))
|
15
|
+
|
16
|
+
sum: ->
|
17
|
+
args = _.toArray(arguments)
|
18
|
+
args.unshift(this.models)
|
19
|
+
return _.sum.apply(_, args)
|
20
|
+
|
13
21
|
# convenience method to create a new subCollection
|
14
22
|
subcollection: (options) ->
|
15
23
|
new Lanes.Models.SubCollection(this, options)
|
@@ -26,6 +34,20 @@ CommonMethods = {
|
|
26
34
|
return this
|
27
35
|
)
|
28
36
|
|
37
|
+
clone: ->
|
38
|
+
new @constructor( @invoke( 'clone' ), @options )
|
39
|
+
|
40
|
+
serialize: (options = {depth: 1}) ->
|
41
|
+
depth = options.depth
|
42
|
+
depth += 1
|
43
|
+
options = _.extend({}, options, {depth})
|
44
|
+
this.map (model) ->
|
45
|
+
if model.serialize
|
46
|
+
model.serialize(options)
|
47
|
+
else
|
48
|
+
out = _.extend({}, model)
|
49
|
+
delete out.collection
|
50
|
+
out
|
29
51
|
}
|
30
52
|
|
31
53
|
class ModelsCollection
|
@@ -54,6 +76,17 @@ class ModelsCollection
|
|
54
76
|
else
|
55
77
|
this.sync('read', this, options)
|
56
78
|
|
79
|
+
getOrFetch: (id, options) ->
|
80
|
+
@get(id) || @fetchId(id, options)
|
81
|
+
|
82
|
+
# Fetch a single model with the given id
|
83
|
+
fetchId: (id, options = {}) ->
|
84
|
+
return if id == @requestInProgress?.query?[@model::idAttribute]
|
85
|
+
this.sync('read', this, _.extend({
|
86
|
+
limit: 1, query: {"#{@model::idAttribute}": id}
|
87
|
+
}, options))
|
88
|
+
|
89
|
+
# Load the collection unless it's already loaded
|
57
90
|
ensureLoaded: (options = {}) ->
|
58
91
|
if options.force || (!@_isLoaded && !this.length )
|
59
92
|
this.fetch(options)
|
@@ -80,7 +113,10 @@ class ModelsCollection
|
|
80
113
|
)
|
81
114
|
this.remove(models)
|
82
115
|
else
|
83
|
-
|
116
|
+
if options.reset
|
117
|
+
update = 'reset'
|
118
|
+
else
|
119
|
+
update = 'set'
|
84
120
|
this[update](data, options)
|
85
121
|
if this._loaded_callbacks
|
86
122
|
cb(this) for cb in this._loaded_callbacks
|
@@ -146,6 +182,7 @@ Lanes.Models.SubCollection = Lanes.lib.MakeBaseClass( Lanes.Vendor.Ampersand.Sub
|
|
146
182
|
|
147
183
|
Lanes.Models.BasicCollection = Lanes.lib.MakeBaseClass(
|
148
184
|
Lanes.Vendor.Ampersand.Collection.extend(Lanes.Vendor.Ampersand.USCollection), BasicCollection
|
185
|
+
|
149
186
|
)
|
150
187
|
|
151
188
|
Lanes.Models.Collection = Lanes.lib.MakeBaseClass( Lanes.Vendor.Ampersand.RestCollection, ModelsCollection )
|
@@ -155,17 +192,23 @@ Lanes.Models.Collection = Lanes.lib.MakeBaseClass( Lanes.Vendor.Ampersand.RestCo
|
|
155
192
|
## Override a few methods on the standard collection to ensure that
|
156
193
|
# models are fetched correctly and have the fk set when they're created
|
157
194
|
class Lanes.Models.AssociationCollection extends Lanes.Models.Collection
|
158
|
-
constructor: (models, options) ->
|
159
|
-
@model = options.model
|
160
|
-
@associationFilter = options.filter
|
195
|
+
constructor: (models, @options) ->
|
196
|
+
@model = @options.model
|
197
|
+
@associationFilter = @options.filter
|
161
198
|
super
|
162
199
|
|
163
200
|
_prepareModel: (attrs, options = {}) ->
|
201
|
+
if @associationFilter
|
202
|
+
_.extend(attrs, @associationFilter)
|
164
203
|
model = super
|
165
|
-
|
204
|
+
if @options.inverse
|
205
|
+
parent = this.parent.clone()
|
206
|
+
parent[@options.inverse.without].reset() if @options.inverse.without
|
207
|
+
model.set(@options.inverse.name, parent, options)
|
166
208
|
model
|
167
209
|
|
168
210
|
fetch: (options) ->
|
169
211
|
options.query ||= {}
|
170
212
|
_.extend(options.query, @associationFilter)
|
213
|
+
_.extend(options, @options)
|
171
214
|
super(options)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Lanes.Models.JobStatus extends Lanes.Models.Base
|
2
|
+
|
3
|
+
props:
|
4
|
+
id: 'string'
|
5
|
+
job_name: 'string'
|
6
|
+
progress: 'number'
|
7
|
+
attempt: 'integer'
|
8
|
+
state: 'string'
|
9
|
+
recorded_at: 'date'
|
10
|
+
queued_at: 'date'
|
11
|
+
errors: 'any'
|
12
|
+
data: 'object'
|
13
|
+
|
14
|
+
events:
|
15
|
+
'remote-update': 'onUpdate'
|
16
|
+
|
17
|
+
derived:
|
18
|
+
isSubmitted:
|
19
|
+
deps: ['id'], fn: -> !@isNew()
|
20
|
+
isExecuting:
|
21
|
+
deps: ['state'], fn: ->
|
22
|
+
_.contains(['unqueued', 'queued', 'started'], @state)
|
23
|
+
isActive:
|
24
|
+
deps: ['isSubmitted', 'isExecuting'], fn: ->
|
25
|
+
!(@isSubmitted or @isExecuting)
|
26
|
+
stepsCompleted:
|
27
|
+
deps: ['data'], fn: ->
|
28
|
+
_.map(_.keys(@data?.output), _.titleize)
|
29
|
+
|
30
|
+
onUpdate: ->
|
31
|
+
@trigger('update', @)
|
32
|
+
@parent?.trigger('update', @)
|
@@ -11,7 +11,8 @@ class ModelType extends Lanes.Models.State
|
|
11
11
|
subscribe: (config) ->
|
12
12
|
model = config.models[0]
|
13
13
|
channel = "/#{_.result(model, 'api_path')}/#{model.id}"
|
14
|
-
Lanes.
|
14
|
+
Lanes.log.info "Subscribe to: #{channel}"
|
15
|
+
Lanes.Models.PubSub.mb.subscribe(channel, (changes) ->
|
15
16
|
for model in config.models
|
16
17
|
model.addChangeSet(changes)
|
17
18
|
)
|
@@ -29,7 +30,8 @@ class ModelType extends Lanes.Models.State
|
|
29
30
|
if ( config = @records[model.id] )
|
30
31
|
_.remove(config.models, (m) -> m == model)
|
31
32
|
if _.isEmpty(config.models)
|
32
|
-
Lanes.
|
33
|
+
Lanes.log.info "Unsubscribe from: #{config.channel}"
|
34
|
+
Lanes.Models.PubSub.mb.unsubscribe( config.channel )
|
33
35
|
delete @records[model.id]
|
34
36
|
|
35
37
|
|
@@ -65,9 +67,9 @@ Lanes.Models.PubSub = {
|
|
65
67
|
@types = new ModelTypesCollection
|
66
68
|
|
67
69
|
initialize: ->
|
68
|
-
|
69
|
-
|
70
|
-
|
70
|
+
@mb = MessageBus.noConflict()
|
71
|
+
@mb.start()
|
72
|
+
@mb.subscribe("/file-change", (changes) ->
|
71
73
|
Lanes.lib.HotReload.initiate(changes)
|
72
74
|
)
|
73
75
|
}
|
@@ -1,17 +1,30 @@
|
|
1
|
-
|
1
|
+
##= require_self
|
2
|
+
##= require ./query/Result
|
3
|
+
##= require ./query/ArrayResult
|
4
|
+
##= require ./query/CollectionResult
|
2
5
|
|
6
|
+
class Field extends Lanes.Models.Base
|
7
|
+
pubsub: false
|
3
8
|
constructor: (attributes) ->
|
4
9
|
super( _.defaults( attributes, {
|
5
10
|
title: _.titleize(_.humanize(attributes.id))
|
6
11
|
}))
|
7
12
|
|
8
13
|
session:
|
9
|
-
id:
|
10
|
-
title:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
id: type: 'string'
|
15
|
+
title: type: 'string'
|
16
|
+
selected: type: 'boolean'
|
17
|
+
visible: type: 'boolean', default: true
|
18
|
+
query: type: 'boolean', default: true
|
19
|
+
editable: type: 'boolean', default: true
|
20
|
+
sortable: type: 'boolean', default: true
|
21
|
+
format: type: 'function'
|
22
|
+
flex: type: 'number', default: 1
|
23
|
+
fixedWidth: type: 'number'
|
24
|
+
textAlign: type: 'string', default: 'left'
|
25
|
+
sortBy: type: 'any'
|
26
|
+
component: type: 'function'
|
27
|
+
onColumnClick: type: 'function'
|
15
28
|
|
16
29
|
derived:
|
17
30
|
default_value: deps: ['id'], fn: ->
|
@@ -20,11 +33,17 @@ class Field extends Lanes.Models.Base
|
|
20
33
|
else ''
|
21
34
|
model_field:
|
22
35
|
deps: ['id'], fn: ->
|
23
|
-
this.collection.query.
|
36
|
+
this.collection.query.model::_definition[@id]
|
24
37
|
type:
|
25
38
|
deps: ['model_field'], fn: ->
|
26
39
|
type = @model_field?.type || 'string'
|
27
40
|
if type == "code" then "string" else type
|
41
|
+
fetchIndex:
|
42
|
+
fn: ->
|
43
|
+
fetchIndex = 0
|
44
|
+
for field, index in this.collection.models
|
45
|
+
return fetchIndex if this == field
|
46
|
+
fetchIndex += 1 if field.query
|
28
47
|
|
29
48
|
validValue: (value) ->
|
30
49
|
if this.type == 'n'
|
@@ -49,6 +68,7 @@ class AvailableFields extends Lanes.Models.Collection
|
|
49
68
|
|
50
69
|
|
51
70
|
class Operator extends Lanes.Models.Base
|
71
|
+
pubsub: false
|
52
72
|
|
53
73
|
session:
|
54
74
|
id: 'string'
|
@@ -70,10 +90,10 @@ class Operators extends Lanes.Models.Collection
|
|
70
90
|
constructor: ->
|
71
91
|
super
|
72
92
|
this.add([
|
73
|
-
{ id: 'like', name: 'Starts With', types:
|
93
|
+
{ id: 'like', name: 'Starts With', types: Lanes.Models.Query.LIKE_QUERY_TYPES }
|
74
94
|
{ id: 'eq', name: 'Equals' }
|
75
|
-
{ id: 'lt', name: 'Less Than',
|
76
|
-
{ id: 'gt', name: 'More Than',
|
95
|
+
{ id: 'lt', name: 'Less Than', types: Lanes.Models.Query.LESS_THAN_QUERY_TYPES }
|
96
|
+
{ id: 'gt', name: 'More Than', types: Lanes.Models.Query.LESS_THAN_QUERY_TYPES }
|
77
97
|
])
|
78
98
|
this.on('change', (changing) ->
|
79
99
|
return unless changing.selected
|
@@ -90,6 +110,7 @@ class Operators extends Lanes.Models.Collection
|
|
90
110
|
|
91
111
|
|
92
112
|
class Clause extends Lanes.Models.Base
|
113
|
+
pubsub: false
|
93
114
|
|
94
115
|
session:
|
95
116
|
value : { type: 'string', default: '' }
|
@@ -120,9 +141,12 @@ class Clause extends Lanes.Models.Base
|
|
120
141
|
@operators.field = @fields.first()
|
121
142
|
@fields.on('change:selected', this.setField, this)
|
122
143
|
@operators.on('change:selected', this.setOperator, this)
|
123
|
-
|
124
|
-
|
125
|
-
|
144
|
+
field = @fields.findWhere(visible: true)
|
145
|
+
if field
|
146
|
+
field.selected = true
|
147
|
+
@setField(field)
|
148
|
+
operator = @operators.find (o) -> o.valid
|
149
|
+
operator?.selected = true
|
126
150
|
|
127
151
|
setFromView: (type, val) ->
|
128
152
|
if type == "fields" || type == "operators"
|
@@ -161,67 +185,124 @@ class Clauses extends Lanes.Models.Collection
|
|
161
185
|
@query = options.query
|
162
186
|
@fields = options.query.fields
|
163
187
|
|
188
|
+
# needs to inherit from Base so network events will be listened to
|
164
189
|
class Lanes.Models.Query extends Lanes.Models.Base
|
190
|
+
pubsub: false
|
191
|
+
|
192
|
+
@LIKE_QUERY_TYPES: ['string', 'code']
|
193
|
+
@LESS_THAN_QUERY_TYPES: ['integer', 'bigdec', 'number']
|
194
|
+
@GREATER_THAN_QUERY_TYPES: ['integer', 'bigdec', 'number']
|
195
|
+
|
196
|
+
@mergedSyncOptions: (args...) ->
|
197
|
+
_.merge {}, args..., (a, b) ->
|
198
|
+
return a.concat(b) if _.isArray(a)
|
165
199
|
|
166
200
|
session:
|
201
|
+
src: 'any'
|
167
202
|
fields: 'collection'
|
168
203
|
clauses: 'collection'
|
169
|
-
modelClass: 'function'
|
170
204
|
initialField: 'state'
|
171
205
|
idIndex: 'number'
|
172
206
|
initialFieldIndex: 'number'
|
173
|
-
pageSize: 'number'
|
207
|
+
pageSize: { type: 'number', default: 100 }
|
208
|
+
syncOptions: 'any'
|
209
|
+
autoRetrieve: {type:'boolean', default: false, required: true}
|
210
|
+
title: { type: 'string', default: 'Find Record' }
|
211
|
+
sortField: 'object'
|
212
|
+
defaultSort: 'any'
|
213
|
+
changeCount: {type: 'integer', default: 0}
|
214
|
+
sortAscending: ['boolean', true, true]
|
174
215
|
|
175
216
|
derived:
|
217
|
+
isCollection:
|
218
|
+
deps: ['src'], fn: -> Lanes.u.isCollection(@src)
|
219
|
+
|
220
|
+
model:
|
221
|
+
deps: ['src'], fn: ->
|
222
|
+
return null unless @src
|
223
|
+
if @isCollection then @src.model else @src
|
224
|
+
|
225
|
+
idAttribute:
|
226
|
+
deps: ['model'], fn: -> @model::idAttribute
|
227
|
+
|
176
228
|
results:
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
229
|
+
deps: ['src'], fn: ->
|
230
|
+
if @isCollection
|
231
|
+
new Lanes.Models.Query.CollectionResult(this)
|
232
|
+
else
|
233
|
+
new Lanes.Models.Query.ArrayResult(this, pageSize: @pageSize)
|
234
|
+
|
235
|
+
events:
|
236
|
+
'change:sortField': '_updateSort'
|
237
|
+
'change:sortAscending': '_updateSort'
|
182
238
|
|
183
239
|
constructor: (options = {}) ->
|
184
240
|
super
|
185
|
-
idName = @modelClass::idAttribute
|
186
|
-
@loadAssociations = options.loadAssociations
|
187
241
|
@fields = new AvailableFields([], query: this)
|
188
242
|
for col, i in options.fields
|
189
243
|
rec = if _.isObject(col) then col else { id: col }
|
190
244
|
@fields.add rec
|
191
|
-
@idIndex = i if rec.id ==
|
245
|
+
@idIndex = i if rec.id == @idAttribute
|
192
246
|
unless @idIndex?
|
193
247
|
@idIndex = @fields.length
|
194
|
-
@fields.add(id:
|
248
|
+
@fields.add(id: @idAttribute)
|
195
249
|
@clauses = new Clauses([], query: this )
|
196
|
-
this.listenTo(@clauses, 'change remove reset',
|
250
|
+
this.listenTo(@clauses, 'change remove reset', =>
|
197
251
|
@results.reset()
|
198
|
-
|
252
|
+
@results.ensureLoaded() if this.autoRetrieve
|
253
|
+
)
|
254
|
+
this.on('change:src change:results', ->
|
255
|
+
this.trigger('load')
|
256
|
+
)
|
257
|
+
this.on('load', ->
|
258
|
+
@changeCount += 1
|
199
259
|
)
|
260
|
+
|
200
261
|
if @initialFieldIndex
|
201
262
|
@initialField = this.fields.at(@initialFieldIndex)
|
263
|
+
|
202
264
|
@initialField ||= this.fields.findWhere(id: "code") ||
|
203
265
|
this.fields.findWhere(id: "visibleId") ||
|
204
266
|
this.fields.first()
|
205
|
-
|
267
|
+
|
268
|
+
@reset()
|
206
269
|
this
|
207
270
|
|
208
|
-
|
209
|
-
|
271
|
+
reset: ->
|
272
|
+
unless @defaultSort is false
|
273
|
+
sort = @defaultSort or @fields.findWhere(visible: true).id
|
274
|
+
@setSortField( @fields.findWhere(id: sort), sortAscending: true, silent: true )
|
275
|
+
|
276
|
+
@clauses.reset([
|
277
|
+
{query: this, available_fields: @fields, field: @initialField}
|
278
|
+
])
|
279
|
+
|
280
|
+
setSortField: (field, options = {silent: false}) ->
|
281
|
+
@set({
|
282
|
+
sortAscending: options.sortAscending || (if @sortField is field then !@sortAscending else true)
|
283
|
+
sortField: field
|
284
|
+
}, options)
|
285
|
+
|
286
|
+
ensureLoaded: -> @results.ensureLoaded()
|
210
287
|
|
211
288
|
isValid: ->
|
212
289
|
! @clauses.findWhere( isValid: false )
|
213
290
|
|
214
|
-
|
215
|
-
|
291
|
+
loadModel: (model, options = {}) ->
|
292
|
+
_.extend(options, _.result(this, 'syncOptions'))
|
293
|
+
model.withAssociations(options.include || [], options)
|
216
294
|
|
217
295
|
loadSingle: (code, options = {}) ->
|
218
296
|
options.query = {}
|
219
297
|
options.query[ @initialField.id ] = code
|
220
|
-
options.
|
221
|
-
@
|
298
|
+
_.extend(options, _.result(this, 'syncOptions'))
|
299
|
+
@src.fetch(options)
|
222
300
|
|
223
301
|
defaultField: ->
|
224
302
|
@fields.findWhere( field: @initialField )
|
225
303
|
|
226
304
|
addNewClause: ->
|
227
305
|
@clauses.add(query: this, available_fields: @fields, field: @initialField)
|
306
|
+
|
307
|
+
_updateSort: _.debounce ->
|
308
|
+
@results._updateSort()
|