rao-service_chain 0.0.41.pre → 0.0.42.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2672cfbd5062d63ae6ef9537ac6fbb32f5520a8be5f84a9fc9cdc28c2fa37739
4
- data.tar.gz: ab9547bf5879c5f9b85e6da8dca62bf4b8a468a469f4d50cc251c11002b03fec
3
+ metadata.gz: eef27fc8f2a5fcc1a1d6434f39519976f2aa24f2736368713aafa4c02c030f2d
4
+ data.tar.gz: d3777a94d300f861958d7dfef5ab83ff4a39d47ed30f62328a6f11ad9b88520c
5
5
  SHA512:
6
- metadata.gz: d90e73e47d5d0c890a5a6e6ffa72200b568276bf79031c03ea87434ab5fcf351149f4d43e88c193da345b24c6346b773c5e4abc01d397cd7951e6d2c0a89581d
7
- data.tar.gz: e6343221aa5c5d8553acfd5b37b40ac78706c9c1e855cbd82c2329ea763f59da2df1d78065bb0125b744995b94c7ca53f75615ffec83e47667e66504c3f0043a
6
+ metadata.gz: 37d0c350c1c86ed978ebabf283ff6d8090a6e8b6e3fd1ab48b10f45e8730486c83858464d231e8e3f02da0435ce59c22793d9c194b538014b5a0f2ea335ead01
7
+ data.tar.gz: c8a355694e8aa24995ae03210522d6db0dfb1ff8d696d2ce93e38558b871b98e4da685f91bd90deae04a60f10c32552922849d5bed920d6b8a811ac1a9a3590b
@@ -0,0 +1,264 @@
1
+
2
+ module Rao
3
+ module ServiceChain
4
+ module Aasm
5
+ class Base
6
+ include ::AASM
7
+
8
+ def initialize(options = {})
9
+ options.each do |k,v|
10
+ send("#{k}=", v)
11
+ end
12
+ end
13
+
14
+ module ServiceConcern
15
+ extend ActiveSupport::Concern
16
+
17
+ class_methods do
18
+ def service_module_name
19
+ nil
20
+ end
21
+ end
22
+
23
+ def service_class_to_state(service_class)
24
+ service_class.name.demodulize.underscore.to_sym
25
+ end
26
+
27
+ def state_to_service_class(state)
28
+ "#{self.class.service_module_name}#{state.to_s.camelize}".constantize
29
+ end
30
+ end
31
+
32
+ include ServiceConcern
33
+
34
+ module StepConcern
35
+ extend ActiveSupport::Concern
36
+
37
+ def actual_step=(service_class)
38
+ aasm.current_state = service_class_to_state(service_class)
39
+ end
40
+
41
+ def actual_step
42
+ return nil if %i(started finished).include?(aasm.current_state)
43
+ wrap(
44
+ state_to_service_class(aasm.current_state),
45
+ completed_if: aasm.states.find { |s| s.name == aasm.current_state }.options[:completed_if],
46
+ router: aasm.states.find { |s| s.name == aasm.current_state }.options[:router],
47
+ url: aasm.states.find { |s| s.name == aasm.current_state }.options[:url],
48
+ )
49
+ end
50
+
51
+ def previous_steps
52
+ current_state = aasm.current_state
53
+ o = []
54
+ i = 0
55
+ while(i < 1000) do
56
+ previous_event = aasm.events.select{ |e| e.name == :previous }.first
57
+ return [] unless previous_event.respond_to?(:transitions)
58
+ targets = previous_event.transitions.select{ |t|
59
+ # targets = aasm.events(permitted: true).select{ |e| e.name == :next }.first.transitions.select{ |t|
60
+ t.from == current_state
61
+ }.select{ |t|
62
+ guards = t.instance_variable_get(:@guards)
63
+ if guards.empty?
64
+ true
65
+ else
66
+ guards.map { |g| send(g) }.all?
67
+ end
68
+ }.map { |t|
69
+ {
70
+ t.to => {
71
+ display: (t.options[:display].presence || -> { true }),
72
+ completed_if: aasm.states.find { |s| s.name == t.to }.options[:completed_if],
73
+ router: aasm.states.find { |s| s.name == t.to }.options[:router],
74
+ url: aasm.states.find { |s| s.name == t.to }.options[:url],
75
+ }
76
+ }
77
+ }
78
+ break if targets.empty? || %i(started finished).include?(targets.first.first[0])
79
+ o << wrap(state_to_service_class(targets.first.first[0]), targets.first.first[1])
80
+ current_state = targets.first.first[0]
81
+ i = i + 1
82
+ end
83
+ o.reverse.compact
84
+ end
85
+
86
+ def next_steps
87
+ current_state = aasm.current_state
88
+ o = []
89
+ i = 0
90
+ while(i < 1000) do
91
+ previous_event = aasm.events.select{ |e| e.name == :next }.first
92
+ return [] unless previous_event.respond_to?(:transitions)
93
+ targets = previous_event.transitions.select{ |t|
94
+ # targets = aasm.events(permitted: true).select{ |e| e.name == :next }.first.transitions.select{ |t|
95
+ t.from == current_state
96
+ }.select{ |t|
97
+ guards = t.instance_variable_get(:@guards)
98
+ if guards.empty?
99
+ true
100
+ else
101
+ guards.map { |g| send(g) }.all?
102
+ end
103
+ }.map { |t|
104
+ {
105
+ t.to => {
106
+ display: (t.options[:display].presence || -> { true }),
107
+ completed_if: aasm.states.find { |s| s.name == t.to }.options[:completed_if],
108
+ router: aasm.states.find { |s| s.name == t.to }.options[:router],
109
+ url: aasm.states.find { |s| s.name == t.to }.options[:url],
110
+ }
111
+ }
112
+ }
113
+ break if targets.empty? || %i(started finished).include?(targets.first.first[0])
114
+ o << wrap(state_to_service_class(targets.first.first[0]), targets.first.first[1])
115
+ current_state = targets.first.first[0]
116
+ i = i + 1
117
+ end
118
+ o.compact
119
+ end
120
+
121
+ def steps
122
+ # aasm.states.map(&:name).map { |s| wrap(state_to_service_class(s)) }
123
+ o = []
124
+
125
+ #walk backwards
126
+ # current_state = aasm.current_state
127
+ # i = 0
128
+ # while(i < 1000) do
129
+ # targets = aasm.events.select{ |e| e.name == :previous }.first.transitions.select{ |t|
130
+ # # targets = aasm.events(permitted: true).select{ |e| e.name == :previous }.first.transitions.select{ |t|
131
+ # t.from == current_state
132
+ # }.select{ |t|
133
+ # guards = t.instance_variable_get(:@guards)
134
+ # if guards.empty?
135
+ # true
136
+ # else
137
+ # guards.map { |g| send(g) }.all?
138
+ # end
139
+ # }.map { |t| t.to }
140
+ # break if targets.empty?
141
+ # o << wrap(state_to_service_class(targets.first))
142
+ # current_state = targets.first
143
+ # i = i + 1
144
+ # end
145
+
146
+ # o.reverse!
147
+
148
+ o << self.previous_steps
149
+
150
+ # add actual state
151
+ o << self.actual_step unless self.actual_step.nil?
152
+ # o << wrap(state_to_service_class(aasm.current_state))
153
+
154
+ # walk forward
155
+ o << self.next_steps
156
+ # current_state = aasm.current_state
157
+ # i = 0
158
+ # while(i < 1000) do
159
+ # targets = aasm.events.select{ |e| e.name == :next }.first.transitions.select{ |t|
160
+ # # targets = aasm.events(permitted: true).select{ |e| e.name == :next }.first.transitions.select{ |t|
161
+ # t.from == current_state
162
+ # }.select{ |t|
163
+ # guards = t.instance_variable_get(:@guards)
164
+ # if guards.empty?
165
+ # true
166
+ # else
167
+ # guards.map { |g| send(g) }.all?
168
+ # end
169
+ # }.map { |t| {t.to => { display: (t.options[:display].presence || -> { true }) } } }
170
+ # break if targets.empty?
171
+ # o << wrap(state_to_service_class(targets.first.first[0]), targets.first.first[1])
172
+ # current_state = targets.first.first[0]
173
+ # i = i + 1
174
+ # end
175
+ o.flatten
176
+ end
177
+
178
+ def step_count
179
+ steps.size
180
+ end
181
+
182
+ def completed_steps
183
+ self.steps.collect { |s| s.completed? ? s : nil }.compact
184
+ end
185
+
186
+ def pending_steps
187
+ self.steps.collect { |s| s.pending? ? s : nil }.compact
188
+ end
189
+
190
+ private
191
+
192
+ def wrap(service, options = {})
193
+ wrapper_class = Rao::ServiceChain::Step::Base
194
+ if service.is_a?(wrapper_class)
195
+ service
196
+ else
197
+ wrapper_class.new(options.merge(service: service, chain: self))
198
+ end
199
+ end
200
+ end
201
+
202
+ include StepConcern
203
+
204
+ module StepOrderConcern
205
+ extend ActiveSupport::Concern
206
+
207
+ def before_actual?(step)
208
+ return false if self.actual_step.nil?
209
+ return false if (si = step_index(wrap(step))).nil?
210
+ self.actual_step_index > si
211
+ end
212
+
213
+ def after_actual?(step)
214
+ return false if self.actual_step.nil?
215
+ return false if (si = step_index(wrap(step))).nil?
216
+ self.actual_step_index < si
217
+ end
218
+
219
+ def step_index(step)
220
+ self.steps.map(&:service).index(step.try(:service))
221
+ end
222
+
223
+ def actual_step_index
224
+ self.steps.map(&:service).index(self.actual_step.try(:service))
225
+ end
226
+
227
+ def next_step
228
+ self.next_steps.first
229
+ # return nil if self.actual_step_index.nil?
230
+ # return nil if self.actual_step_index + 1 >= self.step_count
231
+ # self.steps[self.actual_step_index + 1]
232
+ end
233
+
234
+ def previous_step
235
+ self.previous_steps.last
236
+ # return nil if self.actual_step_index.nil?
237
+ # return nil if self.actual_step_index - 1 < 0
238
+ # self.steps[self.actual_step_index - 1]
239
+ end
240
+
241
+ def next_step_url(options = {})
242
+ context = options.delete(:context)
243
+ self.next_step.url(context)
244
+ end
245
+ end
246
+
247
+ include StepOrderConcern
248
+
249
+ module SerializationConcern
250
+ extend ActiveSupport::Concern
251
+
252
+ def to_hash(context = nil)
253
+ {
254
+ actual_step: self.actual_step.to_hash(context),
255
+ steps: self.steps.map { |s| s.to_hash(context) }
256
+ }
257
+ end
258
+ end
259
+
260
+ include SerializationConcern
261
+ end
262
+ end
263
+ end
264
+ end
@@ -0,0 +1,6 @@
1
+ module Rao
2
+ module ServiceChain
3
+ module Aasm
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,151 @@
1
+ module Rao
2
+ module ServiceChain
3
+ class Base
4
+ attr_accessor :steps
5
+ attr_accessor :actual_step
6
+
7
+ def initialize(options = {})
8
+ options.each do |key, value|
9
+ self.send("#{key}=", value)
10
+ end
11
+ if @actual_step.present?
12
+ actual_service = unwrap(@actual_step)
13
+ @actual_step = find_step_by_service(actual_service)
14
+ end
15
+ end
16
+
17
+ def wrap_actual_step!
18
+ @actual_step = wrap(@actual_step)
19
+ end
20
+
21
+ def steps=(steps)
22
+ @steps = steps.map { |s| wrap(s) }
23
+ end
24
+
25
+ def steps
26
+ raise "Child class responsiblity"
27
+ end
28
+
29
+ def step_index(step)
30
+ self.steps.map(&:service).index(step.try(:service))
31
+ end
32
+
33
+ def service_index(service)
34
+ self.steps.map(&:service).index(service)
35
+ end
36
+
37
+ def find_step_by_service(service)
38
+ self.steps[(service_index(service))]
39
+ end
40
+
41
+ def actual_step_index
42
+ self.steps.map(&:service).index(self.actual_step.try(:service))
43
+ end
44
+
45
+ def step_count
46
+ self.steps.size
47
+ end
48
+
49
+ def previous_step_index
50
+ self.steps.map(&:service).index(self.previous_step.try(:service))
51
+ end
52
+
53
+ def next_step_index
54
+ self.steps.map(&:service).index(self.next_step.try(:service))
55
+ end
56
+
57
+ def previous_step
58
+ return nil if self.actual_step_index.nil?
59
+ return nil if self.actual_step_index - 1 < 0
60
+ self.steps[self.actual_step_index - 1]
61
+ end
62
+
63
+ def previous_steps
64
+ return [] if self.actual_step_index.nil?
65
+ return [] if self.actual_step_index == 0
66
+ self.steps[0..(self.actual_step_index - 1)]
67
+ end
68
+
69
+ def next_step
70
+ if self.actual_step.try(:next_step).respond_to?(:call)
71
+ find_step_by_service(self.actual_step.next_step.call(self.actual_step))
72
+ else
73
+ return nil if self.actual_step_index.nil?
74
+ return nil if self.actual_step_index + 1 >= self.step_count
75
+ self.steps[self.actual_step_index + 1]
76
+ end
77
+ end
78
+
79
+ def next_steps
80
+ return [] if self.actual_step_index.nil?
81
+ self.steps[(self.actual_step_index + 1)..-1]
82
+ end
83
+
84
+ def next_step?
85
+ !!next_step
86
+ end
87
+
88
+ def previous_step?
89
+ !!previous_step
90
+ end
91
+
92
+ def next_step_url(options = {})
93
+ context = options.delete(:context)
94
+ self.next_step.url(context)
95
+ end
96
+
97
+ def steps_with_urls(context)
98
+ self.steps.map { |s| s.url(context); s }
99
+ end
100
+
101
+ def to_hash(context = nil)
102
+ {
103
+ actual_step: self.actual_step.to_hash(context),
104
+ steps: self.steps.map { |s| s.to_hash(context) }
105
+ }
106
+ end
107
+
108
+ def completed_steps
109
+ self.steps.collect { |s| s.completed? ? s : nil }.compact
110
+ end
111
+
112
+ def pending_steps
113
+ self.steps.collect { |s| s.pending? ? s : nil }.compact
114
+ end
115
+
116
+ def before_actual?(step)
117
+ return false if self.actual_step.nil?
118
+ return false if (si = step_index(wrap(step))).nil?
119
+ self.actual_step_index > si
120
+ end
121
+
122
+ def after_actual?(step)
123
+ return false if self.actual_step.nil?
124
+ return false if (si = step_index(wrap(step))).nil?
125
+ self.actual_step_index < si
126
+ end
127
+
128
+ private
129
+
130
+ def wrap(service, options = {})
131
+ if service.is_a?(wrapper_base_class)
132
+ service
133
+ else
134
+ wrapper_base_class.new(options.merge(service: service, chain: self))
135
+ end
136
+ end
137
+
138
+ def unwrap(step_or_service)
139
+ if step_or_service.is_a?(wrapper_base_class)
140
+ step_or_service.service
141
+ else
142
+ step_or_service
143
+ end
144
+ end
145
+
146
+ def wrapper_base_class
147
+ Rao::ServiceChain::Step::Base
148
+ end
149
+ end
150
+ end
151
+ end
@@ -2,7 +2,7 @@ module Rao
2
2
  module ServiceChain
