Files
arcum42-ComfyUI_SageUtils/js/components/cacheUI.js
T

413 lines
11 KiB
JavaScript

/**
* Cache Sidebar UI Components
* Reusable UI component factory functions for the cache sidebar
*/
// Import centralized button components
export { createButton, createIconButton, createButtonGroup, BUTTON_VARIANTS, BUTTON_SIZES, BUTTON_CONFIGS } from './buttons.js';
/**
* Create a labeled container with consistent styling
*/
export function createLabeledContainer(labelText, marginBottom = '10px') {
const container = document.createElement('div');
container.style.marginBottom = marginBottom;
const label = document.createElement('label');
label.textContent = labelText;
label.style.cssText = `
display: block;
margin-bottom: 5px;
color: #ffffff;
font-size: 13px;
font-weight: bold;
`;
container.appendChild(label);
return { container, label };
}
/**
* Create a styled select dropdown
*/
export function createStyledSelect(options = []) {
const select = document.createElement('select');
select.style.cssText = `
width: 100%;
padding: 8px;
background: #333;
color: #fff;
border: 1px solid #555;
border-radius: 4px;
font-size: 12px;
margin-bottom: 10px;
`;
// Add options if provided
options.forEach(option => {
const optionElement = document.createElement('option');
optionElement.value = option.value;
optionElement.textContent = option.text;
select.appendChild(optionElement);
});
return select;
}
/**
* Create a styled input field
*/
export function createStyledInput(type = 'text', placeholder = '') {
const input = document.createElement('input');
input.type = type;
input.placeholder = placeholder;
input.style.cssText = `
width: 100%;
padding: 8px;
background: #333;
color: #fff;
border: 1px solid #555;
border-radius: 4px;
font-size: 12px;
margin-bottom: 10px;
box-sizing: border-box;
`;
return input;
}
/**
* Create a styled button
* @deprecated Use createButton() from buttons.js instead
*/
export function createStyledButton(text, backgroundColor = '#4CAF50', icon = '') {
console.warn('createStyledButton is deprecated. Use createButton() from buttons.js instead.');
// Use the centralized button component
const { createButton } = require('./buttons.js');
return createButton(text, {
color: backgroundColor,
icon
});
}
/**
* Create a filter section with label and select
*/
export function createFilterSection(labelText, options, marginBottom = '10px') {
const { container, label } = createLabeledContainer(labelText, marginBottom);
const select = createStyledSelect(options);
container.appendChild(select);
return { container, label, select };
}
/**
* Create a search input section
*/
export function createSearchSection(labelText = 'Search Models:', placeholder = 'Type to search...') {
const { container, label } = createLabeledContainer(labelText);
const input = createStyledInput('text', placeholder);
container.appendChild(input);
return { container, label, input };
}
/**
* Create a toggle checkbox with label
*/
export function createToggleSection(labelText, checkboxId) {
const container = document.createElement('div');
container.style.cssText = `
margin-bottom: 10px;
display: flex;
align-items: center;
gap: 8px;
`;
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = checkboxId;
checkbox.style.cssText = `
margin: 0;
transform: scale(1.2);
`;
const label = document.createElement('label');
label.htmlFor = checkboxId;
label.textContent = labelText;
label.style.cssText = `
color: #ffffff;
font-size: 13px;
font-weight: bold;
cursor: pointer;
user-select: none;
`;
container.appendChild(checkbox);
container.appendChild(label);
return { container, checkbox, label };
}
/**
* Create a custom dropdown with button and menu
*/
export function createCustomDropdown(buttonText = 'Select a file...') {
const container = document.createElement('div');
container.style.cssText = `
position: relative;
width: 100%;
`;
const button = document.createElement('div');
button.style.cssText = `
width: 100%;
padding: 8px;
background: #333;
color: #fff;
border: 1px solid #555;
border-radius: 4px;
font-size: 12px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
user-select: none;
`;
button.innerHTML = `<span>${buttonText}</span><span>▼</span>`;
const menu = document.createElement('div');
menu.style.cssText = `
position: fixed;
background: #333;
border: 1px solid #555;
border-top: none;
border-radius: 0 0 4px 4px;
max-height: 600px;
overflow-y: auto;
z-index: 1000;
display: none;
box-shadow: 2px 2px 8px rgba(0,0,0,0.3);
`;
container.appendChild(button);
// Append menu to body to avoid container constraints
document.body.appendChild(menu);
return { container, button, menu };
}
// Progress bar functionality moved to progressBar.js
export { createProgressBar } from './progressBar.js';
/**
* Create a button container for multiple buttons
* @deprecated Use createButtonGroup() from buttons.js instead
*/
export function createButtonContainer() {
console.warn('createButtonContainer is deprecated. Use createButtonGroup() from buttons.js instead.');
const container = document.createElement('div');
container.style.cssText = `
display: flex;
gap: 4px;
margin-top: 8px;
flex-wrap: wrap;
`;
return container;
}
/**
* Create the main container with consistent styling
*/
export function createMainContainer() {
const container = document.createElement('div');
container.style.cssText = `
padding: 10px;
height: 100%;
overflow-y: auto;
background: #1e1e1e;
color: #ffffff;
`;
return container;
}
/**
* Create a header section
*/
export function createHeader(title, subtitle) {
const header = document.createElement('div');
header.style.cssText = `
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #444;
`;
const titleHtml = `<h3 style="margin: 0; color: #ffffff; font-size: 16px;">${title}</h3>`;
const subtitleHtml = subtitle ? `<p style="margin: 5px 0 0 0; color: #aaa; font-size: 12px;">${subtitle}</p>` : '';
header.innerHTML = titleHtml + subtitleHtml;
return header;
}
/**
* Create a loading indicator
*/
export function createLoadingIndicator(text = 'Loading...') {
const indicator = document.createElement('div');
indicator.style.cssText = `
text-align: center;
padding: 20px;
color: #888;
font-style: italic;
`;
indicator.textContent = text;
return indicator;
}
/**
* Create an info display container
*/
export function createInfoDisplay() {
const display = document.createElement('div');
display.id = 'cache-info-display';
return display;
}
/**
* Add dropdown styles to the document head
*/
export function addDropdownStyles() {
const style = document.createElement('style');
style.textContent = `
.cache-dropdown-item {
padding: 6px 10px;
cursor: pointer;
position: relative;
border-bottom: 1px solid #444;
font-size: 11px;
}
.cache-dropdown-item:hover {
background: #444;
}
.cache-dropdown-item.folder {
background: #383838;
font-weight: bold;
}
.cache-dropdown-item.folder:hover {
background: #484848;
}
.cache-dropdown-item.folder::after {
content: "▶";
float: right;
}
.cache-dropdown-submenu {
position: fixed;
background: #333;
border: 1px solid #555;
border-radius: 4px;
min-width: 250px;
max-height: 300px;
overflow-y: auto;
z-index: 1001;
display: none;
box-shadow: 2px 2px 8px rgba(0,0,0,0.3);
}
.cache-dropdown-item.file {
color: #e0e0e0;
}
.cache-dropdown-item.selected {
background: #4CAF50;
}
`;
document.head.appendChild(style);
}
/**
* Create tab button with hover effects
* @deprecated Use TabManager class from components/tabs.js instead for complete tab management
* @param {string} text - Button text
* @param {boolean} isActive - Whether the button is initially active
* @returns {HTMLElement} Tab button element
*/
export function createTabButton(text, isActive = false) {
console.warn('[DEPRECATED] createTabButton from cacheUI.js is deprecated. Use TabManager class from components/tabs.js instead.');
const button = document.createElement('button');
button.textContent = text;
button.style.cssText = `
padding: 10px 20px;
border: none;
background: ${isActive ? '#4CAF50' : '#2a2a2a'};
color: ${isActive ? 'white' : '#ccc'};
cursor: pointer;
border-radius: 6px 6px 0 0;
margin-right: 2px;
font-size: 13px;
font-weight: ${isActive ? 'bold' : 'normal'};
transition: all 0.2s ease;
border-bottom: 2px solid ${isActive ? '#4CAF50' : 'transparent'};
position: relative;
top: 2px;
`;
// Hover effects
button.addEventListener('mouseenter', () => {
if (!button.classList.contains('active')) {
button.style.background = '#3a3a3a';
button.style.color = 'white';
button.style.transform = 'translateY(-1px)';
}
});
button.addEventListener('mouseleave', () => {
if (!button.classList.contains('active')) {
button.style.background = '#2a2a2a';
button.style.color = '#ccc';
button.style.transform = 'translateY(0)';
}
});
return button;
}
// BUTTON_CONFIGS has been moved to buttons.js and is re-exported above
/**
* Pre-defined filter options
*/
export const FILTER_OPTIONS = {
modelType: [
{ value: 'all', text: 'All Models' },
{ value: 'Checkpoint', text: 'Checkpoints Only' },
{ value: 'LORA', text: 'LoRAs Only' }
],
lastUsed: [
{ value: 'all', text: 'All Models' },
{ value: 'today', text: 'Used Today' },
{ value: 'week', text: 'Used This Week' },
{ value: 'month', text: 'Used This Month' },
{ value: 'never', text: 'Never Used' }
],
updates: [
{ value: 'all', text: 'All Models' },
{ value: 'available', text: 'Updates Available' },
{ value: 'none', text: 'No Updates Available' }
],
sort: [
{ value: 'name', text: 'Name (A-Z)' },
{ value: 'name-desc', text: 'Name (Z-A)' },
{ value: 'lastused', text: 'Last Used (Recent First)' },
{ value: 'lastused-desc', text: 'Last Used (Oldest First)' },
{ value: 'size', text: 'File Size (Small to Large)' },
{ value: 'size-desc', text: 'File Size (Large to Small)' },
{ value: 'type', text: 'Type' }
]
};