Skip to content

Single-page application powered by Django and Vue

AlexxSurin/task-manager

Repository files navigation

Task manager

This single-page application allows you to create and manage tasks, organize them into projects, schedule recurrences, and track upcoming items.

The backend and frontend communicate primarily via a REST API. When you interact with the app, it synchronizes your actions with a PostgreSQL database. Backend is powered by Python/Django and Django REST Framework. Frontend is powered by Vue. Routing is implemented using Vue Router. When a URL is accessed via the browser, the backend returns only the data required for the current tab, while other tabs are lazy-loaded along with their respective data. Resource collections are stored in global stores powered by Pinia. Each frontend view loads the collections it needs and performs necessary transformations, such as joins, sorting, and filtering. HTTP requests are made using Axios. The frontend is built and served using Vite and uses Vue 3 Composition API, single-file components, TypeScript and Tailwind CSS. Periodic tasks are generated using a custom Django command and Cron. Delayed tasks are handled using Celery, with Redis serving as a message broker.

Описание

Quick launch using Docker

Clone the repository:

git clone https://github.com/AlexxSurin/task-manager.git
cd task-manager

Use this command to get the project up and running completely inside Docker:

docker compose up

The app should now be available at http://127.0.0.1:8000/

Django admin: http://127.0.0.1:8000/admin/ (username: admin, password: admin)

You can change the source code right in the working directory you started the app from — Docker containers are using files from that directory. Django server will automatically reload if you change Python files, and Vite is watching the frontend files with hot reloading in the browser.

You may also want to the change the TIME_ZONE in settings.py according to your time zone for the app to use your local current time.

From now on, you can quickly stop and restart the app using the following commands:

docker compose stop
docker compose start

Dependencies are cached inside Docker, so if you alter the dependency lists, you will need to rebuild images with --build flag:

docker compose up --build

To stop all containers and remove everything created during installation (containers, images, and volumes):

docker compose down -v --remove-orphans --rmi all

Manual setup

Prerequisites

  • Python 3.10+
  • Node 22+
  • PostgreSQL 14+

Instructions

Create and activate a python virtual environment:

python -m venv .venv
source .venv/bin/activate

Install backend dependencies:

pip install -r requirements.txt

Ensure PostgreSQL is running and listening on port 5432, then open its interactive terminal:

psql -h localhost -p 5432 -U postgres

Create a new user and database for this project by running the following queries:

CREATE USER task_manager WITH PASSWORD 'password';
CREATE DATABASE task_manager;
ALTER DATABASE task_manager OWNER TO task_manager;
GRANT ALL PRIVILEGES ON DATABASE task_manager TO task_manager;

You can exit the psql terminal using \q or by typing exit.

If you used different credentials, make sure they are correctly specified in settings.py (DATABASES = ...)

Apply database migrations:

python manage.py migrate

Create an admin user to be able to access Django admin:

python manage.py createsuperuser
Username: admin
Email address: admin@example.com
Password: **********
Password (again): *********
Superuser created successfully.

Django admin should be available at http://127.0.0.1:8000/admin/ once you start the server.

You can import some demo data into the database, if you want:

psql -h localhost -U task_manager -d task_manager -f docker/demo_data.sql

Install frontend dependencies:

npm install

Start serving the frontend:

npm run serve

Start serving the backend:

python manage.py runserver 127.0.0.1:8000

The app should be available at http://127.0.0.1:8000/

Building frontend for production

Build using the following command (the files will be emitted to frontend/dist/):

npm run build

Set USE_BUILT_MEDIA = True in settings.py to test it.

Checking frontend types

npm run type-check

Checking backend types

mypy

Generating periodic tasks

Some tasks can be marked as periodic and recur on specified days of the week.

To generate new periodic tasks automatically at midnight, add the following job to Cron:

0 0 * * * /path-to-project/.venv/bin/python /path-to-project/manage.py generate_periodic_tasks

To test it manually, add periodic recurrence rules via the Django admin (http://127.0.0.1:8000/admin/todo/periodicrecurrence/add/), then change the cron job to run every minute (*/1 * * * *) or run the command manually:

python manage.py generate_periodic_tasks

...and look for the generated tasks in Django admin (http://localhost:8000/admin/todo/task/) or in the app.

Generating delayed tasks

Delayed tasks are generated precisely after the specified delay using Celery. If you mark a task as completed and it has a delayed recurrence rule, a Celery job will be added to the queue. Redis handles the task queue.

In order for such jobs to run on your machine, first install Redis and make sure it is listening on port 6379 (or edit CELERY_BROKER_URL accordingly). The easiest way to do this is using Docker:

docker run -d --name redis -p 6379:6379 redis:7.4.4-alpine

You can start and stop this container later using the following commands:

docker start redis
docker stop redis

Finally, start a Celery worker:

celery -A backend worker --loglevel=info

Since the minimum delay is 1 day, to test it quickly in a local environment, look for the generate_delayed_task.apply_async() call in the code, temporarily change countdown argument to some lower number of seconds and watch the output in the terminal session in which you started a Celery worker.

Note that if you change the code of any Celery task, you need to restart the worker for those changes to take effect.

REST API documentation

Collections

Each collection has the following API endpoint pattern:

Method Endpoint Description
GET /{api_endpoint}/ Retrieve all resources from the collection
POST /{api_endpoint}/ Create a new resource in the collection. Returns the created resource
GET /{api_endpoint}/{id}/ Retrieve a single resource by its ID
PUT /{api_endpoint}/{id}/ Replace an entire resource. Returns the replacing resource
PATCH /{api_endpoint}/{id}/ Partially update a resource. Returns the updated resource
DELETE /{api_endpoint}/{id}/ Delete a resource

'Projects' collection

API endpoint: /api/todo/projects/

DELETE request also deletes related tasks.

Field Type Access Description
id number read-only Project ID
title string writable, optional Task title. Max length: 200. Default: New project
expanded boolean writable, optional Whether the project is expanded in UI. Default: true

'Tasks' collection

API endpoint: /api/todo/tasks/

DELETE request also deletes related periodic and delayed recurrences.

Field Type Access Description
id number read-only Task ID
title string writable, optional Task title. Max length: 200. Default: New task
description string writable, optional Task description. Default: empty string
dueDate string writable, optional The due date for the task. Format: YYYY-MM-DD. Default: tomorrow
overdue boolean read-only Whether the task is overdue
priority integer writable, optional Task priority. A number from 1 (highest) to 3 (lowest). Default: 3
completed boolean writable, optional Whether the task is completed. Default: false
completedAt string read-only Date and time of completion. Returned only for completed tasks. Format: ISO 8601

'Periodic recurrences' collection

API endpoint: /api/todo/recurrences/periodic/

POST request also deletes a delayed recurrence for the task, if it has one.

Field Type Access Description
id number read-only Periodic recurrence ID
schedule number[] writable, optional Days of the week on which the task should recur. Array containing numbers in the range 0-6 representing Mon-Sun respectively. Should contain at least 1 such number. Default: [0]
task number writable, required ID of the recurring task

'Delayed recurrences' collection

API endpoint: /api/todo/recurrences/delayed/

POST request also deletes a periodic recurrence for the task, if it has one.

Field Type Access Description
id number read-only Delayed recurrence ID
delayDays number writable, optional Delay in days. Default: 1
task number writable, required ID of the recurring task

'About' view

API endpoint: GET /api/about/

Field Type Access Description
adminUrl string read-only Django admin's URL

About

Single-page application powered by Django and Vue

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published