docs: add JSDoc comments to AddTaskComponent

This commit is contained in:
Chneemann 2024-11-11 18:51:12 +01:00
parent 928e5a0cf5
commit 7e32e16cdf
2 changed files with 195 additions and 2 deletions

View file

@ -61,12 +61,25 @@ export class AddTaskComponent implements OnInit {
date: this.currentDate, date: this.currentDate,
}; };
/**
* Lifecycle hook that is called after data-bound properties of a directive are initialized.
* This method performs the following actions:
* - Loads task data for editing if applicable.
* - Sets up route parameters to determine task status.
* - Loads any existing task data from local storage.
*/
ngOnInit() { ngOnInit() {
this.loadEditTaskData(); this.loadEditTaskData();
this.routeParams(); this.routeParams();
this.loadLocalStorageData(); this.loadLocalStorageData();
} }
/**
* Loads task data for editing if applicable, or sets the task status if this is a new task overlay.
* @param {string} overlayData The task id or status of the task to be loaded.
* @param {string} overlayType The type of overlay to be opened.
* @returns {void}
*/
loadEditTaskData() { loadEditTaskData() {
const excludedValues = ['', 'todo', 'inprogress', 'awaitfeedback', 'done']; const excludedValues = ['', 'todo', 'inprogress', 'awaitfeedback', 'done'];
if (!excludedValues.includes(this.overlayData)) { if (!excludedValues.includes(this.overlayData)) {
@ -77,6 +90,13 @@ export class AddTaskComponent implements OnInit {
} }
} }
/**
* Lifecycle hook that is called after data-bound properties of a directive are initialized.
* This method performs the following actions:
* - Subscribes to route parameters to determine task status.
* - Updates the task status if a route parameter is present.
* @returns {void}
*/
routeParams() { routeParams() {
if (this.route.params.subscribe()) { if (this.route.params.subscribe()) {
this.route.params.subscribe((params) => { this.route.params.subscribe((params) => {
@ -87,6 +107,11 @@ export class AddTaskComponent implements OnInit {
} }
} }
/**
* Loads any existing task data from local storage and assigns it to the taskData object.
* If no task data is present in local storage, this method saves the current taskData object to local storage.
* @returns {void}
*/
loadLocalStorageData() { loadLocalStorageData() {
const storedTaskData = localStorage.getItem('taskData'); const storedTaskData = localStorage.getItem('taskData');
if (storedTaskData) { if (storedTaskData) {
@ -96,32 +121,57 @@ export class AddTaskComponent implements OnInit {
} }
} }
/**
* Opens the user dialog for the given user id at the position of the mouse click
* @param userId the id of the user
* @param event the MouseEvent that triggered the dialog
*/
openDialog(userId: any, event: MouseEvent) { openDialog(userId: any, event: MouseEvent) {
this.AssignedDialogId = userId; this.AssignedDialogId = userId;
this.updateDialogPosition(event); this.updateDialogPosition(event);
} }
/**
* Updates the position of the user dialog based on the MouseEvent
* @param event the MouseEvent that triggered the dialog
*/
updateDialogPosition(event: MouseEvent) { updateDialogPosition(event: MouseEvent) {
this.dialogX = event.clientX + 25; this.dialogX = event.clientX + 25;
this.dialogY = event.clientY + 10; this.dialogY = event.clientY + 10;
} }
/**
* Closes the assigned user dialog
*/
closeDialog() { closeDialog() {
this.AssignedDialogId = ''; this.AssignedDialogId = '';
} }
/**
* Gets the task data from the Firebase service for the given task id.
* @param taskId the id of the task
* @returns {Task[]} an array of tasks with the given id
*/
getTaskData(taskId: string) { getTaskData(taskId: string) {
return this.firebaseService return this.firebaseService
.getAllTasks() .getAllTasks()
.filter((task) => task.id === taskId); .filter((task) => task.id === taskId);
} }
/**
* Adds a new subtask to the task data
* @param subtaskName the name of the new subtask
*/
addSubtask(subtaskName: string) { addSubtask(subtaskName: string) {
this.taskData.subtasksTitle.unshift(subtaskName); this.taskData.subtasksTitle.unshift(subtaskName);
this.taskData.subtasksDone.push(false); this.taskData.subtasksDone.push(false);
this.saveTaskData(); this.saveTaskData();
} }
/**
* Deletes a subtask from the task data.
* @param subtaskName the name of the subtask to delete
*/
deleteSubtask(subtaskName: string) { deleteSubtask(subtaskName: string) {
const index = this.taskData.subtasksTitle.indexOf(subtaskName); const index = this.taskData.subtasksTitle.indexOf(subtaskName);
if (index !== -1) { if (index !== -1) {
@ -131,6 +181,11 @@ export class AddTaskComponent implements OnInit {
} }
} }
/**
* Updates the filteredUsers array with users that match the current search value
* from the getFilteredUsers list.
* @param taskCreator the id of the task creator
*/
searchTask(taskCreator: string): void { searchTask(taskCreator: string): void {
this.updateSearchInput(); this.updateSearchInput();
this.filteredUsers = this.firebaseService this.filteredUsers = this.firebaseService
@ -143,6 +198,13 @@ export class AddTaskComponent implements OnInit {
); );
} }
/**
* Updates the search input flag and the search value by stripping any XSS
* characters from the search value, and then setting the search input flag
* to true if the search value is not empty, and false otherwise.
*
* @returns The updated search input flag.
*/
updateSearchInput() { updateSearchInput() {
this.searchValue = this.sharedService.replaceXSSChars(this.searchValue); this.searchValue = this.sharedService.replaceXSSChars(this.searchValue);
if (this.searchValue) { if (this.searchValue) {
@ -153,18 +215,39 @@ export class AddTaskComponent implements OnInit {
return this.searchInput; return this.searchInput;
} }
/**
* Updates the subtask value by removing any potential XSS characters.
* This ensures that the subtask value is sanitized before further processing or storage.
*/
updateSubtaskValue() { updateSubtaskValue() {
this.subtaskValue = this.sharedService.replaceXSSChars(this.subtaskValue); this.subtaskValue = this.sharedService.replaceXSSChars(this.subtaskValue);
} }
/**
* Updates the taskData object with the given assigned users.
* @param assigned an array of user ids
* @returns {void}
*/
receiveAssigned(assigned: string[]) { receiveAssigned(assigned: string[]) {
this.taskData.assigned = assigned; this.taskData.assigned = assigned;
} }
/**
* Toggle the assigned menu for the current task.
* This function toggles the boolean flag isAssignedOpen, which determines whether the assigned menu is open or not.
* @returns {void}
*/
toggleAssignedMenu() { toggleAssignedMenu() {
this.isAssignedOpen = !this.isAssignedOpen; this.isAssignedOpen = !this.isAssignedOpen;
} }
/**
* Checks if the selected date is in the past.
*
* This function compares the date selected in the taskData with the current date.
* If the selected date is earlier than the current date, it sets the dateInPast flag to true,
* otherwise it sets the flag to false.
*/
checkDateInput() { checkDateInput() {
const currentDateForm = this.taskData.date.replaceAll('-', ''); const currentDateForm = this.taskData.date.replaceAll('-', '');
const currentDate = new Date() const currentDate = new Date()
@ -176,6 +259,13 @@ export class AddTaskComponent implements OnInit {
: (this.dateInPast = false); : (this.dateInPast = false);
} }
/**
* Toggles the priority of the task between the given priority and the current priority.
* If the given priority is different from the current priority, it sets the priority to the given priority,
* otherwise it keeps the current priority.
* After setting the priority, it saves the task data.
* @param priority the priority to toggle to
*/
togglePriority(priority: string) { togglePriority(priority: string) {
this.taskData.priority !== priority this.taskData.priority !== priority
? (this.taskData.priority = priority) ? (this.taskData.priority = priority)
@ -183,27 +273,56 @@ export class AddTaskComponent implements OnInit {
this.saveTaskData(); this.saveTaskData();
} }
/**
* Saves the current task data to local storage.
*
* This function first runs the cross site scripting check on the task data,
* then saves the task data to local storage.
* @returns {void}
*/
saveTaskData() { saveTaskData() {
this.checkCrossSiteScripting(); this.checkCrossSiteScripting();
localStorage.setItem('taskData', JSON.stringify(this.taskData)); localStorage.setItem('taskData', JSON.stringify(this.taskData));
} }
/**
* Removes the task data from local storage and resets the form and form data.
* @param form the form to reset
* @returns {void}
*/
removeTaskData(form: NgForm) { removeTaskData(form: NgForm) {
localStorage.removeItem('taskData'); localStorage.removeItem('taskData');
this.clearForm(form); this.clearForm(form);
this.clearFormData(); this.clearFormData();
} }
/**
* Closes the overlay and resets the overlay data.
*
* @returns {void}
*/
closeOverlay() { closeOverlay() {
this.overlayService.setOverlayData('', ''); this.overlayService.setOverlayData('', '');
} }
/**
* Resets the title, description, and category form controls to their pristine state.
*
* @param form the form containing the controls to reset
* @returns {void}
*/
clearForm(form: NgForm) { clearForm(form: NgForm) {
form.controls['title'].reset(); form.controls['title'].reset();
form.controls['description'].reset(); form.controls['description'].reset();
form.controls['category'].reset(); form.controls['category'].reset();
} }
/**
* Resets the task data to its initial state.
*
* This method sets the task date to the current date and clears the category,
* assigned users, subtask titles, and subtask completion states.
*/
clearFormData() { clearFormData() {
this.taskData.date = this.currentDate; this.taskData.date = this.currentDate;
this.taskData.category = ''; this.taskData.category = '';
@ -212,6 +331,15 @@ export class AddTaskComponent implements OnInit {
this.taskData.subtasksDone = []; this.taskData.subtasksDone = [];
} }
/**
* Handles the enter key press event in the subtask input field.
*
* If the enter key is pressed while the subtask input field is focused,
* this function adds the subtask title to the task data and resets
* the value of the input field.
* @param event the keyboard event
* @returns {void}
*/
handleEnterKey(event: Event) { handleEnterKey(event: Event) {
event.preventDefault(); event.preventDefault();
if (event instanceof KeyboardEvent) { if (event instanceof KeyboardEvent) {
@ -226,6 +354,20 @@ export class AddTaskComponent implements OnInit {
} }
} }
/**
* Submits the task form and saves the task data to the Firebase Realtime Database.
*
* If the form is valid and the overlay data is one of the allowed values, this
* function adds a new task to the 'tasks' node in the Firebase Realtime Database.
* If the overlay data is not one of the allowed values, this function updates the
* task with the given overlay data in the 'tasks' node.
*
* After submitting the form, this function resets the form and closes the overlay.
* It then navigates to the '/board' route.
* @param ngForm the form to submit
* @param overlayData the overlay data corresponding to the task to be submitted
* @returns {void}
*/
onSubmit(ngForm: NgForm, overlayData: string) { onSubmit(ngForm: NgForm, overlayData: string) {
const allowedValues = [ const allowedValues = [
'', '',
@ -252,6 +394,11 @@ export class AddTaskComponent implements OnInit {
} }
} }
/**
* Sanitizes the task data by removing any potential cross-site scripting characters.
* This ensures that the task data is safe to be stored in the Firebase Realtime Database.
* @returns {void}
*/
checkCrossSiteScripting() { checkCrossSiteScripting() {
this.taskData.title = this.sharedService.replaceXSSChars( this.taskData.title = this.sharedService.replaceXSSChars(
this.taskData.title this.taskData.title
@ -264,12 +411,23 @@ export class AddTaskComponent implements OnInit {
); );
} }
/**
* Deletes the task with the given overlay data from the Firebase Realtime Database and closes the overlay.
* @param overlayData the overlay data of the task to be deleted
* @returns {void}
*/
deleteTaskData(overlayData: string) { deleteTaskData(overlayData: string) {
this.firebaseService.deleteTask(overlayData); this.firebaseService.deleteTask(overlayData);
this.closeOverlay(); this.closeOverlay();
} }
@HostListener('document:click', ['$event']) @HostListener('document:click', ['$event'])
/**
* Closes the assigned dropdown menu if the user clicks anywhere outside of
* the assigned dropdown menu.
* @param event the MouseEvent
* @returns {void}
*/
checkOpenNavbar(event: MouseEvent) { checkOpenNavbar(event: MouseEvent) {
const targetElement = event.target as HTMLElement; const targetElement = event.target as HTMLElement;
if ( if (

View file

@ -2,12 +2,11 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FirebaseService } from '../../../services/firebase.service'; import { FirebaseService } from '../../../services/firebase.service';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { User } from '../../../interfaces/user.interface'; import { User } from '../../../interfaces/user.interface';
import { AddTaskComponent } from '../add-task.component';
@Component({ @Component({
selector: 'app-assigned', selector: 'app-assigned',
standalone: true, standalone: true,
imports: [CommonModule, AddTaskComponent], imports: [CommonModule],
templateUrl: './assigned.component.html', templateUrl: './assigned.component.html',
styleUrl: './assigned.component.scss', styleUrl: './assigned.component.scss',
}) })
@ -23,10 +22,24 @@ export class AssignedComponent {
this.loadTaskAssignedData(); this.loadTaskAssignedData();
} }
/**
* Updates the assignedChange event emitter with the current list of assigned users.
* This should be called whenever the assigned list is updated.
*/
updateAssigned() { updateAssigned() {
this.assignedChange.emit(this.assigned); this.assignedChange.emit(this.assigned);
} }
/**
* Toggles the assignment of a user to the task.
*
* If the user is not currently assigned, they are added to the assigned list.
* If the user is already assigned, they are removed from the list.
* Updates the local storage with the current list of assigned users and emits the
* assignedChange event to notify other components of the update.
*
* @param userId The ID of the user to be added or removed from the assigned list.
*/
addAssignedToTask(userId: string) { addAssignedToTask(userId: string) {
if (!this.assigned.includes(userId)) { if (!this.assigned.includes(userId)) {
this.assigned.push(userId); this.assigned.push(userId);
@ -37,6 +50,13 @@ export class AssignedComponent {
this.updateAssigned(); this.updateAssigned();
} }
/**
* Saves the current list of assigned users to local storage.
*
* Retrieves the current task data from local storage, updates the assigned
* list with the current list of assigned users, and saves the updated task
* data back to local storage.
*/
saveTaskData() { saveTaskData() {
let taskDataString = localStorage.getItem('taskData'); let taskDataString = localStorage.getItem('taskData');
if (taskDataString !== null) { if (taskDataString !== null) {
@ -46,6 +66,12 @@ export class AssignedComponent {
} }
} }
/**
* Loads the list of assigned users from local storage.
*
* Retrieves the task data from local storage, checks if the assigned list exists,
* and if so, assigns the list to the local assigned variable.
*/
loadTaskAssignedData() { loadTaskAssignedData() {
const taskDataString = localStorage.getItem('taskData'); const taskDataString = localStorage.getItem('taskData');
if (taskDataString !== null) { if (taskDataString !== null) {
@ -56,6 +82,15 @@ export class AssignedComponent {
} }
} }
/**
* Returns the list of users that should be displayed in the assigned component.
*
* If the search input is active (i.e., the user is typing in the search box),
* the list of filtered users is returned. Otherwise, the list of users that are
* not the task creator is returned.
*
* @return The list of users to be displayed in the assigned component.
*/
displayAssigned() { displayAssigned() {
if (this.searchInput) { if (this.searchInput) {
return this.filteredUsers; return this.filteredUsers;