lanes 0.1.9 → 0.1.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (447) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/client/fonts/fontawesome-webfont.woff +0 -0
  4. data/client/fonts/fontawesome-webfont.woff2 +0 -0
  5. data/client/lanes/Boot.cjsx +9 -0
  6. data/client/lanes/access/Extension.coffee +18 -4
  7. data/client/lanes/access/LoginDialog.cjsx +78 -0
  8. data/client/lanes/access/Roles.coffee +22 -28
  9. data/client/lanes/access/User.coffee +16 -16
  10. data/client/lanes/access/index.js +4 -5
  11. data/client/lanes/access/screens/user-management/Editor.cjsx +20 -0
  12. data/client/lanes/access/screens/user-management/UserManagement.cjsx +41 -0
  13. data/client/lanes/access/screens/user-management/index.js +0 -1
  14. data/client/lanes/components/grid/EditingMixin.cjsx +64 -0
  15. data/client/lanes/components/grid/Grid.cjsx +139 -0
  16. data/client/lanes/components/grid/PopOverMixin.cjsx +28 -0
  17. data/client/lanes/components/grid/PopoverEditor.cjsx +8 -0
  18. data/client/lanes/components/grid/RowEditor.cjsx +10 -0
  19. data/client/lanes/components/grid/Toolbar.cjsx +14 -0
  20. data/client/lanes/components/grid/config.json +1 -1
  21. data/client/lanes/components/grid/editors.scss +94 -53
  22. data/client/lanes/components/grid/index.js +2 -7
  23. data/client/lanes/components/grid/styles.scss +8 -296
  24. data/client/lanes/components/helpers.coffee +2 -0
  25. data/client/lanes/components/index.js +2 -1
  26. data/client/lanes/components/modal/Modal.cjsx +36 -0
  27. data/client/lanes/components/modal/index.js +1 -2
  28. data/client/lanes/components/modal/styles.scss +0 -19
  29. data/client/lanes/components/record-finder/Clause.cjsx +80 -0
  30. data/client/lanes/components/record-finder/Dialog.cjsx +54 -0
  31. data/client/lanes/components/record-finder/RecordFinder.cjsx +38 -0
  32. data/client/lanes/components/record-finder/config.json +1 -1
  33. data/client/lanes/components/record-finder/index.js +1 -2
  34. data/client/lanes/components/request-spinner/index.js +1 -0
  35. data/client/lanes/components/select-field/SelectField.cjsx +78 -0
  36. data/client/lanes/components/select-field/index.js +2 -1
  37. data/client/lanes/components/select-field/styles.scss +1 -0
  38. data/client/lanes/components/shared/CountBadge.cjsx +9 -0
  39. data/client/lanes/components/shared/ErrorDisplay.cjsx +21 -0
  40. data/client/lanes/components/shared/FieldMixin.cjsx +71 -0
  41. data/client/lanes/components/shared/FieldSet.cjsx +58 -0
  42. data/client/lanes/components/shared/GenericField.cjsx +5 -0
  43. data/client/lanes/components/shared/Helpers.coffee +9 -0
  44. data/client/lanes/components/shared/RadioField.cjsx +14 -0
  45. data/client/lanes/components/shared/Resize.cjsx +152 -0
  46. data/client/lanes/components/shared/TextArea.cjsx +19 -0
  47. data/client/lanes/components/shared/TextField.cjsx +25 -0
  48. data/client/lanes/components/shared/Tooltip.cjsx +10 -0
  49. data/client/lanes/components/shared/fields.scss +35 -0
  50. data/client/lanes/components/shared/fieldset.scss +29 -0
  51. data/client/lanes/components/shared/index.js +3 -0
  52. data/client/lanes/components/shared/styles.scss +32 -0
  53. data/client/lanes/components/toolbar/RemoteChangeSets.cjsx +75 -0
  54. data/client/lanes/components/toolbar/SaveButton.cjsx +3 -0
  55. data/client/lanes/components/toolbar/Toolbar.cjsx +58 -0
  56. data/client/lanes/{workspace/styles → components/toolbar}/changes-notification.scss +10 -23
  57. data/client/lanes/components/toolbar/index.js +3 -0
  58. data/client/lanes/components/toolbar/styles.scss +51 -0
  59. data/client/lanes/extension/Extensions.coffee +19 -10
  60. data/client/lanes/extension/LateLoaded.js.erb +4 -3
  61. data/client/lanes/index.js +3 -5
  62. data/client/lanes/index.scss.erb +6 -14
  63. data/client/lanes/lib/HotReload.coffee +35 -0
  64. data/client/lanes/lib/MakeBaseClass.coffee +10 -11
  65. data/client/lanes/lib/development.coffee +3 -0
  66. data/client/lanes/lib/dom.coffee +49 -0
  67. data/client/lanes/lib/el.coffee +23 -0
  68. data/client/lanes/lib/index.js.erb +16 -0
  69. data/client/lanes/lib/loader.coffee +34 -34
  70. data/client/lanes/lib/namespace.coffee +1 -1
  71. data/client/lanes/lib/objToParam.coffee +37 -0
  72. data/client/lanes/{access/views/.gitkeep → lib/production.coffee} +0 -0
  73. data/client/lanes/lib/utilFunctions.coffee +44 -26
  74. data/client/lanes/models/AssociationMap.coffee +51 -38
  75. data/client/lanes/models/Base.coffee +89 -88
  76. data/client/lanes/models/ChangeMonitor.coffee +10 -10
  77. data/client/lanes/models/ChangeSet.coffee +14 -24
  78. data/client/lanes/models/Collection.coffee +40 -41
  79. data/client/lanes/models/PubSub.coffee +28 -19
  80. data/client/lanes/models/Query.coffee +78 -45
  81. data/client/lanes/models/QueryResults.coffee +93 -0
  82. data/client/lanes/models/ServerCache.coffee +12 -12
  83. data/client/lanes/models/Sync.coffee +53 -50
  84. data/client/lanes/models/User.coffee +31 -17
  85. data/client/lanes/react/Component.coffee +31 -0
  86. data/client/lanes/react/DefaultComponentNotFound.cjsx +9 -0
  87. data/client/lanes/{views → react}/FormBindings.coffee +0 -0
  88. data/client/lanes/{views → react}/ModelObserver.coffee +0 -0
  89. data/client/lanes/{views → react}/ModelUpdate.coffee +0 -0
  90. data/client/lanes/{views → react}/PubSub.coffee +0 -0
  91. data/client/lanes/react/Root.cjsx +14 -0
  92. data/client/lanes/react/Router.cjsx +18 -0
  93. data/client/lanes/react/Screen.coffee +15 -0
  94. data/client/lanes/{views → react}/TimedHighlight.coffee +0 -0
  95. data/client/lanes/{views → react}/TimedMask.coffee +0 -0
  96. data/client/lanes/react/TypeValidators.coffee +21 -0
  97. data/client/lanes/{lib/create-namespace.js → react/Utils.coffee} +0 -0
  98. data/client/lanes/react/Viewport.coffee +30 -0
  99. data/client/lanes/react/index.js +8 -0
  100. data/client/lanes/react/mixins/Access.coffee +27 -0
  101. data/client/lanes/react/mixins/Component.coffee +4 -0
  102. data/client/lanes/react/mixins/Data.coffee +136 -0
  103. data/client/lanes/react/mixins/MonitorSize.coffee +11 -0
  104. data/client/lanes/react/mixins/ReadEditingState.coffee +11 -0
  105. data/client/lanes/react/mixins/RelayEditingState.coffee +17 -0
  106. data/client/lanes/react/mixins/RelayFieldChange.coffee +11 -0
  107. data/client/lanes/react/mixins/Screen.coffee +7 -0
  108. data/client/lanes/react/mixins/Viewport.coffee +11 -0
  109. data/client/lanes/screens/ChangeListener.coffee +3 -3
  110. data/client/lanes/screens/Commands.coffee +27 -0
  111. data/client/lanes/screens/Definitions.coffee +74 -65
  112. data/client/lanes/screens/all.js.erb +1 -1
  113. data/client/lanes/screens/index.js +1 -2
  114. data/client/lanes/screens/mixins/index.js +0 -1
  115. data/client/lanes/screens/register.js.erb +0 -1
  116. data/client/lanes/screens/styles.scss +7 -0
  117. data/client/lanes/styles/bootstrap-custom-grid.scss +67 -37
  118. data/client/lanes/styles/bootstrap.scss +4 -5
  119. data/client/lanes/styles/fonts.scss +10 -23
  120. data/client/lanes/styles/fonts/_animated.scss +34 -0
  121. data/client/lanes/styles/fonts/_bordered-pulled.scss +16 -0
  122. data/client/lanes/styles/fonts/_core.scss +13 -0
  123. data/client/lanes/styles/fonts/_fixed-width.scss +6 -0
  124. data/client/lanes/styles/fonts/_icons.scss +596 -0
  125. data/client/lanes/styles/fonts/_larger.scss +13 -0
  126. data/client/lanes/styles/fonts/_list.scss +19 -0
  127. data/client/lanes/styles/fonts/_mixins.scss +27 -0
  128. data/client/lanes/styles/fonts/_path.scss +10 -0
  129. data/client/lanes/styles/fonts/_rotated-flipped.scss +20 -0
  130. data/client/lanes/styles/fonts/_stacked.scss +20 -0
  131. data/client/lanes/styles/fonts/_variables.scss +606 -0
  132. data/client/lanes/styles/fonts/font-awesome.scss +16 -0
  133. data/client/lanes/styles/fonts/index.scss +2 -0
  134. data/client/lanes/styles/global.scss +2 -0
  135. data/client/lanes/styles/global/fancy-header.scss +14 -0
  136. data/client/lanes/testing/BeforeEach.coffee +15 -40
  137. data/client/lanes/testing/Helpers.coffee +27 -0
  138. data/client/lanes/testing/ModelSaver.coffee +14 -24
  139. data/client/lanes/testing/StubRouter.coffee +27 -0
  140. data/client/lanes/testing/TestObjects.coffee +27 -0
  141. data/client/lanes/testing/index.js +3 -1
  142. data/client/lanes/vendor/base.js +85256 -0
  143. data/client/lanes/vendor/commons.js +20579 -0
  144. data/client/lanes/vendor/development.js +2511 -0
  145. data/client/lanes/vendor/grid.js +6689 -0
  146. data/client/lanes/vendor/grid.scss +387 -0
  147. data/client/lanes/vendor/index.js +3 -0
  148. data/client/lanes/vendor/message-bus.coffee +264 -0
  149. data/client/lanes/vendor/widgets.js +8798 -0
  150. data/client/lanes/vendor/widgets.scss +723 -0
  151. data/client/lanes/workspace/ActiveScreenSwitcher.cjsx +38 -0
  152. data/client/lanes/workspace/Extension.coffee +6 -0
  153. data/client/lanes/workspace/Layout.cjsx +28 -0
  154. data/client/lanes/workspace/Navbar.cjsx +25 -0
  155. data/client/lanes/workspace/ScreenView.cjsx +27 -0
  156. data/client/lanes/workspace/ScreensMenu.cjsx +57 -0
  157. data/client/lanes/workspace/UIState.coffee +17 -16
  158. data/client/lanes/workspace/index.js +7 -2
  159. data/client/lanes/workspace/styles.scss +0 -3
  160. data/client/lanes/workspace/styles/forms.scss +2 -73
  161. data/client/lanes/workspace/styles/header.scss +0 -2
  162. data/client/lanes/workspace/styles/layout.scss +9 -2
  163. data/client/lanes/workspace/styles/screens.scss +0 -59
  164. data/client/lanes/workspace/styles/tabs.scss +16 -15
  165. data/coffeelint.json +49 -0
  166. data/config.ru +1 -0
  167. data/config/database.yml +2 -2
  168. data/config/routes.rb +7 -0
  169. data/docs/command.md +11 -8
  170. data/docs/model.md +2 -5
  171. data/docs/react.md +137 -0
  172. data/lanes.gemspec +1 -0
  173. data/lib/lanes.rb +1 -1
  174. data/lib/lanes/access/authentication_provider.rb +1 -0
  175. data/lib/lanes/access/config/routes.rb +2 -0
  176. data/lib/lanes/access/config/screens.rb +15 -12
  177. data/lib/lanes/access/extension.rb +2 -1
  178. data/lib/lanes/access/role.rb +8 -4
  179. data/lib/lanes/api.rb +4 -3
  180. data/lib/lanes/api/coffeescript_processor.rb +47 -6
  181. data/lib/lanes/api/controller.rb +4 -3
  182. data/lib/lanes/api/default_routes.rb +16 -0
  183. data/lib/lanes/api/javascript_processor.rb +14 -68
  184. data/lib/lanes/api/pub_sub.rb +17 -3
  185. data/lib/lanes/api/request_wrapper.rb +2 -2
  186. data/lib/lanes/api/root.rb +16 -13
  187. data/lib/lanes/api/routing.rb +0 -18
  188. data/lib/lanes/api/sprockets_extension.rb +10 -4
  189. data/lib/lanes/api/test_specs.rb +3 -3
  190. data/lib/lanes/cli.rb +6 -1
  191. data/lib/lanes/command/app.rb +7 -11
  192. data/lib/lanes/command/generate.rb +3 -3
  193. data/lib/lanes/command/generate_component.rb +28 -0
  194. data/lib/lanes/command/generate_component.usage +11 -0
  195. data/lib/lanes/command/generate_screen.rb +24 -7
  196. data/lib/lanes/command/generate_screen.usage +5 -8
  197. data/lib/lanes/configuration.rb +3 -2
  198. data/lib/lanes/extension.rb +12 -18
  199. data/lib/lanes/extension/definition.rb +20 -8
  200. data/lib/lanes/guard_tasks.rb +22 -5
  201. data/lib/lanes/hot_reload_plugin.rb +47 -0
  202. data/lib/lanes/logger.rb +41 -5
  203. data/lib/lanes/screen.rb +40 -16
  204. data/lib/lanes/spec_helper.rb +6 -3
  205. data/lib/lanes/version.rb +1 -1
  206. data/lib/lanes/workspace/extension.rb +1 -0
  207. data/npm-build/{template.js → base.js} +17 -17
  208. data/{client/lanes/workspace/tab.html → npm-build/common.js} +0 -0
  209. data/npm-build/compile.coffee +13 -4
  210. data/npm-build/development.js +7 -0
  211. data/npm-build/grid.js +11 -0
  212. data/npm-build/package.json +62 -58
  213. data/npm-build/react-widgets.js +5 -0
  214. data/npm-build/react-widgets.less +35 -0
  215. data/npm-build/webpack.config.js +39 -0
  216. data/spec/command-reference-files/component/client/appy-app/components/Big.cjsx +4 -0
  217. data/spec/command-reference-files/component/spec/appy-app/components/BigSpec.coffee +5 -0
  218. data/spec/command-reference-files/initial/.rubocop.yml +7 -0
  219. data/spec/command-reference-files/initial/Gemfile +1 -1
  220. data/spec/command-reference-files/initial/client/appy-app/Extension.coffee +17 -5
  221. data/spec/command-reference-files/initial/client/appy-app/components/Base.coffee +9 -0
  222. data/spec/command-reference-files/initial/client/appy-app/index.js +1 -3
  223. data/spec/command-reference-files/initial/client/appy-app/screens/Base.coffee +8 -2
  224. data/spec/command-reference-files/initial/coffeelint.json +49 -0
  225. data/spec/command-reference-files/initial/config.ru +2 -0
  226. data/spec/command-reference-files/initial/config/screens.rb +10 -0
  227. data/spec/command-reference-files/initial/lib/appy-app/extension.rb +7 -0
  228. data/spec/command-reference-files/model/client/appy-app/models/TestTest.coffee +0 -1
  229. data/spec/command-reference-files/screen/client/appy-app/Extension.coffee +34 -0
  230. data/spec/command-reference-files/screen/client/appy-app/screens/ready-set-go/ReadySetGo.cjsx +7 -0
  231. data/spec/command-reference-files/screen/config/screens.rb +19 -9
  232. data/spec/command-reference-files/screen/spec/appy-app/screens/ready-set-go/ReadySetGoSpec.coffee +3 -3
  233. data/spec/lanes/components/grid/GridSpec.coffee +26 -26
  234. data/spec/lanes/models/AssociationMapSpec.coffee +6 -6
  235. data/spec/lanes/models/BaseSpec.coffee +24 -35
  236. data/spec/lanes/models/CollectionSpec.coffee +19 -18
  237. data/spec/lanes/models/EnumMapSpec.coffee +1 -1
  238. data/spec/lanes/models/PubSubSpec.coffee +17 -15
  239. data/spec/lanes/models/SyncSpec.coffee +28 -0
  240. data/spec/lanes/models/UserSpec.coffee +17 -0
  241. data/spec/lanes/react/mixins/DataSpec.coffee +72 -0
  242. data/spec/lanes/screens/DefinitionsSpec.coffee +33 -0
  243. data/spec/lanes/views/BaseSpec.coffee +133 -133
  244. data/spec/lanes/views/FormBindingsSpec.coffee +30 -30
  245. data/spec/server/api/coffeescript_processor_spec.rb +2 -2
  246. data/spec/server/command_spec.rb +3 -3
  247. data/templates/client/Extension.coffee +17 -5
  248. data/templates/client/components/BaseComponent.coffee +9 -0
  249. data/templates/client/components/Component.cjsx +4 -0
  250. data/templates/client/{views → components}/template.html +0 -0
  251. data/templates/client/index.js +1 -3
  252. data/templates/client/models/Model.coffee +0 -1
  253. data/templates/client/screens/BaseScreen.coffee +9 -0
  254. data/templates/client/screens/Screen.cjsx +7 -0
  255. data/templates/config.ru +2 -0
  256. data/templates/config/screen.rb +10 -10
  257. data/templates/config/screens.rb +10 -0
  258. data/templates/lib/namespace/extension.rb +7 -0
  259. data/templates/spec/client/Screen.coffee +4 -4
  260. data/templates/spec/client/components/ComponentSpec.coffee +5 -0
  261. metadata +157 -201
  262. data/client/fonts/lanes/icomoon.eot +0 -0
  263. data/client/fonts/lanes/icomoon.svg +0 -160
  264. data/client/fonts/lanes/icomoon.ttf +0 -0
  265. data/client/fonts/lanes/icomoon.woff +0 -0
  266. data/client/fonts/lanes/selection.json +0 -3565
  267. data/client/lanes/Boot.coffee +0 -50
  268. data/client/lanes/access/LoginDialog.coffee +0 -46
  269. data/client/lanes/access/login-dialog.html +0 -16
  270. data/client/lanes/access/screens/user-management/GridUserEditor.coffee +0 -26
  271. data/client/lanes/access/screens/user-management/UserManagement.coffee +0 -23
  272. data/client/lanes/access/screens/user-management/grid-popover-editor.html +0 -33
  273. data/client/lanes/access/screens/user-management/screen.html +0 -7
  274. data/client/lanes/components/Base.coffee +0 -39
  275. data/client/lanes/components/ChoicesInput.coffee +0 -47
  276. data/client/lanes/components/grid/Editor.coffee +0 -62
  277. data/client/lanes/components/grid/Grid.coffee +0 -205
  278. data/client/lanes/components/grid/PopOverEditor.coffee +0 -29
  279. data/client/lanes/components/grid/RowEditor.coffee +0 -30
  280. data/client/lanes/components/grid/popover-editor.html +0 -18
  281. data/client/lanes/components/grid/row-editor.html +0 -16
  282. data/client/lanes/components/grid/template.html +0 -4
  283. data/client/lanes/components/grid/vendor/dataTables.scroller.js +0 -1262
  284. data/client/lanes/components/grid/vendor/index.js +0 -2
  285. data/client/lanes/components/grid/vendor/jquery.dataTables.js +0 -14839
  286. data/client/lanes/components/modal/ModalDialog.coffee +0 -68
  287. data/client/lanes/components/modal/template.html +0 -18
  288. data/client/lanes/components/multi-select/MultiSelect.coffee +0 -65
  289. data/client/lanes/components/popover/PopOver.coffee +0 -55
  290. data/client/lanes/components/popover/index.js +0 -2
  291. data/client/lanes/components/popover/styles.scss +0 -2
  292. data/client/lanes/components/popover/template.html +0 -5
  293. data/client/lanes/components/radio-group/RadioGroup.coffee +0 -47
  294. data/client/lanes/components/radio-group/index.js +0 -1
  295. data/client/lanes/components/radio-group/styles.scss +0 -1
  296. data/client/lanes/components/record-finder/Clause.coffee +0 -37
  297. data/client/lanes/components/record-finder/Dialog.coffee +0 -45
  298. data/client/lanes/components/record-finder/RecordFinder.coffee +0 -61
  299. data/client/lanes/components/record-finder/clause.html +0 -37
  300. data/client/lanes/components/record-finder/dialog.html +0 -4
  301. data/client/lanes/components/record-finder/field.html +0 -8
  302. data/client/lanes/components/select-field/SelectField.coffee +0 -63
  303. data/client/lanes/components/select2/Select2.coffee +0 -8
  304. data/client/lanes/components/select2/index.js +0 -2
  305. data/client/lanes/lib/Templates.coffee +0 -51
  306. data/client/lanes/lib/debounce.coffee +0 -15
  307. data/client/lanes/lib/defer.coffee +0 -7
  308. data/client/lanes/lib/el.js +0 -115
  309. data/client/lanes/lib/index.js +0 -5
  310. data/client/lanes/plugins/overlay.coffee +0 -41
  311. data/client/lanes/screens/Base.coffee +0 -35
  312. data/client/lanes/screens/Router.coffee +0 -4
  313. data/client/lanes/screens/mixins/Editing.coffee +0 -38
  314. data/client/lanes/styles/bootstrap/old/_alerts.scss +0 -68
  315. data/client/lanes/styles/bootstrap/old/_badges.scss +0 -57
  316. data/client/lanes/styles/bootstrap/old/_breadcrumbs.scss +0 -26
  317. data/client/lanes/styles/bootstrap/old/_button-groups.scss +0 -240
  318. data/client/lanes/styles/bootstrap/old/_buttons.scss +0 -157
  319. data/client/lanes/styles/bootstrap/old/_carousel.scss +0 -243
  320. data/client/lanes/styles/bootstrap/old/_close.scss +0 -35
  321. data/client/lanes/styles/bootstrap/old/_code.scss +0 -68
  322. data/client/lanes/styles/bootstrap/old/_component-animations.scss +0 -35
  323. data/client/lanes/styles/bootstrap/old/_dropdowns.scss +0 -215
  324. data/client/lanes/styles/bootstrap/old/_forms.scss +0 -538
  325. data/client/lanes/styles/bootstrap/old/_glyphicons.scss +0 -237
  326. data/client/lanes/styles/bootstrap/old/_grid.scss +0 -84
  327. data/client/lanes/styles/bootstrap/old/_input-groups.scss +0 -166
  328. data/client/lanes/styles/bootstrap/old/_jumbotron.scss +0 -48
  329. data/client/lanes/styles/bootstrap/old/_labels.scss +0 -66
  330. data/client/lanes/styles/bootstrap/old/_list-group.scss +0 -132
  331. data/client/lanes/styles/bootstrap/old/_media.scss +0 -56
  332. data/client/lanes/styles/bootstrap/old/_mixins.scss +0 -39
  333. data/client/lanes/styles/bootstrap/old/_modals.scss +0 -150
  334. data/client/lanes/styles/bootstrap/old/_navbar.scss +0 -659
  335. data/client/lanes/styles/bootstrap/old/_navs.scss +0 -242
  336. data/client/lanes/styles/bootstrap/old/_normalize.scss +0 -425
  337. data/client/lanes/styles/bootstrap/old/_pager.scss +0 -55
  338. data/client/lanes/styles/bootstrap/old/_pagination.scss +0 -88
  339. data/client/lanes/styles/bootstrap/old/_panels.scss +0 -243
  340. data/client/lanes/styles/bootstrap/old/_popovers.scss +0 -133
  341. data/client/lanes/styles/bootstrap/old/_print.scss +0 -101
  342. data/client/lanes/styles/bootstrap/old/_progress-bars.scss +0 -105
  343. data/client/lanes/styles/bootstrap/old/_responsive-embed.scss +0 -34
  344. data/client/lanes/styles/bootstrap/old/_responsive-utilities.scss +0 -174
  345. data/client/lanes/styles/bootstrap/old/_scaffolding.scss +0 -150
  346. data/client/lanes/styles/bootstrap/old/_tables.scss +0 -233
  347. data/client/lanes/styles/bootstrap/old/_theme.scss +0 -258
  348. data/client/lanes/styles/bootstrap/old/_thumbnails.scss +0 -38
  349. data/client/lanes/styles/bootstrap/old/_tooltip.scss +0 -95
  350. data/client/lanes/styles/bootstrap/old/_type.scss +0 -304
  351. data/client/lanes/styles/bootstrap/old/_utilities.scss +0 -57
  352. data/client/lanes/styles/bootstrap/old/_variables.scss +0 -850
  353. data/client/lanes/styles/bootstrap/old/_wells.scss +0 -29
  354. data/client/lanes/styles/bootstrap/old/bootstrap.scss +0 -50
  355. data/client/lanes/styles/bootstrap/old/mixins/_alerts.scss +0 -14
  356. data/client/lanes/styles/bootstrap/old/mixins/_background-variant.scss +0 -11
  357. data/client/lanes/styles/bootstrap/old/mixins/_border-radius.scss +0 -18
  358. data/client/lanes/styles/bootstrap/old/mixins/_buttons.scss +0 -50
  359. data/client/lanes/styles/bootstrap/old/mixins/_center-block.scss +0 -7
  360. data/client/lanes/styles/bootstrap/old/mixins/_clearfix.scss +0 -22
  361. data/client/lanes/styles/bootstrap/old/mixins/_forms.scss +0 -84
  362. data/client/lanes/styles/bootstrap/old/mixins/_gradients.scss +0 -58
  363. data/client/lanes/styles/bootstrap/old/mixins/_grid-framework.scss +0 -81
  364. data/client/lanes/styles/bootstrap/old/mixins/_grid.scss +0 -122
  365. data/client/lanes/styles/bootstrap/old/mixins/_hide-text.scss +0 -21
  366. data/client/lanes/styles/bootstrap/old/mixins/_image.scss +0 -34
  367. data/client/lanes/styles/bootstrap/old/mixins/_labels.scss +0 -12
  368. data/client/lanes/styles/bootstrap/old/mixins/_list-group.scss +0 -31
  369. data/client/lanes/styles/bootstrap/old/mixins/_nav-divider.scss +0 -10
  370. data/client/lanes/styles/bootstrap/old/mixins/_nav-vertical-align.scss +0 -9
  371. data/client/lanes/styles/bootstrap/old/mixins/_opacity.scss +0 -8
  372. data/client/lanes/styles/bootstrap/old/mixins/_pagination.scss +0 -23
  373. data/client/lanes/styles/bootstrap/old/mixins/_panels.scss +0 -24
  374. data/client/lanes/styles/bootstrap/old/mixins/_progress-bar.scss +0 -10
  375. data/client/lanes/styles/bootstrap/old/mixins/_reset-filter.scss +0 -8
  376. data/client/lanes/styles/bootstrap/old/mixins/_resize.scss +0 -6
  377. data/client/lanes/styles/bootstrap/old/mixins/_responsive-visibility.scss +0 -21
  378. data/client/lanes/styles/bootstrap/old/mixins/_size.scss +0 -10
  379. data/client/lanes/styles/bootstrap/old/mixins/_tab-focus.scss +0 -9
  380. data/client/lanes/styles/bootstrap/old/mixins/_table-row.scss +0 -28
  381. data/client/lanes/styles/bootstrap/old/mixins/_text-emphasis.scss +0 -11
  382. data/client/lanes/styles/bootstrap/old/mixins/_text-overflow.scss +0 -8
  383. data/client/lanes/styles/bootstrap/old/mixins/_vendor-prefixes.scss +0 -219
  384. data/client/lanes/styles/font-definitions.scss +0 -451
  385. data/client/lanes/testing/TestModels.coffee +0 -23
  386. data/client/lanes/vendor/bootstrap/affix.js +0 -162
  387. data/client/lanes/vendor/bootstrap/alert.js +0 -94
  388. data/client/lanes/vendor/bootstrap/button.js +0 -116
  389. data/client/lanes/vendor/bootstrap/carousel.js +0 -240
  390. data/client/lanes/vendor/bootstrap/collapse.js +0 -211
  391. data/client/lanes/vendor/bootstrap/dropdown.js +0 -161
  392. data/client/lanes/vendor/bootstrap/modal.js +0 -324
  393. data/client/lanes/vendor/bootstrap/popover.js +0 -119
  394. data/client/lanes/vendor/bootstrap/scrollspy.js +0 -175
  395. data/client/lanes/vendor/bootstrap/tab.js +0 -153
  396. data/client/lanes/vendor/bootstrap/tooltip.js +0 -478
  397. data/client/lanes/vendor/bootstrap/transition.js +0 -59
  398. data/client/lanes/vendor/message-bus.js +0 -285
  399. data/client/lanes/vendor/modern-stack.js +0 -27
  400. data/client/lanes/vendor/packaged.js +0 -19533
  401. data/client/lanes/views/Assets.coffee +0 -9
  402. data/client/lanes/views/Base.coffee +0 -426
  403. data/client/lanes/views/Functions.coffee +0 -13
  404. data/client/lanes/views/Helpers.coffee +0 -76
  405. data/client/lanes/views/Keys.coffee +0 -59
  406. data/client/lanes/views/RenderContext.coffee +0 -32
  407. data/client/lanes/views/SaveNotify.coffee +0 -32
  408. data/client/lanes/views/Viewport.coffee +0 -18
  409. data/client/lanes/views/_button.html +0 -3
  410. data/client/lanes/views/_toolbar.html +0 -23
  411. data/client/lanes/views/empty-span.html +0 -1
  412. data/client/lanes/views/index.js +0 -2
  413. data/client/lanes/views/model-update.html +0 -15
  414. data/client/lanes/workspace/ActiveScreensSwitcher.coffee +0 -112
  415. data/client/lanes/workspace/Layout.coffee +0 -29
  416. data/client/lanes/workspace/Navbar.coffee +0 -31
  417. data/client/lanes/workspace/Pages.coffee +0 -39
  418. data/client/lanes/workspace/ScreensMenu.coffee +0 -126
  419. data/client/lanes/workspace/WorkspaceView.coffee +0 -8
  420. data/client/lanes/workspace/layout.html +0 -4
  421. data/client/lanes/workspace/menu.html +0 -356
  422. data/client/lanes/workspace/menu_toggle.html +0 -9
  423. data/client/lanes/workspace/navbar.html +0 -17
  424. data/client/lanes/workspace/pages.html +0 -6
  425. data/client/lanes/workspace/screens-menu.html +0 -11
  426. data/client/lanes/workspace/screens-switcher.html +0 -7
  427. data/docs/view.md +0 -292
  428. data/lib/lanes/command/generate_view.rb +0 -38
  429. data/lib/lanes/command/generate_view.usage +0 -13
  430. data/spec/command-reference-files/initial/client/appy-app/Router.coffee +0 -4
  431. data/spec/command-reference-files/initial/client/appy-app/controllers/.gitkeep +0 -0
  432. data/spec/command-reference-files/initial/client/appy-app/views/.gitkeep +0 -0
  433. data/spec/command-reference-files/initial/client/appy-app/views/Base.coffee +0 -5
  434. data/spec/command-reference-files/initial/spec/appy-app/screens/Base.coffee +0 -5
  435. data/spec/command-reference-files/screen/client/appy-app/screens/ready-set-go/ReadySetGo.coffee +0 -6
  436. data/spec/command-reference-files/screen/client/appy-app/screens/ready-set-go/layout.html +0 -3
  437. data/spec/command-reference-files/view/client/appy-app/views/BigView.coffee +0 -10
  438. data/spec/command-reference-files/view/spec/appy-app/views/BigViewSpec.coffee +0 -5
  439. data/templates/client/Router.coffee +0 -4
  440. data/templates/client/components/Component.coffee +0 -1
  441. data/templates/client/screens/Base.coffee +0 -3
  442. data/templates/client/screens/Screen.coffee +0 -11
  443. data/templates/client/screens/layout.html +0 -3
  444. data/templates/client/views/.gitkeep +0 -0
  445. data/templates/client/views/BaseView.coffee +0 -5
  446. data/templates/client/views/View.coffee +0 -10
  447. data/templates/spec/client/views/ViewSpec.coffee +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ed648a6329d1d1b0c9ee0e5df25d1c184b5f5e0
