lanes 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +7 -0
  3. data/Gemfile +2 -2
  4. data/client/lanes/components/Base.coffee +12 -11
  5. data/client/lanes/components/enabled.js.erb +1 -1
  6. data/client/lanes/components/grid/Editor.coffee +2 -2
  7. data/client/lanes/components/grid/Grid.coffee +60 -58
  8. data/client/lanes/components/grid/PopOverEditor.coffee +3 -3
  9. data/client/lanes/components/grid/RowEditor.coffee +1 -1
  10. data/client/lanes/components/grid/{grid.scss → _index.scss} +0 -0
  11. data/client/lanes/components/grid/template.html +1 -1
  12. data/client/lanes/components/modal/ModalDialog.coffee +1 -1
  13. data/client/lanes/components/modal/{modal.scss → _index.scss} +1 -1
  14. data/client/lanes/components/modal/index.js +1 -1
  15. data/client/lanes/components/popover/PopOver.coffee +1 -1
  16. data/client/lanes/components/popover/_index.scss +1 -0
  17. data/client/lanes/components/popover/index.js +1 -1
  18. data/client/lanes/components/select_field/{select_field.scss → _index.scss} +0 -0
  19. data/client/lanes/extension/Extensions.coffee +3 -2
  20. data/client/lanes/lib/Templates.coffee +7 -0
  21. data/client/lanes/minimal.js +1 -1
  22. data/client/lanes/minimal.scss.erb +1 -1
  23. data/client/lanes/models/Base.coffee +16 -19
  24. data/client/lanes/models/Bootstrap.coffee +1 -2
  25. data/client/lanes/models/Collection.coffee +37 -25
  26. data/client/lanes/models/Screens.coffee +6 -18
  27. data/client/lanes/models/Sync.coffee +12 -5
  28. data/client/lanes/screens/Base.coffee +1 -2
  29. data/client/lanes/screens/Instance.coffee +2 -5
  30. data/client/lanes/screens/screen-definitions.js.erb +10 -2
  31. data/client/{styles → lanes/styles}/components/all.scss +0 -0
  32. data/client/{styles → lanes/styles}/components/changes-notification.scss +0 -0
  33. data/client/{styles → lanes/styles}/components/record-finder.scss +0 -0
  34. data/client/{styles → lanes/styles}/components/suggest.scss +0 -0
  35. data/client/{styles → lanes/styles}/fonts/icomoon.eot +0 -0
  36. data/client/{styles → lanes/styles}/fonts/icomoon.svg +0 -0
  37. data/client/{styles → lanes/styles}/fonts/icomoon.ttf +0 -0
  38. data/client/{styles → lanes/styles}/fonts/icomoon.woff +0 -0
  39. data/client/{styles → lanes/styles}/fonts/selection.json +0 -0
  40. data/client/{styles → lanes/styles}/fonts/style.scss +0 -0
  41. data/client/{styles → lanes/styles}/fonts.scss +5 -5
  42. data/client/{styles → lanes/styles}/forms.scss +0 -0
  43. data/client/{styles → lanes/styles}/index.css +0 -0
  44. data/client/{styles → lanes/styles}/keybindings.scss +0 -0
  45. data/client/{styles → lanes/styles}/layout.scss +0 -0
  46. data/client/{styles → lanes/styles}/plugins/all.scss +0 -0
  47. data/client/{styles → lanes/styles}/plugins/overlay.scss +0 -0
  48. data/client/{styles → lanes/styles}/plugins/resize-sensor.scss +0 -0
  49. data/client/{styles → lanes/styles}/screens.scss +0 -0
  50. data/client/{styles → lanes/styles}/tabs.scss +0 -0
  51. data/client/{styles → lanes/styles}/vendor/bootstrap/_alerts.scss +0 -0
  52. data/client/{styles → lanes/styles}/vendor/bootstrap/_badges.scss +0 -0
  53. data/client/{styles → lanes/styles}/vendor/bootstrap/_breadcrumbs.scss +0 -0
  54. data/client/{styles → lanes/styles}/vendor/bootstrap/_button-groups.scss +0 -0
  55. data/client/{styles → lanes/styles}/vendor/bootstrap/_buttons.scss +0 -0
  56. data/client/{styles → lanes/styles}/vendor/bootstrap/_carousel.scss +0 -0
  57. data/client/{styles → lanes/styles}/vendor/bootstrap/_close.scss +0 -0
  58. data/client/{styles → lanes/styles}/vendor/bootstrap/_code.scss +0 -0
  59. data/client/{styles → lanes/styles}/vendor/bootstrap/_component-animations.scss +0 -0
  60. data/client/{styles → lanes/styles}/vendor/bootstrap/_dropdowns.scss +0 -0
  61. data/client/{styles → lanes/styles}/vendor/bootstrap/_forms.scss +0 -0
  62. data/client/{styles → lanes/styles}/vendor/bootstrap/_glyphicons.scss +0 -0
  63. data/client/{styles → lanes/styles}/vendor/bootstrap/_grid.scss +0 -0
  64. data/client/{styles → lanes/styles}/vendor/bootstrap/_input-groups.scss +0 -0
  65. data/client/{styles → lanes/styles}/vendor/bootstrap/_jumbotron.scss +0 -0
  66. data/client/{styles → lanes/styles}/vendor/bootstrap/_labels.scss +0 -0
  67. data/client/{styles → lanes/styles}/vendor/bootstrap/_list-group.scss +0 -0
  68. data/client/{styles → lanes/styles}/vendor/bootstrap/_media.scss +0 -0
  69. data/client/{styles → lanes/styles}/vendor/bootstrap/_mixins.scss +0 -0
  70. data/client/{styles → lanes/styles}/vendor/bootstrap/_modals.scss +0 -0
  71. data/client/{styles → lanes/styles}/vendor/bootstrap/_navbar.scss +0 -0
  72. data/client/{styles → lanes/styles}/vendor/bootstrap/_navs.scss +0 -0
  73. data/client/{styles → lanes/styles}/vendor/bootstrap/_normalize.scss +0 -0
  74. data/client/{styles → lanes/styles}/vendor/bootstrap/_pager.scss +0 -0
  75. data/client/{styles → lanes/styles}/vendor/bootstrap/_pagination.scss +0 -0
  76. data/client/{styles → lanes/styles}/vendor/bootstrap/_panels.scss +0 -0
  77. data/client/{styles → lanes/styles}/vendor/bootstrap/_popovers.scss +0 -0
  78. data/client/{styles → lanes/styles}/vendor/bootstrap/_print.scss +0 -0
  79. data/client/{styles → lanes/styles}/vendor/bootstrap/_progress-bars.scss +0 -0
  80. data/client/{styles → lanes/styles}/vendor/bootstrap/_responsive-embed.scss +0 -0
  81. data/client/{styles → lanes/styles}/vendor/bootstrap/_responsive-utilities.scss +0 -0
  82. data/client/{styles → lanes/styles}/vendor/bootstrap/_scaffolding.scss +0 -0
  83. data/client/{styles → lanes/styles}/vendor/bootstrap/_tables.scss +0 -0
  84. data/client/{styles → lanes/styles}/vendor/bootstrap/_theme.scss +0 -0
  85. data/client/{styles → lanes/styles}/vendor/bootstrap/_thumbnails.scss +0 -0
  86. data/client/{styles → lanes/styles}/vendor/bootstrap/_tooltip.scss +0 -0
  87. data/client/{styles → lanes/styles}/vendor/bootstrap/_type.scss +0 -0
  88. data/client/{styles → lanes/styles}/vendor/bootstrap/_utilities.scss +0 -0
  89. data/client/{styles → lanes/styles}/vendor/bootstrap/_variables.scss +0 -0
  90. data/client/{styles → lanes/styles}/vendor/bootstrap/_wells.scss +0 -0
  91. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_alerts.scss +0 -0
  92. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_background-variant.scss +0 -0
  93. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_border-radius.scss +0 -0
  94. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_buttons.scss +0 -0
  95. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_center-block.scss +0 -0
  96. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_clearfix.scss +0 -0
  97. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_forms.scss +0 -0
  98. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_gradients.scss +0 -0
  99. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_grid-framework.scss +0 -0
  100. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_grid.scss +0 -0
  101. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_hide-text.scss +0 -0
  102. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_image.scss +0 -0
  103. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_labels.scss +0 -0
  104. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_list-group.scss +0 -0
  105. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_nav-divider.scss +0 -0
  106. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_nav-vertical-align.scss +0 -0
  107. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_opacity.scss +0 -0
  108. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_pagination.scss +0 -0
  109. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_panels.scss +0 -0
  110. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_progress-bar.scss +0 -0
  111. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_reset-filter.scss +0 -0
  112. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_resize.scss +0 -0
  113. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_responsive-visibility.scss +0 -0
  114. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_size.scss +0 -0
  115. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_tab-focus.scss +0 -0
  116. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_table-row.scss +0 -0
  117. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_text-emphasis.scss +0 -0
  118. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_text-overflow.scss +0 -0
  119. data/client/{styles → lanes/styles}/vendor/bootstrap/mixins/_vendor-prefixes.scss +0 -0
  120. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_alerts.scss +0 -0
  121. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_badges.scss +0 -0
  122. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_breadcrumbs.scss +0 -0
  123. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_button-groups.scss +0 -0
  124. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_buttons.scss +0 -0
  125. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_carousel.scss +0 -0
  126. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_close.scss +0 -0
  127. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_code.scss +0 -0
  128. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_component-animations.scss +0 -0
  129. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_dropdowns.scss +0 -0
  130. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_forms.scss +0 -0
  131. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_glyphicons.scss +0 -0
  132. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_grid.scss +0 -0
  133. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_input-groups.scss +0 -0
  134. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_jumbotron.scss +0 -0
  135. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_labels.scss +0 -0
  136. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_list-group.scss +0 -0
  137. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_media.scss +0 -0
  138. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_mixins.scss +0 -0
  139. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_modals.scss +0 -0
  140. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_navbar.scss +0 -0
  141. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_navs.scss +0 -0
  142. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_normalize.scss +0 -0
  143. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_pager.scss +0 -0
  144. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_pagination.scss +0 -0
  145. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_panels.scss +0 -0
  146. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_popovers.scss +0 -0
  147. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_print.scss +0 -0
  148. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_progress-bars.scss +0 -0
  149. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_responsive-embed.scss +0 -0
  150. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_responsive-utilities.scss +0 -0
  151. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_scaffolding.scss +0 -0
  152. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_tables.scss +0 -0
  153. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_theme.scss +0 -0
  154. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_thumbnails.scss +0 -0
  155. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_tooltip.scss +0 -0
  156. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_type.scss +0 -0
  157. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_utilities.scss +0 -0
  158. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_variables.scss +0 -0
  159. data/client/{styles → lanes/styles}/vendor/bootstrap/old/_wells.scss +0 -0
  160. data/client/{styles → lanes/styles}/vendor/bootstrap/old/bootstrap.scss +0 -0
  161. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_alerts.scss +0 -0
  162. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_background-variant.scss +0 -0
  163. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_border-radius.scss +0 -0
  164. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_buttons.scss +0 -0
  165. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_center-block.scss +0 -0
  166. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_clearfix.scss +0 -0
  167. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_forms.scss +0 -0
  168. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_gradients.scss +0 -0
  169. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_grid-framework.scss +0 -0
  170. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_grid.scss +0 -0
  171. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_hide-text.scss +0 -0
  172. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_image.scss +0 -0
  173. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_labels.scss +0 -0
  174. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_list-group.scss +0 -0
  175. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_nav-divider.scss +0 -0
  176. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_nav-vertical-align.scss +0 -0
  177. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_opacity.scss +0 -0
  178. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_pagination.scss +0 -0
  179. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_panels.scss +0 -0
  180. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_progress-bar.scss +0 -0
  181. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_reset-filter.scss +0 -0
  182. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_resize.scss +0 -0
  183. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_responsive-visibility.scss +0 -0
  184. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_size.scss +0 -0
  185. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_tab-focus.scss +0 -0
  186. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_table-row.scss +0 -0
  187. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_text-emphasis.scss +0 -0
  188. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_text-overflow.scss +0 -0
  189. data/client/{styles → lanes/styles}/vendor/bootstrap/old/mixins/_vendor-prefixes.scss +0 -0
  190. data/client/{styles → lanes/styles}/vendor/bootstrap-custom-grid.scss +0 -0
  191. data/client/{styles → lanes/styles}/vendor/bootstrap-custom-modals.scss +0 -0
  192. data/client/{styles → lanes/styles}/vendor/bootstrap.scss +2 -2
  193. data/client/{styles → lanes/styles}/vendor/dataTables.scss +0 -0
  194. data/client/lanes/views/Base.coffee +34 -49
  195. data/client/lanes/views/FormBindings.coffee +22 -20
  196. data/client/lanes/views/Helpers.coffee +1 -1
  197. data/client/lanes/views/empty-span.html +1 -0
  198. data/client/lanes/workspace/ActiveScreensSwitcher.coffee +8 -1
  199. data/client/lanes/workspace/Layout.coffee +7 -4
  200. data/client/lanes/workspace/Navbar.coffee +6 -2
  201. data/client/lanes/workspace/Pages.coffee +5 -1
  202. data/client/lanes/workspace/ScreensMenu.coffee +14 -2
  203. data/client/lanes/workspace/WorkspaceView.coffee +5 -0
  204. data/client/lanes/workspace/index.js +1 -0
  205. data/client/lanes/workspace.scss.erb +6 -1
  206. data/lanes.gemspec +1 -1
  207. data/lib/lanes/api/controller.rb +5 -7
  208. data/lib/lanes/api/helper_methods.rb +1 -1
  209. data/lib/lanes/api/javascript_processor.rb +3 -2
  210. data/lib/lanes/command/app.rb +8 -4
  211. data/lib/lanes/command/generate_model.rb +13 -11
  212. data/lib/lanes/command/generate_screen.rb +9 -2
  213. data/lib/lanes/command/generate_view.rb +15 -3
  214. data/lib/lanes/command/generate_view.usage +7 -7
  215. data/lib/lanes/command/named_command.rb +2 -2
  216. data/lib/lanes/command/templates/client/index.js +3 -0
  217. data/lib/lanes/command/templates/client/models/BaseModel.coffee +5 -0
  218. data/lib/lanes/command/templates/client/models/Model.coffee +1 -1
  219. data/lib/lanes/command/templates/client/views/BaseView.coffee +5 -0
  220. data/lib/lanes/command/templates/client/views/View.coffee +1 -1
  221. data/lib/lanes/command/templates/config/screen.rb +8 -0
  222. data/lib/lanes/command/templates/lib/namespace/base_model.rb +9 -0
  223. data/lib/lanes/command/templates/lib/namespace/model.rb +1 -1
  224. data/lib/lanes/command/templates/spec/client/models/ModelSpec.coffee +1 -1
  225. data/lib/lanes/command/templates/spec/client/views/ViewSpec.coffee +1 -1
  226. data/lib/lanes/command.rb +1 -2
  227. data/lib/lanes/components.rb +5 -4
  228. data/lib/lanes/concerns/all.rb +0 -5
  229. data/lib/lanes/concerns/attr_accessor_with_default.rb +5 -3
  230. data/lib/lanes/concerns/set_attribute_data.rb +6 -23
  231. data/lib/lanes/configuration.rb +1 -0
  232. data/lib/lanes/extension.rb +19 -10
  233. data/lib/lanes/guard_tasks.rb +1 -1
  234. data/lib/lanes/model.rb +1 -6
  235. data/lib/lanes/{screens.rb → screen.rb} +40 -23
  236. data/lib/lanes/spec_helper.rb +4 -2
  237. data/lib/lanes/version.rb +1 -1
  238. data/lib/lanes.rb +1 -1
  239. data/spec/api/javascript_processor_spec.rb +3 -3
  240. data/spec/command_spec.rb +49 -0
  241. data/spec/concerns/attr_accessor_with_default_spec.rb +7 -0
  242. data/spec/helpers/lanes-helpers.coffee +46 -22
  243. data/spec/helpers/minitest_assertions.rb +23 -0
  244. data/spec/lanes/models/BaseSpec.coffee +57 -56
  245. data/spec/lanes/models/CollectionSpec.coffee +14 -0
  246. data/spec/lanes/models/PubSubSpec.coffee +5 -5
  247. data/spec/lanes/views/BaseSpec.coffee +32 -31
  248. data/spec/lanes/views/FormBindingsSpec.coffee +32 -0
  249. metadata +183 -179
  250. data/client/lanes/components/popover/popover.scss +0 -1
  251. data/lib/lanes/command/templates/lib/namespace/screen.rb +0 -17
  252. data/lib/lanes/concerns/code_identifier.rb +0 -43
  253. data/lib/lanes/concerns/immutable_model.rb +0 -32
  254. data/lib/lanes/concerns/locked_fields.rb +0 -84
  255. data/lib/lanes/concerns/random_hash_code.rb +0 -40
  256. data/lib/lanes/concerns/visible_id_identifier.rb +0 -53
  257. data/spec/concerns/code_identifier_spec.rb +0 -45
