/**
* RecipeTab - Handles the recipes tab in the Lora Modal
*/
import { showToast } from '../../utils/uiHelpers.js';
import { setSessionItem, removeSessionItem } from '../../utils/storageHelpers.js';
/**
* Loads recipes that use the specified Lora and renders them in the tab
* @param {string} loraName - The display name of the Lora
* @param {string} sha256 - The SHA256 hash of the Lora
*/
export function loadRecipesForLora(loraName, sha256) {
const recipeTab = document.getElementById('recipes-tab');
if (!recipeTab) return;
// Show loading state
recipeTab.innerHTML = `
Loading recipes...
`;
// Fetch recipes that use this Lora by hash
fetch(`/api/recipes/for-lora?hash=${encodeURIComponent(sha256.toLowerCase())}`)
.then(response => response.json())
.then(data => {
if (!data.success) {
throw new Error(data.error || 'Failed to load recipes');
}
renderRecipes(recipeTab, data.recipes, loraName, sha256);
})
.catch(error => {
console.error('Error loading recipes for Lora:', error);
recipeTab.innerHTML = `
Failed to load recipes. Please try again later.
`;
});
}
/**
* Renders the recipe cards in the tab
* @param {HTMLElement} tabElement - The tab element to render into
* @param {Array} recipes - Array of recipe objects
* @param {string} loraName - The display name of the Lora
* @param {string} loraHash - The hash of the Lora
*/
function renderRecipes(tabElement, recipes, loraName, loraHash) {
if (!recipes || recipes.length === 0) {
tabElement.innerHTML = `
No recipes found that use this Lora.
`;
return;
}
// Create header with count and view all button
const headerElement = document.createElement('div');
headerElement.className = 'recipes-header';
headerElement.innerHTML = `
Found ${recipes.length} recipe${recipes.length > 1 ? 's' : ''} using this Lora
`;
// Add event listeners for action buttons
card.querySelector('.fa-copy').addEventListener('click', (e) => {
e.stopPropagation();
copyRecipeSyntax(recipe.id);
});
// Add click handler for the entire card
card.addEventListener('click', () => {
navigateToRecipeDetails(recipe.id);
});
// Add card to grid
cardGrid.appendChild(card);
});
// Clear loading indicator and append content
tabElement.innerHTML = '';
tabElement.appendChild(headerElement);
tabElement.appendChild(cardGrid);
}
/**
* Returns a descriptive title for the LoRA status indicator
* @param {number} totalCount - Total number of LoRAs in recipe
* @param {number} missingCount - Number of missing LoRAs
* @returns {string} Status title text
*/
function getLoraStatusTitle(totalCount, missingCount) {
if (totalCount === 0) return "No LoRAs in this recipe";
if (missingCount === 0) return "All LoRAs available - Ready to use";
return `${missingCount} of ${totalCount} LoRAs missing`;
}
/**
* Copies recipe syntax to clipboard
* @param {string} recipeId - The recipe ID
*/
function copyRecipeSyntax(recipeId) {
if (!recipeId) {
showToast('Cannot copy recipe syntax: Missing recipe ID', 'error');
return;
}
fetch(`/api/recipe/${recipeId}/syntax`)
.then(response => response.json())
.then(data => {
if (data.success && data.syntax) {
return navigator.clipboard.writeText(data.syntax);
} else {
throw new Error(data.error || 'No syntax returned');
}
})
.then(() => {
showToast('Recipe syntax copied to clipboard', 'success');
})
.catch(err => {
console.error('Failed to copy: ', err);
showToast('Failed to copy recipe syntax', 'error');
});
}
/**
* Navigates to the recipes page with filter for the current Lora
* @param {string} loraName - The Lora display name to filter by
* @param {string} loraHash - The hash of the Lora to filter by
* @param {boolean} createNew - Whether to open the create recipe dialog
*/
function navigateToRecipesPage(loraName, loraHash) {
// Close the current modal
if (window.modalManager) {
modalManager.closeModal('loraModal');
}
// Clear any previous filters first
removeSessionItem('lora_to_recipe_filterLoraName');
removeSessionItem('lora_to_recipe_filterLoraHash');
removeSessionItem('viewRecipeId');
// Store the LoRA name and hash filter in sessionStorage
setSessionItem('lora_to_recipe_filterLoraName', loraName);
setSessionItem('lora_to_recipe_filterLoraHash', loraHash);
// Directly navigate to recipes page
window.location.href = '/loras/recipes';
}
/**
* Navigates directly to a specific recipe's details
* @param {string} recipeId - The recipe ID to view
*/
function navigateToRecipeDetails(recipeId) {
// Close the current modal
if (window.modalManager) {
modalManager.closeModal('loraModal');
}
// Clear any previous filters first
removeSessionItem('filterLoraName');
removeSessionItem('filterLoraHash');
removeSessionItem('viewRecipeId');
// Store the recipe ID in sessionStorage to load on recipes page
setSessionItem('viewRecipeId', recipeId);
// Directly navigate to recipes page
window.location.href = '/loras/recipes';
}