model_updates 0.0.11 → 0.0.12

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a5cb133f1b8f65abb2d507c21b386305040af2e0
4
- data.tar.gz: c7d89af1f90f0a65637ba16cb070b71ff27eb422
3
+ metadata.gz: 7ce52aac9e4372e8367b4f38870755ac6504f7a9
4
+ data.tar.gz: '09643ad37dda2f57123e4d09d7638ec1a23f5300'
5
5
  SHA512:
6
- metadata.gz: ba0a40d206e4f5de631469bd8265b52c61ed5fbe4d149e2bbb0b0abb1eaa82bbc1d76768d63512d37f1715dcced6317aeadb9e05b717fd4ef17325405d3dac89
7
- data.tar.gz: 9beab92f2e0173da0b9ae5c265199feb898265ab9e4d0f596cc9b5e1f657604ca62f5a260322b08d695f10ebb42f6de52dc8afde5dc439b245e029b8fb266084
6
+ metadata.gz: c42fe2e6821234087a1b764dc62a4144b10541f356bf985f00e7b7afd39d8f2f4cc6f683b29361ed589553c7944c9fe246694fc98b4093dd07fc7baf3e12a320
7
+ data.tar.gz: '009db022e778a84744276567092167ecf3de57fb0134a3e216e264c39b5306421b7b0b1f11327d3d3888fd78d14bbdc7ce86955a1771f9cd3b06c3908454f81e'
data/README.md CHANGED
@@ -170,6 +170,38 @@ You can refresh elements with a simple call like this:
170
170
  ModelUpdates.update()