@@ -57,8 +57,8 @@ $popover-max-width: 320px;
57
57
  @import "bootstrap/close";
58
58
 
59
59
  // Components w/ JavaScript
60
- //@import "bootstrap/modals";
61
- //@import "bootstrap-custom-modals";
60
+ /* @import "bootstrap/modals"; */
61
+ @import "bootstrap-custom-modals";
62
62
 
63
63
  @import "bootstrap/tooltip";
64
64
 
@@ -25,7 +25,7 @@ class ViewBase
25
25
  pubSub : "boolean"
26
26
  parent : "object"
27
27
  subviewId : { type: "string", setOnce: true }
28
-
28
+ formBindings: { type: 'any', default: false }
29
29
 
30
30
  derived:
31
31
  '$el':
@@ -81,8 +81,8 @@ class ViewBase
81
81
  if !this.pubSub? # if it's unset, not true/false; default to parent or true
82
82
  this.pubSub = if this.parent?.pubSub? then this.parent.pubSub else true
83
83
 
84
-
85
- this.initializeFormBindings() if @form_bindings
84
+ if @formBindings || @parent?.formBindings
85
+ @formBindings = new Lanes.Views.FormBindings(this, @formBindings)
86
86
 
87
87
  if @keyBindings
88
88
  Lanes.Views.Keys.add(this, @keyBindings, @keyScope)
