model_updates 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -0
- data/app/assets/javascripts/model_updates.js +1 -0
- data/app/assets/javascripts/model_updates/activator.es6 +16 -0
- data/app/assets/javascripts/model_updates/events.es6 +88 -0
- data/app/assets/javascripts/model_updates/model_updates_class.es6 +27 -0
- data/app/assets/javascripts/model_updates/update.es6 +13 -0
- data/app/channels/model_updates/events_channel.rb +37 -0
- data/lib/model_updates/model_extensions.rb +21 -0
- data/lib/model_updates/version.rb +1 -1
- metadata +4 -9
- data/app/assets/stylesheets/model_updates/application.css +0 -15
- data/app/controllers/model_updates/application_controller.rb +0 -5
- data/app/helpers/model_updates/application_helper.rb +0 -2
- data/app/jobs/model_updates/application_job.rb +0 -2
- data/app/mailers/model_updates/application_mailer.rb +0 -4
- data/app/models/model_updates/application_record.rb +0 -3
- data/app/views/layouts/model_updates/application.html.erb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ce52aac9e4372e8367b4f38870755ac6504f7a9
|
4
|
+
data.tar.gz: '09643ad37dda2f57123e4d09d7638ec1a23f5300'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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:
|
@@ -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 = {})
|
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.
|
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-
|
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,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>
|