Skip to content

Commit

Permalink
UI/UX patches for workflows and template editor
Browse files Browse the repository at this point in the history
Workflows:
- Patch: Fix display new workflow events in  real time.
- Feature: Added ability to complete task and return workflow by "task api-name". More informative validation error texts for returning a task.
- Patch: Remove formatting when pasting text into the workflow title.

Template editor:
- Patch: Remove "Previous task completed" rule in the task due date widget.
- Patch: Removed the deprecated webhook "task_completed_v2"

Account settings:
Patch: Improved the company logo widget.

Added a custom 502 page
  • Loading branch information
pneumojoseph committed Jan 22, 2025
1 parent c27b004 commit 9ba1d26
Show file tree
Hide file tree
Showing 59 changed files with 4,990 additions and 3,614 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ msgid "Deletion not allowed while the account contains tenants."
msgstr "Löschen nicht erlaubt, solange das Konto Mieter enthält."

#: accounts/messages.py:68
msgid "Your subscription has already expired. Renew subscription or downgrade to Freemium plan."
msgstr "Ihr Abonnement ist bereits abgelaufen. Erneuern Sie das Abonnement oder wechseln Sie zum Freemium-Plan."
msgid "Your subscription has already expired. Renew subscription or contact support."
msgstr "Ihr Abonnement ist abgelaufen. Bitte verlängern Sie Ihr Abonnement oder kontaktieren Sie den Support."

#. Translators: Account owner permission
#: accounts/messages.py:72
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ msgid "Deletion not allowed while the account contains tenants."
msgstr "Eliminación no permitida mientras la cuenta contenga inquilinos."

#: accounts/messages.py:68
msgid "Your subscription has already expired. Renew subscription or downgrade to Freemium plan."
msgstr "Su suscripción ya ha expirado. Renueve la suscripción o cambie al plan Freemium."
msgid "Your subscription has already expired. Renew subscription or contact support."
msgstr "Tu suscripción ha expirado. Renueva tu suscripción o contacta al soporte."

#. Translators: Account owner permission
#: accounts/messages.py:72
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ msgid "Deletion not allowed while the account contains tenants."
msgstr "Suppression non autorisée tant que le compte contient des locataires."

#: accounts/messages.py:68
msgid "Your subscription has already expired. Renew subscription or downgrade to Freemium plan."
msgstr "Votre abonnement a déjà expiré. Renouvelez votre abonnement ou passez au plan Freemium."
msgid "Your subscription has already expired. Renew subscription or contact support."
msgstr "Votre abonnement a expiré. Veuillez le renouveler ou contacter le support."

#. Translators: Account owner permission
#: accounts/messages.py:72
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ msgid "Deletion not allowed while the account contains tenants."
msgstr "Нельзя удалить аккаунт пока он содержит тенантов."

#: accounts/messages.py:68
msgid "Your subscription has already expired. Renew subscription or downgrade to Freemium plan."
msgid "Your subscription has already expired. Renew subscription or contact support."
msgstr "Ваша подписка уже истекла. Обновите подписку или перейдите на план Freemium."

