pmtool / src /services /tasksApi.ts
devarshia5's picture
Upload 487 files
d97b8f9 verified
Raw
History Blame Contribute Delete
9.77 kB
import axios from 'axios';
import { API_BASE_URL } from '@/config';
import apiClient from '@/lib/api/axios-instance';
import { createHeaders } from '@/lib/api';
export interface Task {
id: number;
type: string;
priority?: string;
severity?: string;
description: string;
sprintName: string | null;
estimates: string;
esUnit: number | null;
stateDate: string;
endDate: string | null;
assignedTo: number | null;
remainingHr: number | null;
status: string;
issuesId: number | null;
title: string;
createdAt?: string;
createdBy?: number | null;
createdByName?: string;
updatedAt?: string | null;
updatedBy?: number | null;
updatedByName?: string | null;
taskCode?: string;
version?: string;
url?: string;
stepsToReproduce?: string;
inputs?: string;
environment?: string;
expectedBehavior?: string;
actualBehavior?: string;
resolution?: string;
rootCause?: string;
projectId?: number;
projectName?: string;
issueName?: string;
deliverableName?: string;
relatedUrl?: string;
}
export interface TaskCreateRequest {
id?: number;
type: string;
priority?: string;
severity?: string;
description: string;
sprintName: string | null;
estimates: string;
esUnit: number | null;
stateDate: string;
endDate: string | null;
assignedTo: number | null;
remainingHr: number | null;
status: string;
issuesId: number | null;
title: string;
taskCode?: string;
version?: string;
url?: string;
stepsToReproduce?: string;
inputs?: string;
environment?: string;
expectedBehavior?: string;
actualBehavior?: string;
resolution?: string;
rootCause?: string;
}
export interface TaskUpdateRequest extends TaskCreateRequest {
id: number;
}
// Helper to create a safe task object with default values for null/undefined fields
const createSafeTask = (data: any): Task => {
return {
id: data.id || 0,
title: data.title || '',
description: data.description || '',
type: data.type || 'Medium',
status: data.status || 'New',
sprintName: data.sprintName,
estimates: data.estimates || '',
esUnit: data.esUnit,
stateDate: data.stateDate || new Date().toISOString().split('T')[0],
endDate: data.endDate,
assignedTo: data.assignedTo,
remainingHr: data.remainingHr,
issuesId: data.issuesId,
createdAt: data.createdAt || new Date().toISOString(), // Default to current time if not provided
createdBy: data.createdBy,
createdByName: data.createdByName,
updatedAt: data.updatedAt,
updatedBy: data.updatedBy,
updatedByName: data.updatedByName,
taskCode: data.taskCode || '',
version: data.version || '',
url: data.url || '',
stepsToReproduce: data.stepsToReproduce || '',
inputs: data.inputs || '',
environment: data.environment || '',
expectedBehavior: data.expectedBehavior || '',
actualBehavior: data.actualBehavior || '',
resolution: data.resolution || '',
rootCause: data.rootCause || '',
priority: data.priority,
severity: data.severity,
projectId: data.projectId,
projectName: data.projectName,
issueName: data.issueName,
deliverableName: data.deliverableName,
relatedUrl: data.relatedUrl
};
};
class TasksApi {
private baseUrl = `/api/Tasks`;
async getAll(): Promise<Task[]> {
try {
console.log('TasksApi: Fetching all tasks from', this.baseUrl);
const response = await apiClient.get(this.baseUrl);
console.log('TasksApi: Response status', response.status);
if (!response.data) {
console.warn('TasksApi: No data in response');
return [];
}
if (!Array.isArray(response.data)) {
console.warn('TasksApi: Response is not an array', response.data);
return [];
}
// Map each item to ensure it has all required fields
return response.data.map(item => createSafeTask(item));
} catch (error) {
console.error('Error fetching tasks:', error);
// Return empty array instead of throwing to prevent UI crashes
return [];
}
}
async getByType(type: string): Promise<Task[]> {
try {
console.log(`TasksApi: Fetching tasks of type ${type}`);
console.log(`TasksApi: Requesting from URL: ${this.baseUrl}/GetTaskByType?type=${type}`);
const response = await apiClient.get(`${this.baseUrl}/GetTaskByType?type=${type}`);
console.log('TasksApi: Response status:', response.status);
console.log('TasksApi: Response headers:', response.headers);
if (!response.data) {
console.warn('TasksApi: No data in response');
return [];
}
// Log the raw response data
console.log('TasksApi: Raw response data type:', typeof response.data);
console.log('TasksApi: Raw response data sample:',
Array.isArray(response.data)
? response.data.slice(0, 1)
: response.data
);
if (!Array.isArray(response.data)) {
console.warn('TasksApi: Response is not an array', response.data);
// Try to handle if the response is enclosed in another object
if (response.data && typeof response.data === 'object' && response.data.items && Array.isArray(response.data.items)) {
console.log('TasksApi: Found array in response.data.items');
response.data = response.data.items;
} else {
console.warn('TasksApi: Unable to extract array from response');
return [];
}
}
console.log(`TasksApi: Found ${response.data.length} ${type} tasks`);
// Map each item to ensure it has all required fields
const mappedTasks = response.data.map(item => createSafeTask(item));
console.log(`TasksApi: Returning ${mappedTasks.length} mapped ${type} tasks`);
if (mappedTasks.length > 0) {
console.log('TasksApi: First mapped task sample:', mappedTasks[0]);
}
return mappedTasks;
} catch (error) {
console.error(`Error fetching tasks of type ${type}:`, error);
// Return empty array instead of throwing to prevent UI crashes
return [];
}
}
async getById(id: number): Promise<Task | null> {
try {
const response = await apiClient.get(`${this.baseUrl}/${id}`);
if (response.data) {
return createSafeTask(response.data);
}
return null;
} catch (error) {
console.error(`Error fetching task ${id}:`, error);
return null;
}
}
async create(task: TaskCreateRequest): Promise<Task> {
try {
// Remove id if it's 0, undefined, or null
const taskData = { ...task };
if (taskData.id === 0 || taskData.id === undefined || taskData.id === null) {
delete taskData.id;
}
// Don't fill empty fields with default values
// Instead, let null values pass through to the API
// Only format dates that actually have values
if (taskData.stateDate && typeof taskData.stateDate === 'string') {
// Check if the date already has a time part
if (!taskData.stateDate.includes('T')) {
taskData.stateDate = taskData.stateDate + 'T12:00:00.000Z';
}
}
if (taskData.endDate && typeof taskData.endDate === 'string') {
// Check if the date already has a time part
if (!taskData.endDate.includes('T')) {
taskData.endDate = taskData.endDate + 'T12:00:00.000Z';
}
}
console.log('TasksApi: Creating task with data', taskData);
const response = await apiClient.post(this.baseUrl, taskData);
console.log('TasksApi: Create response status', response.status);
return createSafeTask(response.data);
} catch (error) {
console.error('Error creating task:', error);
throw error;
}
}
async update(id: number, task: TaskUpdateRequest): Promise<Task> {
try {
// Don't fill empty fields with default values
// Instead, let null values pass through to the API
const taskData = { ...task };
// Only format dates that actually have values
if (taskData.stateDate && typeof taskData.stateDate === 'string') {
// Check if the date already has a time part
if (!taskData.stateDate.includes('T')) {
taskData.stateDate = taskData.stateDate + 'T12:00:00.000Z';
}
}
if (taskData.endDate && typeof taskData.endDate === 'string') {
// Check if the date already has a time part
if (!taskData.endDate.includes('T')) {
taskData.endDate = taskData.endDate + 'T12:00:00.000Z';
}
}
console.log(`TasksApi: Updating task ${id} with data`, taskData);
const response = await apiClient.put(`${this.baseUrl}/${id}`, taskData);
console.log(`TasksApi: Update response status for task ${id}`, response.status);
return createSafeTask(response.data);
} catch (error) {
console.error(`Error updating task ${id}:`, error);
throw error;
}
}
async delete(id: number): Promise<void> {
try {
console.log(`TasksApi: Deleting task ${id}`);
await apiClient.delete(`${this.baseUrl}/${id}`);
console.log(`TasksApi: Task ${id} deleted successfully`);
} catch (error) {
console.error(`Error deleting task ${id}:`, error);
throw error;
}
}
}
export const tasksApi = new TasksApi();