3
3
  module Step
4
4
  class Base
5
- attr_accessor :service, :service_name, :label, :chain
5
+ attr_accessor :service, :service_name, :label, :chain, :router
6
6
 
7
7
  def initialize(options = {})
8
8
  @service = options.delete(:service)
@@ -12,12 +12,13 @@ module Rao
12
12
  @service_name = @service.try(:name)
13
13
  @label = service.try(:model_name).try(:human)
14
14
  @url = options.delete(:url)
15
+ @router = options.delete(:router) || :main_app
15
16
  end
16
17
 
17
18
  def url(context = nil)
18
19
  return nil if context.nil?
19
20
  return context.instance_exec(@service, &@url) if @url.respond_to?(:call)
20
- @url ||= context.url_for([:new, @service, only_path: true])
21
+ @url ||= context.send(router).url_for([:new, @service, only_path: true])
21
22
  end
22
23
 
23
24
  def completed?
@@ -1,3 +1,4 @@
1
+ require "aasm"
1
2
  require "haml-rails"
2
3
 
3
4
  require "rao"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rao-service_chain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.41.pre
4
+ version: 0.0.42.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Vasquez Angel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-24 00:00:00.000000000 Z
11
+ date: 2020-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: aasm
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: haml-rails
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -164,7 +178,10 @@ files:
164
178
  - app/assets/stylesheets/rao/service_chain/application.css
165
179
  - app/assets/stylesheets/rao/service_chain/application/wizard.css
166
180
  - app/concerns/rao/service/chain/controller_concern.rb
181
+ - app/service_chains/rao/service_chain/aasm.rb
182
+ - app/service_chains/rao/service_chain/aasm/base.rb
167
183
  - app/service_chains/rao/service_chain/base.rb
184
+ - app/service_chains/rao/service_chain/base~.rb
168
185
  - app/service_steps/rao/service_chain/step/base.rb
169
186
  - app/view_helpers/rao/service_chain/application_view_helper.rb
170
187
  - app/views/rao/service_chain/application_view_helper/render_progress/_bootstrap4.html.haml
@@ -195,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
212
  - !ruby/object:Gem::Version
196
213
  version: 1.3.1
197
214
  requirements: []
198
- rubygems_version: 3.1.2
215
+ rubygems_version: 3.1.3
199
216
  signing_key:
200
217
  specification_version: 4
201
218
  summary: Service Chains for Ruby on Rails.