frontend_nyla/src/api/roleApi.ts
2026-02-23 17:13:31 +01:00

182 lines
4.7 KiB
TypeScript

import { ApiRequestOptions } from '../hooks/useApi';
// ============================================================================
// TYPES & INTERFACES
// ============================================================================
export interface Role {
id: string;
[key: string]: any; // Allow additional properties from backend
}
export type RoleUpdateData = Partial<Omit<Role, 'id'>>;
export interface PaginationParams {
page?: number;
pageSize?: number;
sort?: Array<{ field: string; direction: 'asc' | 'desc' }>;
filters?: Record<string, any>;
search?: string;
}
export interface PaginatedResponse<T> {
items: T[];
pagination?: {
currentPage: number;
pageSize: number;
totalItems: number;
totalPages: number;
};
}
// Type for the request function passed to API functions
export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;
// ============================================================================
// API REQUEST FUNCTIONS
// ============================================================================
/**
* Fetch list of roles with optional pagination
* Endpoint: GET /api/rbac/roles
* Query parameter: pagination (optional, JSON-encoded string)
* Example: /api/rbac/roles?pagination={"page":1,"pageSize":10}
*/
export async function fetchRoles(
request: ApiRequestFunction,
params?: PaginationParams
): Promise<PaginatedResponse<Role> | Role[]> {
const requestParams: any = {};
// Build pagination object if provided
if (params) {
const paginationObj: any = {};
if (params.page !== undefined) paginationObj.page = params.page;
if (params.pageSize !== undefined) paginationObj.pageSize = params.pageSize;
if (params.sort) paginationObj.sort = params.sort;
if (params.filters) paginationObj.filters = params.filters;
if (params.search) paginationObj.search = params.search;
if (Object.keys(paginationObj).length > 0) {
requestParams.pagination = JSON.stringify(paginationObj);
}
}
const data = await request({
url: '/api/rbac/roles',
method: 'get',
params: requestParams
});
return data;
}
/**
* Fetch a single role by ID
* Endpoint: GET /api/rbac/roles/{roleId}
*/
export async function fetchRoleById(
request: ApiRequestFunction,
roleId: string
): Promise<Role | null> {
try {
const data = await request({
url: `/api/rbac/roles/${roleId}`,
method: 'get'
});
return data || null;
} catch (error: any) {
console.error('Error fetching role by ID:', error);
return null;
}
}
/**
* Create a new role
* Endpoint: POST /api/rbac/roles
* Request body: Role object
* Required fields:
* - roleLabel: string (e.g., "admin", "user")
* - description: TextMultilingual object (at least en is required)
*/
export async function createRole(
request: ApiRequestFunction,
roleData: Partial<Role>
): Promise<Role> {
console.log('🔵 createRole - Complete request structure:', {
url: '/api/rbac/roles',
method: 'post',
requestOptions: {
url: '/api/rbac/roles',
method: 'post',
data: roleData
},
roleData: roleData,
roleDataKeys: Object.keys(roleData || {}),
roleDataValues: Object.entries(roleData || {}).map(([key, value]) => ({
key,
value,
type: typeof value,
isObject: typeof value === 'object' && value !== null,
isArray: Array.isArray(value),
stringified: typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value)
})),
dataStringified: JSON.stringify(roleData, null, 2),
dataStringifiedCompact: JSON.stringify(roleData)
});
try {
const result = await request({
url: '/api/rbac/roles',
method: 'post',
data: roleData
});
console.log('✅ createRole - Response:', result);
return result;
} catch (error: any) {
console.error('❌ createRole - Request failed:', {
error,
errorMessage: error.message,
errorResponse: error.response,
errorResponseData: error.response?.data,
errorResponseStatus: error.response?.status,
errorResponseHeaders: error.response?.headers,
errorRequest: error.request,
errorConfig: error.config
});
throw error;
}
}
/**
* Update a role
* Endpoint: PUT /api/rbac/roles/{roleId}
*/
export async function updateRole(
request: ApiRequestFunction,
roleId: string,
updateData: RoleUpdateData
): Promise<Role> {
return await request({
url: `/api/rbac/roles/${roleId}`,
method: 'put',
data: updateData
});
}
/**
* Delete a role
* Endpoint: DELETE /api/rbac/roles/{roleId}
*/
export async function deleteRole(
request: ApiRequestFunction,
roleId: string
): Promise<void> {
await request({
url: `/api/rbac/roles/${roleId}`,
method: 'delete'
});
}