tech_mahindra/src/api/viewService.ts
2026-05-23 00:02:17 +05:30

361 lines
10 KiB
TypeScript

import { APP_ID } from "../config";
const TOKEN_KEY = "zino_token";
function baseUrl(): string {
return (import.meta.env.VITE_ZINO_API_URL || "").replace(/\/+$/, "");
}
function headers(): Record<string, string> {
const h: Record<string, string> = { "Content-Type": "application/json" };
const token = localStorage.getItem(TOKEN_KEY);
if (token) h["Authorization"] = `Bearer ${token}`;
return h;
}
async function request<T>(method: string, path: string, body?: unknown): Promise<T> {
const res = await fetch(`${baseUrl()}${path}`, {
method,
headers: headers(),
body: body ? JSON.stringify(body) : undefined,
});
if (res.status === 401) {
localStorage.removeItem(TOKEN_KEY);
localStorage.removeItem("zino_user");
window.location.href = "/login";
throw new Error("Unauthorized");
}
if (!res.ok) {
let msg = res.statusText;
try { const e = await res.json(); if (e.error) msg = e.error; } catch {}
throw new Error(msg);
}
if (res.status === 204) return undefined as T;
return res.json() as Promise<T>;
}
// ---------------------------------------------------------------------------
// Header
// ---------------------------------------------------------------------------
export interface HeaderConfig {
slots: { left: string[]; right: string[]; center: string[] };
layout: { type: string; height: string; position: string; full_width: boolean };
components: {
nav?: { items: NavItem[] };
logo?: { text?: string; image_url?: string; display_type: string };
profile?: { shape: string; show_name: boolean };
};
}
export interface NavItem {
id: string;
icon: string;
type: string;
label: string;
screen_uuid: string;
}
export async function getHeaderConfig(deviceType = "desktop"): Promise<HeaderConfig> {
const raw = await request<any>("GET", `/app/${APP_ID}/view/header/${deviceType}`);
return raw.config ?? raw;
}
// ---------------------------------------------------------------------------
// Screens
// ---------------------------------------------------------------------------
export interface ScreenListItem {
id: number;
source_screen_id: number;
screen_name: string;
device: string;
description: string;
}
export interface ScreenLayout {
id: number;
source_screen_id: number;
screen_name: string;
layout: LayoutElement[];
}
export interface LayoutElement {
type: string;
style?: Record<string, string>;
config: Record<string, any>;
classes?: string[];
}
export function getScreens(deviceType = "desktop"): Promise<ScreenListItem[]> {
return request("GET", `/app/${APP_ID}/view/screens?device_type=${deviceType}`);
}
export function getScreen(idOrUuid: number | string): Promise<ScreenLayout> {
return request("GET", `/app/${APP_ID}/view/screens/${idOrUuid}`);
}
// ---------------------------------------------------------------------------
// RV Screens
// ---------------------------------------------------------------------------
export interface RVScreen {
id: number;
source_screen_id: number;
screen_name: string;
rv_template_uid: string;
layout?: any;
}
// Accepts either the numeric source_screen_id OR the source_uuid — both
// are accepted by the view-service's rv-screens endpoint.
export function getRVScreen(idOrUuid: number | string): Promise<RVScreen> {
return request("GET", `/app/${APP_ID}/view/rv-screens/${idOrUuid}`);
}
// ---------------------------------------------------------------------------
// Record View (POST-based)
// ---------------------------------------------------------------------------
export interface SearchQuery {
page?: number;
limit?: number;
sort_by?: string;
sort_dir?: "asc" | "desc";
search?: string;
filters?: Array<{ field_key: string; value: string; data_type?: string }>;
}
export interface RecordViewField {
field_key: string;
output_label: string;
data_type: string;
is_filter: boolean;
is_search: boolean;
type?: string;
activity_id?: string;
}
export interface RecordViewResponse {
config: { fields: RecordViewField[] };
data: Record<string, unknown>[];
pagination?: {
page: number;
limit: number;
total_count: number;
total_pages: number;
};
}
export function getRecordView(
rvTemplateUid: string,
rvScreenId: string | number,
query: SearchQuery = {},
): Promise<RecordViewResponse> {
return request("POST", `/app/${APP_ID}/view/recordview`, {
rv_template_uid: rvTemplateUid,
rv_screen_id: String(rvScreenId),
search_query: {
page: query.page || 1,
limit: query.limit || 50,
sort_by: query.sort_by || "",
sort_dir: query.sort_dir || "desc",
search: query.search || "",
filters: query.filters || [],
},
});
}
export function getRecordViewLegacy(
rvUid: string,
query: SearchQuery = {},
): Promise<RecordViewResponse> {
const qs = new URLSearchParams();
qs.set("rv_id", rvUid);
if (query.page) qs.set("page", String(query.page));
if (query.limit) qs.set("limit", String(query.limit));
if (query.sort_by) qs.set("sort_by", query.sort_by);
if (query.sort_dir) qs.set("sort_dir", query.sort_dir);
if (query.search) qs.set("search", query.search);
if (query.filters) {
for (const f of query.filters) {
qs.set(`filter.${f.field_key}`, f.value);
}
}
return request("GET", `/recordview?${qs.toString()}`);
}
// ---------------------------------------------------------------------------
// DV Screens
// ---------------------------------------------------------------------------
export interface DVScreen {
id: number;
source_screen_id: number;
screen_name: string;
dv_template_uid: string;
layout?: any;
}
export function getDVScreen(idOrUuid: number | string): Promise<DVScreen> {
return request("GET", `/app/${APP_ID}/view/dv-screens/${idOrUuid}`);
}
// ---------------------------------------------------------------------------
// Detail View
// ---------------------------------------------------------------------------
export interface DetailViewResponse {
config: { fields: Array<{ field_key: string; output_label: string; data_type: string }> };
data: Record<string, unknown>;
}
export function getDetailView(dvSourceIdOrUid: number | string, instanceId: string): Promise<DetailViewResponse> {
return request(
"GET",
`/app/${APP_ID}/view/detailview/${encodeURIComponent(String(dvSourceIdOrUid))}?instance_id=${encodeURIComponent(instanceId)}`,
);
}
export function getDetailViewLegacy(dvUid: string, instanceId: string): Promise<DetailViewResponse> {
return request(
"GET",
`/detailview?dv_id=${encodeURIComponent(dvUid)}&instance_id=${encodeURIComponent(instanceId)}`,
);
}
// ---------------------------------------------------------------------------
// Form Screens
// ---------------------------------------------------------------------------
export interface FormScreenField {
id: string;
uid: string;
name: string;
type: string;
data_type: string;
mandatory: boolean;
value?: any;
properties?: {
options?: Array<{ label: string; value: string }>;
country_code?: string;
};
}
export interface FormScreenResponse {
id: number;
activity_uid: string;
activity_name: string;
device_type: string;
fields: FormScreenField[];
grid_config: Array<{ i: string; x: number; y: number; w: number; h: number }>;
layout: any[];
}
export function getFormScreen(
activityId: string,
instanceId?: string,
deviceType = "desktop",
): Promise<FormScreenResponse> {
return request("POST", `/app/${APP_ID}/view/form-screens`, {
activity_id: activityId,
device_type: deviceType,
...(instanceId ? { instance_id: instanceId } : {}),
});
}
// ---------------------------------------------------------------------------
// Workflow Actions
// ---------------------------------------------------------------------------
export interface WorkflowResponse {
success: boolean;
status_code?: number;
message?: string;
data?: Record<string, unknown>;
instance_id?: string;
}
// Core-service expects the workflow UUID as `workflow_uuid` — the numeric
// `workflow_id` field was removed when the clone-portable identifier rolled out.
export function startWorkflow(
workflowUuid: string,
activityId: string,
data?: Record<string, unknown>,
): Promise<WorkflowResponse> {
return request("POST", `/app/${APP_ID}/start`, {
workflow_uuid: workflowUuid,
activity_id: activityId,
data,
});
}
export function performActivity(
workflowUuid: string,
instanceId: string,
activityId: string,
data?: Record<string, unknown>,
): Promise<WorkflowResponse> {
return request("POST", `/app/${APP_ID}/activity`, {
workflow_uuid: workflowUuid,
instance_id: instanceId,
activity_id: activityId,
data,
});
}
export function submitForm(
workflowUuid: string,
activityId: string,
formData: Record<string, unknown>,
instanceId?: string,
deviceType = "desktop",
): Promise<WorkflowResponse> {
return request("POST", `/app/${APP_ID}/form/submit`, {
workflow_uuid: workflowUuid,
activity_id: activityId,
device_type: deviceType,
form_data: formData,
...(instanceId ? { instance_id: instanceId } : {}),
});
}
// ---------------------------------------------------------------------------
// Instance
// ---------------------------------------------------------------------------
export interface InstanceResponse {
instance_id: string;
workflow_id: string;
current_state_id: string;
current_state_name: string;
data: Record<string, unknown>;
created_at: string;
updated_at: string;
}
export function getInstance(workflowUuid: string, instanceId: string): Promise<InstanceResponse> {
return request("POST", `/app/${APP_ID}/instance`, {
workflow_uuid: workflowUuid,
instance_id: instanceId,
});
}
// ---------------------------------------------------------------------------
// Audit
// ---------------------------------------------------------------------------
export interface AuditEntry {
id: number;
user_id: string;
user_roles: string[];
activity_id: string;
data: Record<string, unknown>;
execution_state: string;
created_at: string;
}
export function getAuditLog(instanceId: string): Promise<AuditEntry[]> {
return request("GET", `/app/${APP_ID}/view/audit?instance_id=${encodeURIComponent(instanceId)}`);
}