@@ -114,21 +114,15 @@ class ViewBase
114
114
  # **render** is the core function that your view can override, its job is
115
115
  # to populate its element (`this.el`), with the appropriate HTML.
116
116
  render: ->
117
- this.withRenderContext( this.renderWithTemplate )
118
- return this;
119
-
120
- withRenderContext: (fn, args...)->
121
117
  Lanes.Views.RenderContext.push( @subviewId, @model )
122
- returned = fn.apply(this,args)
118
+ this.renderContextFree()
123
119
  Lanes.Views.RenderContext.pop()
124
- this.onRender?()
125
- returned
120
+ this
126
121
 
127
122
  renderContextFree: ->
128
- this.renderWithTemplate();
123
+ this.replaceEl( this.renderTemplateMethod() );
129
124
  this
130
125
 
131
-
132
126
  # ## listenToAndRun
133
127
  # Shortcut for registering a listener for a model
134
128
  # and also triggering it right away.
@@ -137,50 +131,42 @@ class ViewBase
137
131
  this.listenTo(object, events, bound)
138
132
  bound();
139
133
 
140
- # Replaces the current root element with a newly created dom element
141
- #
142
- # Either define a `template` property of your view
143
- # or pass in a template directly.
144
- # The template can either be a string or a function.
145
- # If it's a function it will be passed the `context`
146
- # argument.
147
- renderWithTemplate: (templateArg)->
148
- template = templateArg || this.resultsFor('template')
149
- throw new Error('Template string or function needed.') unless template
150
- template_fn = Lanes.Templates.find(template, this.FILE.extension)
151
- newDom = if template_fn then template_fn( _.result(this,'templateModels')) else template
152
- newDom = Lanes.Vendor.domify(newDom) if _.isString(newDom);
134
+ # Replaces the current root element with the contents of template
135
+ replaceEl: (template)->
136
+ newDom = Lanes.Vendor.domify(template)
153
137
  parent = this.el && this.el.parentNode;