4
- data.tar.gz: 023a41ef58e894aa882ae712edb9a77b12d57d73
3
+ metadata.gz: f9ee3d792d48f1c5052df8f8def69d9b41feb772
4
+ data.tar.gz: 65421bc19936cb0890bf8309ca3496e9088a46c8
5
5
  SHA512:
6
- metadata.gz: b6cfb3a4c38ec8dd175c17047aafc03ced98e6d30ce04e48f5bd5b2550aa88521cad0ac12252a00dfdaacff9c606bd68f5d3bdccf8b5882e7b396e16c2f189e6
7
- data.tar.gz: 8befe413cd47f78796a50d344ffcd89e7021ad7d4541889a67d483b0a02c41bda1b6335de7c3263a00d30124b68dc1cd091e793ceacb9c030ed695943da95468
6
+ metadata.gz: 7af3b91f0c5a4a899ce73523d7723b1ae360de9550a0e6146207247545d2a2f4e6f011396d9ab4fd21b0632fde382445b284aba1f653656af8aa1b9144b9ab8f
7
+ data.tar.gz: f7d0b171766d83f2b6253a4c702a9d4a9b1b66ec32bad409c2519f14230e832cc14a106c858a5ca517b56696ffe7e16181bd14bebe0d4cfc0ab1f055b0dfbd74
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  *.rbc
3
+ .DS_Store
3
4
  .bundle
