mirror of
https://github.com/viewflow/viewflow.git
synced 2025-07-28 07:43:10 +08:00
Changes sync
This commit is contained in:
@ -2,10 +2,13 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
GIT VERSION
|
||||
-----------
|
||||
2.0.0.b5 2023-07-10
|
||||
-------------------
|
||||
|
||||
- Alow attach layout to forms in default form rendering template
|
||||
- Fix subprocess node activation
|
||||
- Added db indexes for workflow models
|
||||
- Improve workflow REST API support
|
||||
|
||||
2.0.0.b4 2023-06-05
|
||||
-------------------
|
||||
|
14
README.md
14
README.md
@ -179,17 +179,13 @@ modifications of Viewflow. You can find the commercial license terms in
|
||||
|
||||
## Changelog
|
||||
|
||||
2.0.0.b4 2023-06-05
|
||||
2.0.0.b5 2023-07-10
|
||||
-------------------
|
||||
|
||||
- New flow.SplitFirst Node
|
||||
- New celery.Timer Node
|
||||
- Expose REST API with drf-spectacular
|
||||
- Expose list_ordering_fields in a ModelViewset
|
||||
- Retain history and return to the Inbox/Queue list views after completing a flow task
|
||||
- Enable smooth page transitions in Chrome/Safari
|
||||
- Hotwire/Turbo integration for Django Admin with viewflow.contrib.admin app
|
||||
- Resolved issue with viewflow.fsm reporting unmet condition messages
|
||||
- Alow attach layout to forms in default form rendering template
|
||||
- Fix subprocess node activation
|
||||
- Added db indexes for workflow models
|
||||
- Improve workflow REST API support
|
||||
|
||||
|
||||
|
||||
|
2
setup.py
2
setup.py
@ -4,7 +4,7 @@ README = open("README.md", "r", encoding="utf-8").read()
|
||||
|
||||
setuptools.setup(
|
||||
name="django-viewflow",
|
||||
version="2.0.0b4",
|
||||
version="2.0.0b5",
|
||||
author_email="kmmbvnr@gmail.com",
|
||||
author="Mikhail Podgurskiy",
|
||||
description="Reusable library to build business applications fast",
|
||||
|
@ -34,7 +34,11 @@ class DashboardView(
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
sorted_nodes, _ = chart.topsort(self.flow_class)
|
||||
nodes = [node for node in sorted_nodes if node.task_type in ["HUMAN", "JOB"]]
|
||||
nodes = [
|
||||
node
|
||||
for node in sorted_nodes
|
||||
if node.task_type in ["HUMAN", "JOB", "SUBPROCESS"]
|
||||
]
|
||||
|
||||
start_nodes = [
|
||||
{"node": node, "can_execute": node.can_execute(self.request.user)}
|
||||
|
@ -8,6 +8,7 @@ from django.db.models.constants import LOOKUP_SEP
|
||||
from django.db.models.query import ModelIterable
|
||||
|
||||
from .status import STATUS
|
||||
from .utils import get_next_process_task
|
||||
|
||||
|
||||
def _available_flows(flow_classes, user):
|
||||
@ -257,22 +258,28 @@ class TaskQuerySet(QuerySet):
|
||||
Prefer assigned tasks first, if not, return first task from user queue
|
||||
"""
|
||||
|
||||
# first try to find an assigned task
|
||||
task = self.filter(process=process, owner=user, status=STATUS.ASSIGNED).first()
|
||||
# task inside a same process
|
||||
task = get_next_process_task(self, process, user)
|
||||
|
||||
# lookup for a task in a queue
|
||||
# task inside subprocess
|
||||
if task is None:
|
||||
task = (
|
||||
self.user_queue(user).filter(process=process, status=STATUS.NEW).first()
|
||||
)
|
||||
subprocess_task = self.filter(process__parent_task__process=process).first()
|
||||
if subprocess_task:
|
||||
task = get_next_process_task(self, subprocess_task.process, user)
|
||||
|
||||
# lookup for a job
|
||||
if task is None:
|
||||
task = (
|
||||
self.filter(process=process, flow_task_type='JOB', status__in=[
|
||||
STATUS.NEW, STATUS.SCHEDULED, STATUS.STARTED
|
||||
]).first()
|
||||
)
|
||||
# task inside parent process
|
||||
if task is None and process.parent_task_id:
|
||||
task = get_next_process_task(self, process.parent_task.process, user)
|
||||
|
||||
# task inside other subprocesses of parent task
|
||||
if task is None and process.parent_task_id:
|
||||
processes = process.__class__._default_manager.filter(
|
||||
parent_task__process=process.parent_task.process
|
||||
).exclude(pk=process.pk)
|
||||
for sub_process in processes:
|
||||
task = get_next_process_task(self, sub_process, user)
|
||||
if task:
|
||||
break
|
||||
|
||||
return task
|
||||
|
||||
|
@ -1,20 +1,48 @@
|
||||
from .status import STATUS
|
||||
|
||||
|
||||
class Act(object):
|
||||
"""Shortcut to access activation data."""
|
||||
|
||||
@property
|
||||
def process(self):
|
||||
"""Shortcut for lambda activation: activation.process...)"""
|
||||
|
||||
class Lookup(object):
|
||||
def __getattribute__(self, name):
|
||||
return lambda activation: getattr(activation.process, name)
|
||||
|
||||
return Lookup()
|
||||
|
||||
@property
|
||||
def task(self):
|
||||
"""Shortcut for lambda activation: activation.task...)"""
|
||||
|
||||
class Lookup(object):
|
||||
def __getattribute__(self, name):
|
||||
return lambda activation: getattr(activation.task, name)
|
||||
|
||||
return Lookup()
|
||||
|
||||
|
||||
act = Act()
|
||||
|
||||
|
||||
def get_next_process_task(manager, process, user):
|
||||
task = manager.filter(process=process, owner=user, status=STATUS.ASSIGNED).first()
|
||||
|
||||
# lookup for a task in a queue
|
||||
if task is None:
|
||||
task = (
|
||||
manager.user_queue(user).filter(process=process, status=STATUS.NEW).first()
|
||||
)
|
||||
|
||||
# lookup for a job
|
||||
if task is None:
|
||||
task = manager.filter(
|
||||
process=process,
|
||||
flow_task_type="JOB",
|
||||
status__in=[STATUS.NEW, STATUS.SCHEDULED, STATUS.STARTED],
|
||||
).first()
|
||||
|
||||
return task
|
||||
|
Reference in New Issue
Block a user