Spaces:
Running
Running
Add loading states and debugging to ControlPanel
Browse files- Show 'Loading...' while fetching models and languages
- Show 'No models/languages available' if API fails
- Add console.log debugging to see what's being loaded
- Disable dropdowns while loading
- This will help identify if API calls are failing
frontend/src/components/ControlPanel.tsx
CHANGED
|
@@ -25,15 +25,23 @@ export default function ControlPanel({
|
|
| 25 |
}: ControlPanelProps) {
|
| 26 |
const [models, setModels] = useState<Model[]>([]);
|
| 27 |
const [languages, setLanguages] = useState<Language[]>([]);
|
|
|
|
| 28 |
|
| 29 |
useEffect(() => {
|
| 30 |
-
|
| 31 |
-
loadLanguages();
|
| 32 |
}, []);
|
| 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
const loadModels = async () => {
|
| 35 |
try {
|
|
|
|
| 36 |
const modelsList = await apiClient.getModels();
|
|
|
|
| 37 |
setModels(modelsList);
|
| 38 |
} catch (error) {
|
| 39 |
console.error('Failed to load models:', error);
|
|
@@ -42,7 +50,9 @@ export default function ControlPanel({
|
|
| 42 |
|
| 43 |
const loadLanguages = async () => {
|
| 44 |
try {
|
|
|
|
| 45 |
const { languages: languagesList } = await apiClient.getLanguages();
|
|
|
|
| 46 |
setLanguages(languagesList);
|
| 47 |
} catch (error) {
|
| 48 |
console.error('Failed to load languages:', error);
|
|
@@ -61,14 +71,20 @@ export default function ControlPanel({
|
|
| 61 |
<select
|
| 62 |
value={selectedLanguage}
|
| 63 |
onChange={(e) => onLanguageChange(e.target.value as Language)}
|
| 64 |
-
disabled={isGenerating}
|
| 65 |
className="w-full px-4 py-3 bg-[#3a3a3c] text-[#e5e5e7] text-sm border border-[#48484a] rounded-xl focus:outline-none focus:ring-2 focus:ring-[#007aff] focus:border-transparent disabled:opacity-50 font-medium shadow-sm"
|
| 66 |
>
|
| 67 |
-
{
|
| 68 |
-
<option
|
| 69 |
-
|
| 70 |
-
</option>
|
| 71 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 72 |
</select>
|
| 73 |
</div>
|
| 74 |
|
|
@@ -80,16 +96,22 @@ export default function ControlPanel({
|
|
| 80 |
<select
|
| 81 |
value={selectedModel}
|
| 82 |
onChange={(e) => onModelChange(e.target.value)}
|
| 83 |
-
disabled={isGenerating}
|
| 84 |
className="w-full px-4 py-3 bg-[#3a3a3c] text-[#e5e5e7] text-sm border border-[#48484a] rounded-xl focus:outline-none focus:ring-2 focus:ring-[#007aff] focus:border-transparent disabled:opacity-50 font-medium shadow-sm"
|
| 85 |
>
|
| 86 |
-
{
|
| 87 |
-
<option
|
| 88 |
-
|
| 89 |
-
</option>
|
| 90 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
</select>
|
| 92 |
-
{models.find(m => m.id === selectedModel) && (
|
| 93 |
<p className="text-xs text-[#86868b] mt-3 leading-relaxed">
|
| 94 |
{models.find(m => m.id === selectedModel)?.description}
|
| 95 |
</p>
|
|
|
|
| 25 |
}: ControlPanelProps) {
|
| 26 |
const [models, setModels] = useState<Model[]>([]);
|
| 27 |
const [languages, setLanguages] = useState<Language[]>([]);
|
| 28 |
+
const [isLoading, setIsLoading] = useState(true);
|
| 29 |
|
| 30 |
useEffect(() => {
|
| 31 |
+
loadData();
|
|
|
|
| 32 |
}, []);
|
| 33 |
|
| 34 |
+
const loadData = async () => {
|
| 35 |
+
setIsLoading(true);
|
| 36 |
+
await Promise.all([loadModels(), loadLanguages()]);
|
| 37 |
+
setIsLoading(false);
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
const loadModels = async () => {
|
| 41 |
try {
|
| 42 |
+
console.log('Loading models...');
|
| 43 |
const modelsList = await apiClient.getModels();
|
| 44 |
+
console.log('Models loaded:', modelsList);
|
| 45 |
setModels(modelsList);
|
| 46 |
} catch (error) {
|
| 47 |
console.error('Failed to load models:', error);
|
|
|
|
| 50 |
|
| 51 |
const loadLanguages = async () => {
|
| 52 |
try {
|
| 53 |
+
console.log('Loading languages...');
|
| 54 |
const { languages: languagesList } = await apiClient.getLanguages();
|
| 55 |
+
console.log('Languages loaded:', languagesList);
|
| 56 |
setLanguages(languagesList);
|
| 57 |
} catch (error) {
|
| 58 |
console.error('Failed to load languages:', error);
|
|
|
|
| 71 |
<select
|
| 72 |
value={selectedLanguage}
|
| 73 |
onChange={(e) => onLanguageChange(e.target.value as Language)}
|
| 74 |
+
disabled={isGenerating || isLoading}
|
| 75 |
className="w-full px-4 py-3 bg-[#3a3a3c] text-[#e5e5e7] text-sm border border-[#48484a] rounded-xl focus:outline-none focus:ring-2 focus:ring-[#007aff] focus:border-transparent disabled:opacity-50 font-medium shadow-sm"
|
| 76 |
>
|
| 77 |
+
{isLoading ? (
|
| 78 |
+
<option value="">Loading...</option>
|
| 79 |
+
) : languages.length === 0 ? (
|
| 80 |
+
<option value="">No languages available</option>
|
| 81 |
+
) : (
|
| 82 |
+
languages.map((lang) => (
|
| 83 |
+
<option key={lang} value={lang} className="bg-[#3a3a3c]">
|
| 84 |
+
{lang.charAt(0).toUpperCase() + lang.slice(1)}
|
| 85 |
+
</option>
|
| 86 |
+
))
|
| 87 |
+
)}
|
| 88 |
</select>
|
| 89 |
</div>
|
| 90 |
|
|
|
|
| 96 |
<select
|
| 97 |
value={selectedModel}
|
| 98 |
onChange={(e) => onModelChange(e.target.value)}
|
| 99 |
+
disabled={isGenerating || isLoading}
|
| 100 |
className="w-full px-4 py-3 bg-[#3a3a3c] text-[#e5e5e7] text-sm border border-[#48484a] rounded-xl focus:outline-none focus:ring-2 focus:ring-[#007aff] focus:border-transparent disabled:opacity-50 font-medium shadow-sm"
|
| 101 |
>
|
| 102 |
+
{isLoading ? (
|
| 103 |
+
<option value="">Loading...</option>
|
| 104 |
+
) : models.length === 0 ? (
|
| 105 |
+
<option value="">No models available</option>
|
| 106 |
+
) : (
|
| 107 |
+
models.map((model) => (
|
| 108 |
+
<option key={model.id} value={model.id} className="bg-[#3a3a3c]">
|
| 109 |
+
{model.name}
|
| 110 |
+
</option>
|
| 111 |
+
))
|
| 112 |
+
)}
|
| 113 |
</select>
|
| 114 |
+
{!isLoading && models.find(m => m.id === selectedModel) && (
|
| 115 |
<p className="text-xs text-[#86868b] mt-3 leading-relaxed">
|
| 116 |
{models.find(m => m.id === selectedModel)?.description}
|
| 117 |
</p>
|