4
5
  .config
5
6
  .yardoc
@@ -0,0 +1,9 @@
1
+ Lanes.renderScreenTo = (selector, options) ->
2
+ Lanes.config.set(options)
3
+ Lanes.Models.Bootstrap.initialize(options)
4
+ document.addEventListener "DOMContentLoaded", ->
5
+ viewport = new Lanes.React.Viewport(selector: selector)
6
+ Lanes.Models.PubSub.initialize()
7
+ Lanes.Extensions.fireOnInitialized(viewport)
8
+ Lanes.React.runRouter(viewport)
9
+ Lanes.Extensions.fireOnAvailable(viewport)
@@ -2,13 +2,27 @@ class Lanes.Access.Extension extends Lanes.Extensions.Base
2
2
 
3
3
  identifier: "lanes-access"
4
4
 
5
- setBootstrapData: (data)->
5
+ setBootstrapData: (data) ->
6
+ Lanes.Models.Role.all = new Lanes.Models.Role.Collection( data.roles )
6
7
  Lanes.current_user = new Lanes.Models.User
7
- Lanes.Models.Roles.all = new Lanes.Models.Roles( data.roles )
8
8
  if data.user
9
9
  Lanes.current_user.set(data.user)
10
10
  if data.access
11
11
  Lanes.current_user.access_data = data.access
