refactor: implement project package segment lazy select

This commit is contained in:
2026-06-18 16:30:06 +05:30
parent 6cf363dce1
commit 9e76b8e6d0
31 changed files with 513 additions and 1076 deletions

View File

@@ -16,14 +16,14 @@ export const chainageService = {
* Fetch all chainages
*/
getChainages: async (
params?: PaginationParams,
params?: PaginationParams & { search_term?: string },
): Promise<PaginatedResponse<Chainage>> => {
const skip = params?.skip ?? 0;
const limit = params?.limit ?? 100;
const response = await axiosClient.get<PaginatedResponse<Chainage>>(
API_ROUTES.CHAINAGES.BASE,
{
params: { skip, limit },
params: { skip, limit, search_term: params?.search_term },
},
);
return response.data;
@@ -34,19 +34,34 @@ export const chainageService = {
*/
getChainagesByPackage: async (
packageId: string,
params?: PaginationParams,
params?: PaginationParams & { search_term?: string },
): Promise<PaginatedResponse<Chainage>> => {
const skip = params?.skip ?? 0;
const limit = params?.limit ?? 100;
const response = await axiosClient.get<PaginatedResponse<Chainage>>(
API_ROUTES.CHAINAGES.BASE,
{
params: { package_id: packageId, skip, limit },
params: {
package_id: packageId,
skip,
limit,
search_term: params?.search_term,
},
},
);
return response.data;
},
/**
* Fetch a chainage by ID
*/
getChainageById: async (chainageId: string): Promise<Chainage> => {
const response = await axiosClient.get<Chainage>(
API_ROUTES.CHAINAGES.DETAIL(chainageId),
);
return response.data;
},
/**
* Create a new chainage
*/

View File

@@ -5,7 +5,6 @@ export * from './auth.service';
export { chainageService } from './chainage.service';
export * from './video.service';
export * from './detection.service';
export * from './session.service';
export * from './permission.service';
export * from './role.service';
export * from './user.service';

View File

@@ -16,14 +16,14 @@ export const packageService = {
* Fetch all packages
*/
getPackages: async (
params?: PaginationParams,
params?: PaginationParams & { search_term?: string },
): Promise<PaginatedResponse<Package>> => {
const skip = params?.skip ?? 0;
const limit = params?.limit ?? 100;
const response = await axiosClient.get<PaginatedResponse<Package>>(
API_ROUTES.PACKAGES.BASE,
{
params: { skip, limit },
params: { skip, limit, search_term: params?.search_term },
},
);
return response.data;
@@ -34,19 +34,34 @@ export const packageService = {
*/
getPackagesByProject: async (
projectId: string,
params?: PaginationParams,
params?: PaginationParams & { search_term?: string },
): Promise<PaginatedResponse<Package>> => {
const skip = params?.skip ?? 0;
const limit = params?.limit ?? 100;
const response = await axiosClient.get<PaginatedResponse<Package>>(
API_ROUTES.PACKAGES.BASE,
{
params: { project_id: projectId, skip, limit },
params: {
project_id: projectId,
skip,
limit,
search_term: params?.search_term,
},
},
);
return response.data;
},
/**
* Fetch a package by ID
*/
getPackageById: async (packageId: string): Promise<Package> => {
const response = await axiosClient.get<Package>(
API_ROUTES.PACKAGES.DETAIL(packageId),
);
return response.data;
},
/**
* Create a new package
*/

View File

@@ -16,19 +16,29 @@ export const projectService = {
* Fetch all projects
*/
getProjects: async (
params?: PaginationParams,
params?: PaginationParams & { search_term?: string },
): Promise<PaginatedResponse<Project>> => {
const skip = params?.skip ?? 0;
const limit = params?.limit ?? 100;
const response = await axiosClient.get<PaginatedResponse<Project>>(
API_ROUTES.PROJECTS.BASE,
{
params: { skip, limit },
params: { skip, limit, search_term: params?.search_term },
},
);
return response.data;
},
/**
* Fetch a project by ID
*/
getProjectById: async (projectId: string): Promise<Project> => {
const response = await axiosClient.get<Project>(
API_ROUTES.PROJECTS.DETAIL(projectId),
);
return response.data;
},
/**
* Create a new project
*/

View File

@@ -1,73 +0,0 @@
import { SessionContext, VideoResultData, emptySessionContext } from '@/types';
// Session Storage Keys
const SESSION_KEY = 'visionroad_session';
const VIDEO_DATA_KEY = 'visionroad_video_data';
const DETECTION_TYPE_KEY = 'visionroad_detection_type';
/**
* Session Service
*/
export const sessionService = {
/**
* Save session to localStorage
*/
saveSession: (session: SessionContext): void => {
if (typeof window !== 'undefined') {
localStorage.setItem(SESSION_KEY, JSON.stringify(session));
}
},
/**
* Load session from localStorage
*/
loadSession: (): SessionContext => {
if (typeof window !== 'undefined') {
const stored = localStorage.getItem(SESSION_KEY);
if (stored) {
return JSON.parse(stored);
}
}
return emptySessionContext;
},
/**
* Clear all session data
*/
clearSession: (): void => {
if (typeof window !== 'undefined') {
localStorage.removeItem(SESSION_KEY);
localStorage.removeItem(VIDEO_DATA_KEY);
localStorage.removeItem(DETECTION_TYPE_KEY);
}
},
/**
* Save video result data
*/
saveVideoData: (data: VideoResultData): void => {
if (typeof window !== 'undefined') {
localStorage.setItem(VIDEO_DATA_KEY, JSON.stringify(data));
}
},
/**
* Load video result data
*/
loadVideoData: (): VideoResultData | null => {
if (typeof window !== 'undefined') {
const stored = localStorage.getItem(VIDEO_DATA_KEY);
if (stored) {
return JSON.parse(stored);
}
}
return null;
},
/**
* Check if session is complete
*/
isSessionValid: (session: SessionContext): boolean => {
return !!(session.projectId && session.packageId && session.chainageId);
},
};

View File

@@ -1,55 +1,11 @@
import axiosClient from '../axios/axios';
import { API_ROUTES } from '@/constants/apiRoutes';
import { CompletedVideoResult, Video, PaginationParams } from '@/types';
import { CompletedVideoResult } from '@/types';
/**
* Video Service
*/
export const videoService = {
/**
* Fetch all videos and transform them to match the Video interface
*/
getVideos: async (params?: PaginationParams): Promise<Video[]> => {
const skip = params?.skip ?? 0;
const limit = params?.limit ?? 100;
const response = await axiosClient.get<{
videos: Array<{
video_id: string;
status: string;
progress: number;
summary?: {
unique_defected_sign_board?: number;
unique_pothole?: number;
unique_road_crack?: number;
unique_damaged_road_marking?: number;
unique_good_sign_board?: number;
total_road_damage?: number;
total_detections?: number;
};
}>;
}>(API_ROUTES.VIDEOS.LIST, {
params: { skip, limit },
});
// Transform the response to match our Video interface
return response.data.videos.map((v) => ({
id: v.video_id,
filename: v.video_id,
detection_type: 'pot-sign-detection' as const,
status: v.status as Video['status'],
unique_defected_sign_board: v.summary?.unique_defected_sign_board,
unique_pothole: v.summary?.unique_pothole,
unique_road_crack: v.summary?.unique_road_crack,
unique_damaged_road_marking: v.summary?.unique_damaged_road_marking,
unique_good_sign_board: v.summary?.unique_good_sign_board,
total_road_damage: v.summary?.total_road_damage,
total_detections: v.summary?.total_detections,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
}));
},
/**
* Upload a video for processing
*/
@@ -66,14 +22,6 @@ export const videoService = {
return response.data;
},
/**
* Get processing status of a video
*/
getVideoStatus: async (videoId: string): Promise<any> => {
const response = await axiosClient.get(API_ROUTES.VIDEOS.STATUS(videoId));
return response.data;
},
/**
* Get analysis results for a video
*/