2026-02-24 20:44:16 +00:00
|
|
|
import React, { createContext, useContext, useState, useEffect } from "react";
|
2026-03-01 20:43:25 +00:00
|
|
|
import { developerKitService } from "@/services/developerKit.service";
|
2026-02-24 20:44:16 +00:00
|
|
|
import {
|
2026-03-01 20:43:25 +00:00
|
|
|
CrudEndpoint,
|
|
|
|
|
CreateUpdateSqlTableDto,
|
|
|
|
|
SqlTable,
|
|
|
|
|
} from "@/proxy/developerKit/models";
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
export const FIELD_TYPE_OPTIONS = [
|
|
|
|
|
{ label: "String", value: "string" },
|
|
|
|
|
{ label: "Number", value: "number" },
|
|
|
|
|
{ label: "Boolean", value: "boolean" },
|
|
|
|
|
{ label: "Date", value: "date" },
|
|
|
|
|
{ label: "Guid", value: "guid" },
|
|
|
|
|
{ label: "Decimal", value: "decimal" },
|
|
|
|
|
] as const;
|
|
|
|
|
|
|
|
|
|
export type EntityFieldType = (typeof FIELD_TYPE_OPTIONS)[number]["value"];
|
|
|
|
|
|
|
|
|
|
interface EntityContextType {
|
2026-03-01 20:43:25 +00:00
|
|
|
entities: SqlTable[];
|
2026-02-24 20:44:16 +00:00
|
|
|
generatedEndpoints: CrudEndpoint[];
|
|
|
|
|
loading: boolean;
|
|
|
|
|
error: string | null;
|
|
|
|
|
// Entity operations
|
2026-03-01 20:43:25 +00:00
|
|
|
addEntity: (entity: CreateUpdateSqlTableDto) => Promise<void>;
|
|
|
|
|
updateEntity: (id: string, entity: CreateUpdateSqlTableDto) => Promise<void>;
|
2026-02-24 20:44:16 +00:00
|
|
|
deleteEntity: (id: string) => Promise<void>;
|
2026-03-01 20:43:25 +00:00
|
|
|
getEntity: (id: string) => SqlTable | undefined;
|
2026-02-24 20:44:16 +00:00
|
|
|
refreshEntities: () => Promise<void>;
|
|
|
|
|
toggleEntityActiveStatus: (id: string) => Promise<void>;
|
|
|
|
|
// Generated endpoint operations
|
|
|
|
|
generateCrudEndpoints: (entityId: string) => Promise<void>;
|
|
|
|
|
toggleEndpoint: (endpointId: string) => Promise<void>;
|
|
|
|
|
getEntityEndpoints: (entityId: string) => CrudEndpoint[];
|
|
|
|
|
deleteGeneratedEndpoint: (id: string) => Promise<void>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const EntityContext = createContext<EntityContextType | undefined>(undefined);
|
|
|
|
|
|
|
|
|
|
// eslint-disable-next-line react-refresh/only-export-components
|
|
|
|
|
export const useEntities = () => {
|
|
|
|
|
const context = useContext(EntityContext);
|
|
|
|
|
if (context === undefined) {
|
|
|
|
|
throw new Error("useEntities must be used within an EntityProvider");
|
|
|
|
|
}
|
|
|
|
|
return context;
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-01 20:43:25 +00:00
|
|
|
export const EntityProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
|
|
|
const [entities, setEntities] = useState<SqlTable[]>([]);
|
|
|
|
|
const [generatedEndpoints, setGeneratedEndpoints] = useState<CrudEndpoint[]>([]);
|
2026-02-24 20:44:16 +00:00
|
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
|
|
|
|
|
|
const refreshEntities = async () => {
|
|
|
|
|
try {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
2026-03-01 20:43:25 +00:00
|
|
|
const [entitiesData, generatedEndpointsData] = await Promise.all([
|
|
|
|
|
developerKitService.getSqlTables(),
|
|
|
|
|
developerKitService.getGeneratedEndpoints(),
|
|
|
|
|
]);
|
2026-02-24 20:44:16 +00:00
|
|
|
setEntities(entitiesData.items || []);
|
|
|
|
|
setGeneratedEndpoints(generatedEndpointsData.items || []);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
setError(err instanceof Error ? err.message : "Failed to fetch data");
|
|
|
|
|
console.error("Failed to fetch data:", err);
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
refreshEntities();
|
|
|
|
|
}, []);
|
|
|
|
|
|
2026-03-01 20:43:25 +00:00
|
|
|
const addEntity = async (entityData: CreateUpdateSqlTableDto) => {
|
2026-02-24 20:44:16 +00:00
|
|
|
try {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
2026-03-01 20:43:25 +00:00
|
|
|
const newEntity = await developerKitService.createSqlTable(entityData);
|
2026-02-24 20:44:16 +00:00
|
|
|
setEntities((prev) => [...prev, newEntity]);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
setError(err instanceof Error ? err.message : "Failed to create entity");
|
|
|
|
|
throw err;
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-01 20:43:25 +00:00
|
|
|
const updateEntity = async (id: string, entityData: CreateUpdateSqlTableDto) => {
|
2026-02-24 20:44:16 +00:00
|
|
|
try {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
2026-03-01 20:43:25 +00:00
|
|
|
const updatedEntity = await developerKitService.updateSqlTable(id, entityData);
|
|
|
|
|
setEntities((prev) => prev.map((e) => (e.id === id ? updatedEntity : e)));
|
2026-02-24 20:44:16 +00:00
|
|
|
await refreshEntities();
|
|
|
|
|
} catch (err) {
|
|
|
|
|
setError(err instanceof Error ? err.message : "Failed to update entity");
|
|
|
|
|
throw err;
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const deleteEntity = async (id: string) => {
|
|
|
|
|
try {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
2026-03-01 20:43:25 +00:00
|
|
|
await developerKitService.deleteSqlTable(id);
|
|
|
|
|
setEntities((prev) => prev.filter((e) => e.id !== id));
|
|
|
|
|
setGeneratedEndpoints((prev) => prev.filter((ep) => ep.entityId !== id));
|
2026-02-24 20:44:16 +00:00
|
|
|
} catch (err) {
|
|
|
|
|
setError(err instanceof Error ? err.message : "Failed to delete entity");
|
|
|
|
|
throw err;
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const toggleEntityActiveStatus = async (id: string) => {
|
|
|
|
|
try {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
2026-03-01 20:43:25 +00:00
|
|
|
await developerKitService.toggleSqlTableActiveStatus(id);
|
2026-02-24 20:44:16 +00:00
|
|
|
await refreshEntities();
|
|
|
|
|
} catch (err) {
|
2026-03-01 20:43:25 +00:00
|
|
|
setError(err instanceof Error ? err.message : "Failed to toggle entity status");
|
2026-02-24 20:44:16 +00:00
|
|
|
throw err;
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-01 20:43:25 +00:00
|
|
|
const getEntity = (id: string): SqlTable | undefined =>
|
|
|
|
|
entities.find((e) => e.id === id);
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
const generateCrudEndpoints = async (entityId: string) => {
|
|
|
|
|
try {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
const endpointsData = await developerKitService.generateCrudEndpoints(entityId);
|
|
|
|
|
setGeneratedEndpoints((prev) => [
|
|
|
|
|
...prev.filter((e) => e.entityId !== entityId),
|
2026-03-01 20:43:25 +00:00
|
|
|
...(endpointsData.items || []),
|
2026-02-24 20:44:16 +00:00
|
|
|
]);
|
|
|
|
|
await refreshEntities();
|
|
|
|
|
} catch (err) {
|
|
|
|
|
setError(err instanceof Error ? err.message : "Failed to generate CRUD endpoints");
|
|
|
|
|
throw err;
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const toggleEndpoint = async (endpointId: string) => {
|
|
|
|
|
try {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
const updatedEndpoint = await developerKitService.toggleGeneratedEndpoint(endpointId);
|
|
|
|
|
setGeneratedEndpoints((prev) =>
|
2026-03-01 20:43:25 +00:00
|
|
|
prev.map((e) => (e.id === endpointId ? updatedEndpoint : e)),
|
2026-02-24 20:44:16 +00:00
|
|
|
);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
setError(err instanceof Error ? err.message : "Failed to toggle endpoint");
|
|
|
|
|
throw err;
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-03-01 20:43:25 +00:00
|
|
|
const getEntityEndpoints = (entityId: string): CrudEndpoint[] =>
|
|
|
|
|
generatedEndpoints.filter((e) => e.entityId === entityId);
|
2026-02-24 20:44:16 +00:00
|
|
|
|
|
|
|
|
const deleteGeneratedEndpoint = async (id: string) => {
|
|
|
|
|
try {
|
|
|
|
|
setLoading(true);
|
|
|
|
|
setError(null);
|
|
|
|
|
await developerKitService.deleteGeneratedEndpoint(id);
|
2026-03-01 20:43:25 +00:00
|
|
|
setGeneratedEndpoints((prev) => prev.filter((e) => e.id !== id));
|
2026-02-24 20:44:16 +00:00
|
|
|
} catch (err) {
|
|
|
|
|
setError(err instanceof Error ? err.message : "Failed to delete generated endpoint");
|
|
|
|
|
throw err;
|
|
|
|
|
} finally {
|
|
|
|
|
setLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<EntityContext.Provider
|
|
|
|
|
value={{
|
|
|
|
|
entities,
|
|
|
|
|
generatedEndpoints,
|
|
|
|
|
loading,
|
|
|
|
|
error,
|
|
|
|
|
addEntity,
|
|
|
|
|
updateEntity,
|
|
|
|
|
deleteEntity,
|
|
|
|
|
getEntity,
|
|
|
|
|
refreshEntities,
|
|
|
|
|
toggleEntityActiveStatus,
|
|
|
|
|
generateCrudEndpoints,
|
|
|
|
|
toggleEndpoint,
|
|
|
|
|
getEntityEndpoints,
|
|
|
|
|
deleteGeneratedEndpoint,
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{children}
|
|
|
|
|
</EntityContext.Provider>
|
|
|
|
|
);
|
|
|
|
|
};
|