12
12
 
13
- onAvailable: (view)->
14
- Lanes.Access.createLoginDialog(view)
13
+ showLogin: ->
14
+ Lanes.Workspace.Extension.uistate.modalDialog = Lanes.Access.LoginDialog.instance()
15
+
16
+ hideLogin: ->
17
+ Lanes.Workspace.Extension.uistate.modalDialog = null
18
+
19
+ onAvailable: (viewport) ->
20
+ @viewport = viewport
21
+ Lanes.current_user.on('change:isLoggedIn', =>
22
+ if Lanes.current_user.isLoggedIn
23
+ @hideLogin()
24
+ else
25
+ @showLogin()
26
+ )
27
+ unless Lanes.current_user.isLoggedIn
28
+ @showLogin()
@@ -0,0 +1,78 @@
1
+ class Session extends Lanes.Models.Base
2
+ api_path: 'user-session'
3
+ props:
4
+ id: 'integer'
5
+ login: 'string'
6
+ password: 'string'
7
+ access: 'object'
8
+ user: 'object'
9
+
10
+
11
+ class Lanes.Access.LoginDialog extends Lanes.React.Component
12
+
13
+ mixins: [
14
+ Lanes.React.Mixins.RelayEditingState
15
+ ]
16
+
17
+ getDefaultProps: ->
18
+ writable: true, editOnly: true
19
+
20
+ dataObjects: ->
21
+ model: new Session
22
+
23
+ login: ->
24
+ @model.save().then =>
25
+ Lanes.current_user.setLoginData(@model.user, @model.access) if @model.user
26
+
27
+ warning: ->
28
+ <BS.Alert bsStyle='warning'>
29
+ <strong>{@model.lastServerMessage}</strong>
30
+ </BS.Alert>
31
+
32
+ render: ->
33
+ <LC.Modal title='Please log in'
34
+ backdrop={false}
35
+ closeButton=false
36
+ animation={false}>
37
+
38
+ <div className='modal-body'>
39
+
40
+ {@warning() if @state?.hasError}
41
+
42
+ <BS.Row>
43
+ <BS.Col mdOffset={2} xs={12} md={8}>
44
+
45
+ <LC.TextField
46
+ model={@model}
47
+ autoFocus writable
48
+ name="login"
49
+ label='Username'
50
+ placeholder='Enter Login'
51
+ />
52
+
53
+ <LC.TextField
54
+ writable
55
+ model={@model}
56
+ name="password"
57
+ type='password'
58
+ label='Password'
59
+ placeholder='Enter Password'
60
+ />
61
+
62
+ </BS.Col>
63
+ </BS.Row>
64
+ </div>
65
+
66
+
67
+ <div className='modal-footer'>
68
+ <BS.Button onClick={@login} bsStyle='primary'>Login</BS.Button>
69
+ </div>
70
+
71
+ </LC.Modal>
72
+
73
+
74
+
75
+ # Function that returns a factory (or function) for the LoginDialog.
76
+ # Intended as an extension point for other users to override if needed
77
+ Lanes.Access.LoginDialog.instance = ->
78
+ @cache ||= React.createFactory(Lanes.Access.LoginDialog)
@@ -1,39 +1,33 @@
1
- class Role extends Lanes.Models.BasicModel
1
+ class Lanes.Models.Role extends Lanes.Models.Base
2
2
  props:
3
3
  id: 'string'
4
4
  name: 'string'
5
5
  member: { type: 'boolean', default: false }
6
6
 
7
-
8
- class Lanes.Models.Roles extends Lanes.Models.BasicCollection
9
- model: Role
10
- comparator: 'name'
11
-
12
-
13
7
  class UserRole
14
- constructor: (config={})->
8
+ constructor: (config = {}) ->
15
9
  @type = config.type
16
10
  for method in RWD
17
- this[method] = _.map(config[method],klassFor)
11
+ this[method] = _.map(config[method], klassFor)
18
12
 
19
- can: (type,model)->
13
+ can: (type, model) ->
20
14
  -1 != this[type].indexOf(model)
21
15
 
22
- decodeLockedFields: (fields, previous={})->
16
+ decodeLockedFields: (fields, previous = {}) ->
23
17
  decoded = _.extend({}, previous)
24
18
  for lock in fields
25
19
  if klass = klassFor(lock.type)
26
- decoded[ klass ] = locks = {}
20
+ decoded[ klass::api_path() ] = locks = {}
27
21
  locks[field] = grants for field, grants of lock.locks
28
22
  decoded
29
23
 
30
- RWD = ['read','write','delete']
24
+ RWD = ['read', 'write', 'delete']
31
25
 
