aasm_progressable 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +57 -0
- data/app/assets/stylesheets/aasm_progressable.css.scss +32 -0
- data/app/helpers/aasm_progressable/helper.rb +62 -0
- data/app/views/aasm_progressable/states/_list.html.erb +9 -0
- data/lib/aasm_progressable.rb +5 -0
- data/lib/aasm_progressable/engine.rb +5 -0
- data/lib/aasm_progressable/model_mixin.rb +53 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b02c82b67010f9ab734beab0cec83dc3e2aaf0fc
|
4
|
+
data.tar.gz: 3b159e1d8fc17986bf5593759dec67a072965a02
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0319067fe12b531167669eaa3ca4f6850e55b5f2bfb40f23debd0c9481e7d518dab2ab0babbbac44ed5760b93cf35f196a39d2c2c2a65622993082c684f2a9df
|
7
|
+
data.tar.gz: e47d7ae2467fea32e275f73881433f64a03742deb5b07023d9e8e6879009564873ef836dc4150552d9c63c9fb7f8a4b5488e7d0d7be7f7f0ed3c3a3f8d3c06ce
|
data/README.md
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
aasm_progressable
|
2
|
+
=================
|
3
|
+
|
4
|
+
Rails helper to render the progress indicators for simple linear [AASM](https://github.com/aasm/aasm) workflows. It allows users to see steps in a workflow they have completed, which step is in progress, and which steps have not been completed. See the following image for an example.
|
5
|
+
|
6
|
+
![Example Screenshot](https://raw.github.com/WorkflowsOnRails/aasm_progressable/master/docs/sample-screenshot.png)
|
7
|
+
|
8
|
+
|
9
|
+
Using aasm_progressable
|
10
|
+
-----------------------
|
11
|
+
|
12
|
+
Add `aasm_progressable` to your Gemfile, and run bundler to install it. For each model with an appropriate workflow, include `AasmProgressable::ModelMixin`, and add a call to `aasm_state_order` with an array of symbols corresponding to
|
13
|
+
the expected order in which the states will be traversed. For example, if we have an `Order` class that starts from the `new` state, proceeds to `processing`, and then `shipping`, we might have
|
14
|
+
|
15
|
+
```rb
|
16
|
+
class Order < ActiveRecord::Base
|
17
|
+
include AASM
|
18
|
+
aasm do
|
19
|
+
state :new, initial: true
|
20
|
+
state :processing
|
21
|
+
state :shipping
|
22
|
+
|
23
|
+
event :confirm do
|
24
|
+
transitions from: :new, to: :processing
|
25
|
+
end
|
26
|
+
event :dispatch do
|
27
|
+
transitions from: :processing, to: :shipping
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
aasm_state_order [:new, :processing, :shipping]
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
In order to render the progress indicator, we need to add `helper AasmProgressable::Helper` to your ApplicationController. Then, in any detailed views for the order (such as orders#show), we can add `<%= render_state_indicator the_model_instance %>` to render an indicator for the state of the specified instance of the model. By default, this will render an ordered list (`ol`) with one element per state, with the elements corresponding to complete, current, and incomplete states being classed with `complete`, `active`, and `incomplete` respectively. You can add a ` *= require aasm_progressable` line to your application stylesheet to include some default styling for the indicator.
|
36
|
+
|
37
|
+
|
38
|
+
Customizing and Localizing aasm_progressable
|
39
|
+
--------------------------------------------
|
40
|
+
|
41
|
+
aasm_progressable uses `AASM::Localizer#human_state_name` to convert AASM states to output text. By default, this method will replace underscores with spaces, and capitalize the first letter of the state name. However, it can also fetch state names from a locale key of the form `activerecord.attributes.<model-table-name>.<aasm-column-name>/<state-symbol>`. By default, `<aasm-column-name>` will be "aasm_state".
|
42
|
+
|
43
|
+
As an example, if we wanted to display "Unconfirmed" as English name for the `:new` order state in the previous example, we could add the following to config/locales/en.yml:
|
44
|
+
|
45
|
+
```yaml
|
46
|
+
en:
|
47
|
+
activerecord:
|
48
|
+
attributes:
|
49
|
+
order:
|
50
|
+
aasm_state/new: "Unconfirmed"
|
51
|
+
```
|
52
|
+
|
53
|
+
|
54
|
+
Limitations
|
55
|
+
------------
|
56
|
+
|
57
|
+
Models that use aasm_progressable should have a strictly linear workflow, ie. there should be no branches in the state machine. Loops and skipped states are permitted, but there may not be alternative states. If a model instance is in a state that does not appear in the model's `aasm_state_order` declaration, then the helper will not be able to infer the state transition history of the instance and all states will be rendered as if they were completed.
|
@@ -0,0 +1,32 @@
|
|
1
|
+
.state-indicator {
|
2
|
+
display: table;
|
3
|
+
table-layout: fixed;
|
4
|
+
width: 100%;
|
5
|
+
border-collapse: separate;
|
6
|
+
font-size: 16px;
|
7
|
+
|
8
|
+
ol {
|
9
|
+
display: table-row;
|
10
|
+
}
|
11
|
+
li {
|
12
|
+
display: table-cell;
|
13
|
+
padding: 6px 16px;
|
14
|
+
border-right: 4px solid #fff;
|
15
|
+
|
16
|
+
&:last-child {
|
17
|
+
border-right: none;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
.complete {
|
21
|
+
background: #6aa3d5;
|
22
|
+
color: #fff;
|
23
|
+
}
|
24
|
+
.active {
|
25
|
+
background: #357ebd;
|
26
|
+
color: #fff;
|
27
|
+
}
|
28
|
+
.incomplete {
|
29
|
+
background: #eae8ec;
|
30
|
+
color: #999;
|
31
|
+
}
|
32
|
+
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# The ActionView helper. This should be made accessible to appropriate
|
2
|
+
# controllers by adding a `helper AasmProgressable::Helper` declaration
|
3
|
+
# to them.
|
4
|
+
#
|
5
|
+
# @author Brendan MacDonell
|
6
|
+
module AasmProgressable
|
7
|
+
# Internal class to manage display attribute associated with each
|
8
|
+
# model state, such as the name to display, and if the state has
|
9
|
+
# been completed yet or not.
|
10
|
+
class State
|
11
|
+
attr_reader :id # the internal ID for the state (as a string)
|
12
|
+
attr_reader :name # name displayed to the user
|
13
|
+
|
14
|
+
def initialize(id, name, status_classes)
|
15
|
+
@id = id.to_s
|
16
|
+
@name = name
|
17
|
+
@status_classes = status_classes
|
18
|
+
end
|
19
|
+
|
20
|
+
# html_class may contain complete, previous, active, next, or incomplete.
|
21
|
+
def html_class
|
22
|
+
@status_classes.join(' ')
|
23
|
+
end
|
24
|
+
|
25
|
+
def is?(status_class)
|
26
|
+
@status_classes.include? status_class
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns an Array of State instances corresponding to the states
|
30
|
+
# of a model instance. The State instances are returned in the order
|
31
|
+
# given by the `aasm_state_order` declaration in the model.
|
32
|
+
def self.create_all(object)
|
33
|
+
localizer = AASM::Localizer.new
|
34
|
+
state_order = object.aasm_state_order
|
35
|
+
current_state = object.aasm.current_state
|
36
|
+
|
37
|
+
current_state_index = state_order.index(current_state)
|
38
|
+
|
39
|
+
object.aasm_state_order.each_with_index.map do |state, index|
|
40
|
+
status_classes = []
|
41
|
+
status_classes << :complete if index < current_state_index
|
42
|
+
status_classes << :previous if index == current_state_index - 1
|
43
|
+
status_classes << :active if index == current_state_index
|
44
|
+
status_classes << :next if index == current_state_index + 1
|
45
|
+
status_classes << :incomplete if index > current_state_index
|
46
|
+
|
47
|
+
name = localizer.human_state_name(object.class, state)
|
48
|
+
State.new(state, name, status_classes)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module Helper
|
54
|
+
# Renders a state indicator for a specified model instance.
|
55
|
+
def render_state_indicator(object, locals: {})
|
56
|
+
states = State.create_all(object)
|
57
|
+
locals = {states: states}.merge(locals)
|
58
|
+
rendered = render partial: 'aasm_progressable/states/list', locals: locals
|
59
|
+
rendered.html_safe
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Mixin for models with linear AASM-defined workflows.
|
2
|
+
#
|
3
|
+
# This mixin provides the aasm_state_order class settor, as well as
|
4
|
+
# a similarly-named instance gettor.
|
5
|
+
#
|
6
|
+
# @author Brendan MacDonell
|
7
|
+
module AasmProgressable
|
8
|
+
module ModelMixin
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
# Instance gettor to return the state order for the model
|
12
|
+
def aasm_state_order
|
13
|
+
self.class.get_aasm_state_order
|
14
|
+
end
|
15
|
+
|
16
|
+
def have_completed?(state)
|
17
|
+
current_index, target_index = state_index(self.aasm.current_state, state)
|
18
|
+
current_index > target_index
|
19
|
+
end
|
20
|
+
|
21
|
+
def have_not_completed?(state)
|
22
|
+
not have_completed?(state)
|
23
|
+
end
|
24
|
+
|
25
|
+
def have_started?(state)
|
26
|
+
current_index, target_index = state_index(self.aasm.current_state, state)
|
27
|
+
current_index >= target_index
|
28
|
+
end
|
29
|
+
|
30
|
+
def have_not_started?(state)
|
31
|
+
not have_started?(state)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Class gettors and settors for the state order
|
35
|
+
module ClassMethods
|
36
|
+
def aasm_state_order order
|
37
|
+
@state_order = order
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_aasm_state_order
|
41
|
+
@state_order
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# Returns an array of zero-index state indices, where each index indicates
|
48
|
+
# the state's position in the ordered state collection.
|
49
|
+
def state_index(*states)
|
50
|
+
states.map { |state| self.aasm_state_order.index(state) }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aasm_progressable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brendan MacDonell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: aasm
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sass-rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.0'
|
55
|
+
description: Progress indicators for linear AASM workflows
|
56
|
+
email: brendan@macdonell.net
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- README.md
|
62
|
+
- app/assets/stylesheets/aasm_progressable.css.scss
|
63
|
+
- app/helpers/aasm_progressable/helper.rb
|
64
|
+
- app/views/aasm_progressable/states/_list.html.erb
|
65
|
+
- lib/aasm_progressable.rb
|
66
|
+
- lib/aasm_progressable/engine.rb
|
67
|
+
- lib/aasm_progressable/model_mixin.rb
|
68
|
+
homepage: http://rubygems.org/gems/aasm_progressable
|
69
|
+
licenses:
|
70
|
+
- MIT
|
71
|
+
metadata: {}
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
requirements: []
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 2.2.2
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: AASM Progressable
|
92
|
+
test_files: []
|
93
|
+
has_rdoc:
|