Refactor ProgressModal and API logging
- Removed AI request logging from `autoGenerateIdeas`, `generateSingleIdea`, `autoGenerateContent`, and `autoGenerateImages` functions to streamline API calls. - Updated `useProgressModal` to enhance step logging by directly processing request and response steps, improving clarity and performance. - Cleaned up deprecated logging imports in `TablePageTemplate` to reflect the removal of frontend debug logging.
This commit is contained in:
@@ -496,33 +496,6 @@ export function useProgressModal(): UseProgressModalReturn {
|
|||||||
// Sort by step number and update state
|
// Sort by step number and update state
|
||||||
allSteps.sort((a, b) => a.stepNumber - b.stepNumber);
|
allSteps.sort((a, b) => a.stepNumber - b.stepNumber);
|
||||||
setStepLogs(allSteps);
|
setStepLogs(allSteps);
|
||||||
|
|
||||||
// Also update AI request logs store
|
|
||||||
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
|
|
||||||
const logs = useAIRequestLogsStore?.getState().logs || [];
|
|
||||||
const log = logs.find(l => l.response?.data?.task_id === taskId);
|
|
||||||
if (log) {
|
|
||||||
const addRequestStep = useAIRequestLogsStore?.getState().addRequestStep;
|
|
||||||
const addResponseStep = useAIRequestLogsStore?.getState().addResponseStep;
|
|
||||||
|
|
||||||
if (meta.request_steps && Array.isArray(meta.request_steps)) {
|
|
||||||
meta.request_steps.forEach((step: any) => {
|
|
||||||
// Only add if not already present
|
|
||||||
if (!log.requestSteps.find(s => s.stepNumber === step.stepNumber)) {
|
|
||||||
addRequestStep?.(log.id, step);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta.response_steps && Array.isArray(meta.response_steps)) {
|
|
||||||
meta.response_steps.forEach((step: any) => {
|
|
||||||
// Only add if not already present
|
|
||||||
if (!log.responseSteps.find(s => s.stepNumber === step.stepNumber)) {
|
|
||||||
addResponseStep?.(log.id, step);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (response.state === 'SUCCESS') {
|
} else if (response.state === 'SUCCESS') {
|
||||||
const meta = response.meta || {};
|
const meta = response.meta || {};
|
||||||
@@ -586,32 +559,6 @@ export function useProgressModal(): UseProgressModalReturn {
|
|||||||
// Sort by step number and update state
|
// Sort by step number and update state
|
||||||
allSteps.sort((a, b) => a.stepNumber - b.stepNumber);
|
allSteps.sort((a, b) => a.stepNumber - b.stepNumber);
|
||||||
setStepLogs(allSteps);
|
setStepLogs(allSteps);
|
||||||
|
|
||||||
// Also update AI request logs store
|
|
||||||
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
|
|
||||||
const logs = useAIRequestLogsStore?.getState().logs || [];
|
|
||||||
// Find log by task_id in response data or by matching the most recent log
|
|
||||||
const log = logs.find(l => l.response?.data?.task_id === taskId) || logs[0];
|
|
||||||
if (log) {
|
|
||||||
const addRequestStep = useAIRequestLogsStore?.getState().addRequestStep;
|
|
||||||
const addResponseStep = useAIRequestLogsStore?.getState().addResponseStep;
|
|
||||||
|
|
||||||
if (meta.request_steps && Array.isArray(meta.request_steps)) {
|
|
||||||
meta.request_steps.forEach((step: any) => {
|
|
||||||
if (!log.requestSteps.find(s => s.stepNumber === step.stepNumber)) {
|
|
||||||
addRequestStep?.(log.id, step);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta.response_steps && Array.isArray(meta.response_steps)) {
|
|
||||||
meta.response_steps.forEach((step: any) => {
|
|
||||||
if (!log.responseSteps.find(s => s.stepNumber === step.stepNumber)) {
|
|
||||||
addResponseStep?.(log.id, step);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop polling on SUCCESS
|
// Stop polling on SUCCESS
|
||||||
@@ -634,29 +581,40 @@ export function useProgressModal(): UseProgressModalReturn {
|
|||||||
|
|
||||||
// Update step logs from failure response
|
// Update step logs from failure response
|
||||||
if (meta.request_steps || meta.response_steps) {
|
if (meta.request_steps || meta.response_steps) {
|
||||||
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
|
const allSteps: Array<{
|
||||||
const logs = useAIRequestLogsStore?.getState().logs || [];
|
stepNumber: number;
|
||||||
const log = logs.find(l => l.response?.data?.task_id === taskId);
|
stepName: string;
|
||||||
if (log) {
|
status: string;
|
||||||
const addRequestStep = useAIRequestLogsStore?.getState().addRequestStep;
|
message: string;
|
||||||
const addResponseStep = useAIRequestLogsStore?.getState().addResponseStep;
|
timestamp?: number;
|
||||||
|
}> = [];
|
||||||
if (meta.request_steps && Array.isArray(meta.request_steps)) {
|
|
||||||
meta.request_steps.forEach((step: any) => {
|
if (meta.request_steps && Array.isArray(meta.request_steps)) {
|
||||||
if (!log.requestSteps.find(s => s.stepNumber === step.stepNumber)) {
|
meta.request_steps.forEach((step: any) => {
|
||||||
addRequestStep?.(log.id, step);
|
allSteps.push({
|
||||||
}
|
stepNumber: step.stepNumber || 0,
|
||||||
|
stepName: step.stepName || 'Unknown',
|
||||||
|
status: step.status || 'error',
|
||||||
|
message: step.message || '',
|
||||||
|
timestamp: step.timestamp,
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
if (meta.response_steps && Array.isArray(meta.response_steps)) {
|
|
||||||
meta.response_steps.forEach((step: any) => {
|
|
||||||
if (!log.responseSteps.find(s => s.stepNumber === step.stepNumber)) {
|
|
||||||
addResponseStep?.(log.id, step);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (meta.response_steps && Array.isArray(meta.response_steps)) {
|
||||||
|
meta.response_steps.forEach((step: any) => {
|
||||||
|
allSteps.push({
|
||||||
|
stepNumber: step.stepNumber || 0,
|
||||||
|
stepName: step.stepName || 'Unknown',
|
||||||
|
status: step.status || 'error',
|
||||||
|
message: step.message || '',
|
||||||
|
timestamp: step.timestamp,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
allSteps.sort((a, b) => a.stepNumber - b.stepNumber);
|
||||||
|
setStepLogs(allSteps);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop polling on FAILURE
|
// Stop polling on FAILURE
|
||||||
|
|||||||
@@ -596,165 +596,33 @@ export async function autoClusterKeywords(keywordIds: number[], sectorId?: numbe
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function autoGenerateIdeas(clusterIds: number[]): Promise<{ success: boolean; task_id?: string; ideas_created?: number; message?: string; error?: string }> {
|
export async function autoGenerateIdeas(clusterIds: number[]): Promise<{ success: boolean; task_id?: string; ideas_created?: number; message?: string; error?: string }> {
|
||||||
const startTime = Date.now();
|
|
||||||
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
|
|
||||||
const addLog = useAIRequestLogsStore?.getState().addLog;
|
|
||||||
|
|
||||||
const endpoint = `/v1/planner/clusters/auto_generate_ideas/`;
|
const endpoint = `/v1/planner/clusters/auto_generate_ideas/`;
|
||||||
const requestBody = { ids: clusterIds };
|
const requestBody = { ids: clusterIds };
|
||||||
|
|
||||||
addLog?.({
|
|
||||||
function: 'autoGenerateIdeas',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
status: 'pending',
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetchAPI(endpoint, {
|
const response = await fetchAPI(endpoint, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(requestBody),
|
body: JSON.stringify(requestBody),
|
||||||
});
|
});
|
||||||
|
|
||||||
const duration = Date.now() - startTime;
|
|
||||||
addLog({
|
|
||||||
function: 'autoGenerateIdeas',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
status: 200,
|
|
||||||
data: response,
|
|
||||||
},
|
|
||||||
status: 'success',
|
|
||||||
duration,
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const duration = Date.now() - startTime;
|
|
||||||
|
|
||||||
// Parse error message to extract error type
|
|
||||||
let errorType = 'UNKNOWN_ERROR';
|
|
||||||
let errorMessage = error.message || 'Unknown error';
|
|
||||||
|
|
||||||
if (errorMessage.includes('OperationalError')) {
|
|
||||||
errorType = 'DATABASE_ERROR';
|
|
||||||
errorMessage = errorMessage.replace(/API Error \(\d+\): /, '').replace(/ - .*OperationalError.*/, ' - Database operation failed');
|
|
||||||
} else if (errorMessage.includes('ValidationError')) {
|
|
||||||
errorType = 'VALIDATION_ERROR';
|
|
||||||
} else if (errorMessage.includes('PermissionDenied')) {
|
|
||||||
errorType = 'PERMISSION_ERROR';
|
|
||||||
} else if (errorMessage.match(/API Error \(\d+\): ([^-]+)/)) {
|
|
||||||
const match = errorMessage.match(/API Error \(\d+\): ([^-]+)/);
|
|
||||||
if (match) {
|
|
||||||
errorType = match[1].trim();
|
|
||||||
errorMessage = errorMessage.replace(/API Error \(\d+\): [^-]+ - /, '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addLog?.({
|
|
||||||
function: 'autoGenerateIdeas',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
status: 500,
|
|
||||||
error: errorMessage,
|
|
||||||
errorType,
|
|
||||||
},
|
|
||||||
status: 'error',
|
|
||||||
duration,
|
|
||||||
});
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateSingleIdea(ideaId: string | number, clusterId: number): Promise<{ success: boolean; task_id?: string; idea_created?: number; message?: string; error?: string }> {
|
export async function generateSingleIdea(ideaId: string | number, clusterId: number): Promise<{ success: boolean; task_id?: string; idea_created?: number; message?: string; error?: string }> {
|
||||||
const startTime = Date.now();
|
|
||||||
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
|
|
||||||
const addLog = useAIRequestLogsStore?.getState().addLog;
|
|
||||||
|
|
||||||
const endpoint = `/v1/planner/ideas/${ideaId}/generate_idea/`;
|
const endpoint = `/v1/planner/ideas/${ideaId}/generate_idea/`;
|
||||||
const requestBody = { cluster_id: clusterId };
|
const requestBody = { cluster_id: clusterId };
|
||||||
|
|
||||||
addLog?.({
|
|
||||||
function: 'generateSingleIdea',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
status: 'pending',
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetchAPI(endpoint, {
|
const response = await fetchAPI(endpoint, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(requestBody),
|
body: JSON.stringify(requestBody),
|
||||||
});
|
});
|
||||||
|
|
||||||
const duration = Date.now() - startTime;
|
|
||||||
addLog?.({
|
|
||||||
function: 'generateSingleIdea',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
status: 200,
|
|
||||||
data: response,
|
|
||||||
},
|
|
||||||
status: 'success',
|
|
||||||
duration,
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const duration = Date.now() - startTime;
|
|
||||||
|
|
||||||
// Parse error message to extract error type
|
|
||||||
let errorType = 'UNKNOWN_ERROR';
|
|
||||||
let errorMessage = error.message || 'Unknown error';
|
|
||||||
|
|
||||||
if (errorMessage.includes('OperationalError')) {
|
|
||||||
errorType = 'DATABASE_ERROR';
|
|
||||||
errorMessage = errorMessage.replace(/API Error \(\d+\): /, '').replace(/ - .*OperationalError.*/, ' - Database operation failed');
|
|
||||||
} else if (errorMessage.includes('ValidationError')) {
|
|
||||||
errorType = 'VALIDATION_ERROR';
|
|
||||||
} else if (errorMessage.includes('PermissionDenied')) {
|
|
||||||
errorType = 'PERMISSION_ERROR';
|
|
||||||
} else if (errorMessage.match(/API Error \(\d+\): ([^-]+)/)) {
|
|
||||||
const match = errorMessage.match(/API Error \(\d+\): ([^-]+)/);
|
|
||||||
if (match) {
|
|
||||||
errorType = match[1].trim();
|
|
||||||
errorMessage = errorMessage.replace(/API Error \(\d+\): [^-]+ - /, '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addLog?.({
|
|
||||||
function: 'generateSingleIdea',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
status: 500,
|
|
||||||
error: errorMessage,
|
|
||||||
errorType,
|
|
||||||
},
|
|
||||||
status: 'error',
|
|
||||||
duration,
|
|
||||||
});
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1051,161 +919,33 @@ export async function bulkUpdateTasksStatus(ids: number[], status: string): Prom
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function autoGenerateContent(ids: number[]): Promise<{ success: boolean; task_id?: string; tasks_updated?: number; message?: string; error?: string }> {
|
export async function autoGenerateContent(ids: number[]): Promise<{ success: boolean; task_id?: string; tasks_updated?: number; message?: string; error?: string }> {
|
||||||
const startTime = Date.now();
|
|
||||||
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
|
|
||||||
const addLog = useAIRequestLogsStore?.getState().addLog;
|
|
||||||
|
|
||||||
const endpoint = `/v1/writer/tasks/auto_generate_content/`;
|
const endpoint = `/v1/writer/tasks/auto_generate_content/`;
|
||||||
const requestBody = { ids };
|
const requestBody = { ids };
|
||||||
|
|
||||||
addLog?.({
|
|
||||||
function: 'autoGenerateContent',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
status: 'pending',
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetchAPI(endpoint, {
|
const response = await fetchAPI(endpoint, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(requestBody),
|
body: JSON.stringify(requestBody),
|
||||||
});
|
});
|
||||||
|
|
||||||
const duration = Date.now() - startTime;
|
|
||||||
addLog({
|
|
||||||
function: 'autoGenerateContent',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
status: 200,
|
|
||||||
data: response,
|
|
||||||
},
|
|
||||||
status: 'success',
|
|
||||||
duration,
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const duration = Date.now() - startTime;
|
|
||||||
|
|
||||||
// Parse error message to extract error type
|
|
||||||
let errorType = 'UNKNOWN_ERROR';
|
|
||||||
let errorMessage = error.message || 'Unknown error';
|
|
||||||
|
|
||||||
if (errorMessage.includes('OperationalError')) {
|
|
||||||
errorType = 'DATABASE_ERROR';
|
|
||||||
errorMessage = errorMessage.replace(/API Error \(\d+\): /, '').replace(/ - .*OperationalError.*/, ' - Database operation failed');
|
|
||||||
} else if (errorMessage.includes('ValidationError')) {
|
|
||||||
errorType = 'VALIDATION_ERROR';
|
|
||||||
} else if (errorMessage.match(/API Error \(\d+\): ([^-]+)/)) {
|
|
||||||
const match = errorMessage.match(/API Error \(\d+\): ([^-]+)/);
|
|
||||||
if (match) {
|
|
||||||
errorType = match[1].trim();
|
|
||||||
errorMessage = errorMessage.replace(/API Error \(\d+\): [^-]+ - /, '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addLog?.({
|
|
||||||
function: 'autoGenerateContent',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
status: 500,
|
|
||||||
error: errorMessage,
|
|
||||||
errorType,
|
|
||||||
},
|
|
||||||
status: 'error',
|
|
||||||
duration,
|
|
||||||
});
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function autoGenerateImages(taskIds: number[]): Promise<{ success: boolean; task_id?: string; images_created?: number; message?: string; error?: string }> {
|
export async function autoGenerateImages(taskIds: number[]): Promise<{ success: boolean; task_id?: string; images_created?: number; message?: string; error?: string }> {
|
||||||
const startTime = Date.now();
|
|
||||||
const { useAIRequestLogsStore } = await import('../store/aiRequestLogsStore').catch(() => ({ useAIRequestLogsStore: null }));
|
|
||||||
const addLog = useAIRequestLogsStore?.getState().addLog;
|
|
||||||
|
|
||||||
const endpoint = `/v1/writer/tasks/auto_generate_images/`;
|
const endpoint = `/v1/writer/tasks/auto_generate_images/`;
|
||||||
const requestBody = { task_ids: taskIds };
|
const requestBody = { task_ids: taskIds };
|
||||||
|
|
||||||
addLog?.({
|
|
||||||
function: 'autoGenerateImages',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
status: 'pending',
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetchAPI(endpoint, {
|
const response = await fetchAPI(endpoint, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(requestBody),
|
body: JSON.stringify(requestBody),
|
||||||
});
|
});
|
||||||
|
|
||||||
const duration = Date.now() - startTime;
|
|
||||||
addLog({
|
|
||||||
function: 'autoGenerateImages',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
status: 200,
|
|
||||||
data: response,
|
|
||||||
},
|
|
||||||
status: 'success',
|
|
||||||
duration,
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const duration = Date.now() - startTime;
|
|
||||||
|
|
||||||
// Parse error message to extract error type
|
|
||||||
let errorType = 'UNKNOWN_ERROR';
|
|
||||||
let errorMessage = error.message || 'Unknown error';
|
|
||||||
|
|
||||||
if (errorMessage.includes('OperationalError')) {
|
|
||||||
errorType = 'DATABASE_ERROR';
|
|
||||||
errorMessage = errorMessage.replace(/API Error \(\d+\): /, '').replace(/ - .*OperationalError.*/, ' - Database operation failed');
|
|
||||||
} else if (errorMessage.includes('ValidationError')) {
|
|
||||||
errorType = 'VALIDATION_ERROR';
|
|
||||||
} else if (errorMessage.match(/API Error \(\d+\): ([^-]+)/)) {
|
|
||||||
const match = errorMessage.match(/API Error \(\d+\): ([^-]+)/);
|
|
||||||
if (match) {
|
|
||||||
errorType = match[1].trim();
|
|
||||||
errorMessage = errorMessage.replace(/API Error \(\d+\): [^-]+ - /, '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addLog?.({
|
|
||||||
function: 'autoGenerateImages',
|
|
||||||
endpoint,
|
|
||||||
request: {
|
|
||||||
method: 'POST',
|
|
||||||
body: requestBody,
|
|
||||||
},
|
|
||||||
response: {
|
|
||||||
status: 500,
|
|
||||||
error: errorMessage,
|
|
||||||
errorType,
|
|
||||||
},
|
|
||||||
status: 'error',
|
|
||||||
duration,
|
|
||||||
});
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ import BulkStatusUpdateModal from '../components/common/BulkStatusUpdateModal';
|
|||||||
import { CompactPagination } from '../components/ui/pagination';
|
import { CompactPagination } from '../components/ui/pagination';
|
||||||
import SectorSelector from '../components/common/SectorSelector';
|
import SectorSelector from '../components/common/SectorSelector';
|
||||||
import { usePageSizeStore } from '../store/pageSizeStore';
|
import { usePageSizeStore } from '../store/pageSizeStore';
|
||||||
// DEPRECATED: Frontend debug logging removed - now using backend console logging
|
|
||||||
// import { useAIRequestLogsStore } from '../store/aiRequestLogsStore';
|
|
||||||
import ToggleTableRow, { ToggleButton } from '../components/common/ToggleTableRow';
|
import ToggleTableRow, { ToggleButton } from '../components/common/ToggleTableRow';
|
||||||
|
|
||||||
interface ColumnConfig {
|
interface ColumnConfig {
|
||||||
|
|||||||
Reference in New Issue
Block a user