Skip to content

Commit

Permalink
Backend support for todolists and todolist templates (#453)
Browse files Browse the repository at this point in the history
* Revert "Checklist models (#449)"

This reverts commit a9de904.

* [WIP] Create a 2-pane interface that allows you to skip a todo

* [WIP] refactored code

* [WIP] refactored code

* [WIP] refactored code

* [WIP] refactored code

* Revert "Revert "Checklist models (#449)""

This reverts commit 4352de6.

* Renamed checklistTemplate to TodoListTemplates and other changes

* Updated the migration script and fixed lint errors

* Changed the name from checklist to todolist

* Removed unused code

* added the json schema for todolist

* added the json schema for todolist

* Fixed the tests for skipped_datetime field

* Fixed the tests for skipped_datetime field

* added the json schema reference in todo serializer

* Adding jsl and jsonschema to requirement.tx

* Removed the skipped field

* Add the skipped_datetime field doc

* Fixed the todo models on_delete cascade

* Fixed the todo models on_delete cascade

* [WIP] Added a tree view for todolist

* Integrated the tree view with todo list

* Removed unused dummy response data

* Removed commented code

* Refactored the scss

* Removed empty tag

* Removed commented scss

* Removed inline HTML import for angular-ui-tree

* Changed the item template id

* Fixed the scss

* Fixed the tree view skip

* added checklist template api view and serializer

* Preventing text from wrapping around checkbox

* Removed the padding on top of skipped list

* add crud apis for todolist templates

* Added a function to transform flat array todos to nested todos

* Added the api to add checklist template to todo

* Added auth check for add todos from checklist template

* Added test for auth check for add todos from checklist template

* Fixed the lint and test errors

* Fixed the tests for todolist templates

* Added login required auth check

* Restoring old migration

* Restoring old migration

* Refactored the api decorators

* Added code to handle invalid task and todolist template

* Fixed the class name for Todos test class

* Fixed the api to add template todolist

* Fixed the css for the scenario where nested todos are mixed with individual todos on skipped pane

* Fixed the function names in directive

* Revert "Fixed the css for the scenario where nested todos are mixed with individual todos on skipped pane"

This reverts commit beb07cb.

* Revert "Fixed the function names in directive"

This reverts commit 020b767.

* Created a conditional decorator for api_endpoint
  • Loading branch information
adbharadwaj committed Jun 25, 2018
1 parent 3ff97f7 commit 36e144b
Show file tree
Hide file tree
Showing 14 changed files with 537 additions and 124 deletions.
14 changes: 14 additions & 0 deletions orchestra/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from orchestra.models import TaskAssignment
from orchestra.models import TimeEntry
from orchestra.models import Todo
from orchestra.models import TodoListTemplate
from orchestra.models import Worker
from orchestra.models import WorkerCertification
from orchestra.models import Workflow
Expand Down Expand Up @@ -185,6 +186,19 @@ class TodoAdmin(AjaxSelectAdmin):
list_filter = ('task__project__workflow_version',)


@admin.register(TodoListTemplate)
class TodoListTemplateAdmin(AjaxSelectAdmin):
form = make_ajax_form(TodoListTemplate, {
'creator': 'workers',
})
list_display = ('id', 'created_at', 'slug', 'name')
ordering = ('-created_at',)
search_fields = (
'slug', 'name', 'todos',
'description')
list_filter = ('creator__user__username',)


@admin.register(Worker)
class WorkerAdmin(AjaxSelectAdmin):
form = make_ajax_form(Worker, {
Expand Down
2 changes: 2 additions & 0 deletions orchestra/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from orchestra.models.core.models import TimeEntry
from orchestra.models.core.models import TaskTimer
from orchestra.models.core.models import Todo
from orchestra.models.core.models import TodoListTemplate
from orchestra.models.core.models import PayRate


Expand All @@ -38,5 +39,6 @@
'TimeEntry',
'TaskTimer',
'Todo',
'TodoListTemplate',
'PayRate',
]
36 changes: 0 additions & 36 deletions orchestra/project_api/decorators.py

This file was deleted.

29 changes: 23 additions & 6 deletions orchestra/project_api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@
from orchestra.models import Workflow
from orchestra.project import create_project_with_tasks
from orchestra.project_api.api import get_project_information
from orchestra.project_api.decorators import api_endpoint
from orchestra.utils.decorators import api_endpoint
from orchestra.utils.load_json import load_encoded_json
from orchestra.utils.task_lifecycle import assign_task
from orchestra.project_api.auth import OrchestraProjectAPIAuthentication
from orchestra.project_api.auth import IsSignedUser

logger = logging.getLogger(__name__)


@api_endpoint(['POST'])
@api_endpoint(methods=['POST'],
permissions=(IsSignedUser,),
logger=logger,
auths=(OrchestraProjectAPIAuthentication,))
def project_information(request):
try:
data = load_encoded_json(request.body)
Expand All @@ -31,7 +36,10 @@ def project_information(request):
raise BadRequest('No project for given id')


@api_endpoint(['POST'])
@api_endpoint(methods=['POST'],
permissions=(IsSignedUser,),
logger=logger,
auths=(OrchestraProjectAPIAuthentication,))
def create_project(request):
project_details = load_encoded_json(request.body)
try:
Expand All @@ -54,7 +62,10 @@ def create_project(request):
return {'project_id': project.id}


@api_endpoint(['POST'])
@api_endpoint(methods=['POST'],
permissions=(IsSignedUser,),
logger=logger,
auths=(OrchestraProjectAPIAuthentication,))
def project_details_url(request):
project_details = load_encoded_json(request.body)
project_id = project_details.get('project_id')
Expand All @@ -72,7 +83,10 @@ def project_details_url(request):
return {'project_details_url': url}


@api_endpoint(['GET'])
@api_endpoint(methods=['GET'],
permissions=(IsSignedUser,),
logger=logger,
auths=(OrchestraProjectAPIAuthentication,))
def workflow_types(request):
workflows = {
w.slug: {
Expand All @@ -90,7 +104,10 @@ def workflow_types(request):
return {'workflows': workflows}


@api_endpoint(['POST'])
@api_endpoint(methods=['POST'],
permissions=(IsSignedUser,),
logger=logger,
auths=(OrchestraProjectAPIAuthentication,))
def assign_worker_to_task(request):
data = load_encoded_json(request.body)
errors = {}
Expand Down
53 changes: 32 additions & 21 deletions orchestra/static/dist/main.js

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions orchestra/static/orchestra/todos/todo-list.directive.es6.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { reduce } from 'lodash'
import { reduce, defaults } from 'lodash'
import template from './todo-list.html'
import moment from 'moment-timezone'
import './todo-list.scss'
Expand Down Expand Up @@ -101,6 +101,16 @@ export default function todoList (orchestraApi) {
$scope.$apply()
}

todoList.transformToTree = (todos) => {
var nodes = {}
return todos.filter(function (obj) {
nodes[obj.id] = defaults(obj, nodes[obj.id], { items: [] })
obj.parent_todo && (nodes[obj.parent_todo] = (nodes[obj.parent_todo] || { items: [] }))['items'].push(obj)

return !obj.parent_todo
})
}

orchestraApi.projectInformation(todoList.projectId)
.then((response) => {
const humanSteps = new Set(response.data.steps.filter(step => step.is_human).map(step => step.slug))
Expand All @@ -118,7 +128,7 @@ export default function todoList (orchestraApi) {

// TODO(marcua): parallelize requests rather than chaining `then`s.
todoApi.list(todoList.projectId).then((todos) => {
todoList.todos = todos
todoList.todos = todoList.transformToTree(todos)
todoList.ready = true
})
})
Expand Down
14 changes: 14 additions & 0 deletions orchestra/tests/helpers/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,20 @@ class Meta:
model = 'orchestra.Todo'


class TodoListTemplateFactory(factory.django.DjangoModelFactory):
slug = factory.Sequence(
lambda n: 'todolist_template_{}'.format(n))
name = factory.Sequence(
lambda n: 'TodoList template {}'.format(n))
description = factory.Sequence(
lambda n: 'Description {}'.format(n))
creator = None
todos = {'items': []}

class Meta:
model = 'orchestra.TodoListTemplate'


class CommunicationPreferenceFactory(factory.django.DjangoModelFactory):

worker = factory.SubFactory(WorkerFactory)
Expand Down

0 comments on commit 36e144b

Please sign in to comment.