Add task progress tracking methods and enhance UI components
- Introduced a comprehensive guide for users on task progress tracking methods, including manual, weighted, and time-based progress. - Implemented backend support for progress calculations, including SQL functions and migrations to accommodate new progress features. - Enhanced frontend components to support progress input and display, including updates to task and project drawers. - Added localization for new progress-related terms and validation messages. - Integrated real-time updates for task progress and weight changes through socket events.
This commit is contained in:
@@ -515,6 +515,142 @@ BEGIN
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.get_task_form_view_model(_user_id UUID, _team_id UUID, _task_id UUID, _project_id UUID) RETURNS JSON
|
||||
LANGUAGE plpgsql
|
||||
AS
|
||||
$$
|
||||
DECLARE
|
||||
_task JSON;
|
||||
_priorities JSON;
|
||||
_projects JSON;
|
||||
_statuses JSON;
|
||||
_team_members JSON;
|
||||
_assignees JSON;
|
||||
_phases JSON;
|
||||
BEGIN
|
||||
|
||||
-- Select task info
|
||||
SELECT COALESCE(ROW_TO_JSON(rec), '{}'::JSON)
|
||||
INTO _task
|
||||
FROM (WITH RECURSIVE task_hierarchy AS (
|
||||
-- Base case: Start with the given task
|
||||
SELECT id,
|
||||
parent_task_id,
|
||||
0 AS level
|
||||
FROM tasks
|
||||
WHERE id = _task_id
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- Recursive case: Traverse up to parent tasks
|
||||
SELECT t.id,
|
||||
t.parent_task_id,
|
||||
th.level + 1 AS level
|
||||
FROM tasks t
|
||||
INNER JOIN task_hierarchy th ON t.id = th.parent_task_id
|
||||
WHERE th.parent_task_id IS NOT NULL)
|
||||
SELECT id,
|
||||
name,
|
||||
description,
|
||||
start_date,
|
||||
end_date,
|
||||
done,
|
||||
total_minutes,
|
||||
priority_id,
|
||||
project_id,
|
||||
created_at,
|
||||
updated_at,
|
||||
status_id,
|
||||
parent_task_id,
|
||||
sort_order,
|
||||
(SELECT phase_id FROM task_phase WHERE task_id = tasks.id) AS phase_id,
|
||||
CONCAT((SELECT key FROM projects WHERE id = tasks.project_id), '-', task_no) AS task_key,
|
||||
(SELECT start_time
|
||||
FROM task_timers
|
||||
WHERE task_id = tasks.id
|
||||
AND user_id = _user_id) AS timer_start_time,
|
||||
parent_task_id IS NOT NULL AS is_sub_task,
|
||||
(SELECT COUNT('*')
|
||||
FROM tasks
|
||||
WHERE parent_task_id = tasks.id
|
||||
AND archived IS FALSE) AS sub_tasks_count,
|
||||
(SELECT COUNT(*)
|
||||
FROM tasks_with_status_view tt
|
||||
WHERE (tt.parent_task_id = tasks.id OR tt.task_id = tasks.id)
|
||||
AND tt.is_done IS TRUE)
|
||||
AS completed_count,
|
||||
(SELECT COUNT(*) FROM task_attachments WHERE task_id = tasks.id) AS attachments_count,
|
||||
(SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(r))), '[]'::JSON)
|
||||
FROM (SELECT task_labels.label_id AS id,
|
||||
(SELECT name FROM team_labels WHERE id = task_labels.label_id),
|
||||
(SELECT color_code FROM team_labels WHERE id = task_labels.label_id)
|
||||
FROM task_labels
|
||||
WHERE task_id = tasks.id
|
||||
ORDER BY name) r) AS labels,
|
||||
(SELECT color_code
|
||||
FROM sys_task_status_categories
|
||||
WHERE id = (SELECT category_id FROM task_statuses WHERE id = tasks.status_id)) AS status_color,
|
||||
(SELECT COUNT(*) FROM tasks WHERE parent_task_id = _task_id) AS sub_tasks_count,
|
||||
(SELECT name FROM users WHERE id = tasks.reporter_id) AS reporter,
|
||||
(SELECT get_task_assignees(tasks.id)) AS assignees,
|
||||
(SELECT id FROM team_members WHERE user_id = _user_id AND team_id = _team_id) AS team_member_id,
|
||||
billable,
|
||||
schedule_id,
|
||||
progress_value,
|
||||
weight,
|
||||
(SELECT MAX(level) FROM task_hierarchy) AS task_level
|
||||
FROM tasks
|
||||
WHERE id = _task_id) rec;
|
||||
|
||||
SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
|
||||
INTO _priorities
|
||||
FROM (SELECT id, name FROM task_priorities ORDER BY value) rec;
|
||||
|
||||
SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
|
||||
INTO _phases
|
||||
FROM (SELECT id, name FROM project_phases WHERE project_id = _project_id ORDER BY name) rec;
|
||||
|
||||
SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
|
||||
INTO _projects
|
||||
FROM (SELECT id, name
|
||||
FROM projects
|
||||
WHERE team_id = _team_id
|
||||
AND (CASE
|
||||
WHEN (is_owner(_user_id, _team_id) OR is_admin(_user_id, _team_id) IS TRUE) THEN TRUE
|
||||
ELSE is_member_of_project(projects.id, _user_id, _team_id) END)
|
||||
ORDER BY name) rec;
|
||||
|
||||
SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
|
||||
INTO _statuses
|
||||
FROM (SELECT id, name FROM task_statuses WHERE project_id = _project_id) rec;
|
||||
|
||||
SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec))), '[]'::JSON)
|
||||
INTO _team_members
|
||||
FROM (SELECT team_members.id,
|
||||
(SELECT name FROM team_member_info_view WHERE team_member_info_view.team_member_id = team_members.id),
|
||||
(SELECT email FROM team_member_info_view WHERE team_member_info_view.team_member_id = team_members.id),
|
||||
(SELECT avatar_url
|
||||
FROM team_member_info_view
|
||||
WHERE team_member_info_view.team_member_id = team_members.id)
|
||||
FROM team_members
|
||||
LEFT JOIN users u ON team_members.user_id = u.id
|
||||
WHERE team_id = _team_id
|
||||
AND team_members.active IS TRUE) rec;
|
||||
|
||||
SELECT get_task_assignees(_task_id) INTO _assignees;
|
||||
|
||||
RETURN JSON_BUILD_OBJECT(
|
||||
'task', _task,
|
||||
'priorities', _priorities,
|
||||
'projects', _projects,
|
||||
'statuses', _statuses,
|
||||
'team_members', _team_members,
|
||||
'assignees', _assignees,
|
||||
'phases', _phases
|
||||
);
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- Add use_manual_progress, use_weighted_progress, and use_time_progress to projects table if they don't exist
|
||||
ALTER TABLE projects
|
||||
ADD COLUMN IF NOT EXISTS use_manual_progress BOOLEAN DEFAULT FALSE,
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
-- Migration: Add progress and weight activity types support
|
||||
-- Date: 2025-04-24
|
||||
-- Version: 1.0.0
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- Update the get_activity_logs_by_task function to handle progress and weight attribute types
|
||||
CREATE OR REPLACE FUNCTION get_activity_logs_by_task(_task_id uuid) RETURNS json
|
||||
LANGUAGE plpgsql
|
||||
AS
|
||||
$$
|
||||
DECLARE
|
||||
_result JSON;
|
||||
BEGIN
|
||||
SELECT ROW_TO_JSON(rec)
|
||||
INTO _result
|
||||
FROM (SELECT (SELECT tasks.created_at FROM tasks WHERE tasks.id = _task_id),
|
||||
(SELECT name
|
||||
FROM users
|
||||
WHERE id = (SELECT reporter_id FROM tasks WHERE id = _task_id)),
|
||||
(SELECT avatar_url
|
||||
FROM users
|
||||
WHERE id = (SELECT reporter_id FROM tasks WHERE id = _task_id)),
|
||||
(SELECT COALESCE(ARRAY_TO_JSON(ARRAY_AGG(ROW_TO_JSON(rec2))), '[]'::JSON)
|
||||
FROM (SELECT task_id,
|
||||
created_at,
|
||||
attribute_type,
|
||||
log_type,
|
||||
|
||||
-- Case for previous value
|
||||
(CASE
|
||||
WHEN (attribute_type = 'status')
|
||||
THEN (SELECT name FROM task_statuses WHERE id = old_value::UUID)
|
||||
WHEN (attribute_type = 'priority')
|
||||
THEN (SELECT name FROM task_priorities WHERE id = old_value::UUID)
|
||||
WHEN (attribute_type = 'phase' AND old_value <> 'Unmapped')
|
||||
THEN (SELECT name FROM project_phases WHERE id = old_value::UUID)
|
||||
WHEN (attribute_type = 'progress' OR attribute_type = 'weight')
|
||||
THEN old_value
|
||||
ELSE (old_value) END) AS previous,
|
||||
|
||||
-- Case for current value
|
||||
(CASE
|
||||
WHEN (attribute_type = 'assignee')
|
||||
THEN (SELECT name FROM users WHERE id = new_value::UUID)
|
||||
WHEN (attribute_type = 'label')
|
||||
THEN (SELECT name FROM team_labels WHERE id = new_value::UUID)
|
||||
WHEN (attribute_type = 'status')
|
||||
THEN (SELECT name FROM task_statuses WHERE id = new_value::UUID)
|
||||
WHEN (attribute_type = 'priority')
|
||||
THEN (SELECT name FROM task_priorities WHERE id = new_value::UUID)
|
||||
WHEN (attribute_type = 'phase' AND new_value <> 'Unmapped')
|
||||
THEN (SELECT name FROM project_phases WHERE id = new_value::UUID)
|
||||
WHEN (attribute_type = 'progress' OR attribute_type = 'weight')
|
||||
THEN new_value
|
||||
ELSE (new_value) END) AS current,
|
||||
|
||||
-- Case for assigned user
|
||||
(CASE
|
||||
WHEN (attribute_type = 'assignee')
|
||||
THEN (SELECT ROW_TO_JSON(rec)
|
||||
FROM (SELECT (CASE
|
||||
WHEN (new_value IS NOT NULL)
|
||||
THEN (SELECT name FROM users WHERE users.id = new_value::UUID)
|
||||
ELSE (next_string) END) AS name,
|
||||
(SELECT avatar_url FROM users WHERE users.id = new_value::UUID)) rec)
|
||||
ELSE (NULL) END) AS assigned_user,
|
||||
|
||||
-- Case for label data
|
||||
(CASE
|
||||
WHEN (attribute_type = 'label')
|
||||
THEN (SELECT ROW_TO_JSON(rec)
|
||||
FROM (SELECT (SELECT name FROM team_labels WHERE id = new_value::UUID),
|
||||
(SELECT color_code FROM team_labels WHERE id = new_value::UUID)) rec)
|
||||
ELSE (NULL) END) AS label_data,
|
||||
|
||||
-- Case for previous status
|
||||
(CASE
|
||||
WHEN (attribute_type = 'status')
|
||||
THEN (SELECT ROW_TO_JSON(rec)
|
||||
FROM (SELECT (SELECT name FROM task_statuses WHERE id = old_value::UUID),
|
||||
(SELECT color_code
|
||||
FROM sys_task_status_categories
|
||||
WHERE id = (SELECT category_id FROM task_statuses WHERE id = old_value::UUID)),
|
||||
(SELECT color_code_dark
|
||||
FROM sys_task_status_categories
|
||||
WHERE id = (SELECT category_id FROM task_statuses WHERE id = old_value::UUID))) rec)
|
||||
ELSE (NULL) END) AS previous_status,
|
||||
|
||||
-- Case for next status
|
||||
(CASE
|
||||
WHEN (attribute_type = 'status')
|
||||
THEN (SELECT ROW_TO_JSON(rec)
|
||||
FROM (SELECT (SELECT name FROM task_statuses WHERE id = new_value::UUID),
|
||||
(SELECT color_code
|
||||
FROM sys_task_status_categories
|
||||
WHERE id = (SELECT category_id FROM task_statuses WHERE id = new_value::UUID)),
|
||||
(SELECT color_code_dark
|
||||
FROM sys_task_status_categories
|
||||
WHERE id = (SELECT category_id FROM task_statuses WHERE id = new_value::UUID))) rec)
|
||||
ELSE (NULL) END) AS next_status,
|
||||
|
||||
-- Case for previous priority
|
||||
(CASE
|
||||
WHEN (attribute_type = 'priority')
|
||||
THEN (SELECT ROW_TO_JSON(rec)
|
||||
FROM (SELECT (SELECT name FROM task_priorities WHERE id = old_value::UUID),
|
||||
(SELECT color_code FROM task_priorities WHERE id = old_value::UUID)) rec)
|
||||
ELSE (NULL) END) AS previous_priority,
|
||||
|
||||
-- Case for next priority
|
||||
(CASE
|
||||
WHEN (attribute_type = 'priority')
|
||||
THEN (SELECT ROW_TO_JSON(rec)
|
||||
FROM (SELECT (SELECT name FROM task_priorities WHERE id = new_value::UUID),
|
||||
(SELECT color_code FROM task_priorities WHERE id = new_value::UUID)) rec)
|
||||
ELSE (NULL) END) AS next_priority,
|
||||
|
||||
-- Case for previous phase
|
||||
(CASE
|
||||
WHEN (attribute_type = 'phase' AND old_value <> 'Unmapped')
|
||||
THEN (SELECT ROW_TO_JSON(rec)
|
||||
FROM (SELECT (SELECT name FROM project_phases WHERE id = old_value::UUID),
|
||||
(SELECT color_code FROM project_phases WHERE id = old_value::UUID)) rec)
|
||||
ELSE (NULL) END) AS previous_phase,
|
||||
|
||||
-- Case for next phase
|
||||
(CASE
|
||||
WHEN (attribute_type = 'phase' AND new_value <> 'Unmapped')
|
||||
THEN (SELECT ROW_TO_JSON(rec)
|
||||
FROM (SELECT (SELECT name FROM project_phases WHERE id = new_value::UUID),
|
||||
(SELECT color_code FROM project_phases WHERE id = new_value::UUID)) rec)
|
||||
ELSE (NULL) END) AS next_phase,
|
||||
|
||||
-- Case for done by
|
||||
(SELECT ROW_TO_JSON(rec)
|
||||
FROM (SELECT (SELECT name FROM users WHERE users.id = tal.user_id),
|
||||
(SELECT avatar_url FROM users WHERE users.id = tal.user_id)) rec) AS done_by,
|
||||
|
||||
-- Add log text for progress and weight
|
||||
(CASE
|
||||
WHEN (attribute_type = 'progress')
|
||||
THEN 'updated the progress of'
|
||||
WHEN (attribute_type = 'weight')
|
||||
THEN 'updated the weight of'
|
||||
ELSE ''
|
||||
END) AS log_text
|
||||
|
||||
|
||||
FROM task_activity_logs tal
|
||||
WHERE task_id = _task_id
|
||||
ORDER BY created_at DESC) rec2) AS logs) rec;
|
||||
RETURN _result;
|
||||
END;
|
||||
$$;
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user