154
138
  parent.replaceChild(newDom, this.el) if parent
155
139
  if newDom.nodeName == '#document-fragment'
156
- throw new Error('Views can only have one root element.')
140
+ throw new Error("View #{this.FILE.path} can only have one root element.")
157
141
  if newDom.nodeName == '#text'
158
- throw new Error('Views must have a root element.')
142
+ throw new Error("View #{this.FILE.path} must have a root element.")
159
143
  this.el = newDom;
144
+ this.onRender?()
160
145
  return this;
161
146
 
162
- templateName: -> _.underscore( this.FILE.file )
163
-
164
- template: ->
165
- this.FILE.extension.toLowerCase() + "/views/" + _.result(this,'templateName')
147
+ # Renders the results of calling method "name"
148
+ # to a string and returns it.
149
+ #
150
+ # The template can either be a string property or a function that returns a string.
151
+ renderTemplateMethod:(name="template",data)->
152
+ template = if this[name]
153
+ _.result(this, name)
154
+ else
155
+ data ||= _.result(this,"#{name}Data")
156
+ path = _.result(this,'templatePrefix') + _.result(this, "#{name}Name")
157
+ Lanes.Templates.render(this, path, data)
158
+ throw new Error("#{this.FILE.path} failed to render #{name}") unless template
159
+ template
166
160
 
