Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(todo): enhance todo functionality and error handling #198

Merged
merged 15 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions web/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,11 +580,21 @@ def post(self, request):
req = self.request
data = req.data

subdomain_id = data.get('subdomain_id')
scan_history_id = data.get('scan_history_id')
subdomain_id = data.get('subdomain')
scan_history_id = data.get('scan_history')
title = data.get('title')
description = data.get('description')
project = data.get('project')

if not title:
return Response({"status": False, "error": "Title is required."}, status=400)
if scan_history_id is None:
return Response({"status": False, "error": "Scan history is required."}, status=400)
if subdomain_id is None:
return Response({"status": False, "error": "Subdomain is required."}, status=400)
if not project:
return Response({"status": False, "error": "Project is required."}, status=400)


try:
project = Project.objects.get(slug=project)
Expand All @@ -608,12 +618,10 @@ def post(self, request):

note.project = project
note.save()
response = {'status': True}
return Response({"status": True, "error": False, "id": note.id}, status=200)
except Exception as e:
response = {'status': False, 'message': str(e)}

return Response(response)

logger.error(e)
return Response({"status": False, "error": "An error occurred."}, status=400)

class ToggleSubdomainImportantStatus(APIView):
def post(self, request):
Expand Down
161 changes: 75 additions & 86 deletions web/recon_note/static/note/js/todo.js
AnonymousWP marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -89,47 +89,6 @@
$_targetText += ' Subdomain : ' + $_taskSubdomain;
}

$html = '<div class="todo-item all-list">'+
'<div class="todo-item-inner">'+
'<div class="n-chk text-center">'+
'<label class="new-control new-checkbox checkbox-primary">'+
'<input type="checkbox" class="form-check-input inbox-chkbox">'+
'<span class="new-control-indicator"></span>'+
'</label>'+
'</div>'+

'<div class="todo-content">'+
'<h5 class="todo-heading">'+htmlEncode($_task)+'</h5>'+
'<p class="target">'+$_targetText+'</h5>'+
"<p class='todo-text' >"+htmlEncode($_taskDescriptionText)+"</p>"+
'</div>'+

'<div class="action-dropdown custom-dropdown-icon">'+
'<div class="dropdown dropstart">'+
'<a class="dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">'+
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-more-vertical"><circle cx="12" cy="12" r="1"></circle><circle cx="12" cy="5" r="1"></circle><circle cx="12" cy="19" r="1"></circle></svg>'+
'</a>'+

'<div class="dropdown-menu">'+
'<a class="important dropdown-item" href="javascript:void(0);">Toggle Important</a>'+
'<a class="dropdown-item delete" href="javascript:void(0);">Delete</a>'+
'</div>'+
'</div>'+
'</div>'+

'</div>'+
'</div>';


$("#ct").prepend($html);
$('#addTaskModal').modal('hide');
checkCheckbox();
todoItem();
importantDropdown();
deleteDropdown();
new dynamicBadgeNotification('allList');
$(".list-actions#all-list").trigger('click');

data = {
'title': $_task,
'description': $_taskDescriptionText
Expand All @@ -154,25 +113,64 @@
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(res => res.json())
.then(res => console.log(res));
}).then(function (response) {
return response.json().then(function(data) {
swal.queue([{
title: response.status === 200 ? 'Note added successfully!' :
response.status === 400 ? 'Oops! Unable to add todo!\r\n' + data.error :
response.status === 404 ? 'Oops! Note not found!\r\n' + data.error :
'Oops! An error occurred!\r\n' + data.error,
icon: response.status === 200 ? 'success' : 'error'
}]);

if (response.status === 200) {
const newNote = {
id: data.id,
title: $_task,
description: $_taskDescriptionText,
domain_name: $_targetText,
subdomain_name: $_taskSubdomain,
is_done: false
};

let todoHTML = $('#todo-template').html();

todoHTML = todoHTML
.replace(/{task_id}/g, newNote.id)
.replace(/{title}/g, htmlEncode(newNote.title))
.replace(/{target_text}/g, newNote.domain_name ? `Domain: ${newNote.domain_name}` : '')
.replace(/{description}/g, htmlEncode(newNote.description))
.replace(/{is_done}/g, newNote.is_done ? 'todo-task-done' : '')
.replace(/{checked}/g, newNote.is_done ? 'checked' : '');

// Créer un nouvel élément avec la classe todo-item
const $newTodo = $('<div class="todo-item all-list"></div>').append(todoHTML);
Fixed Show fixed Hide fixed

$("#ct").prepend($newTodo);
$('#addTaskModal').modal('hide');
checkCheckbox();
todoItem();
importantDropdown();
deleteDropdown();
new dynamicBadgeNotification('allList');
$(".list-actions#all-list").trigger('click');
}
});
});
});

$('.tab-title .nav-pills a.nav-link').on('click', function(event) {
$(this).parents('.mail-box-container').find('.tab-title').removeClass('mail-menu-show')
$(this).parents('.mail-box-container').find('.mail-overlay').removeClass('mail-overlay-show')
})

}

