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
data/config/routes.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
-
|
1
|
+
Lanes::API.routes.for_extension 'lanes' do
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
root_view :lanes_root_view
|
4
|
+
|
5
|
+
get 'job-statuses/:id.json' do
|
6
|
+
wrap_reply do
|
7
|
+
status = Lanes::Job.status_for_id(params[:id])
|
8
|
+
raise ActiveRecord::RecordNotFound unless status
|
9
|
+
std_api_reply :update, status, success: true
|
10
|
+
end
|
6
11
|
end
|
12
|
+
|
7
13
|
end
|
data/config/screens.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Lanes::Screen.for_extension 'lanes' do | screens |
|
2
|
+
|
3
|
+
screens.define "user-preferences" do | screen |
|
4
|
+
screen.title = "User Preferences"
|
5
|
+
screen.description = "Modify User Profile"
|
6
|
+
screen.icon = "user-secret"
|
7
|
+
screen.group_id = "system-settings"
|
8
|
+
screen.model_class = "User"
|
9
|
+
screen.view_class = "UserPreferences"
|
10
|
+
screen.js = ''
|
11
|
+
screen.css = ''
|
12
|
+
end
|
13
|
+
|
14
|
+
screens.define "system-settings" do | screen |
|
15
|
+
screen.title = "System Settings"
|
16
|
+
screen.description = "Update System Settings"
|
17
|
+
screen.icon = "cogs"
|
18
|
+
screen.group_id = "system-settings"
|
19
|
+
screen.model_class = "User"
|
20
|
+
screen.view_class = "SystemSettings"
|
21
|
+
screen.js = ''
|
22
|
+
screen.css = ''
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/docs/todo-example-part-1.md
CHANGED
@@ -15,7 +15,7 @@ lanes new todo
|
|
15
15
|
|
16
16
|
This will create a new directory with a skeleton Lanes application. Read more about the directories and what their purposes are at {% doc_link command heading:'lanes new' %}.
|
17
17
|
|
18
|
-
[Our example app at this point](https://github.com/argosity/lanes-todo-demo/tree/
|
18
|
+
[Our example app at this point](https://github.com/argosity/lanes-todo-demo/tree/c5ee64a5e932055470bf2d13d417f118b89114d6)
|
19
19
|
|
20
20
|
# Setup
|
21
21
|
|
@@ -23,40 +23,40 @@ A sample database configuration file is located in `config/database.yml` which w
|
|
23
23
|
|
24
24
|
Fire up the lanes testing server: `lanes serve`. The test server will start the app and you can view it at: `http://localhost:8888/`. You should see a simple "Todo" message. You can also view the Jasmine specs at `http://localhost:8888/spec`
|
25
25
|
|
26
|
-
|
26
|
+
Next we'll create a data model `lanes generate model task title:string{80} completed:boolean` [commit](https://github.com/argosity/lanes-todo-demo/commit/e22d058d49c482f9be0167068adab1e37be868bc)
|
27
|
+
|
28
|
+
Since a task should default to being non-completed, we'll edit the migration to default that field to `false` and add a validation to the model [commit](https://github.com/argosity/lanes-todo-demo/commit/4fda061c13d399062850173eff7bb616563a82bf)
|
27
29
|
|
28
|
-
|
30
|
+
Lanes uses the concept of **Screens** to dynamically load a React component and all it's dependencies. In this case, the Todo app will have only one screen which we can create by running: `lanes generate screen main` [commit](https://github.com/argosity/lanes-todo-demo/commit/f8614fd7d2e29987639ed7c6141e35c5e51e035f)
|
29
31
|
|
30
|
-
|
32
|
+
Looking at the Todo app, it has four distinct areas. A `sidebar`, `header`, `footer` and `listing` components. We can create views for them by executing `lanes generate component <name>`, where '< name >' is the view to create. [commit](https://github.com/argosity/lanes-todo-demo/commit/cdd63af42efada9d3c9a05658337e44141a0500a)
|
31
33
|
|
32
|
-
|
34
|
+
We'll copy the styles from the [TodoMVC template](https://github.com/tastejs/todomvc/tree/master/template).
|
33
35
|
|
34
|
-
|
36
|
+
First we take the TodoMVC html template and break it apart into sections and copy them to each view. We're then able to plug each component's into the Screen. [commit](https://github.com/argosity/lanes-todo-demo/commit/cb2651fc3c7bfc0d2f093023056241b93c9b0597)
|
35
37
|
|
36
38
|
Run migration: `lanes db migrate`
|
37
39
|
|
38
|
-
We'll also create a TaskSummary model that is in charge of summarizing the state of the tasks. It will listen to the tasks collection and perform calculations when events occur. [commit](https://github.com/argosity/lanes-todo-demo/commit/
|
40
|
+
We'll also create a TaskSummary model that is in charge of summarizing the state of the tasks. It will listen to the tasks collection and perform calculations when events occur. [commit](https://github.com/argosity/lanes-todo-demo/commit/61a9cb6a6101816becf7f0aa556dd6506f9ffed4)
|
39
41
|
|
40
42
|
# Data and events
|
41
43
|
|
42
|
-
## Header
|
43
|
-
It's responsible for interaction with the "What needs to be done?" input. When text is present and the "enter" key is pressed, it should save a record and add it to the collection. We're able to do so in [just a few lines of code](https://github.com/argosity/lanes-todo-demo/
|
44
|
+
## Header
|
45
|
+
It's responsible for interaction with the "What needs to be done?" input. When text is present and the "enter" key is pressed, it should save a record and add it to the collection. We're able to do so in [just a few lines of code](https://github.com/argosity/lanes-todo-demo/commit/bbdf8c8a95ddea8285615d4a7898d9054b22c4b4)
|
44
46
|
|
45
|
-
|
47
|
+
## Listing
|
48
|
+
This component is a bit more complex. It's split into two components, a parent which handles toggling all todo's between being complete and pending, and a collection of task components that model each individual task. [Listing](https://github.com/argosity/lanes-todo-demo/blob/master/client/todo/components/Listing.cjsx)
|
46
49
|
|
47
|
-
|
48
|
-
This view is a bit more complex. It has a parent view which handles toggling all todo's between being complete and pending, and a collection of subviews that model each individual task. [ListingView](https://github.com/argosity/lanes-todo-demo/blob/master/client/todo/views/Listing.coffee)
|
50
|
+
Each Task component is responsible for handling it's own editing state and saving value to it's model. [TaskComponent](https://github.com/argosity/lanes-todo-demo/blob/master/client/todo/components/Task.cjsx)
|
49
51
|
|
50
|
-
|
52
|
+
## Footer
|
53
|
+
The only action this component takes is to delete any tasks that are marked as complete when the "Clear Completed" button is clicked. It also displays quite a few values from our TasksSummary. Lane's data-bindings make these easy to wire up. [Footer](https://github.com/argosity/lanes-todo-demo/blob/master/client/todo/components/Footer.cjsx)
|
51
54
|
|
52
|
-
|
53
|
-
The only action this view takes is to delete any tasks that are marked as complete when the "Clear Completed" button is clicked. It also displays quite a few values from our TasksSummary. Lane's declarative bindings make these easy to wire up. [FooterView](https://github.com/argosity/lanes-todo-demo/blob/master/client/todo/views/Footer.coffee)
|
54
|
-
|
55
|
-
You might notice that Lanes makes it super easy to batch update or delete a collection. The footer simply calls destroyAll on the "completed" sub-collection provided by the TaskSummary. Since that sub-collection filters the main collection to only contain "completed" tasks, it's safe to just destroy all the model's in one go. It's so easy in fact that the FooterView demonstrates an alternative use of events. The function is directly given to the "events" property, rather than a method reference. [Save Call](https://github.com/argosity/lanes-todo-demo/blob/master/client/todo/views/Footer.coffee#L27)
|
55
|
+
You might notice that Lanes makes it super easy to batch update or delete a collection. The footer simply calls destroyAll on the "completed" sub-collection provided by the TaskSummary. Since that sub-collection filters the main collection to only contain "completed" tasks, it's safe to just destroy all the model's in one go.
|
56
56
|
|
57
57
|
# Routing
|
58
58
|
|
59
|
-
For a simple app like the this one, it's easiest to just allow the URL change to trigger what the filtered collection is displaying.
|
59
|
+
For a simple app like the this one, it's easiest to just allow the URL change to trigger what the filtered collection is displaying. [Routing](https://github.com/argosity/lanes-todo-demo/blob/master/client/todo/Routes.cjsx)
|
60
60
|
|
61
61
|
# Deploying
|
62
62
|
|
@@ -67,5 +67,3 @@ Simply commit the source and add a remote per Heroku's instructions: [https://de
|
|
67
67
|
When you `git push heroku`, Heroku will notice that Lanes uses sprockets and will automatically run `rake assets:precompile`, and then run the application using the puma webserver.
|
68
68
|
|
69
69
|
On first deploy and when your db schema has changed, you will have to provision and migrate the database on Heroku by running: `heroku run rake db:migrate`
|
70
|
-
|
71
|
-
|
data/lanes.gemspec
CHANGED
@@ -25,19 +25,23 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.required_ruby_version = ">= 2.0"
|
26
26
|
|
27
27
|
spec.add_dependency "activerecord", "~> 4.2"
|
28
|
+
spec.add_dependency "activejob", "~> 4.2"
|
29
|
+
spec.add_dependency "jobba", "~> 1.4"
|
30
|
+
|
31
|
+
spec.add_dependency "resque", "~> 1.25"
|
28
32
|
spec.add_dependency "pg", "~> 0.17"
|
29
33
|
spec.add_dependency "sinatra", "~> 1.4"
|
30
34
|
spec.add_dependency "bcrypt", "~> 3.1"
|
31
35
|
spec.add_dependency "oj", "~> 2.1"
|
32
|
-
spec.add_dependency "message_bus", "
|
33
|
-
spec.add_dependency "
|
34
|
-
spec.add_dependency "sprockets", "~>
|
36
|
+
spec.add_dependency "message_bus", "2.0.0.beta.6"
|
37
|
+
spec.add_dependency "rack-protection", "~> 1.5"
|
38
|
+
spec.add_dependency "sprockets", "~> 3.0"
|
35
39
|
spec.add_dependency "coffee-script", "~> 2.3"
|
36
40
|
spec.add_dependency "coffee-react", "~> 3.0"
|
37
41
|
spec.add_dependency "execjs", "~> 2.2"
|
38
42
|
spec.add_dependency "thor", "~> 0.19"
|
39
43
|
spec.add_dependency "sass", "~> 3.4"
|
40
|
-
spec.add_dependency "sprockets-helpers", "~> 1.
|
44
|
+
spec.add_dependency "sprockets-helpers", "~> 1.2"
|
41
45
|
spec.add_dependency "compass-import-once", "~> 1.0"
|
42
46
|
spec.add_dependency "guard", "~> 2.0"
|
43
47
|
spec.add_dependency "hashie", "~> 3.3"
|
@@ -45,13 +49,18 @@ Gem::Specification.new do |spec|
|
|
45
49
|
spec.add_dependency "minitest-around", "~> 0.2"
|
46
50
|
spec.add_dependency "mocha", "~> 1.1"
|
47
51
|
spec.add_dependency "guard-minitest", "~> 2.3"
|
48
|
-
|
49
|
-
spec.add_dependency "
|
52
|
+
|
53
|
+
spec.add_dependency "uglifier", "~> 2.7"
|
50
54
|
spec.add_dependency "guard-jasmine", "~> 2.0"
|
51
55
|
spec.add_dependency "rake", "~> 10.0"
|
52
56
|
spec.add_dependency "jasmine-core", "~> 2.0"
|
53
57
|
spec.add_dependency "require_all", "~> 1.3"
|
54
58
|
spec.add_dependency "sanitize", "~> 3.0"
|
59
|
+
spec.add_dependency "carrierwave", "~> 0.10.0"
|
60
|
+
spec.add_dependency "fog", "~> 1.37.0"
|
61
|
+
spec.add_dependency "mini_magick", "~> 4.3.6"
|
62
|
+
spec.add_dependency "fastimage", "~> 1.8.1"
|
63
|
+
|
55
64
|
spec.add_development_dependency "bundler", "~> 1.5"
|
56
65
|
spec.add_development_dependency "growl", "~> 1.0"
|
57
66
|
spec.add_development_dependency "diffy", "~> 3.0"
|
data/lib/lanes.rb
CHANGED
@@ -3,18 +3,20 @@ require 'active_record'
|
|
3
3
|
require_relative "lanes/version"
|
4
4
|
require_relative "lanes/environment"
|
5
5
|
require_relative "lanes/configuration"
|
6
|
+
require_relative "lanes/redis"
|
6
7
|
require_relative "lanes/logger"
|
7
8
|
if defined?(::Rails)
|
8
9
|
require_relative "lanes/rails_engine"
|
9
10
|
end
|
10
11
|
require_relative "lanes/db"
|
11
|
-
|
12
12
|
require_relative "lanes/strings"
|
13
13
|
require_relative "lanes/numbers"
|
14
14
|
require_relative "lanes/concerns/all"
|
15
15
|
require_relative "lanes/validators/all"
|
16
16
|
require_relative "lanes/model"
|
17
|
-
|
17
|
+
require_relative "lanes/system_settings"
|
18
18
|
require_relative "lanes/components"
|
19
19
|
require_relative "lanes/extension"
|
20
20
|
require_relative "lanes/screen"
|
21
|
+
require_relative "lanes/job"
|
22
|
+
require_relative "lanes/job/failure_logger"
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module Lanes
|
2
|
-
API.routes.
|
2
|
+
Lanes::API.routes.for_extension 'lanes-access' do
|
3
3
|
|
4
|
-
|
4
|
+
resources User
|
5
|
+
|
6
|
+
post "user-session.json" do
|
5
7
|
wrap_reply do
|
6
8
|
user = User.where(login: data['login']).first
|
7
9
|
Lanes.logger.warn "Found User: #{user}"
|
@@ -15,7 +17,7 @@ module Lanes
|
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
|
-
delete "
|
20
|
+
delete "user-session/:id.json" do
|
19
21
|
session.destroy
|
20
22
|
wrap_reply do
|
21
23
|
{ success: true, message: "Logout succeeded", data: {} }
|
@@ -4,7 +4,7 @@ class CreateLanesUsers < ActiveRecord::Migration
|
|
4
4
|
t.string :login, :name, :email, null: false
|
5
5
|
t.string :password_digest, null: false
|
6
6
|
t.string "role_names", array: true, null:false, default: []
|
7
|
-
t.
|
7
|
+
t.jsonb "options", null: false, default: {}
|
8
8
|
t.timestamps null:false
|
9
9
|
end
|
10
10
|
add_index :lanes_users, :role_names, using: 'gin'
|
data/lib/lanes/access/user.rb
CHANGED
@@ -16,7 +16,7 @@ module Lanes
|
|
16
16
|
|
17
17
|
def workspace_data
|
18
18
|
my_data = attributes.slice('id','login','name','email','created_at',
|
19
|
-
'created_by','updated_at','updated_by','role_names')
|
19
|
+
'created_by','updated_at','updated_by','role_names', 'options')
|
20
20
|
{ user: my_data, access: Access.for_user(self) }
|
21
21
|
end
|
22
22
|
|
data/lib/lanes/api.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative '../lanes'
|
2
2
|
require_relative 'api/request_wrapper'
|
3
3
|
require_relative 'api/error_formatter'
|
4
|
+
require_relative 'api/formatted_reply'
|
4
5
|
require_relative 'api/controller'
|
5
6
|
require_relative 'api/root'
|
6
7
|
|
@@ -8,5 +9,5 @@ Lanes.config.get(:environment) do
|
|
8
9
|
require_relative("api/test_specs") unless Lanes.env.production?
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
+
require_relative "api/handlers/file.rb"
|
12
13
|
require_relative 'api/default_routes'
|
data/lib/lanes/api/controller.rb
CHANGED
@@ -22,6 +22,7 @@ module Lanes
|
|
22
22
|
class Controller
|
23
23
|
|
24
24
|
attr_reader :model, :user, :params, :data
|
25
|
+
include FormattedReply
|
25
26
|
|
26
27
|
def initialize(model, authentication, params, data={})
|
27
28
|
@user = authentication.current_user
|
@@ -33,19 +34,18 @@ module Lanes
|
|
33
34
|
def perform_retrieval
|
34
35
|
query = build_query
|
35
36
|
options = build_reply_options
|
36
|
-
options[:total_count] = query.dup.count if should_include_total_count?
|
37
37
|
query = add_modifiers_to_query(query)
|
38
|
-
|
38
|
+
options[:total_count] = query.dup.unscope(:select).count if should_include_total_count?
|
39
39
|
if params[:id]
|
40
40
|
query = query.first!
|
41
41
|
end
|
42
|
-
|
42
|
+
std_api_reply(:retrieve, query, options)
|
43
43
|
end
|
44
44
|
|
45
45
|
def perform_creation
|
46
46
|
record = model.from_attribute_data(data, user)
|
47
47
|
options = build_reply_options.merge(success: record.save)
|
48
|
-
|
48
|
+
std_api_reply(:create, record, options)
|
49
49
|
end
|
50
50
|
|
51
51
|
def perform_update
|
@@ -64,12 +64,12 @@ module Lanes
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
|
67
|
+
protected
|
68
68
|
|
69
69
|
def perform_single_destroy
|
70
70
|
record = model.find(params[:id])
|
71
71
|
record.destroy
|
72
|
-
|
72
|
+
std_api_reply(:destroy, record, {})
|
73
73
|
end
|
74
74
|
|
75
75
|
def perform_multiple_destroy
|
@@ -81,7 +81,7 @@ module Lanes
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
options = build_reply_options.merge(success: success)
|
84
|
-
|
84
|
+
std_api_reply(:destroy, records, options)
|
85
85
|
end
|
86
86
|
|
87
87
|
def perform_multiple_updates
|
@@ -95,13 +95,13 @@ module Lanes
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
options = build_reply_options.merge(success: success)
|
98
|
-
|
98
|
+
std_api_reply(:update, records, options)
|
99
99
|
end
|
100
100
|
|
101
101
|
def perform_single_update(record)
|
102
102
|
record.set_attribute_data(data, user)
|
103
103
|
options = build_reply_options.merge(success: record.save)
|
104
|
-
|
104
|
+
std_api_reply(:update, record, options)
|
105
105
|
end
|
106
106
|
|
107
107
|
# @return [Array<String>] The fields to include in query. May represent either an attribute or a method
|
@@ -112,7 +112,7 @@ module Lanes
|
|
112
112
|
params[:df] == 'array'
|
113
113
|
end
|
114
114
|
def query_scopes
|
115
|
-
params[:w]
|
115
|
+
[*params[:w]]
|
116
116
|
end
|
117
117
|
def query_params
|
118
118
|
params[:q]
|
@@ -131,51 +131,6 @@ module Lanes
|
|
131
131
|
params[:s]
|
132
132
|
end
|
133
133
|
|
134
|
-
# json methods
|
135
|
-
# constructs a Hash with success, messages, and data keys and
|
136
|
-
# populates them appropriately
|
137
|
-
|
138
|
-
def build_reply(query, type, options)
|
139
|
-
success = options[:success].nil? ? true : options[:success]
|
140
|
-
json = {}
|
141
|
-
if query.is_a?(ActiveRecord::Base) && query.errors.any?
|
142
|
-
json[:errors] = {}
|
143
|
-
success = false
|
144
|
-
query.errors.each{ | attr, message |
|
145
|
-
json[:errors][attr] = message
|
146
|
-
}
|
147
|
-
end
|
148
|
-
if options[:total_count]
|
149
|
-
json[:total] = options.delete(:total_count)
|
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, type, options) : []
|
155
|
-
)
|
156
|
-
end
|
157
|
-
|
158
|
-
|
159
|
-
# @return Array<Array> returns either an array of fields
|
160
|
-
def records_for_reply(query, type, options)
|
161
|
-
return [] if :destroy == type
|
162
|
-
if reply_with_array?
|
163
|
-
query.pluck( *requested_fields )
|
164
|
-
else
|
165
|
-
query.as_json(options)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
def json_status_str(record, type, success)
|
170
|
-
if success
|
171
|
-
return type + " succeeded"
|
172
|
-
elsif record
|
173
|
-
return type + " failed: " + record.errors.full_messages.join("; ")
|
174
|
-
else
|
175
|
-
return "Record not found"
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
134
|
# reply options
|
180
135
|
|
181
136
|
# Should the result include the total number of available records
|
@@ -195,6 +150,7 @@ module Lanes
|
|
195
150
|
if requested_fields.any?
|
196
151
|
options[:methods] = requested_fields.select{|f| model.has_exported_method?(f,user) }
|
197
152
|
end
|
153
|
+
options[:format] = reply_with_array? ? 'array' : 'object'
|
198
154
|
options
|
199
155
|
end
|
200
156
|
|
@@ -233,9 +189,6 @@ module Lanes
|
|
233
189
|
if params[:nested_attribute]
|
234
190
|
query = query.where(params[:nested_attribute])
|
235
191
|
end
|
236
|
-
if query_scopes.present?
|
237
|
-
query = add_scope_to_query(query)
|
238
|
-
end
|
239
192
|
if query_params.present?
|
240
193
|
query = add_params_to_query(query)
|
241
194
|
end
|
@@ -243,9 +196,11 @@ module Lanes
|
|
243
196
|
end
|
244
197
|
|
245
198
|
def add_modifiers_to_query(query)
|
199
|
+
if query_scopes.present?
|
200
|
+
query = add_scope_to_query(query)
|
201
|
+
end
|
246
202
|
query = query.limit(query_limit_size)
|
247
203
|
query = query.offset(query_offset.to_i) if query_offset.present?
|
248
|
-
|
249
204
|
if include_associations.any?
|
250
205
|
allowed_includes = include_associations.each_with_object([]) do |desired, results|
|
251
206
|
if desired.is_a?(Hash)
|
@@ -262,11 +217,12 @@ module Lanes
|
|
262
217
|
end
|
263
218
|
if sort_order.present?
|
264
219
|
sort_order.each do | fld, dir |
|
265
|
-
query =
|
220
|
+
query = model.append_sort_to_query(
|
221
|
+
query, fld, dir.downcase.to_sym
|
222
|
+
)
|
266
223
|
end
|
267
224
|
end
|
268
225
|
query
|
269
|
-
|
270
226
|
end
|
271
227
|
|
272
228
|
|
@@ -288,12 +244,13 @@ module Lanes
|
|
288
244
|
def add_params_to_query(query)
|
289
245
|
query_params.each do | field, value |
|
290
246
|
next unless ( field = convert_field_to_arel(field) )
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
247
|
+
if value.is_a?(Hash) && value.has_key?('value')
|
248
|
+
op = value['op']
|
249
|
+
value = value['value']
|
250
|
+
end
|
251
|
+
query = query.where(
|
252
|
+
field_to_predicate(field, value, op)
|
253
|
+
)
|
297
254
|
end
|
298
255
|
query
|
299
256
|
end
|
@@ -306,20 +263,24 @@ module Lanes
|
|
306
263
|
else
|
307
264
|
nil
|
308
265
|
end
|
309
|
-
|
266
|
+
elsif model.attribute_method?(field)
|
310
267
|
model.arel_table[field]
|
268
|
+
else
|
269
|
+
Arel::Nodes::SqlLiteral.new(
|
270
|
+
model.connection.quote_column_name(field)
|
271
|
+
)
|
311
272
|
end
|
312
273
|
end
|
313
274
|
|
314
275
|
# complete list: https://github.com/rails/arel/blob/master/lib/arel/predications.rb
|
315
|
-
def
|
276
|
+
def field_to_predicate( field, value, op = nil )
|
316
277
|
case op
|
317
|
-
when 'eq'
|
278
|
+
when nil, 'eq' then field.eq(value)
|
279
|
+
when 'like' then field.matches( value )
|
318
280
|
when 'ne' then field.not_eq(value)
|
319
281
|
when 'lt' then field.lt(value)
|
320
282
|
when ( op=='in' && value=~/.*:.*/ ) then field.in( Range.new( *value.split(':') ) )
|
321
283
|
when 'gt' then field.gt(value)
|
322
|
-
when 'like' then field.matches( value )
|
323
284
|
else
|
324
285
|
value =~ /%/ ? field.matches( value ) : field.eq( value )
|
325
286
|
end
|