mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-07-29 08:35:30 +00:00
Demo ready
This commit is contained in:
parent
1c342b60ba
commit
ed618648e0
@ -26,8 +26,10 @@ if errorlevel 1 (
|
|||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
REM Find the built JAR
|
REM Find the built JAR(s)
|
||||||
for %%f in (build\libs\Stirling-PDF-*.jar) do set STIRLING_JAR=%%f
|
echo ▶ Listing all built JAR files in stirling-pdf\build\libs:
|
||||||
|
dir /b stirling-pdf\build\libs\Stirling-PDF-*.jar
|
||||||
|
for %%f in (stirling-pdf\build\libs\Stirling-PDF-*.jar) do set STIRLING_JAR=%%f
|
||||||
if not exist "%STIRLING_JAR%" (
|
if not exist "%STIRLING_JAR%" (
|
||||||
echo ❌ No Stirling-PDF JAR found in build/libs/
|
echo ❌ No Stirling-PDF JAR found in build/libs/
|
||||||
exit /b 1
|
exit /b 1
|
||||||
@ -43,6 +45,10 @@ echo ▶ Copying JAR to Tauri libs directory...
|
|||||||
copy "%STIRLING_JAR%" "frontend\src-tauri\libs\"
|
copy "%STIRLING_JAR%" "frontend\src-tauri\libs\"
|
||||||
echo ✅ JAR copied to frontend\src-tauri\libs\
|
echo ✅ JAR copied to frontend\src-tauri\libs\
|
||||||
|
|
||||||
|
REM Log out all JAR files now in the Tauri libs directory
|
||||||
|
echo ▶ Listing all JAR files in frontend\src-tauri\libs after copy:
|
||||||
|
dir /b frontend\src-tauri\libs\Stirling-PDF-*.jar
|
||||||
|
|
||||||
echo ▶ Creating custom JRE with jlink...
|
echo ▶ Creating custom JRE with jlink...
|
||||||
if exist "frontend\src-tauri\runtime\jre" rmdir /s /q "frontend\src-tauri\runtime\jre"
|
if exist "frontend\src-tauri\runtime\jre" rmdir /s /q "frontend\src-tauri\runtime\jre"
|
||||||
|
|
||||||
|
@ -62,13 +62,13 @@ fi
|
|||||||
print_step "Building Stirling-PDF JAR..."
|
print_step "Building Stirling-PDF JAR..."
|
||||||
./gradlew clean bootJar --no-daemon
|
./gradlew clean bootJar --no-daemon
|
||||||
|
|
||||||
if [ ! -f "build/libs/Stirling-PDF-"*.jar ]; then
|
if [ ! -f "stirling-pdf/build/libs/Stirling-PDF-"*.jar ]; then
|
||||||
print_error "Failed to build Stirling-PDF JAR"
|
print_error "Failed to build Stirling-PDF JAR"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Find the built JAR
|
# Find the built JAR
|
||||||
STIRLING_JAR=$(ls build/libs/Stirling-PDF-*.jar | head -n 1)
|
STIRLING_JAR=$(ls stirling-pdf/build/libs/Stirling-PDF-*.jar | head -n 1)
|
||||||
print_success "Built JAR: $STIRLING_JAR"
|
print_success "Built JAR: $STIRLING_JAR"
|
||||||
|
|
||||||
# Create directories for Tauri
|
# Create directories for Tauri
|
||||||
|
@ -8,6 +8,7 @@ use std::collections::VecDeque;
|
|||||||
|
|
||||||
static BACKEND_PROCESS: Mutex<Option<tauri_plugin_shell::process::CommandChild>> = Mutex::new(None);
|
static BACKEND_PROCESS: Mutex<Option<tauri_plugin_shell::process::CommandChild>> = Mutex::new(None);
|
||||||
static BACKEND_LOGS: Mutex<VecDeque<String>> = Mutex::new(VecDeque::new());
|
static BACKEND_LOGS: Mutex<VecDeque<String>> = Mutex::new(VecDeque::new());
|
||||||
|
static BACKEND_STARTING: Mutex<bool> = Mutex::new(false);
|
||||||
|
|
||||||
// Helper function to add log entry
|
// Helper function to add log entry
|
||||||
fn add_log(message: String) {
|
fn add_log(message: String) {
|
||||||
@ -20,25 +21,42 @@ fn add_log(message: String) {
|
|||||||
println!("{}", message); // Also print to console
|
println!("{}", message); // Also print to console
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper function to reset starting flag
|
||||||
|
fn reset_starting_flag() {
|
||||||
|
let mut starting_guard = BACKEND_STARTING.lock().unwrap();
|
||||||
|
*starting_guard = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Command to start the backend with bundled JRE
|
// Command to start the backend with bundled JRE
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn start_backend(app: tauri::AppHandle) -> Result<String, String> {
|
async fn start_backend(app: tauri::AppHandle) -> Result<String, String> {
|
||||||
add_log("🚀 start_backend() called - Attempting to start backend with bundled JRE...".to_string());
|
add_log("🚀 start_backend() called - Attempting to start backend with bundled JRE...".to_string());
|
||||||
|
|
||||||
// Check if backend is already running
|
// Check if backend is already running or starting
|
||||||
{
|
{
|
||||||
let process_guard = BACKEND_PROCESS.lock().unwrap();
|
let process_guard = BACKEND_PROCESS.lock().unwrap();
|
||||||
if process_guard.is_some() {
|
if process_guard.is_some() {
|
||||||
add_log("⚠️ Backend already running, skipping start".to_string());
|
add_log("⚠️ Backend process already running, skipping start".to_string());
|
||||||
return Ok("Backend already running".to_string());
|
return Ok("Backend already running".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check and set starting flag to prevent multiple simultaneous starts
|
||||||
|
{
|
||||||
|
let mut starting_guard = BACKEND_STARTING.lock().unwrap();
|
||||||
|
if *starting_guard {
|
||||||
|
add_log("⚠️ Backend already starting, skipping duplicate start".to_string());
|
||||||
|
return Ok("Backend startup already in progress".to_string());
|
||||||
|
}
|
||||||
|
*starting_guard = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Use Tauri's resource API to find the bundled JRE and JAR
|
// Use Tauri's resource API to find the bundled JRE and JAR
|
||||||
let resource_dir = app.path().resource_dir().map_err(|e| {
|
let resource_dir = app.path().resource_dir().map_err(|e| {
|
||||||
let error_msg = format!("❌ Failed to get resource directory: {}", e);
|
let error_msg = format!("❌ Failed to get resource directory: {}", e);
|
||||||
add_log(error_msg.clone());
|
add_log(error_msg.clone());
|
||||||
|
reset_starting_flag();
|
||||||
error_msg
|
error_msg
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -55,6 +73,7 @@ async fn start_backend(app: tauri::AppHandle) -> Result<String, String> {
|
|||||||
if !java_executable.exists() {
|
if !java_executable.exists() {
|
||||||
let error_msg = format!("❌ Bundled JRE not found at: {:?}", java_executable);
|
let error_msg = format!("❌ Bundled JRE not found at: {:?}", java_executable);
|
||||||
add_log(error_msg.clone());
|
add_log(error_msg.clone());
|
||||||
|
reset_starting_flag();
|
||||||
return Err(error_msg);
|
return Err(error_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,26 +85,32 @@ async fn start_backend(app: tauri::AppHandle) -> Result<String, String> {
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let error_msg = format!("Failed to read libs directory: {}. Make sure the JAR is copied to libs/", e);
|
let error_msg = format!("Failed to read libs directory: {}. Make sure the JAR is copied to libs/", e);
|
||||||
add_log(error_msg.clone());
|
add_log(error_msg.clone());
|
||||||
|
reset_starting_flag();
|
||||||
error_msg
|
error_msg
|
||||||
})?
|
})?
|
||||||
.filter_map(|entry| entry.ok())
|
.filter_map(|entry| entry.ok())
|
||||||
.filter(|entry| {
|
.filter(|entry| {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
path.extension().and_then(|s| s.to_str()) == Some("jar")
|
// Match any .jar file containing "stirling-pdf" (case-insensitive)
|
||||||
&& path.file_name().unwrap().to_string_lossy().contains("Stirling-PDF")
|
path.extension().and_then(|s| s.to_str()).map(|ext| ext.eq_ignore_ascii_case("jar")).unwrap_or(false)
|
||||||
|
&& path.file_name()
|
||||||
|
.and_then(|f| f.to_str())
|
||||||
|
.map(|name| name.to_ascii_lowercase().contains("stirling-pdf"))
|
||||||
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if jar_files.is_empty() {
|
if jar_files.is_empty() {
|
||||||
let error_msg = "No Stirling-PDF JAR found in libs directory.".to_string();
|
let error_msg = "No Stirling-PDF JAR found in libs directory.".to_string();
|
||||||
add_log(error_msg.clone());
|
add_log(error_msg.clone());
|
||||||
|
reset_starting_flag();
|
||||||
return Err(error_msg);
|
return Err(error_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort by filename to get the latest version
|
// Sort by filename to get the latest version (case-insensitive)
|
||||||
jar_files.sort_by(|a, b| {
|
jar_files.sort_by(|a, b| {
|
||||||
let name_a = a.file_name().to_string_lossy().to_string();
|
let name_a = a.file_name().to_string_lossy().to_ascii_lowercase();
|
||||||
let name_b = b.file_name().to_string_lossy().to_string();
|
let name_b = b.file_name().to_string_lossy().to_ascii_lowercase();
|
||||||
name_b.cmp(&name_a) // Reverse order to get latest first
|
name_b.cmp(&name_a) // Reverse order to get latest first
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -155,6 +180,7 @@ async fn start_backend(app: tauri::AppHandle) -> Result<String, String> {
|
|||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let error_msg = format!("❌ Failed to spawn sidecar: {}", e);
|
let error_msg = format!("❌ Failed to spawn sidecar: {}", e);
|
||||||
add_log(error_msg.clone());
|
add_log(error_msg.clone());
|
||||||
|
reset_starting_flag();
|
||||||
error_msg
|
error_msg
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -249,6 +275,10 @@ async fn start_backend(app: tauri::AppHandle) -> Result<String, String> {
|
|||||||
println!("⏳ Waiting for backend startup...");
|
println!("⏳ Waiting for backend startup...");
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(10000)).await;
|
tokio::time::sleep(std::time::Duration::from_millis(10000)).await;
|
||||||
|
|
||||||
|
// Reset the starting flag since startup is complete
|
||||||
|
reset_starting_flag();
|
||||||
|
add_log("✅ Backend startup sequence completed, starting flag cleared".to_string());
|
||||||
|
|
||||||
Ok("Backend startup initiated successfully with bundled JRE".to_string())
|
Ok("Backend startup initiated successfully with bundled JRE".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,8 +349,12 @@ async fn check_jar_exists(app: tauri::AppHandle) -> Result<String, String> {
|
|||||||
.filter_map(|entry| entry.ok())
|
.filter_map(|entry| entry.ok())
|
||||||
.filter(|entry| {
|
.filter(|entry| {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
path.extension().and_then(|s| s.to_str()) == Some("jar")
|
// Match any .jar file containing "stirling-pdf" (case-insensitive)
|
||||||
&& path.file_name().unwrap().to_string_lossy().contains("Stirling-PDF")
|
path.extension().and_then(|s| s.to_str()).map(|ext| ext.eq_ignore_ascii_case("jar")).unwrap_or(false)
|
||||||
|
&& path.file_name()
|
||||||
|
.and_then(|f| f.to_str())
|
||||||
|
.map(|name| name.to_ascii_lowercase().contains("stirling-pdf"))
|
||||||
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
.map(|entry| entry.file_name().to_string_lossy().to_string())
|
.map(|entry| entry.file_name().to_string_lossy().to_string())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React from 'react';
|
|
||||||
import { RainbowThemeProvider } from './components/shared/RainbowThemeProvider';
|
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
|
import { RainbowThemeProvider } from './components/shared/RainbowThemeProvider';
|
||||||
import HomePage from './pages/HomePage';
|
import HomePage from './pages/HomePage';
|
||||||
|
|
||||||
// Import global styles
|
// Import global styles
|
||||||
@ -15,11 +14,14 @@ export default function App() {
|
|||||||
const initializeBackend = async () => {
|
const initializeBackend = async () => {
|
||||||
try {
|
try {
|
||||||
// Check if we're running in Tauri environment
|
// Check if we're running in Tauri environment
|
||||||
if (typeof window !== 'undefined' && window.__TAURI__) {
|
if (typeof window !== 'undefined' && (window.__TAURI__ || window.__TAURI_INTERNALS__)) {
|
||||||
const { tauriBackendService } = await import('./services/tauriBackendService');
|
const { tauriBackendService } = await import('./services/tauriBackendService');
|
||||||
console.log('Running in Tauri - Starting backend on React app startup...');
|
console.log('Running in Tauri - Starting backend on React app startup...');
|
||||||
await tauriBackendService.startBackend();
|
await tauriBackendService.startBackend();
|
||||||
console.log('Backend started successfully');
|
console.log('Backend started successfully');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.warn('Not running in Tauri - Backend will not be started');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to start backend on app startup:', error);
|
console.error('Failed to start backend on app startup:', error);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
import { makeApiUrl } from '../utils/api';
|
||||||
|
|
||||||
export interface AppConfig {
|
export interface AppConfig {
|
||||||
baseUrl?: string;
|
baseUrl?: string;
|
||||||
@ -46,7 +47,7 @@ export function useAppConfig(): UseAppConfigReturn {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
const response = await fetch('/api/v1/config/app-config');
|
const response = await fetch(makeApiUrl('/api/v1/config/app-config'));
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`Failed to fetch config: ${response.status} ${response.statusText}`);
|
throw new Error(`Failed to fetch config: ${response.status} ${response.statusText}`);
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
import { makeApiUrl } from '../utils/api';
|
||||||
|
import { useBackendHealth } from './useBackendHealth';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook to check if a specific endpoint is enabled
|
* Hook to check if a specific endpoint is enabled
|
||||||
*/
|
*/
|
||||||
export function useEndpointEnabled(endpoint: string): {
|
export function useEndpointEnabled(endpoint: string, backendHealthy?: boolean): {
|
||||||
enabled: boolean | null;
|
enabled: boolean | null;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
@ -24,7 +26,7 @@ export function useEndpointEnabled(endpoint: string): {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
const response = await fetch(`/api/v1/config/endpoint-enabled?endpoint=${encodeURIComponent(endpoint)}`);
|
const response = await fetch(makeApiUrl(`/api/v1/config/endpoint-enabled?endpoint=${encodeURIComponent(endpoint)}`));
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`Failed to check endpoint: ${response.status} ${response.statusText}`);
|
throw new Error(`Failed to check endpoint: ${response.status} ${response.statusText}`);
|
||||||
@ -42,8 +44,16 @@ export function useEndpointEnabled(endpoint: string): {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchEndpointStatus();
|
// Only fetch endpoint status if backend is healthy (or if backendHealthy is not provided)
|
||||||
}, [endpoint]);
|
if (backendHealthy === undefined || backendHealthy === true) {
|
||||||
|
fetchEndpointStatus();
|
||||||
|
} else {
|
||||||
|
// Backend is not healthy, reset state
|
||||||
|
setEnabled(null);
|
||||||
|
setLoading(false);
|
||||||
|
setError('Backend not available');
|
||||||
|
}
|
||||||
|
}, [endpoint, backendHealthy]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
enabled,
|
enabled,
|
||||||
@ -57,7 +67,7 @@ export function useEndpointEnabled(endpoint: string): {
|
|||||||
* Hook to check multiple endpoints at once using batch API
|
* Hook to check multiple endpoints at once using batch API
|
||||||
* Returns a map of endpoint -> enabled status
|
* Returns a map of endpoint -> enabled status
|
||||||
*/
|
*/
|
||||||
export function useMultipleEndpointsEnabled(endpoints: string[]): {
|
export function useMultipleEndpointsEnabled(endpoints: string[], backendHealthy?: boolean): {
|
||||||
endpointStatus: Record<string, boolean>;
|
endpointStatus: Record<string, boolean>;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
error: string | null;
|
error: string | null;
|
||||||
@ -80,7 +90,7 @@ export function useMultipleEndpointsEnabled(endpoints: string[]): {
|
|||||||
|
|
||||||
// Use batch API for efficiency
|
// Use batch API for efficiency
|
||||||
const endpointsParam = endpoints.join(',');
|
const endpointsParam = endpoints.join(',');
|
||||||
const response = await fetch(`/api/v1/config/endpoints-enabled?endpoints=${encodeURIComponent(endpointsParam)}`);
|
const response = await fetch(makeApiUrl(`/api/v1/config/endpoints-enabled?endpoints=${encodeURIComponent(endpointsParam)}`));
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`Failed to check endpoints: ${response.status} ${response.statusText}`);
|
throw new Error(`Failed to check endpoints: ${response.status} ${response.statusText}`);
|
||||||
@ -105,8 +115,16 @@ export function useMultipleEndpointsEnabled(endpoints: string[]): {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchAllEndpointStatuses();
|
// Only fetch endpoint statuses if backend is healthy (or if backendHealthy is not provided)
|
||||||
}, [endpoints.join(',')]); // Re-run when endpoints array changes
|
if (backendHealthy === undefined || backendHealthy === true) {
|
||||||
|
fetchAllEndpointStatuses();
|
||||||
|
} else {
|
||||||
|
// Backend is not healthy, reset state
|
||||||
|
setEndpointStatus({});
|
||||||
|
setLoading(false);
|
||||||
|
setError('Backend not available');
|
||||||
|
}
|
||||||
|
}, [endpoints.join(','), backendHealthy]); // Re-run when endpoints array changes or backend health changes
|
||||||
|
|
||||||
return {
|
return {
|
||||||
endpointStatus,
|
endpointStatus,
|
||||||
@ -114,4 +132,50 @@ export function useMultipleEndpointsEnabled(endpoints: string[]): {
|
|||||||
error,
|
error,
|
||||||
refetch: fetchAllEndpointStatuses,
|
refetch: fetchAllEndpointStatuses,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience hook that combines backend health checking with endpoint status checking
|
||||||
|
* Only checks endpoint status once backend is healthy
|
||||||
|
*/
|
||||||
|
export function useEndpointEnabledWithHealthCheck(endpoint: string): {
|
||||||
|
enabled: boolean | null;
|
||||||
|
loading: boolean;
|
||||||
|
error: string | null;
|
||||||
|
backendHealthy: boolean;
|
||||||
|
refetch: () => Promise<void>;
|
||||||
|
} {
|
||||||
|
const { isHealthy: backendHealthy } = useBackendHealth();
|
||||||
|
const { enabled, loading, error, refetch } = useEndpointEnabled(endpoint, backendHealthy);
|
||||||
|
|
||||||
|
return {
|
||||||
|
enabled,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
backendHealthy,
|
||||||
|
refetch,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience hook that combines backend health checking with multiple endpoint status checking
|
||||||
|
* Only checks endpoint statuses once backend is healthy
|
||||||
|
*/
|
||||||
|
export function useMultipleEndpointsEnabledWithHealthCheck(endpoints: string[]): {
|
||||||
|
endpointStatus: Record<string, boolean>;
|
||||||
|
loading: boolean;
|
||||||
|
error: string | null;
|
||||||
|
backendHealthy: boolean;
|
||||||
|
refetch: () => Promise<void>;
|
||||||
|
} {
|
||||||
|
const { isHealthy: backendHealthy } = useBackendHealth();
|
||||||
|
const { endpointStatus, loading, error, refetch } = useMultipleEndpointsEnabled(endpoints, backendHealthy);
|
||||||
|
|
||||||
|
return {
|
||||||
|
endpointStatus,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
backendHealthy,
|
||||||
|
refetch,
|
||||||
|
};
|
||||||
}
|
}
|
@ -24,7 +24,7 @@ import CompressPdfPanel from "../tools/Compress";
|
|||||||
import MergePdfPanel from "../tools/Merge";
|
import MergePdfPanel from "../tools/Merge";
|
||||||
import ToolRenderer from "../components/tools/ToolRenderer";
|
import ToolRenderer from "../components/tools/ToolRenderer";
|
||||||
import QuickAccessBar from "../components/shared/QuickAccessBar";
|
import QuickAccessBar from "../components/shared/QuickAccessBar";
|
||||||
import { useMultipleEndpointsEnabled } from "../hooks/useEndpointConfig";
|
import { useMultipleEndpointsEnabledWithHealthCheck } from "../hooks/useEndpointConfig";
|
||||||
|
|
||||||
type ToolRegistryEntry = {
|
type ToolRegistryEntry = {
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
@ -79,7 +79,7 @@ export default function HomePage() {
|
|||||||
|
|
||||||
// Get all unique endpoints for batch checking
|
// Get all unique endpoints for batch checking
|
||||||
const allEndpoints = Array.from(new Set(Object.values(toolEndpoints).flat()));
|
const allEndpoints = Array.from(new Set(Object.values(toolEndpoints).flat()));
|
||||||
const { endpointStatus, loading: endpointsLoading } = useMultipleEndpointsEnabled(allEndpoints);
|
const { endpointStatus, loading: endpointsLoading, backendHealthy } = useMultipleEndpointsEnabledWithHealthCheck(allEndpoints);
|
||||||
|
|
||||||
// Persist active files across reloads
|
// Persist active files across reloads
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -4,7 +4,7 @@ import { Stack, Slider, Group, Text, Button, Checkbox, TextInput, Loader, Alert
|
|||||||
import { FileWithUrl } from "../types/file";
|
import { FileWithUrl } from "../types/file";
|
||||||
import { fileStorage } from "../services/fileStorage";
|
import { fileStorage } from "../services/fileStorage";
|
||||||
import { makeApiUrl } from "../utils/api";
|
import { makeApiUrl } from "../utils/api";
|
||||||
import { useEndpointEnabled } from "../hooks/useEndpointConfig";
|
import { useEndpointEnabledWithHealthCheck } from "../hooks/useEndpointConfig";
|
||||||
|
|
||||||
export interface CompressProps {
|
export interface CompressProps {
|
||||||
files?: FileWithUrl[];
|
files?: FileWithUrl[];
|
||||||
@ -37,7 +37,7 @@ const CompressPdfPanel: React.FC<CompressProps> = ({
|
|||||||
|
|
||||||
const [selected, setSelected] = useState<boolean[]>(files.map(() => false));
|
const [selected, setSelected] = useState<boolean[]>(files.map(() => false));
|
||||||
const [localLoading, setLocalLoading] = useState<boolean>(false);
|
const [localLoading, setLocalLoading] = useState<boolean>(false);
|
||||||
const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled("compress-pdf");
|
const { enabled: endpointEnabled, loading: endpointLoading, backendHealthy } = useEndpointEnabledWithHealthCheck("compress-pdf");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
compressionLevel,
|
compressionLevel,
|
||||||
|
@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { FileWithUrl } from "../types/file";
|
import { FileWithUrl } from "../types/file";
|
||||||
import { fileStorage } from "../services/fileStorage";
|
import { fileStorage } from "../services/fileStorage";
|
||||||
import { makeApiUrl } from "../utils/api";
|
import { makeApiUrl } from "../utils/api";
|
||||||
import { useEndpointEnabled } from "../hooks/useEndpointConfig";
|
import { useEndpointEnabledWithHealthCheck } from "../hooks/useEndpointConfig";
|
||||||
|
|
||||||
export interface MergePdfPanelProps {
|
export interface MergePdfPanelProps {
|
||||||
files: FileWithUrl[];
|
files: FileWithUrl[];
|
||||||
@ -28,7 +28,7 @@ const MergePdfPanel: React.FC<MergePdfPanelProps> = ({
|
|||||||
const [downloadUrl, setLocalDownloadUrl] = useState<string | null>(null);
|
const [downloadUrl, setLocalDownloadUrl] = useState<string | null>(null);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||||
const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled("merge-pdfs");
|
const { enabled: endpointEnabled, loading: endpointLoading, backendHealthy } = useEndpointEnabledWithHealthCheck("merge-pdfs");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setSelectedFiles(files.map(() => true));
|
setSelectedFiles(files.map(() => true));
|
||||||
|
@ -17,7 +17,7 @@ import { useTranslation } from "react-i18next";
|
|||||||
import DownloadIcon from "@mui/icons-material/Download";
|
import DownloadIcon from "@mui/icons-material/Download";
|
||||||
import { FileWithUrl } from "../types/file";
|
import { FileWithUrl } from "../types/file";
|
||||||
import { fileStorage } from "../services/fileStorage";
|
import { fileStorage } from "../services/fileStorage";
|
||||||
import { useEndpointEnabled } from "../hooks/useEndpointConfig";
|
import { useEndpointEnabledWithHealthCheck } from "../hooks/useEndpointConfig";
|
||||||
|
|
||||||
export interface SplitPdfPanelProps {
|
export interface SplitPdfPanelProps {
|
||||||
file: { file: FileWithUrl; url: string } | null;
|
file: { file: FileWithUrl; url: string } | null;
|
||||||
@ -83,7 +83,7 @@ const SplitPdfPanel: React.FC<SplitPdfPanelProps> = ({
|
|||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
|
|
||||||
const { enabled: endpointEnabled, loading: endpointLoading } = useEndpointEnabled(getEndpointName(mode));
|
const { enabled: endpointEnabled, loading: endpointLoading, backendHealthy } = useEndpointEnabledWithHealthCheck(getEndpointName(mode));
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!file) {
|
if (!file) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user