function dynamicBadgeNotification( setTodoCategoryCount ) {
function dynamicBadgeNotification(setTodoCategoryCount) {
var todoCategoryCount = setTodoCategoryCount;

// Get Parents Div(s)
var get_ParentsDiv = $('.todo-item');
var get_TodoAllListParentsDiv = $('.todo-item.all-list');
var get_TodoCompletedListParentsDiv = $('.todo-item.todo-task-done');
var get_TodoImportantListParentsDiv = $('.todo-item.todo-task-important');
var get_TodoAllListParentsDiv = $('.todo-item.all-list').not('.todo-item-template'); // Ignorer le modèle
var get_TodoCompletedListParentsDiv = $('.todo-item.todo-task-done').not('.todo-item-template'); // Ignorer le modèle
var get_TodoImportantListParentsDiv = $('.todo-item.todo-task-important').not('.todo-item-template'); // Ignorer le modèle

// Get Parents Div(s) Counts
var get_TodoListElementsCount = get_TodoAllListParentsDiv.length;
Expand All @@ -184,7 +182,6 @@
var getBadgeCompletedTaskListDiv = $('#todo-task-done .todo-badge');
var getBadgeImportantTaskListDiv = $('#todo-task-important .todo-badge');


if (todoCategoryCount === 'allList') {
if (get_TodoListElementsCount === 0) {
getBadgeTodoAllListDiv.text('');
Expand Down Expand Up @@ -242,54 +239,48 @@
swal.queue([{
title: 'Are you sure you want to delete this Recon Note?',
text: "You won't be able to revert this!",
type: 'warning',
icon: 'warning',
showCancelButton: true,
confirmButtonText: 'Delete',
padding: '2em',
showLoaderOnConfirm: true,
preConfirm: function() {
return fetch('../delete_note', {
return fetch('/recon_note/delete_note', {
method: 'POST',
credentials: "same-origin",
headers: {
"X-CSRFToken": getCookie("csrftoken")
},
body: JSON.stringify({
'id': parseInt(id),
})
body: JSON.stringify({ 'id': parseInt(id) })
})
.then(function (response) {
if(!$(main_this).parents('.todo-item').hasClass('todo-task-trash')) {
var getTodoParent = $(main_this).parents('.todo-item');
var getTodoClass = getTodoParent.attr('class');

var getFirstClass = getTodoClass.split(' ')[1];
var getSecondClass = getTodoClass.split(' ')[2];
var getThirdClass = getTodoClass.split(' ')[3];

if (getFirstClass === 'all-list') {
getTodoParent.removeClass(getFirstClass);
}
if (getSecondClass === 'todo-task-done' || getSecondClass === 'todo-task-important') {
getTodoParent.removeClass(getSecondClass);
const errorMessages = {
400: 'Oops! Unable to delete todo!',
404: 'Oops! Note not found!',
200: 'Note deleted successfully!'
};

if (response.status in errorMessages) {
swal.insertQueueStep({
icon: response.status === 200 ? 'success' : 'error',
title: errorMessages[response.status]
});

if (response.status === 200) {
const getTodoParent = $(main_this).parents('.todo-item');
getTodoParent.remove();
new dynamicBadgeNotification('allList');
new dynamicBadgeNotification('completedList');
new dynamicBadgeNotification('importantList');
}
if (getThirdClass === 'todo-task-done' || getThirdClass === 'todo-task-important') {
getTodoParent.removeClass(getThirdClass);
}
$(main_this).parents('.todo-item').addClass('todo-task-trash');
} else if($(main_this).parents('.todo-item').hasClass('todo-task-trash')) {
$(main_this).parents('.todo-item').removeClass('todo-task-trash');
}
new dynamicBadgeNotification('allList');
new dynamicBadgeNotification('completedList');
new dynamicBadgeNotification('importantList');
})
.catch(function() {
swal.insertQueueStep({
type: 'error',
title: 'Oops! Unable to delete todo!'
})
})
});
});
}
}]);
});
Expand All @@ -303,16 +294,15 @@
$(this).parents('.todo-item').removeClass('todo-task-done');
}
new dynamicBadgeNotification('completedList');
fetch('../flip_todo_status', {
fetch('/recon_note/flip_todo_status', {
method: 'post',
headers: {
"X-CSRFToken": getCookie("csrftoken")
},
body: JSON.stringify({
'id': parseInt(this.id.split('_')[1]),
})
}).then(res => res.json())
.then(res => console.log(res));
}).then(res => res.json());
});
}

Expand Down Expand Up @@ -344,16 +334,15 @@
$("#important-badge-"+badge_id).empty();
}
new dynamicBadgeNotification('importantList');
fetch('../flip_important_status', {
fetch('/recon_note/flip_important_status', {
method: 'post',
headers: {
"X-CSRFToken": getCookie("csrftoken")
},
body: JSON.stringify({
'id': parseInt(this.id.split('_')[1]),
})
}).then(res => res.json())
.then(res => console.log(res));
}).then(res => res.json());
});
}

Expand Down
Loading
Loading