167
- FILE: FILE
161
+ templateName: -> _.underscore( this.FILE.path )
168
162
 
169
- templateModels: ->
170
- { model: this.model, collection: this.collection }
163
+ templatePrefix: -> this.FILE.extensionName.toLowerCase() + "/views/"
171
164
 
172
- renderTemplate:(name,data={})->
173
- template = Lanes.Templates.find(name, this.FILE.name)
174
- if template
175
- template(data)
176
- else
177
- Lanes.fatal( "Template #{name} doesn't exist!" )
178
- ''
165
+ templateData: ->
166
+ { model: @model?.toJSON?(), collection: @collection?.toJSON?() }
179
167
 
180
- renderTemplateMethod: (method)->
181
- return null unless name = _.result(this, method)
182
- this.renderTemplate(name, _.result(this, "#{method}Models") || @model)
183
168
 
169
+ FILE: FILE
184
170
 
185
171
  # Remove this view by taking the element out of the DOM, and removing any
186
172
  # applicable events listeners.
@@ -327,7 +313,6 @@ class ViewBase
327
313
  new klass(_.extend(options,{ el: el, parent: self }))
328
314
 
329
315
  }
330
-
331
316
  action = ->
332
317
  return if (!this.el || !(el = this.query(opts.selector)))
333
318
  if (!opts.waitFor || _.getPath(this, opts.waitFor))
@@ -391,10 +376,10 @@ class ViewBase
391
376
 
392
377
  initializeKeyBindings: Lanes.emptyFn
393
378
 
394
- initializeFormBindings: ->
395
- @_form_bindings = {}
396
- for data, selector of @form_bindings
397
- @_form_bindings[data] = new Lanes.Views.FormBindings(this, data, selector)
379
+ # initializeFormBindings: ->
380
+ # @_form_bindings = {}
381
+ # for data, selector of @form_bindings
382
+ # @_form_bindings[data] =
398
383
 
399
384
  setFieldsFromBindings: ->
400
385
  binding.setAllFields() for name, binding of @_form_bindings
@@ -1,22 +1,21 @@
1
1
  class Lanes.Views.FormBindings
2
2
 
3
- constructor: (@view, @keypath, @selector)->
3
+ constructor: (@view, config={})->
4
4
  _.bindAll(this,'onFieldChange')
5
- @selector = "#{@selector} " if @selector
6
- @view.on( "change:el", this.rebindForm, this )
7
- @view.on( "change:#{@keypath}", this.rebindModel, this )
8
- @view.on( "remove", this.teardown, this )
9
- this.rebindModel( @view, @model() )
5
+ @selector = if config.selector then "#{config.selector} " else ""
6
+ @view.on( "change:el", this.rebindForm, this )
7
+ @view.on( "change:model", this.rebindModel, this )
8
+ @view.on( "remove", this.teardown, this )
9
+ this.rebindModel( @view, @view.model )
10
10
 
11
11
  onFieldChange: (ev)->
12
12
  el = Lanes.$(ev.target);
13
13
  name = el.attr('name');
14
- m = this.model();
14
+ m = @view.model;
15
15
  return unless m.hasAttribute(name)
16
16
  val = el.val()
17
-
18
17
  el[0]._is_setting=true; m.set( name, val ); delete el[0]._is_setting
19
- msg = m.validateFieldChange(name,val)
18
+ msg = m.checkValid(name,val)
20
19
  this.setError( el, msg )
21
20
 
22
21
  onAttributeUpdate: (model, opts={})->
@@ -24,7 +23,7 @@ class Lanes.Views.FormBindings
24
23
  if attributes['errors'] && ! _.isEmpty(attributes['errors'])
25
24
  for name, message of attributes['errors']
26
25
  this.setError(Lanes.$(el),message) if el = this.getElement(name)
27
- for name, _ of attributes
26
+ for name, _val of attributes
28
27
  el = this.getElement(name)
29
28
  this.setElValue(Lanes.$(el),model.get(name)) if el && ! el._is_setting
30
29
 
@@ -32,7 +31,8 @@ class Lanes.Views.FormBindings
32
31
  if el.attr('type')
33
32
  switch el.attr('type')
34
33
  when 'radio'
