frontend_nyla/src/api/connectionApi.ts

221 lines
5.8 KiB
TypeScript

import { ApiRequestOptions } from '../hooks/useApi';
// ============================================================================
// TYPES & INTERFACES
// ============================================================================
export interface Connection {
id: string;
userId: string;
authority: 'local' | 'google' | 'msft';
externalId: string;
externalUsername: string;
externalEmail?: string;
status: 'active' | 'expired' | 'revoked' | 'pending';
connectedAt: number; // Backend uses float for UTC timestamp in seconds
lastChecked: number; // Backend uses float for UTC timestamp in seconds
expiresAt?: number; // Backend uses Optional[float] for UTC timestamp in seconds
[key: string]: any; // Allow additional properties
}
export interface AttributeDefinition {
name: string;
label: string;
type: 'string' | 'number' | 'date' | 'boolean' | 'enum';
sortable?: boolean;
filterable?: boolean;
searchable?: boolean;
width?: number;
minWidth?: number;
maxWidth?: number;
filterOptions?: string[];
}
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;
};
}
export interface CreateConnectionData {
id?: string;
userId?: string;
authority?: 'msft' | 'google';
type?: 'msft' | 'google'; // Backend expects this field
externalId?: string;
externalUsername?: string;
externalEmail?: string;
status?: 'active' | 'expired' | 'revoked' | 'pending';
connectedAt?: number;
lastChecked?: number;
expiresAt?: number;
}
export interface ConnectResponse {
authUrl: string;
}
// Type for the request function passed to API functions
export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;
// ============================================================================
// API REQUEST FUNCTIONS
// ============================================================================
/**
* Fetch connection attributes from backend
* Endpoint: GET /api/attributes/UserConnection
*/
export async function fetchConnectionAttributes(_request: ApiRequestFunction): Promise<AttributeDefinition[]> {
// Note: This uses api.get directly due to response format handling
// For now, we'll use api.get directly in the hook as well
throw new Error('fetchConnectionAttributes should use api instance directly for response format handling');
}
/**
* Fetch list of connections with optional pagination
* Endpoint: GET /api/connections/
*/
export async function fetchConnections(
request: ApiRequestFunction,
params?: PaginationParams
): Promise<PaginatedResponse<Connection> | Connection[]> {
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/connections/',
method: 'get',
params: requestParams
});
return data;
}
/**
* Create a new connection
* Endpoint: POST /api/connections/
*/
export async function createConnection(
request: ApiRequestFunction,
connectionData: CreateConnectionData
): Promise<Connection> {
return await request({
url: '/api/connections/',
method: 'post',
data: connectionData
});
}
/**
* Connect to a service (initiate OAuth)
* Endpoint: POST /api/connections/{connectionId}/connect
*/
export async function connectService(
request: ApiRequestFunction,
connectionId: string
): Promise<ConnectResponse> {
return await request({
url: `/api/connections/${connectionId}/connect`,
method: 'post'
});
}
/**
* Disconnect from a service
* Endpoint: POST /api/connections/{connectionId}/disconnect
*/
export async function disconnectService(
request: ApiRequestFunction,
connectionId: string
): Promise<{ message: string }> {
return await request({
url: `/api/connections/${connectionId}/disconnect`,
method: 'post'
});
}
/**
* Delete a connection
* Endpoint: DELETE /api/connections/{connectionId}
*/
export async function deleteConnection(
request: ApiRequestFunction,
connectionId: string
): Promise<{ message: string }> {
return await request({
url: `/api/connections/${connectionId}`,
method: 'delete'
});
}
/**
* Update a connection
* Endpoint: PUT /api/connections/{connectionId}
*/
export async function updateConnection(
request: ApiRequestFunction,
connectionId: string,
updateData: Partial<Connection>
): Promise<Connection> {
return await request({
url: `/api/connections/${connectionId}`,
method: 'put',
data: updateData
});
}
/**
* Refresh Microsoft token
* Endpoint: POST /api/connections/{connectionId}/refresh-microsoft-token
*/
export async function refreshMicrosoftToken(
request: ApiRequestFunction,
connectionId: string
): Promise<Connection> {
return await request({
url: `/api/connections/${connectionId}/refresh-microsoft-token`,
method: 'post'
});
}
/**
* Refresh Google token
* Endpoint: POST /api/connections/{connectionId}/refresh-google-token
*/
export async function refreshGoogleToken(
request: ApiRequestFunction,
connectionId: string
): Promise<Connection> {
return await request({
url: `/api/connections/${connectionId}/refresh-google-token`,
method: 'post'
});
}