32
26
 
33
27
  # The admin is special and can do anything
34
28
  class Administrator
35
29
  constructor: ->
36
- UserRole.prototype.constructor.apply(this,arguments)
30
+ UserRole.prototype.constructor.apply(this, arguments)
37
31
  can: -> true
38
32
 
39
33
  decodeLockedFields: ->
@@ -46,7 +40,7 @@ RoleMap = {
46
40
 
47
41
  class Lanes.Models.UserRoleSet
48
42
 
49
- constructor: (access={})->
43
+ constructor: (access = {}) ->
50
44
  _.defaults(access, { roles: [], locked_fields: [] })
51
45
  @roles = []
52
46
  @locked_fields = {}
@@ -56,33 +50,33 @@ class Lanes.Models.UserRoleSet
56
50
  @roles.push( role )
57
51
  @locked_fields = role.decodeLockedFields(access.locked_fields, @locked_fields)
58
52
 
59
- can:(method,model,field)->
53
+ can: (method, model, field) ->
60
54
  if model instanceof Lanes.Models.Base
61
55
  model = model.constructor
62
56
 
63
- if field && ( locks = @locked_fields[model] ) && ( grants = locks[field] )
57
+ if field && ( locks = @locked_fields[model::api_path()] ) && ( grants = locks[field] )
64
58
  for grant in grants
65
59
  if grant.only && grant.only != method
66
- return this.testModelAccess(method,model)
60
+ return this.testModelAccess(method, model)
67
61
  else
68
62
  for role in @roles
69
63
  return true if role.type == grant.role
70
64
  return false
71
65
  else
72
- return this.testModelAccess(method,model)
66
+ return this.testModelAccess(method, model)
73
67
 
74
- testModelAccess:(method,model)->
75
- !!_.detect( @roles, (role)->role.can(method,model) )
68
+ testModelAccess:(method, model) ->
69
+ !!_.detect( @roles, (role) -> role.can(method, model) )
76
70
 
77
- canRead:(model,field)->
78
- this.can('read',model,field)
71
+ canRead:(model, field) ->
72
+ this.can('read', model, field)
79
73
 
80
- canWrite:(model,field)->
81
- this.can('write',model,field)
74
+ canWrite:(model, field) ->
75
+ this.can('write', model, field)
82
76
 
83
- canDelete:(model)->
84
- this.can('delete',model)
77
+ canDelete:(model) ->
78
+ this.can('delete', model)
85
79
 
86
- klassFor = (identifier)->
80
+ klassFor = (identifier) ->
87
81
  Lanes.u.getPath(identifier) ||
88
82
  Lanes.warn("Model #{identifier} not found for role")
@@ -1,10 +1,10 @@
1
1
  class Lanes.Models.User extends Lanes.Models.Base
2
2
 
3
- constructor: (attributes,access)->
3
+ constructor: (attributes, access) ->
4
4
  super
5
5
  this.access_data = access
6
6
 
7
- api_path: 'users'
7
+ api_path: -> 'users'
8
8
  derived:
9
9
  roles:
10
10
  deps: ['role_names', 'access_data']
@@ -14,9 +14,9 @@ class Lanes.Models.User extends Lanes.Models.Base
14
14
  allRoles:
15
15
  deps: ['role_names', 'access_data']
16
16
  fn: ->
17
- role_data = Lanes.Models.Roles.all?.toJSON() || []
18
- roles = new Lanes.Models.Roles( role_data )
19
- _.each( this.role_names, (name)->
17
+ role_data = Lanes.Models.Role.all?.toJSON() || []
18
+ roles = new Lanes.Models.Role.Collection( role_data )
19
+ _.each( this.role_names, (name) ->
20
20
  roles.get(name)?.member = true
21
21
  )
22
22
  roles
@@ -33,34 +33,34 @@ class Lanes.Models.User extends Lanes.Models.Base
33
33
  options: 'object'
34
34
  password: 'string'
35
35
 
36
- canRead: (model,field) -> this.roles.canRead(model,field)
37
- canWrite: (model,field) -> this.roles.canWrite(model,field)
38
- canDelete: (model) -> this.roles.canDelete(model)
36
+ canRead: (model, field) -> this.roles.canRead(model, field)
37
+ canWrite: (model, field) -> this.roles.canWrite(model, field)
38
+ canDelete: (model) -> this.roles.canDelete(model)
39
39
 
40
40
  logout: ->
41
+ return unless @isLoggedIn
41
42
  session = new Session( id: this.id )
42
43
  session
43
44
  .destroy()
44
45
  .then =>
45
- _.each(@attributes, (value,key)=> @set(key, null) )
46
+ @access_data = []
47
+ @role_names = []
48
+ _.each(@attributes, (value, key) => @set(key, null) )
46
49
 
47
- setLoginData: (attrs, access)->
50
+ setLoginData: (attrs, access) ->
48
51
  this.access_data = access
49
52
  this.set(attrs)
50
53
 
51
- @attemptLogin: (login, password, options)->
54
+ @attemptLogin: (login, password, options) ->
52
55
  session = new Session( login: login, password: password )
53
56
  success = options.success
54
- session.save(_.extend(options,{
55
- success: (reply)->
57
+ session.save(_.extend(options, {
58
+ success: (reply) ->
56
59
  Lanes.current_user.setLoginData(session.user, session.access)
57
60
  success.apply(options.scope, arguments)
58
61
  }))
59
62
  session
60
63
 
61
- class Lanes.Models.UserCollection extends Lanes.Models.Collection
62
- model: Lanes.Models.User
63
-
64
64
 
65
65
  class Session extends Lanes.Models.Base
66
66
  api_path: 'user-session'
@@ -1,5 +1,4 @@
1
- //=require ./User
2
- //=require ./Roles
3
- //=require ./LoginDialog
4
- //=require ./login-dialog
5
- //=require ./Extension
1
+ //= require ./User
2
+ //= require ./Roles
3
+ //= require ./LoginDialog
4
+ //= require ./Extension
@@ -0,0 +1,20 @@
1
+ class Lanes.Access.Screens.UserManagement.Editor extends Lanes.React.Component
2
+
3
+ mixins: [Lanes.Components.Grid.PopoverMixin]
4
+
5
+ getInitialState: ->
6
+ link: LC.Helpers.modelLinkFields(@props.model)
7
+ recordName: @props.model.name || @props.model.title
8
+
9
+ renderBody: ->
10
+ <form>
11
+ {@renderFields()}
12
+ <div className="field">
13
+ <label>Password</label>
14
+ <input {...@state.link('password')} type="password" />
15
+ </div>
16
+ {@renderControls()}
17
+ </form>
18
+
19
+ render: ->
20
+ @renderPopover()
@@ -0,0 +1,41 @@
1
+ class Lanes.Access.Screens.UserManagement extends Lanes.React.Screen
2
+
3
+ getInitialState: ->
4
+ fields = [
5
+ {id:'id', visible: false}
6
+ 'login', 'name', 'email', {id:'role_names', title:'Role Names'}
7
+ ]
8
+ query: new Lanes.Models.Query({
9
+ fields: fields, modelClass: Lanes.Models.User
10
+ })
11
+
12
+ rolesForUser: (user) ->
13
+ {value: user.role_names, roles: _.map(user.role_names, _.field2title)}
14
+
15
+ setRolesForUser: (model, roles) ->
16
+ model.role_names = _.pluck(roles, 'id')
17
+
18
+ editors: (props) ->
19
+ role_names: ({model}) =>
20
+ <LC.SelectField
21
+ id="role_names"
22
+ key="row-select"
23
+ editOnly multi writable unstyled
24
+ model={model}
25
+ name="roles"
26
+ getSelection={@rolesForUser}
27
+ setSelection={@setRolesForUser}
28
+ collection={Lanes.Models.Role.all}
29
+ name="role_names"
30
+ />
31
+
32
+ render: ->
33
+ <div>
34
+ <h1>Users Management</h1>
35
+ <LC.Grid
36
+ query={@state.query}
37
+ allowCreate
38
+ editor={Lanes.Access.Screens.UserManagement.Editor}
39
+ columEditors={@editors()}
40
+ ref="grid"/>
41
+ </div>
@@ -1,3 +1,2 @@
1
1
  //= require ./UserManagement
2
- //= require ./GridUserEditor
3
2
  //= require_tree .
@@ -0,0 +1,64 @@
1
+ Lanes.Components.Grid.EditingMixin = {
2
+
3
+ propTypes:
4
+ topOffset: React.PropTypes.number.isRequired
5
+ rowIndex: React.PropTypes.number.isRequired
6
+ rowHeight: React.PropTypes.number.isRequired
7
+ onSave: React.PropTypes.func.isRequired
8
+ model: Lanes.PropTypes.State.isRequired
9
+ query: Lanes.PropTypes.State.isRequired
10
+ editors: React.PropTypes.object
11
+ hideEditor: React.PropTypes.func.isRequired
12
+
13
+ topOffset: ->
14
+ @props.topOffset + (@props.rowIndex * @props.rowHeight)
15
+
16
+ renderControls: ->
17
+ <div className="controls">
18
+ <div className="buttons">
19
+ <button type="button" className="btn cancel" onClick={@props.hideEditor}>
20
+ <i className="icon icon-refresh" /> Cancel
21
+ </button>
22
+ <button type="button" className="btn save" onClick={@saveRecord}>
23
+ <i className="icon icon-save" />Save
24
+ </button>
25
+ </div>
26
+ </div>
27
+
28
+ getFieldValue: (column) ->
29
+ @props.model[column.id]
30
+
31
+ onFieldChange: (column, ev) ->
32
+ @props.model[column.id] = ev.target.value
33
+
34
+ renderFields: ->
35
+ @props.query.fields.visible.map @renderField
36
+
37
+ renderEditingBody: ->
38
+ if _.isFunction(@renderBody)
39
+ @renderBody()
40
+ else
41
+ <div className="body">
42
+ <div className="fields">
43
+ {@renderFields()}
44
+ </div>
45
+ {@renderControls()}
46
+ </div>
47
+
48
+ renderField: (column) ->
49
+ return null unless column.visible
50
+ control = if @props.editors[column.id]
51
+ @props.editors[column.id](model: @props.model)
52
+ else
53
+ <input type="text"
54
+ value={@getFieldValue(column)}
55
+ onChange={_.partial(@onFieldChange, column)} />
56
+ <div key={column.id} className="field">
57
+ <label>{column.title}</label>
58
+ {control}
59
+ </div>
60
+
61
+ saveRecord: ->
62
+ @props.model.save().then (model) =>
63
+ @props.onSave(model)
64
+ }