35
- for input in Lanes.$(this.view.el).find("#{@selector}input[type=radio][name=#{el.attr('name')}]")
34
+ selector="#{@selector}input[type=radio][name=#{el.attr('name')}]"
35
+ for input in Lanes.$(this.view.el).find(selector)
36
36
  input.checked = input.value == value
37
37
  when 'checkbox'
38
38
  el.prop('checked', !!value)
@@ -67,27 +67,29 @@ class Lanes.Views.FormBindings
67
67
  attrs
68
68
 
69
69
  fields: ->
70
- @cached_fields ||= Lanes.$(@view.el).find("#{@selector}input, #{@selector}.ro-input.update")
70
+ @cached_fields ||= @view.el?.querySelectorAll("#{@selector}input, #{@selector}.ro-input.update")
71
71
 
72
72
  getElement: (name)->
73
- _.find( this.fields(), (i)->i.getAttribute('name') == name )
73
+ return unless fields = this.fields()
74
+ for field in fields
75
+ return field if field.getAttribute('name') == name
76
+ null
74
77
 
75
78
  setAllFields: ->
76
- this.onAttributeUpdate(this.model(), all: true)
77
-
78
- model: ->
79
- @cached_model ||= Lanes.getPath(@keypath, @view)
79
+ this.onAttributeUpdate(@view.model, all: true)
80
80
 
81
81
  rebindForm: (view, el)->
82
82
  input_selector = "#{@selector}input, #{@selector}select"
83
83
  if old_el = @view.changedAttributes()['el']
84
84
  Lanes.$(el).off("change", input_selector, this.onFieldChange )
85
85
  @cached_fields = null
86
- Lanes.$(el).on("change",input_selector, this.onFieldChange )
86
+ if @view.model
87
+ this.setAllFields()
88
+ @view.$el.on("change", input_selector, this.onFieldChange )
87
89
 
88
90
  rebindModel: (view, model)->
89
91
  this.clearErrors()
90
- if old_model = @view.changedAttributes()[@keypath]
92
+ if old_model = @view.changedAttributes()['model']
91
93
  old_model.off( "change", this.onAttributeUpdate )
92
94
  if model
93
95
  this.onAttributeUpdate(model, { all: true } )
@@ -95,4 +97,4 @@ class Lanes.Views.FormBindings
95
97
  model.on('change', this.onAttributeUpdate, this )
96
98
 
97
99
  teardown: ->
