Backend/API service for a simple workflow automation software
pip install -r requirements.txtpython manage.py runserverThis uses the default settings in the settings.py file, but in order to use
custom settings e.g. different database user or database name, then duplicate the
settings.dev.ini file and name it settings.ini and put in your own values here.
The reason for duplicating is that, settings.ini is ignored by git so it
doesn't affect the other developer. This way we can keep different custom
non-application-dependent settings.
Sign up - Endpoint: https://workflow801.herokuapp.com/account/signup
Sample request:
{"email":"demouser@gmail.com","password":"demouser","first_name":"Demo","last_name":"User"}Sample Response:
{
"Token": "b9bf9516f1b62d625273b803f37df6c462aef43f",
"Expires_in": "86399.984865",
"User": {
"id": 2,
"first_name": "Demo",
"last_name": "User",
"email": "demouser@gmail.com",
"date_of_birth": null,
"address": null,
"state": null,
"gender": null,
"phone_number": "",
"profile_pic": null,
"createdorgs": [],
"createdgroups": [],
"userorganizations": [],
"usergroups": [],
"createdprocesses": [],
"createdstage": [],
"createdtask": [],
"userforms": [],
"userdocuments": [],
"tasks_to_user": [],
"userformresponse": []
}
}Login - Endpoint: https://workflow801.herokuapp.com/account/login
Sample request:
{"email":"demouser@gmail.com","password":"demouser"}Sample response:
{
"Token": "b9bf9516f1b62d625273b803f37df6c462aef43f",
"Expires_in": "86399.984865",
"User": {
"id": 2,
"first_name": "Demo",
"last_name": "User",
"email": "demouser@gmail.com",
"date_of_birth": null,
"address": null,
"state": null,
"gender": null,
"phone_number": "",
"profile_pic": null,
"createdorgs": [],
"createdgroups": [],
"userorganizations": [],
"usergroups": [],
"createdprocesses": [],
"createdstage": [],
"createdtask": [],
"userforms": [],
"userdocuments": [],
"tasks_to_user": [],
"userformresponse": []
}
} We are using a (modified) Django rest-framework in-built token authentication (similar to JWT). After a login or signup, you must include the authentication token in your request header like this;
{
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
} Take not of the "Token" keyword before the actual token, it must be included exactly the same way, else Django rest-framework won't acknowledge it. When a token has expired, the user will need to login in again and a refreshed token will be issued. Token lifespan is 24 hours.
View the full Schema of the application at; https://workflow801.herokuapp.com/schema
To integrate the forms into the front-end:
Firstly, you need to make the user access token which you obtain from the authentication stage
accessible for the forms to use by setting variable WORKFLOW_TOKEN to the document window.
Something like window.WORKFLOW_TOKEN = 'c3e0ed87dec308e20f32bcce63185f0940810a2a'
The whole form process doesn't really involve the frontend designer so much, you are just
required to handle end events of processes such as (form creation, form submission ...).
Remember to user full URLs when hitting the endpoints as you follow the guide.
- On the page where you intend to create the form in the front end, create an
<iframe>element wherever on the page you want the form builder to appear. For example, I created this:
<iframe src="" id="form-builder" frameborder="0" style="min-height: 600px; overflow: auto; width: 100%;"></iframe>- Send a
GETajax request to endpoint/process/formbuilder/org/<organization_id>/create/(Fill in <organization_id> with the organization this form would be created under), response type isHTML, fill in the response into theiframeyou created earlier. For example:
$.ajax({
url: "/process/formbuilder/org/1/create/", // 1 is my organization_id
headers: {"Authorization": "Token " + window.WORKFLOW_TOKEN},
success: function (response) {
$('#form-builder').attr('srcdoc', response)
}
});- At this point, the form builder should be visible on the page already. When the admin finishes constructing the form as required
and clicks on SAVE, an event is triggered from the formbuilder which might be needed on the frontend, maybe to navigate to another
page. Event name
workflow-form-savedwhen save succeeds anduser-submitted-workflow-form-failurewhen save fails. To handle this event, we use the regular iframe communication mechanism. In case you need some data here from what is going on in the iframe, you can access data returned from the server through thedetailattribute of the event. Sample below:
window.document.addEventListener('workflow-form-saved', function (e) {
// Your code would go in here, and to access data sent, just do 'e.detail'
}, false)
// and if it fails
window.document.addEventListener('user-submitted-workflow-form-failure', function (e) {
// Your code would go in here, and to access data sent, just do 'e.detail'
}, false)- If you also wish to update the form built, you can go through the similar process and retrieve the html code from
/process/formbuilder/org/<organization_id>/view/<form_id>/and slot the response into an iframe. Sample code:
$.ajax({
url: "/process/formbuilder/org/1/update/15/", // 1 is the organization_id and 15 is the form_id I wish to update
headers: {"Authorization": "Token " + window.WORKFLOW_TOKEN},
success: function (response) {
$('#form-builder').attr('srcdoc', response) // form-builder is the id of the iframe we are using
}
});Same thing also goes here, an event is triggered from the iframe which you can handle on the outdie using the sample initally stated.
- Lastly, on the user end, when the user needs to fill the form, there's only one endpoint you need to hit in this case,
since a user can fill a form only once, if eventually the frontend permits them to comeback to it, they'd only be updating the previous
data as form would be prepopulated with their data. End point is
/process/formbuilder/org/<organization_id>/view/<form_id>/Sample code:
$.ajax({
url: "/process/formbuilder/org/1/view/15/", // 1 is the organization_id and 15 is the form_id I wish to update
headers: {"Authorization": "Token " + window.WORKFLOW_TOKEN},
success: function (response) {
$('#form-builder-render').attr('srcdoc', response) // form-builder-render is the id of the iframe we are using
}
});Event emitted by this action, (when the user submits the form) is user-submitted-workflow-form when submission succeeds
and user-submitted-workflow-form-failure when it fails. So you might be able to handle
this event with.
window.document.addEventListener('user-submitted-workflow-form', function (e) {
// Your code would go in here, and to access data sent, just do 'e.detail'
}, false)
// In case of failure
window.document.addEventListener('user-submitted-workflow-form-failure', function (e) {
// Your code would go in here, and to access data sent, just do 'e.detail'
}, false)After the user must have filled the forms, we would want to retrieve these data. This is possible through endpoint:
/process/formbuilder/org/<organization_id>/view/<form_id>/responses/.
And this endpoint would return data like this.
[
{
"id": 5,
"created_date": "2019-08-07T20:03:12.509302Z",
"modified_date": "2019-08-07T21:46:00.409645Z",
"response": {
"First Name": [
"Something"
],
"Last Name": [
"Name"
],
"Other": [
"Hello"
],
"Checkbox Group": [
"Option 1",
"Option 2"
]
},
"user": 1,
"form": 15
}
]If there is a need to export the database on the remote server to use on development machine, we can reach
https://sitename.com/utility/db-export/Understood that this may be a security risk, so it's going to be available only in
development mode i.e. when DEBUG=True in settings.
👤 Python Group CSC 801
Contributions, issues and feature requests are welcome!
Feel free to check issues page.
Give a ⭐️ if this project helped you!
This README was generated with ❤️ by readme-md-generator