/
MaXGrig
/
TaskManager
Обзор
Документация
Войти
/
MaXGrig
/
TaskManager
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
task.js
226 строк
5 KB
MaXGrig
create: task.js
25 апр 2026, 15:53
Верифицирован
25 апр 2026, 15:53
cee5c0f
Код
Авторство
О чём код?
class Task { static #lastId = 0; static #PRIORITY_LABELS = { 1: "Low", 2: "Medium", 3: "High", 4: "Urgent", 5: "Critical", }; static #STATUS_LABELS = { todo: "To Do", "in-progress": "In Progress", done: "Done", }; #id; #title; #description; #status; #priority; #completedAt; constructor(title, description, status = "todo", priority = 3) { if (!title || !description) { throw new Error("Title and description are required"); } if (!["todo", "in-progress", "done"].includes(status)) { throw new Error("Invalid status"); } if (!Number.isInteger(priority) || priority < 1 || priority > 5) { throw new Error("Priority must be an integer between 1 and 5"); } Task.#lastId++; this.#id = Task.#lastId; this.#title = title; this.#description = description; this.#status = status; this.#priority = priority; this.#completedAt = status === "done" ? new Date() : null; const now = new Date(); Object.defineProperties(this, { id: { get: () => this.#id, enumerable: true, configurable: false, }, title: { get: () => this.#title, set: function (v) { if (!v) throw new Error("Title cannot be empty"); this.#title = v; this.#touch(); }, enumerable: true, configurable: false, }, description: { get: () => this.#description, set: function (v) { if (!v) throw new Error("Description cannot be empty"); this.#description = v; this.#touch(); }, enumerable: true, configurable: false, }, status: { get: () => this.#status, set: function (v) { if (!["todo", "in-progress", "done"].includes(v)) { throw new Error("Invalid status"); } this.#status = v; if (v === "done") { this.#completedAt = new Date(); } else { this.#completedAt = null; } this.#touch(); }, enumerable: true, configurable: false, }, priority: { get: () => this.#priority, set: function (v) { if (Number.isInteger(v) && v >= 1 && v <= 5) { this.#priority = v; this.#touch(); } }, enumerable: true, configurable: false, }, createdAt: { value: now, writable: false, enumerable: true, configurable: false, }, updatedAt: { value: now, writable: true, enumerable: true, configurable: false, }, completedAt: { get: () => this.#completedAt, enumerable: true, configurable: false, }, }); } getPriorityLabel() { return Task.#PRIORITY_LABELS[this.#priority]; } getStatusLabel() { return Task.#STATUS_LABELS[this.#status]; } isCompleted() { return this.#status === "done"; } toString() { return `[${this.id}] ${this.title} - ${this.getStatusLabel()} (${this.getPriorityLabel()})`; } start() { this.status = "in-progress"; } complete() { this.status = "done"; } reset() { this.status = "todo"; } updatePriority(newPriority) { this.priority = newPriority; } updateTitle(newTitle) { this.title = newTitle; } updateDescription(newDescription) { this.description = newDescription; } #touch() { this.updatedAt = new Date(); } } class TaskService { constructor() { this.tasks = []; } getTaskById(id) { return this.tasks.find(task => task.id === id); } addTask(title, description, status = 'todo', priority = 3) { const task = new Task(title, description, status, priority); this.tasks.push(task); return task; } updateTask(id, updatedData) { const task = this.getTaskById(id); if (!task) { throw new Error(`Task with id ${id} not found`); } if ('title' in updatedData) { task.title = updatedData.title; } if ('description' in updatedData) { task.description = updatedData.description; } if ('status' in updatedData) { task.status = updatedData.status; } if ('priority' in updatedData) { task.priority = updatedData.priority; } return task; } deleteTask(id) { const index = this.tasks.findIndex(task => task.id === id); if (index === -1) { throw new Error(`Task with id ${id} not found`); } this.tasks.splice(index, 1); } getStatistics() { const count = this.tasks.length; const countByStatus = { todo: 0, 'in-progress': 0, done: 0 }; let totalPriority = 0; for (const task of this.tasks) { countByStatus[task.status]++; totalPriority += task.priority; } const averagePriority = count > 0 ? parseFloat((totalPriority / count).toFixed(1)) : 0; const doneCount = countByStatus.done; const completionPercentage = count > 0 ? Math.floor((doneCount / count) * 100) : 0; return { count, countByStatus, averagePriority, completionPercentage: `${completionPercentage}%`, }; } } module.exports = { Task, TaskService };