Skip to content

Commit

Permalink
Custom node sample for #69
Browse files Browse the repository at this point in the history
  • Loading branch information
kmmbvnr committed Aug 12, 2014
1 parent 3e66357 commit 0909fee
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 2 deletions.
Empty file.
14 changes: 14 additions & 0 deletions tests/examples/customnode/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from django.contrib import admin
from viewflow.admin import ProcessAdmin
from . import models, flows


@admin.register(models.DynamicSplitProcess)
class DynamicSplitAdmin(ProcessAdmin):
list_display = ['pk', 'created', 'get_status_display', 'participants',
'split_count', 'decisions_list']

list_display_links = ['pk', 'created']

def decisions_list(self, obj):
return ', '.join(['No', 'Yes'][answer.decision] for answer in obj.decision_set.all())
29 changes: 29 additions & 0 deletions tests/examples/customnode/flows.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from viewflow import flow
from viewflow.base import this, Flow
from viewflow.site import viewsite
from viewflow.views import StartView

from . import models, views
from .nodes import DynamicSplit


class DynamicSplitFlow(Flow):
process_cls = models.DynamicSplitProcess

start = flow.Start(StartView, fields=['split_count']) \
.Permission(auto_create=True) \
.Next(this.spit_on_decision)

spit_on_decision = DynamicSplit(lambda p: p.split_count) \
.Next(this.make_decision)

make_decision = flow.View(views.DecisionView) \
.Next(this.join_on_decision)

join_on_decision = flow.Join() \
.Next(this.end)

end = flow.End()


viewsite.register(DynamicSplitFlow)
13 changes: 13 additions & 0 deletions tests/examples/customnode/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.db import models
from django.conf import settings
from viewflow.models import Process


class DynamicSplitProcess(Process):
split_count = models.IntegerField(default=0)


class Decision(models.Model):
process = models.ForeignKey(DynamicSplitProcess)
user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
decision = models.BooleanField(default=False)
53 changes: 53 additions & 0 deletions tests/examples/customnode/nodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from viewflow.activation import GateActivation
from viewflow.flow.base import Gateway, Edge
from viewflow.token import Token


class DynamicSplitActivation(GateActivation):
def execute(self):
self._split_count = self.flow_task._task_count_callback(self.process)

def activate_next(self):
if self._split_count:
token_source = Token.split_token_source(self.task.token, self.task.pk)
for _ in range(self._split_count):
self.flow_task._next_task.activate(prev_activation=self, token=next(token_source))


class DynamicSplit(Gateway):
"""
Activates several outgoing task instances depends on callback value
Example::
spit_on_decision = flow.DynamicSplit(lambda p: 4) \\
.Next(this.make_decision)
make_decision = flow.View(MyView) \\
.Next(this.join_on_decision)
join_on_decision = flow.Join() \\
.Next(this.end)
"""
task_type = 'SPLIT'
activation_cls = DynamicSplitActivation

def __init__(self, callback):
super(DynamicSplit, self).__init__()
self._next_task, self._task_count_callback = None, callback

def _outgoing(self):
yield Edge(src=self, dst=self._next_task, edge_class='next')

def Next(self, node):
self._next_task = node
return self


# TODO: Some boilerplate to remove
from viewflow.resolve import resolve_children_links


@resolve_children_links.register(DynamicSplit)
def _(flow_node, resolver):
flow_node._next_task = resolver.get_implementation(flow_node._next_task)
18 changes: 18 additions & 0 deletions tests/examples/customnode/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from django.views import generic
from viewflow import flow

from . import models


class DecisionView(flow.TaskFormViewMixin, generic.CreateView):
model = models.Decision
fields = ['decision']

def activation_done(self, form):
self.object = form.save(commit=False)

self.object.user = self.request.user
self.object.process = self.activation.process
self.object.save()

self.activation.done()
3 changes: 2 additions & 1 deletion tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
'tests.integration',
# Examples
'tests.examples.shipment',
'tests.examples.helloworld'
'tests.examples.helloworld',
'tests.examples.customnode',
)

MIDDLEWARE_CLASSES = (
Expand Down
3 changes: 2 additions & 1 deletion tests/templates/viewflow/base_site.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
<ul class="nav">
<li {% if request.path == "/" %}class="active"{% endif %}><a href="/">Home</a></li>
<li {% if "/helloworld/" in request.path %}class="active"{% endif %}><a href="{% flowurl 'helloworld/HelloWorldFlow' 'viewflow:index' %}">Hello, World</a></li>
<li {% if "/shipment" in request.path %}class="active"{% endif %}><a href="{% flowurl 'shipment/ShipmentFlow' 'viewflow:index' %}">Shipment</a></li>
<li {% if "/shipment/" in request.path %}class="active"{% endif %}><a href="{% flowurl 'shipment/ShipmentFlow' 'viewflow:index' %}">Shipment</a></li>
<li {% if "/dynamicsplit/" in request.path %}class="active"{% endif %}><a href="{% flowurl 'customnode/DynamicSplitFlow' 'viewflow:index' %}">Dynamic Split</a></li>
</ul>
{% endblock %}

Expand Down

0 comments on commit 0909fee

Please sign in to comment.