98
- this.model().off( "change", this.onAttributeUpdate )
100
+ @view.model?.off( "change", this.onAttributeUpdate )
@@ -15,7 +15,7 @@ impl = {
15
15
  this.markSafe(contents)
16
16
 
17
17
  template: (template,data)->
18
- this.markSafe( Lanes.Templates.find('views/_'+template)(data) )
18
+ this.markSafe( Lanes.Templates.find('lanes/views/_'+template)(data) )
19
19
 
20
20
  markSafe: (str)->
21
21
  result = new String(str)
@@ -0,0 +1 @@
1
+ <span></span>
@@ -1,6 +1,10 @@
1
1
  class TabView extends Lanes.Views.Base
2
2
 
3
3
  template: "<li><a data-toggle='tab'></a><span class='close'>×</span></li>"
4
+ FILE: FILE
5
+ mixins:[
6
+ Lanes.Workspace.WorkspaceView
7
+ ]
4
8
 
5
9
  bindings:
6
10
  'model.screen.title': { selector: 'a', type: 'text' }
@@ -22,7 +26,10 @@ TAB_PADDING = 0
22
26
 
23
27
  class Lanes.Workspace.ActiveScreenSwitcher extends Lanes.Views.Base
24
28
 
25
- template: 'workspace/screens-switcher'
29
+ templateName: 'screens-switcher'
30
+ mixins:[
31
+ Lanes.Workspace.WorkspaceView
32
+ ]
26
33
 
27
34
  key_scope: { name: 'nav', shortcut: '⌘+shift+t,ctrl+shift+t' }
28
35
  key_bindings:
@@ -1,16 +1,19 @@
1
-
2
1
  class Lanes.Workspace.Layout extends Lanes.Views.Base
3
2
 
4
- template: 'workspace/layout'
3
+ templateName: 'layout'
4
+ mixins:[
5
+ Lanes.Workspace.WorkspaceView
6
+ ]
7
+ FILE: FILE
5
8
 
6
9
  subviews:
7
10
  navbar:
8
11
  hook: 'navbar-container'
9
- view: 'Lanes.Workspace.Navbar'
12
+ view: 'Workspace.Navbar'
10
13
 
11
14
  pages:
12
15
  hook: 'page-container'
13
- view: 'Lanes.Workspace.Pages'
16
+ view: 'Workspace.Pages'
14
17
 
15
18
  subviewOptions: -> { model: this.model }
16
19
 
@@ -1,6 +1,10 @@
1
1
  class Lanes.Workspace.Navbar extends Lanes.Views.Base
2
2
 
3
- template: 'workspace/navbar'
3
+ templateName: 'navbar'
4
+ FILE: FILE
5
+ mixins:[
6
+ Lanes.Workspace.WorkspaceView
7
+ ]
4
8
 
5
9
  events:
6
10
  'click .screens-menu-toggle': 'switchMenu'
@@ -9,7 +13,7 @@ class Lanes.Workspace.Navbar extends Lanes.Views.Base
9
13
  subviews:
10
14
  screens:
11
15
  hook: 'screens-container'
12
- view: 'Lanes.Workspace.ActiveScreenSwitcher'
16
+ view: 'Workspace.ActiveScreenSwitcher'
13
17
  model: 'model'
14
18
 
15
19
  bindings:
@@ -1,6 +1,10 @@
1
1
  class Lanes.Workspace.Pages extends Lanes.Views.Base
2
2
 
3
- template: 'workspace/pages'
3
+ templateName: 'pages'
4
+ FILE: FILE
5
+ mixins:[
6
+ Lanes.Workspace.WorkspaceView
7
+ ]
4
8
 
5
9
  bindings:
6
10
  'model.screen_menu_size': { type: 'class' }
@@ -1,6 +1,10 @@
1
1
  class ScreenList extends Lanes.Views.Base
2
2
 
3
3
  template: "<li><a href='#'><span></span><i></i></a></li>"
4
+ FILE: FILE
5
+ mixins:[
6
+ Lanes.Workspace.WorkspaceView
7
+ ]
4
8
 
5
9
  events:
6
10
  click: 'displayScreen'
@@ -16,6 +20,10 @@ class ScreenList extends Lanes.Views.Base
16
20
  class ScreenGroup extends Lanes.Views.Base
17
21
 
18
22
  template: -> '<li class="group"><a href="#"><span></span><i></i></a><ul></ul></li>'
23
+ FILE: FILE
24
+ mixins:[
25
+ Lanes.Workspace.WorkspaceView
26
+ ]
19
27
  events:
20
28
  'click .group>a': 'toggleMenu'
21
29
 
@@ -42,8 +50,12 @@ class ScreenGroup extends Lanes.Views.Base
42
50
 
43
51
  class Lanes.Workspace.ScreensMenu extends Lanes.Views.Base
44
52
 
45
- constructor: -> super
46
- template: 'workspace/screens-menu'
53
+ templateName: 'screens-menu'
54
+ mixins:[
55
+ Lanes.Workspace.WorkspaceView
56
+ ]
57
+
58
+ FILE: FILE
47
59
 
48
60
  subviews:
49
61
  navigation:
@@ -0,0 +1,5 @@
1
+ Lanes.Workspace.WorkspaceView = {
2
+
3
+ templatePrefix: -> 'workspace/'
4
+
5
+ }
@@ -1,4 +1,5 @@
1
1
  //= require ../minimal
2
2
  //= require_self
3
+ //= require ./WorkspaceView
3
4
  //= require_tree .
4
5
  Lanes.namespace( 'Workspace' );
@@ -11,7 +11,7 @@
11
11
  @import "<%= ext.stylesheet_include %>";
12
12
  <% end %>
13
13
  <% Lanes::Components.enabled_with_dependencies(self) do | component | %>
14
- @import "components/<%= component %>/<%= component %>";
14
+ @import "lanes/components/<%= component %>/index";
15
15
  <% end %>
16
16
  @import "styles/plugins/all";
17
17
  @import "styles/layout";
@@ -22,3 +22,8 @@
22
22
  @import "styles/forms";
23
23
  @import "styles/keybindings";
24
24
  }
25
+ <% if !Lanes.config.initial_workspace_screen_id.blank? &&
26
+ screen = Lanes::Screen[Lanes.config.initial_workspace_screen_id]
27
+ %>
28
+ @import "<%= screen.css.remove(/\.css$/) + "/index.scss" %>"
29
+ <% end %>
data/lanes.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.required_ruby_version = ">= 2.0"
26
26
 
27
- spec.add_dependency "activerecord", "~> 4.1"
27
+ spec.add_dependency "activerecord", "~> 4.2"
28
28
  spec.add_dependency "pg", "~> 0.17"
29
29
  spec.add_dependency "sinatra", "~> 1.4"
30
30
  spec.add_dependency "bcrypt", "~> 3.1"
@@ -148,12 +148,11 @@ module Lanes
148
148
  if options[:total_count]
149
149
  json[:total] = options.delete(:total_count)
150
150
  end
151
- json.merge!({
152
- :success => success,
153
- :message => options[:messsage] || json_status_str(query, type.to_s.capitalize, success),
154
- :data => success ? records_for_reply(query, options) : []
155
- })
156
- return json
151
+ json.merge(
152
+ success: success,
153
+ message: options[:messsage] || json_status_str(query, type.to_s.capitalize, success),
154
+ data: success ? records_for_reply(query, options) : []
155
+ )
157
156
  end
158
157
 
159
158
 
@@ -327,5 +326,4 @@ module Lanes
327
326
 
328
327
  end
329
328
  end
330
-
331
329
  end
@@ -10,7 +10,7 @@ module Lanes
10
10
  def lanes_stylesheet_tag
11
11
  stylesheet_tag( Extensions.require_workspace? ? 'lanes/workspace' : 'lanes/minimal' )
12
12
  end
13
-
13
+
14
14
  def client_bootstrap_data
15
15
  Oj.dump(Extensions.client_bootstrap_data(self), mode: :compat)
16
16
  end
@@ -26,14 +26,15 @@ module Lanes
26
26
  # if the file is being loaded under the "lanes" directory
27
27
  # it's not an extension