171
171
  ```
172
172
 
173
+ ## Events
174
+
175
+ Call an event on a specific model:
176
+ ```ruby
177
+ user = User.find(user_id)
178
+ user.model_updates_call("changed-password", new_password: "test")
179
+ ```
180
+
181
+ Connect to a specific model:
182
+ ```js
183
+ ModelUpdates.connectModel("User", userId, "changed-password", function(args) {
184
+ console.log("User changed his password to: " + args.new_password)
185
+ })
186
+ ```
187
+
188
+ Call an event on a model class:
189
+ ```ruby
190
+ User.model_updates_call("changed-password", new_password: "test")
191
+ ```
192
+
193
+ Connect to events called on a models class:
194
+ ```js
195
+ ModelUpdates.connectModelClass("User", "changed-password", function(args) {
196
+ console.log("Someone his password to: " + args.new_password)
197
+ })
198
+ ```
199
+
200
+ Call this at the end of your JavaScript, which will actually connect to all the defined events in a batched way:
201
+ ```js
202
+ ModelUpdates.connectEvents()
203
+ ```
204
+
173
205
  ### Debugging
174
206
 
175
207
  In case you want to enable debug output from ModelUpdates from JavaScript:
@@ -1,6 +1,7 @@
1
1
  //= require model_updates/model_updates_class
2
2
  //= require model_updates/activator
3
3
  //= require model_updates/create
4
+ //= require model_updates/events
4
5
  //= require model_updates/formatters
5
6
  //= require model_updates/update
6
7
 
@@ -3,10 +3,26 @@ ModelUpdates.Activator = class Activator {
3
3
  ModelUpdates.debug("Activator constructor")
4
4
 
5
5
  this.modelSubscriptions = {}
6
+ this.callbacks = {}
6
7
  this.connectedUpdates = {}
7
8
  this.connectedDestroyes = {}
8
9
  }
9
10
 
11
+ connectUpdate(model, id, callback) {
12
+ if (!this.modelSubscriptions[model])
13
+ this.modelSubscriptions[model] = {}
14
+
15
+ this.modelSubscriptions[model][id] = true
16
+
17
+ if (!this.callbacks[model])
18
+ this.callbacks[model] = {}
19
+
20
+ if (!this.callbacks[model][id])
21
+ this.callbacks[model][id] = []
22
+
23
+ this.callbacks[model][id].push(callback)
24
+ }
25
+
10
26
  update() {
11
27
  ModelUpdates.debug("Update was called")
12
28
  this.updateFoundElements()
@@ -0,0 +1,88 @@
1
+ ModelUpdates.Events = class Events {
2
+ constructor() {
3
+ this.modelCallbacks = {}
4
+ this.modelClassCallbacks = {}
5
+ this.resetCallbackData()
6
+ }
7
+
8
+ connectModel(args, callback) {
9
+ if (!this.modelCallbacks[args.model])
10
+ this.modelCallbacks[args.model] = {}
11
+
12
+ if (!this.callbackData["connect_model"][args.model])
13
+ this.callbackData["connect_model"][args.model] = []
14
+
15
+ if (!this.modelCallbacks[args.model][args.id]) {
16
+ this.modelCallbacks[args.model][args.id] = []
17
+ this.callbackData["connect_model"][args.model].push(args.id)
18
+ }
19
+
20
+ this.modelCallbacks[args.model][args.id].push(args)
21
+ }
22
+
23
+ connectModelClass(args, callback) {
24
+ if (!this.modelClassCallbacks[args.model])
25
+ this.modelClassCallbacks[args.model] = []
26
+
27
+ this.modelClassCallbacks[args.model].push(args)
28
+ this.callbackData["connect_model_class"].push(args.model)
29
+ }
30
+
31
+ connect() {
32
+ ModelUpdates.debug("Connecting: " + JSON.stringify(this.callbackData))
33
+
34
+ var events = this
35
+ App.cable.subscriptions.create(
36
+ {channel: "ModelUpdates::EventsChannel", callback_data: this.callbackData},
37
+ {
38
+ received: function(json) {
39
+ ModelUpdates.debug("Incoming event: " + JSON.stringify(json))
40
+
41
+ if (json.callback_type == "model") {
42
+ events.callModelCallbacks(json)
43
+ } else if(json.callback_type == "model_class") {
44
+ events.callModelClassCallbacks(json)
45
+ } else {
46
+ console.log("Didnt know how to handle: " + JSON.stringify(json))
47
+ }
48
+ }
49
+ }
50
+ )
51
+
52
+ this.resetCallbackData()
53
+ }
54
+
55
+ callModelCallbacks(args) {
56
+ var modelClass = args.model
57
+ var modelId = args.id
58
+ var callbacks = this.modelCallbacks[modelClass][modelId]
59
+
60
+ for(var callbackNumber in callbacks) {
61
+ var callback = callbacks[callbackNumber]
62
+
63
+ if (!callback.name || callback.name == args.event_name) {
64
+ callback.callback(args)
65
+ }
66
+ }
67
+ }
68
+
69
+ callModelClassCallbacks(args) {
70
+ var modelClass = args.model
71
+ var callbacks = this.modelClassCallbacks[modelClass]
72
+
73
+ for(var callbackNumber in callbacks) {
74
+ var callback = callbacks[callbackNumber]
75
+
76
+ if (!callback.name || callback.name == args.event_name) {
77
+ callback.callback(args)
78
+ }
79
+ }
80
+ }
81
+
82
+ resetCallbackData() {
83
+ this.callbackData = {
84
+ "connect_model_class": [],
85
+ "connect_model": {}
86
+ }
87
+ }
88
+ }
@@ -1,4 +1,24 @@
1
1
  class ModelUpdates {
2
+ static connectChanged(model, id, callback) {
3
+ ModelUpdates.current().activator().connectUpdate(model, id, callback)
4
+ }
5
+
6
+ static connectModel(modelName, modelId, eventName, callback) {
7
+ ModelUpdates.current().events().connectModel({"model": modelName, "id": modelId, "name": eventName, "callback": function(args) {
8
+ callback(args.args)
9
+ }})
10
+ }
11
+
12
+ static connectModelClass(modelName, eventName, callback) {
13
+ ModelUpdates.current().events().connectModelClass({"model": modelName, "name": eventName, "callback": function(args) {
14
+ callback(args.args)
15
+ }})
16
+ }
17
+
18
+ static connectEvents() {
19
+ ModelUpdates.current().events().connect()
20
+ }
21
+
2
22
  static debug(message) {
3
23
  if (ModelUpdates.configuration.debug) {
4
24
  console.log("ModelUpdates: " + message)
@@ -24,6 +44,13 @@ class ModelUpdates {
24
44
  return this.activatorElement
25
45
  }
26
46
 
47
+ events() {
48
+ if (!this.eventsElement)
49
+ this.eventsElement = new ModelUpdates.Events()
50
+
51
+ return this.eventsElement
52
+ }
53
+
27
54
  update() {
28
55
  ModelUpdates.debug("Instance method update called")
29
56
  this.activator().update()
@@ -6,6 +6,19 @@ ModelUpdates.Update = class Update {
6
6
  {channel: "ModelUpdates::UpdateChannel", ids: args.ids},
7
7
  {
8
8
  received: function(json) {
9
+ if (ModelUpdates.current().activator().callbacks[json.model] && ModelUpdates.current().activator().callbacks[json.model][json.id]) {
10
+ var callbacks = ModelUpdates.current().activator().callbacks[json.model][json.id]
11
+
12
+ ModelUpdates.debug("Found callbacks for " + json.model + "(" + json.id + ")")
13
+
14
+ for(var key in callbacks) {
15
+ var callback = callbacks[key]
16
+ ModelUpdates.debug("Calling callback")
17
+ callback.apply(json)
18
+ }
19
+ } else {
20
+ console.log("No callbacks for " + json.model + "(" + json.id + ")")
21
+ }
9
22
 
10
23
  if (json.type == "destroy") {
11
24
  var elements = $(".model-updates[data-model-updates-model='" + json.model + "'][data-model-updates-id='" + json.id + "'][data-model-updates-remove-on-destroy='true']")
@@ -0,0 +1,37 @@
1
+ class ModelUpdates::EventsChannel < ApplicationCable::Channel
2
+ def subscribed
3
+ connect_models if params[:callback_data][:connect_model].present?
4
+ connect_model_classes if params[:callback_data][:connect_model_class].present?
5
+ end
6
+
7
+ private
8
+
9
+ def connect_models
10
+ params[:callback_data][:connect_model].each do |model_class_name, ids|
11
+ models = model_class_name.safe_constantize.accessible_by(current_ability).where(id: ids)
12
+ models.find_each do |model|
13
+ stream_model(model: model)
14
+ end
15
+ end
16
+ end
17
+
18
+ def connect_model_classes
19
+ params[:callback_data][:connect_model_class].each do |model_class_name|
20
+ stream_model_class(model_class: model_class_name.safe_constantize)
21
+ end
22
+ end
23
+
24
+ def stream_model(model:)
25
+ channel_name = "model_updates_events_model_#{model.class.name}_model_#{model.id}"
26
+ stream_from(channel_name, coder: ActiveSupport::JSON) do |data|
27
+ transmit data
28
+ end
29
+ end
30
+
31
+ def stream_model_class(model_class:)
32
+ channel_name = "model_updates_events_class_#{model_class.name}"
33
+ stream_from(channel_name, coder: ActiveSupport::JSON) do |data|
34
+ transmit data
35
+ end
36
+ end
37
+ end
@@ -73,6 +73,27 @@ module ModelUpdates::ModelExtensions
73
73
  )
74
74
  end
75
75
  end
76
+
77
+ def model_updates_call(event_name, args = {})
78
+ ActionCable.server.broadcast(
79
+ "model_updates_events_class_#{name}",
80
+ event_name: event_name,
81
+ model: name,
82
+ callback_type: "model_class",
83
+ args: args
84
+ )
85
+ end
86
+ end
87
+
88
+ def model_updates_call(event_name, args = {})
89
+ ActionCable.server.broadcast(
90
+ "model_updates_events_model_#{self.class.name}_model_#{id}",
91
+ event_name: event_name,
92
+ id: id,
93
+ model: self.class.name,
94
+ callback_type: "model",
95
+ args: args
96
+ )
76
97
  end
77
98
 
78
99
  def model_updates_attrs(key, more = {})
@@ -1,3 +1,3 @@
1
1
  module ModelUpdates
2
- VERSION = "0.0.11".freeze
2
+ VERSION = "0.0.12".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: model_updates
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 0.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - kaspernj
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-01-05 00:00:00.000000000 Z
11
+ date: 2018-03-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -52,18 +52,13 @@ files:
52
52
  - app/assets/javascripts/model_updates.js
53
53
  - app/assets/javascripts/model_updates/activator.es6
54
54
  - app/assets/javascripts/model_updates/create.es6
55
+ - app/assets/javascripts/model_updates/events.es6
55
56
  - app/assets/javascripts/model_updates/formatters.js
56
57
  - app/assets/javascripts/model_updates/model_updates_class.es6
57
58
  - app/assets/javascripts/model_updates/update.es6
58
- - app/assets/stylesheets/model_updates/application.css
59
59
  - app/channels/model_updates/create_channel.rb
60
+ - app/channels/model_updates/events_channel.rb
60
61
  - app/channels/model_updates/update_channel.rb
61
- - app/controllers/model_updates/application_controller.rb
62
- - app/helpers/model_updates/application_helper.rb
63
- - app/jobs/model_updates/application_job.rb
64
- - app/mailers/model_updates/application_mailer.rb
65
- - app/models/model_updates/application_record.rb
66
- - app/views/layouts/model_updates/application.html.erb
67
62
  - config/routes.rb
68
63
  - lib/model_updates.rb
69
64
  - lib/model_updates/attribute_generator.rb
@@ -1,15 +0,0 @@
1
- /*
2
- * This is a manifest file that'll be compiled into application.css, which will include all the files
3
- * listed below.
4
- *
5
- * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
- * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
- *
8
- * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
- * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
- * files in this directory. Styles in this file should be added after the last require_* statement.
11
- * It is generally better to create a new file per style scope.
12
- *
13
- *= require_tree .
14
- *= require_self
15
- */
@@ -1,5 +0,0 @@
1
- module ModelUpdates; end
2
-
3
- class ModelUpdates::ApplicationController < ActionController::Base
4
- protect_from_forgery with: :exception
5
- end
@@ -1,2 +0,0 @@
1
- module ModelUpdates::ApplicationHelper
2
- end
@@ -1,2 +0,0 @@
1
- class ModelUpdates::ApplicationJob < ActiveJob::Base
2
- end
@@ -1,4 +0,0 @@
1
- class ModelUpdates::ApplicationMailer < ActionMailer::Base
2
- default from: "from@example.com"
3
- layout "mailer"
4
- end
@@ -1,3 +0,0 @@
1
- class ModelUpdates::ApplicationRecord < ActiveRecord::Base
2
- self.abstract_class = true
3
- end
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Model updates</title>
5
- <%= stylesheet_link_tag "model_updates/application", media: "all" %>
6
- <%= javascript_include_tag "model_updates/application" %>
7
- <%= csrf_meta_tags %>
8
- </head>
9
- <body>
10
-
11
- <%= yield %>
12
-
13
- </body>
14
- </html>