Taskup helps to manage tasks of your projects.
This is a university project for teaching object-oriented programming at UniMoRe university (a.y. 2022/2023).
- Taskup
- Documentation for Users
- Documentation for Developers
To start this app all required dependencies have to be installed.
To run this project are required the followings dependencies:
- Python 3.10+
- Eel v0.15.x (Python module to create GUI)
- Colorama (Python module for Logger)
- GitPython (Python module to manage Git)
- Chromium based software (as Google Chrome or Firefox)
Below are the commands to install the required dependencies:
# before you must install Python
pip install eel
pip install colorama
pip install GitPython
# then...
python main.py run
In addiction, you can re-build frontend installing Nodejs
and Angular CLI
. This is helpful if you pull updates using Git
instead of releases.
After dependencies installation, this app can be opened using main.py
.
main.py
accepts some parameters based on execution modality.
If desired, you can create a working executable all-in-one by downloading PyInstaller and running the following command: python3 -m eel main.py frontend/ --onefile
.
run
,r
: launch the applicationdemo
,d
[-flag1 -flag2 ...] <path>
: launch application with a demo database in path specified, path has to be the last parameter-f
: force erase if there is already a database-o
: open app at end-v
: verbose
init
,i
[-flag1 -flag2 ...] <path>
: initialize this app in users projects-f
: force re-initialization-o
: open app at end
help
,h
: print helpversion
,v
: print version
It is possible to manage application settings using settings.json
, this file has to be created in root directory (same level of main.py
).
Inserting custom settings in it, they override base default settings (managed by SettingsManager
).
The settings available are:
vault_path
, a string that contains the path of directory in which will be saved the file which stores user's credentialscurrent_project_path
, a string which contains the project path which will be loaded at the beginningprojects_stored_paths
, a list of strings which contains the paths of already opened projectsuse_localtime
, boolean value which indicates if database must use localtimedebug
, boolean value (default false) which indicates if the app must run in debug mode (i.e. use 4200 port for front-end)frontend
, a string which represents path of front-end directoryfrontend_start
, a string which represents the entry point of front-endfrontend_debug_port
, an integer value which represents the port of frontend in debug modeport
, an integer value which represents the port of Eel's webserververbose
, a boolean value to make verbose the appprojects_paths_stored
, a list of strings that contains all project paths already openedapp_mode
, a string which represents the open modalitychrome
to open app in a stand-alone pagechrome-app
to open app in Chrome browseredge
to open app in Edge browser
Everyone can contribute to this project.
Contributing is possible via pull request. You can develop something present in the TODO file or new feature from scratch.
The only constraints for the approval of a pull request are the presence of docstrings
in each method and a clean syntax, so that the project remains maintainable over time.
This documentation is written for the app's users. This app is a tasks manager for small and big projects, in particular for software projects. From now, we will call the project to manage MyProject.
By default, the users have one role between the following roles:
- Project Manager, usually an only user who manages MyProject
- Supervisor, users named by the PM to manage MyProject
- Teammate, simple teammates
- Base, usually guest users of same company, and they don't develop continuously MyProject
- External, role for external users of company
Each role has a list of different permissions where PM has all permissions, while Externals doesn't have any permissions. The PM is the user who has created MyProject, he is able to create other users and manages them, Task options and so on.
Roles can be modified in a second moment if the user has specific permission.
The Dashboard is the application core. It is used to manage tasks. Based on user's permission, the logged user is able to see all tasks or only assigned tasks. Dashboard is divided in a different section for each task status. For example To-do state, Doing state, Done state and so on. Dashboard has a sticky header used to keep in mind: the current task status visualized and the number of tasks for current status. It also has two buttons to go in the default next and prev status. For example, doing status may have to-do as previously status and done as next status. In addition, other functionality are showed using the button in top-right side.
In the dashboard, each task has its own card which shows all task's information.
Task can be refreshing using the button on the right side.
Each section can be ordered by priority or deadline (ascending or descending) using specific button.
Each task has a priority value which indicates the priority of task. The priority increases with the corresponding numerical value. This value is shown in the badge on left of task name.
The More details section is a collapsible section which is used to show secondary information of the task as the author, creation date, identifier task code and so on.
Labels are a fast visible identifiers. Usually, they are used to group tasks of common work areas, for example the Front-end labels is assigned to all tasks that describe a task to do for front-end of MyProject. The task's labels are shown in top of the task's card. Using "+" button at the end of labels list it is possible to add a new label. Clicking on a label it is possible remove that label.
Creating a new task is simple, clicking on FAB button on bottom-right a modal will be showed. It is used to insert name, description and priority of the new task. Checking the checkbox it is possible to assign yourself to the task.
Each logged user is able to manage his own profile using My Profile page. It can be accessed through dropdown menu on the header avatar:
From My Profile page is possible to edit user master data (name, surname, username, email and so on), avatar color and the password.
Passwords must contain at least 8 characters, an uppercase letter, a lowercase letter and a number.
WARNING: when a user edits email or password, he will be logged out.
With the appropriate permissions, a user, as a project manager (PM), is able to manage task status, task labels, users, and roles.
There are the corresponding pages to manage each of these items. Each page is shown only if the corresponding permission is satisfied. The user interface (UI) is the same for all pages. From these pages, it is possible to:
- Create a new resource
- Edit resources
- Delete resources
For example, the Manage Task Label page looks like this:
In addition, if there are a lot of resources, it is possible to use filters.
Home page provides a set of sections where is possible:
- Watch project information
- Initialize new project
- Open projects
In this section, it is possible to see the project's path, its app's database, and if the logged-in user has the specific permission, this app can be removed from the project.
In this section is possible to initialize a project.
To initialize a project, it is necessary to indicate the project's path and provide basic information about the project's project manager who oversees the project.
WARNING: Avoid to lose project manager's password, because the nature of this application makes it impossible to recover password without previously login.
If the indicated project is already initialized, checking force initialize is possible to re-initialize project.
Open project is possible in two-way:
- Manually entering the path
- Selecting the path from a set of already opened projects
This is a basic and simple documentation to illustrate this project to both old and new developers. For the complete documentation, please refer to the Sphinx documentation.
To run Sphinx doc:
- Navigate to the
/doc
directory - Run
sphinx-apidoc -o source/ ..
orsphinx-apidoc -o source/ ../lib
to refresh only lib packages - Run
make html
- Go in
doc/build/html
- Base Directory: Refers to the project directory path
- Project Directory: Refers to the path of the managed project
- Work Directory: Refers to the work directory inside the project directory
AppManager is the class which provides methods to manage this app.
In particular, AppManager has a set of services, which are classes that provide specific functionality.
For example AuthService
provides authentication system.
AppManager has only one service reference for each type to avoid duplications when exposed by the Eel library. Therefore, the services need to be refreshed instead of re-instantiated.
ProjectManager manage the projects, usually only one project at time. It allows initializing a new project or opening an existing project.
AuthService provides authentication system.
It also manages vault (vault.json
), where "remember me" user credentials are stored.
This project uses the Eel library to send data between the client (frontend) and the server (Python). Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.
Eel hosts a local web server and allows functions in Python to be called from JavaScript, and vice versa.
The App class in app.py
implements __init__
and start
methods to load and start Eel. It takes the configuration files
from settings.json
using the Settings class.
In the __init__
method, it uses the Exposer class to expose all methods for frontend.
The Exposer class is responsible for exposing methods using the "expose" methods of Eel. Specifically,
Eel provides two methods to expose a function (other than @expose
decorator):
expose()
, which exposes a method (and function) as it is_expose()
, which is a protected method of Eel library. It exposes a method or function with an alias. This is particularly important because the entity managers have methods with the same names for creating, reading, updating, and other operations on entities. Each manager has its own prefix. For example, the UsersManager has the prefix "user_". For more information on how to set an alias in Eel, refer to here.
The Eel's webserver implements a Web Socket for data transmission.
It is hosted on port 8000 (as specified in app.py
), so in development mode, the frontend needs to be hosted on a different port, such as port 4200.
Refer to here for more information.
Since the webserver is implemented with WebSocket, only one data transfer can occur at a time.
The DBManager class is used to establish a connection with the database. It also provides functionality to create the basic structure of the database, including tables and relationships between them.
The BEM class serves as the base class for entity models. It implements several common and useful methods.
The EntitiesManager class serves as the base class for entity managers. These managers are responsible for managing entities, such as finding, creating, and deleting them.
The entities (User, Task, TaskLabel, etc.) are classes used to manage individual entities in the database. Each entity manager has shared base methods as well as specific methods. For example, the TaskManager and TaskLabelManager have an add_label
method to add a label to a specific task.
The QueryBuilder is a custom query builder based on Python sqlite3
module. It provides utilities for constructing queries using Python code instead of raw SQL. It also supports binding values using the enable_binding
method.
During the creation of tables (using the Table
component from the db module, which accepts a list of Field objects, as well as other parameters such as FKConstraint
and Trigger
), a set of triggers is configured.
These triggers are used to update the updated_at
field of the task table whenever a component linked to a task is modified.
There are three triggers (on update, on create, and on delete) for the following tables: todo_item
, pivot_assignment
, and pivot_labels
. However, for the task table, there is only an on update trigger, as it is unnecessary to update the field when a task is created or deleted.
The frontend of this application is built using the Angular framework. Angular is a TypeScript-based, free and open-source web application framework led by the Angular Team at Google and a community of developers and organizations. The frontend is structured as follows:
- page: This directory contains the final pages of the application, such as the login page and home page
- widget: This directory contains simple widgets that are shared between pages, such as a user avatar
- service: This directory contains services that are used to implement shared methods and handle communication with the backend
- model: This directory contains interfaces for objects that represent entity data to be displayed
- directive: This directory contains custom Angular directives
In Angular, services are used to manage connections with the backend and provide additional functionality to the application.
To communicate with the Eel backend, an EelService
was implemented. It utilizes a globally declared variable eel
to provide the call
method, which is used to invoke Python-exposed methods.
The EntityApiService
is a service used to share common methods among entity services.
It utilizes a generic type that represents the specific entity model, allowing it to be used in various methods. Each method returns a Promise of Observable,
where the observable is connected to the backend's WebSocket. To invoke specific methods of entity services, this class utilizes readonly abstract variables, which are overridden by each child service.
For example, the find
method retrieves the data of an entity by its ID.
export abstract class EntityApiService<T> {
readonly abstract ALL: string;
constructor(public eelService: EelService) { }
public async find(id: number): Promise<Observable<T>> {
return this.eelService.call(this.FIND, id);
}
}
Using, for example, TaskService:
this.taskService.find(id).then((respose) => {
respose.subscribe({
next: (task: TaskModel) => {
// ...
}
})
})
In addition, the entities services as TaskService
or UserService
have other specific methods.
For example, TaskService
has addAssignment
method:
public async addAssignment(taskId: number, userId: number): Promise<Observable<boolean>> {
return this.eelService.call(this.ADD_ASSIGNMENT, taskId, userId);
}
The task visualization is made using a set of widgets:
- TaskPreview: This is the main component that represents a card displaying all the information about a task, such as the title, description, and more
- TaskPreviewList: This component is used to display a list of tasks by rendering multiple instances of the TaskPreview component
- TaskTodo and TaskTodoList: These components are used to show the list of todo items associated with each task. The TaskTodo component represents an individual todo item, while the TaskTodoList component displays a list of todo items for a specific task.
- Run Angular frontend with
ng serve
using 4200 port (the default port) - Set Eel using whatever directory, but using
{ 'port': 4200 }
as start file! - Set another port (i.e. 8000) in Eel
.start(...)
- Run Eel python script
import eel
class MyClass:
def my_method(self):
pass
my_class = MyClass()
eel._expose("other_name", my_class.my_method)
Watch out "_" in _expose(...)
, it is different from expose(...)
- Bootstrap framework
- Bootstrap icon
- Eel library
- Sqlite3 library
- Colorama library
- Mazer template