28
28
  if ns && ns != "Lanes"
29
+ ns = ns.underscore.camelize
29
30
  ref = "(window.Lanes ? window.Lanes['#{ns}'] : null)"
30
31
  "(function(Lanes, #{ns}, _, window, FILE, undefined)"\
31
32
  "{\n#{js}\n})(window.Lanes,#{ref},window._, window,"\
32
- "{namespace:#{ref},extension:'#{ns}',file:'#{file}'});"
33
+ "{namespace:#{ref},extensionName:'#{ns}',path:'#{file}'});"
33
34
  else
34
35
  "(function(Lanes, _, window, FILE, undefined)"\
35
36
  "{\n#{js}\n})(window.Lanes,window._, window,"\
36
- "{namespace:window.Lanes,extension:'Lanes',file:'#{file}'});"
37
+ "{namespace:window.Lanes,extensionName:'Lanes',path:'#{file}'});"
37
38
  end
38
39
  end
39
40
 
@@ -24,30 +24,34 @@ module Lanes
24
24
  template "lib/namespace.rb", "lib/#{name}.rb"
25
25
  template "lib/namespace/version.rb", "lib/#{name}/version.rb"
26
26
  template "lib/namespace/extension.rb", "lib/#{name}/extension.rb"
27
+ template "lib/namespace/base_model.rb", "lib/#{name}/model.rb"
27
28
  template "config/routes.rb"
28
29
  template "config/lanes.rb"
29
30
  template "gitignore",".gitignore"
30
31
  create_file "tmp/.gitkeep",""
31
32
  create_file "db/.gitkeep", ""
33
+ create_file "config/screens.rb"
32
34
  end
33
35
 
34
36
  def create_client_files
35
37
  self.class.source_root.join('client').children.each do | path |
36
38
  next unless path.directory?
37
- empty_directory "#{client_dir}/#{path.basename}"
39
+ empty_directory "#{client_dir}/#{path.basename}"
38
40
  create_file "#{client_dir}/#{path.basename}/.gitkeep"
39
41
  end
42
+ template "client/models/BaseModel.coffee", "#{client_dir}/models/Base.coffee"
43
+ template "client/views/BaseView.coffee", "#{client_dir}/views/Base.coffee"
40
44
  template "client/index.js", "#{client_dir}/index.js"
41
45
  template "client/Extension.coffee", "#{client_dir}/Extension.coffee"
42
46
  template "client/styles.scss", "#{client_dir}/styles.scss"
43
47
  end
44
48
 
45
49
  def create_spec
46
-
50
+
47
51
  end
48
-
52
+
49
53
  def create_first_screen
50
- invoke GenerateScreen, ["base"], title: name.titleize, namespace: name
54
+ template "client/screens/Screen.coffee", "#{client_dir}/screens/Base.coffee"
51
55
  end
52
56
  end
53
57
 
@@ -28,7 +28,8 @@ module Lanes
28
28
  end
29
29
 
30
30
  def create_migration
31
- migration = exising_migration || Time.now.utc.strftime("%Y%m%d%H%M%S") + "_create_#{table_name}.rb"
31
+ migration = exising_migration ||
32
+ Time.now.utc.strftime("%Y%m%d%H%M%S") + "_create_#{table_name}.rb"
32
33
  self.fields = fields.map{ |field| ModelAttribute.parse(field) }
33
34
  template "db/create_table_migration.rb", "db/migrate/#{migration}"
34
35
  end
@@ -36,15 +37,16 @@ module Lanes
36
37
  def create_model
37
38
  template "lib/namespace/model.rb", "lib/#{namespace}/#{file_name}.rb"
38
39
  template "spec/namespace/model_spec.rb", "#{spec_dir}/#{file_name}.rb"
39
- template "spec/fixtures/namespace/model.yml", "spec/fixtures/#{namespace}/#{file_name}.yml"
40
+ template "spec/fixtures/namespace/model.yml",
41
+ "spec/fixtures/#{namespace}/#{file_name}.yml"
40
42
  end
41
43
 
42
44
  def create_client
43
45
  self.fields.unshift ModelAttribute.parse("id:integer")
44
46
  template "client/models/Model.coffee", \
45
- "#{client_dir}/models/#{class_name}.coffee"
47
+ "#{client_dir}/models/#{class_name}.coffee"
46
48
  template "spec/client/models/ModelSpec.coffee", \
47
- "#{spec_dir}/models/#{class_name}Spec.coffee"
49
+ "#{spec_dir}/models/#{class_name}Spec.coffee"
48
50
  end
49
51
 
50
52
  def add_route
@@ -83,13 +85,13 @@ module Lanes
83
85
  end
84
86
  end
85
87
 
86
- def client_parent
87
- if options[:parent] == 'Lanes::Model'
88
- "Lanes.Models.Base"
89
- else
90
- "Lanes.#{namespace.camelize}.#{options[:parent]}"
91
- end
92
- end
88
+ # def client_parent
89
+ # if options[:parent] == 'Lanes::Model'
90
+ # "Lanes.Models.Base"
91
+ # else
92
+ # "#{namespace.camelize}.Models.#{options[:parent]}"
93
+ # end
94
+ # end
93
95
 
94
96
  def max_field_length
95
97
  @max_field_length ||= fields.map{|field|