#. Translators: Account owner permission
Expand Down
2 changes: 1 addition & 1 deletion core/pneumatic_backend/accounts/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
MSG_A_0034 = _('Deletion not allowed while the account contains tenants.')
MSG_A_0035 = _(
'Your subscription has already expired. '
'Renew subscription or downgrade to Freemium plan.'
'Renew subscription or contact support.'
)
# Translators: Account owner permission
MSG_A_0036 = _('Only the account owner is allowed to perform this action.')
Expand Down
2 changes: 1 addition & 1 deletion core/pneumatic_backend/authentication/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def __init__(

def _get_wf_filter(self):
result, params = self._to_sql_list(
values=WorkflowStatus.END_STATUSES,
values=WorkflowStatus.DONE,
prefix='wf_status'
)
self.params.update(params)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,9 @@ def test_authenticate__empty_token__return_none(
# assert
assert user is None

@pytest.mark.parametrize('wf_status', WorkflowStatus.END_STATUSES)
def test_authenticate__workflow_ended__raise_exception(
self,
mocker,
wf_status,
):

# arrange
Expand All @@ -205,7 +203,7 @@ def test_authenticate__workflow_ended__raise_exception(
)
guest = create_test_guest(account=account)
workflow = create_test_workflow(account_owner, tasks_count=1)
workflow.status = wf_status
workflow.status = WorkflowStatus.DONE
workflow.save()
task = workflow.tasks.first()
TaskPerformer.objects.create(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
from typing import Optional, Dict, Any
from django.utils import timezone
from django.contrib.auth import get_user_model
from pneumatic_backend.processes.consts import WORKFLOW_NAME_LENGTH
from pneumatic_backend.processes.models import (
Workflow,
Task,
)
from pneumatic_backend.processes.utils.common import (
string_abbreviation,
)
from pneumatic_backend.processes.serializers.kickoff_value import (
KickoffValueSerializer
)
from pneumatic_backend.processes.enums import (
WorkflowStatus,
)
from pneumatic_backend.processes.api_v2.services.task.task import TaskService


Expand Down Expand Up @@ -85,37 +77,3 @@ def _partial_update_workflow(self, **kwargs):
if update_fields:
self.instance.save(update_fields=update_fields)
return self.instance


class BaseWorkflowRevertSerializerMixin:

def _update_workflow(
self,
workflow: Workflow,
current_task: Task,
reverted_to: int = None,
) -> None:

# TODO Move to WorkflowActionService

update_fields = ['current_task']
if workflow.status == WorkflowStatus.DELAYED:
delay = current_task.get_active_delay()
delay.end_date = timezone.now()
if delay.directly_status:
delay.save(update_fields=['end_date'])
else:
current_task.reset_delay(delay)
if workflow.status in [WorkflowStatus.DELAYED, WorkflowStatus.DONE]:
if workflow.status == WorkflowStatus.DONE:
workflow.date_completed = None
update_fields.append('date_completed')
workflow.status = WorkflowStatus.RUNNING
update_fields.append('status')

workflow.current_task -= 1

if reverted_to is not None:
workflow.current_task = reverted_to

workflow.save(update_fields=update_fields)
5 changes: 2 additions & 3 deletions core/pneumatic_backend/processes/api_v2/services/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
WorkflowEventType,
WorkflowEventActionType,
CommentStatus,
WorkflowStatus,
)
from pneumatic_backend.processes.api_v2.services.exceptions import (
AttachmentNotFound,
Expand Down Expand Up @@ -610,7 +609,7 @@ def _send_workflow_event(self):
def _validate_comment_action(self):
if self.instance.status == CommentStatus.DELETED:
raise CommentIsDeleted()
if self.instance.workflow.status in WorkflowStatus.END_STATUSES:
if self.instance.workflow.is_completed:
raise CommentedWorkflowNotRunning()

def create(
Expand All @@ -624,7 +623,7 @@ def create(
then only a notification about a new comment
will be sent to him """

if workflow.status in WorkflowStatus.END_STATUSES:
if workflow.is_completed:
raise CommentedWorkflowNotRunning()
if not text and not attachments:
raise CommentTextRequired()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
)
from pneumatic_backend.processes.enums import (
DirectlyStatus,
WorkflowStatus
)
from pneumatic_backend.processes.api_v2.services.task.exceptions import (
PerformersServiceException
Expand Down Expand Up @@ -73,7 +72,7 @@ def _validate(
):

workflow = task.workflow
if workflow.status in WorkflowStatus.END_STATUSES:
if workflow.is_completed:
raise PerformersServiceException(MSG_PW_0017)
if task.number != workflow.current_task:
raise PerformersServiceException(MSG_PW_0018)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def _validate_permission_to_mark(
if not user_permission:
raise exceptions.ChecklistServiceException(MSG_PW_0019)
workflow = task.workflow
if workflow.status in WorkflowStatus.END_STATUSES:
if workflow.is_completed:
raise exceptions.ChecklistServiceException(MSG_PW_0017)
if workflow.status == WorkflowStatus.DELAYED:
raise exceptions.ChecklistServiceException(MSG_PW_0020)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,7 @@ def test_create__not_found_attachments_in_text__ok(text, mocker):
assert task.contains_comments is True


@pytest.mark.parametrize('status', WorkflowStatus.END_STATUSES)
def test_create__workflow_ended__raise_exception(mocker, status):
def test_create__workflow_ended__raise_exception(mocker):

# arrange
account = create_test_account()
Expand All @@ -697,7 +696,7 @@ def test_create__workflow_ended__raise_exception(mocker, status):
workflow = create_test_workflow(
account_owner,
tasks_count=1,
status=status
status=WorkflowStatus.DONE
)
task = workflow.current_task_instance
task.performers.add(user)
Expand Down Expand Up @@ -1351,14 +1350,13 @@ def test_validate_comment_action__deleted__raise_exception():
assert ex.value.message == messages.MSG_PW_0049


@pytest.mark.parametrize('status', WorkflowStatus.END_STATUSES)
def test_validate_comment__workflow_ended__raise_exception(status):
def test_validate_comment__workflow_ended__raise_exception():

# arrange
user = create_test_user()
workflow = create_test_workflow(
user=user,
status=status
status=WorkflowStatus.DONE
)
event = WorkflowEvent.objects.create(
account=user.account,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,7 @@ def test_validate__request_user_not_template_owner__exception(
# assert
assert ex.value.message == messages.MSG_PW_0021

@pytest.mark.parametrize('status', WorkflowStatus.END_STATUSES)
def test_validate__workflow_ended__exception(self, status):
def test_validate__workflow_ended__exception(self):

# arrange
account = create_test_account()
Expand All @@ -224,7 +223,7 @@ def test_validate__workflow_ended__exception(self, status):
is_account_owner=False,
)
workflow = create_test_workflow(request_user)
workflow.status = status
workflow.status = WorkflowStatus.DONE
workflow.save()
task = workflow.current_task_instance

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ def test_retrieve__revert_delayed_task__not_found(
f'/workflows/{workflow.id}/task-complete',
data={'task_id': second_task.id}
)
response3 = api_client.post(
response_revert = api_client.post(
f'/workflows/{workflow.id}/task-revert',
)
workflow.refresh_from_db()
Expand All @@ -475,7 +475,7 @@ def test_retrieve__revert_delayed_task__not_found(
# assert
assert response1.status_code == 204
assert response2.status_code == 400
assert response3.status_code == 400
assert response_revert.status_code == 400
assert response4.status_code == 404
assert current_task.id == second_task.id

Expand Down
1 change: 0 additions & 1 deletion core/pneumatic_backend/processes/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class WorkflowStatus:
(DONE, 'Workflow done'),
(DELAYED, 'Workflow delayed'),
)
END_STATUSES = {DONE}
RUNNING_STATUSES = {RUNNING, DELAYED}


Expand Down
Loading

0 comments on commit 9ba1d26

Please sign in to comment.