- Fixed some bugs
- Added Templates support
- Added ability categorize custom categories
- Added preview (list of used nodes)
- Added Workflow support!
- Added ability to rename workflows
- Added ability to remove workflows
- Added ability to categorize workflows
- Added preview (list of used nodes), (disabled by default)
This commit is contained in:
@@ -11,6 +11,21 @@ For what i know nobody did it, so i did it.
|
||||
Maybe you don't need it. I need it >.<
|
||||
|
||||
# Updates
|
||||
- 25-05-2024
|
||||
- Fixed some bugs
|
||||
- Added Templates support**
|
||||
- Added ability categorize custom categories
|
||||
- Added preview (list of used nodes)
|
||||
|
||||
- Added Workflow support!
|
||||
- Added ability to rename workflows
|
||||
- Added ability to remove workflows
|
||||
- Added ability to categorize workflows
|
||||
- Added preview (list of used nodes), (disabled by default)
|
||||
|
||||
** i did not enabled the **rename** and **delete** because it's conflicing with the TemplateManager
|
||||
|
||||
|
||||
- 21-04-2024
|
||||
- Rewritten a lot of the code to improve performance and readability, and slightly adjusted the UI to ensure compatibility with future updates.
|
||||
- ADDED CUSTOM CATEGORIES
|
||||
@@ -80,7 +95,6 @@ This feature is enabled by default, you can disable it in the settings. I've use
|
||||

|
||||
|
||||
|
||||
|
||||
### ➕Expand/Collapse Categories/Sidebar➖
|
||||

|
||||
|
||||
@@ -92,14 +106,21 @@ This feature is enabled by default, you can disable it in the settings. I've use
|
||||
### 👁 Preview Node 👁
|
||||

|
||||
|
||||
### 📄 Templates Support 📄
|
||||

|
||||
|
||||
#### 📄 Workflow Support 📄
|
||||

|
||||
|
||||
### 🎨 ComfyUI Themes Support 🎨
|
||||

|
||||
|
||||
### 🎨 New Settings Panel 🎨
|
||||

|
||||
|
||||
### Additional Features
|
||||
- Width and Minimized State of the sidebar are saved in cookies
|
||||
PS: Workflow Path
|
||||
|
||||
|
||||
|
||||
|
||||
### Todo:
|
||||
|
||||
+97
-3
@@ -3,6 +3,8 @@ import folder_paths
|
||||
from aiohttp import web
|
||||
import os
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +16,8 @@ class JSONConfigManager:
|
||||
"menuctx_options": [],
|
||||
"menuctx_subOptions": [],
|
||||
"menuctx_opt_callback": [],
|
||||
"menuctx_sub_opt_callback": []
|
||||
"menuctx_sub_opt_callback": [],
|
||||
"sb_wf_path": ""
|
||||
}"""
|
||||
if os.path.isfile(file_name):
|
||||
self.data = self.read_json_file()
|
||||
@@ -67,7 +70,7 @@ else:
|
||||
|
||||
|
||||
|
||||
file_path = os.path.join(folder_paths.get_folder_paths("custom_nodes")[0],"ComfyUI-N-Sidebar","app","settings.json")
|
||||
file_path = os.path.join(os.path.dirname(os.path.realpath(__file__)),"app","settings.json")
|
||||
|
||||
|
||||
config_manager = JSONConfigManager(file_path)
|
||||
@@ -75,8 +78,27 @@ config_manager = JSONConfigManager(file_path)
|
||||
NODE_CLASS_MAPPINGS = {}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
|
||||
list_panels = os.path.join(folder_paths.get_folder_paths("custom_nodes")[0],"ComfyUI-N-Sidebar","app","panels")
|
||||
|
||||
default_path = os.path.join(folder_paths.base_path, "workflows")
|
||||
try:
|
||||
list_workflows_dirs = config_manager.read_item("sb_wf_path").replace("\n\r", "\n").split('\n')
|
||||
except:
|
||||
print("No 'sb_wf_path' in settings.json. Using default path.")
|
||||
list_workflows_dirs = []
|
||||
|
||||
workflow_dirs = []
|
||||
|
||||
for list_workflows in list_workflows_dirs:
|
||||
if os.path.isdir(list_workflows.strip()):
|
||||
workflow_dirs.append(list_workflows.strip())
|
||||
|
||||
|
||||
workflow_dirs.insert(0, default_path)
|
||||
|
||||
|
||||
list_panels = os.path.join(os.path.dirname(os.path.realpath(__file__)),"app","panels")
|
||||
|
||||
list_workflows_array = []
|
||||
list_panels_array = []
|
||||
#list folders
|
||||
folders = os.listdir(list_panels)
|
||||
@@ -86,6 +108,78 @@ for folder in folders:
|
||||
|
||||
|
||||
|
||||
@server.PromptServer.instance.routes.get("/sidebar/workflows" )
|
||||
async def s_get(request):
|
||||
workflows_dict = {}
|
||||
existing_names = set()
|
||||
|
||||
for list_workflows in workflow_dirs:
|
||||
for entry in os.scandir(list_workflows):
|
||||
if entry.is_file() and entry.name.endswith('.json'):
|
||||
base_name = entry.name[:-5] # Remove the '.json' extension
|
||||
unique_name = base_name
|
||||
|
||||
if unique_name in workflows_dict:
|
||||
folder_name = os.path.basename(list_workflows)
|
||||
unique_name = f"{base_name} (from {folder_name})"
|
||||
|
||||
workflows_dict[unique_name] = entry.path
|
||||
existing_names.add(unique_name)
|
||||
sorted_workflows_dict = dict(sorted(workflows_dict.items()))
|
||||
|
||||
return web.json_response(sorted_workflows_dict, content_type='application/json')
|
||||
|
||||
|
||||
|
||||
@server.PromptServer.instance.routes.post("/sidebar/workflow")
|
||||
async def s_get(request):
|
||||
|
||||
data = await request.json()
|
||||
|
||||
action = data["action"]
|
||||
|
||||
if action == "delete":
|
||||
path = Path(data["path"])
|
||||
os.remove(path)
|
||||
result = {"result": "OK"}
|
||||
return web.json_response(result, content_type='application/json')
|
||||
|
||||
elif action == "rename":
|
||||
path = Path(data["path"])
|
||||
newName = data["newName"]
|
||||
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"The system cannot find the path specified: {path}")
|
||||
|
||||
# Ottieni la directory e il nuovo percorso
|
||||
new_path = path.with_name(newName).with_suffix('.json')
|
||||
if new_path.exists():
|
||||
result = {"result": "File already exists!"}
|
||||
else:
|
||||
#rename
|
||||
os.rename(path, new_path)
|
||||
result = {"result": "OK"}
|
||||
return web.json_response(result, content_type='application/json')
|
||||
else:
|
||||
file = data["path"]
|
||||
|
||||
# if file exists
|
||||
if os.path.isfile(file):
|
||||
|
||||
return web.FileResponse(file)
|
||||
else:
|
||||
return web.Response(status=403)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@server.PromptServer.instance.routes.get("/sidebar/panels" )
|
||||
async def s_get(request):
|
||||
result = {"panels": list_panels_array}
|
||||
|
||||
+31
-4
@@ -84,7 +84,7 @@
|
||||
|
||||
}
|
||||
|
||||
.clearIcon, .searchCategoryIcon, .clearIconCustomCategory, .searchCategoryIconCustomCategory {
|
||||
.clearIcon, .searchCategoryIcon, .clearIconCustomCategory, .searchCategoryIconCustomCategory, .clearIconCustomTemplate, .searchTemplateIconCustomTemplate, .clearIconCustomWorkflow, .searchWorkflowIconCustomWorkflow {
|
||||
position: absolute;
|
||||
padding: 5px;
|
||||
right: 30px;
|
||||
@@ -98,11 +98,11 @@
|
||||
}
|
||||
|
||||
|
||||
.clearIcon:hover, .clearIconCustomCategory:hover {
|
||||
.clearIcon:hover, .clearIconCustomCategory:hover, .clearIconCustomTemplate:hover, .clearIconCustomWorkflow:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.searchCategoryIcon, .searchCategoryIconCustomCategory {
|
||||
.searchCategoryIcon, .searchCategoryIconCustomCategory, .searchTemplateIconCustomTemplate, .searchWorkflowIconCustomWorkflow {
|
||||
right: 0px;
|
||||
padding: 3px;
|
||||
font-size: larger;
|
||||
@@ -117,7 +117,7 @@
|
||||
|
||||
}
|
||||
|
||||
.searchCategoryIcon:hover, .searchCategoryIconCustomCategory:hover {
|
||||
.searchCategoryIcon:hover, .searchCategoryIconCustomCategory:hover, .searchTemplateIconCustomTemplate:hover, .searchWorkflowIconCustomWorkflow:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@@ -528,6 +528,7 @@
|
||||
|
||||
border-radius: 5px;
|
||||
margin-left: 7px;
|
||||
|
||||
}
|
||||
|
||||
.panel_sidebar label{
|
||||
@@ -648,6 +649,27 @@
|
||||
|
||||
}
|
||||
|
||||
#sb_settingsDiv .setting input[type="text"]{
|
||||
background: var(--comfy-menu-bg);
|
||||
color: var(--drag-text);
|
||||
padding: 5px;
|
||||
float: right;
|
||||
width: 129px;
|
||||
margin-right: 47px;
|
||||
border-radius: 5px;
|
||||
border: solid 1px var(--descrip-text);
|
||||
}
|
||||
#sb_settingsDiv .setting textarea{
|
||||
background: var(--comfy-menu-bg);
|
||||
color: var(--drag-text);
|
||||
padding: 5px;
|
||||
float: right;
|
||||
width: calc(100% - 60px);
|
||||
resize: vertical;
|
||||
margin-right: 47px;
|
||||
border-radius: 5px;
|
||||
border: solid 1px var(--descrip-text);
|
||||
}
|
||||
#sb_settingsDiv .setting input[type="checkbox"]{
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
@@ -756,4 +778,9 @@
|
||||
#switch_sidebar{
|
||||
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#sbModal{
|
||||
display: none;
|
||||
z-index: 9999;
|
||||
}
|
||||
+44
-32
@@ -1,49 +1,61 @@
|
||||
<div class="sidebar" id="sidebar" style="width:{{sidebar_width}};">
|
||||
<div class="sidebar-header" id="sidebar-header" data-content="panel_head_home">
|
||||
<input type="text" id="searchInput" placeholder="Search..." autocomplete="off">
|
||||
<span class="clearIcon">×</span>
|
||||
<span class="searchCategoryIcon">C</span>
|
||||
<input type="text" id="searchInput" placeholder="Search..." autocomplete="off">
|
||||
<span class="clearIcon">×</span>
|
||||
<span class="searchCategoryIcon">C</span>
|
||||
</div>
|
||||
<div class="content_sidebar" id ="content_sidebar_home" data-expanded="false" data-content="panel_content_home" >
|
||||
<div class="content_sidebar" id="content_sidebar_home" data-expanded="false" data-content="panel_content_home">
|
||||
|
||||
|
||||
<div id="spacer"></div>
|
||||
<label class="sb_label" id="sb_label_pinned">PINNED</label>
|
||||
<ul id="sidebarBookmarks"></ul>
|
||||
<label class="sb_label" id="sb_label_custom">CUSTOM NODES<button class="expand_node" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 52 52" enable-background="new 0 0 52 52" xml:space="preserve">
|
||||
<path d="M48,9.5C48,8.7,47.3,8,46.5,8h-41C4.7,8,4,8.7,4,9.5v3C4,13.3,4.7,14,5.5,14h41c0.8,0,1.5-0.7,1.5-1.5V9.5z"
|
||||
/>
|
||||
<div id="spacer"></div>
|
||||
<label class="sb_label" id="sb_label_pinned">PINNED</label>
|
||||
<ul id="sidebarBookmarks"></ul>
|
||||
<label class="sb_label" id="sb_label_custom">CUSTOM NODES<button class="expand_node">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52" enable-background="new 0 0 52 52"
|
||||
xml:space="preserve">
|
||||
<path
|
||||
d="M48,9.5C48,8.7,47.3,8,46.5,8h-41C4.7,8,4,8.7,4,9.5v3C4,13.3,4.7,14,5.5,14h41c0.8,0,1.5-0.7,1.5-1.5V9.5z" />
|
||||
<path d="M48,39.5c0-0.8-0.7-1.5-1.5-1.5h-41C4.7,38,4,38.7,4,39.5v3C4,43.3,4.7,44,5.5,44h41c0.8,0,1.5-0.7,1.5-1.5
|
||||
V39.5z"/>
|
||||
V39.5z" />
|
||||
<path d="M30,29h4.5c0.8,0,1.5-0.7,1.5-1.5v-3c0-0.8-0.7-1.5-1.5-1.5H30c-0.6,0-1-0.4-1-1v-4.5c0-0.8-0.7-1.5-1.5-1.5
|
||||
h-3c-0.8,0-1.5,0.7-1.5,1.5V22c0,0.6-0.4,1-1,1h-4.5c-0.8,0-1.5,0.7-1.5,1.5v3c0,0.8,0.7,1.5,1.5,1.5H22c0.6,0,1,0.4,1,1v4.5
|
||||
c0,0.8,0.7,1.5,1.5,1.5h3c0.8,0,1.5-0.7,1.5-1.5V30C29,29.4,29.4,29,30,29z"/>
|
||||
<rect class="expand_node" style="opacity:0" x="0" y="0" width="52" height="52" />
|
||||
</svg>
|
||||
</button></label>
|
||||
<ul id="sidebarCustomNodes"></ul>
|
||||
</div>
|
||||
c0,0.8,0.7,1.5,1.5,1.5h3c0.8,0,1.5-0.7,1.5-1.5V30C29,29.4,29.4,29,30,29z" />
|
||||
<rect class="expand_node" style="opacity:0" x="0" y="0" width="52" height="52" />
|
||||
</svg>
|
||||
</button></label>
|
||||
<ul id="sidebarCustomNodes"></ul>
|
||||
</div>
|
||||
|
||||
<div id="sidebar_views">
|
||||
<div class="view_button" id ="switch_sidebar">☰</div>
|
||||
<div class="view_button" id ="switch_home" data-content="home"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" style="enable-background:new 0 0 100 100; fill:var(--input-text);" xml:space="preserve"><g><path d="M29,82h13V63.1c0-1.7,1.3-3,3-3h10.3c1.7,0,3,1.3,3,3V82H71c1.7,0,3-1.3,3-3V43.2c0-0.8-0.3-1.6-0.9-2.1l-21-21 c-1.2-1.2-3.1-1.2-4.2,0l-21,21c-0.6,0.6-0.9,1.3-0.9,2.1V79C26,80.7,27.3,82,29,82z"/></g></svg></div>
|
||||
<div class="view_button" id ="switch_settings">⚙</div>
|
||||
<div id="sidebar_views">
|
||||
<div class="view_button" id="switch_sidebar">☰</div>
|
||||
<div class="view_button" id="switch_home" data-content="home"><svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100"
|
||||
style="enable-background:new 0 0 100 100; fill:var(--input-text);" xml:space="preserve">
|
||||
<g>
|
||||
<path
|
||||
d="M29,82h13V63.1c0-1.7,1.3-3,3-3h10.3c1.7,0,3,1.3,3,3V82H71c1.7,0,3-1.3,3-3V43.2c0-0.8-0.3-1.6-0.9-2.1l-21-21 c-1.2-1.2-3.1-1.2-4.2,0l-21,21c-0.6,0.6-0.9,1.3-0.9,2.1V79C26,80.7,27.3,82,29,82z" />
|
||||
</g>
|
||||
</svg></div>
|
||||
<div class="view_button" id="switch_settings">⚙</div>
|
||||
</div>
|
||||
<div class="dragHandle" id="dragHandle"></div>
|
||||
<div id="previewDiv"></div>
|
||||
<div id="sb-modal-backdrop-settings" class="sb-modal-backdrop-settings sb_hidden"></div>
|
||||
<div id="sb_settingsDiv" class="sb_hidden"><h1>SideBar Settings</h1>
|
||||
<button id="sb_resetButton">Soft Reset</button> <button id="sb_factoryResetButton">Factory Reset</button></div>
|
||||
<div id="sb_settingsDiv" class="sb_hidden">
|
||||
<h1>SideBar Settings</h1>
|
||||
<button id="sb_resetButton">Soft Reset</button>
|
||||
<button id="sb_factoryResetButton">Factory Reset</button>
|
||||
</div>
|
||||
<a href="#" id="sb_scrollToTopButton">
|
||||
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 330 330" xml:space="preserve">
|
||||
<path id="XMLID_224_" d="M325.606,229.393l-150.004-150C172.79,76.58,168.974,75,164.996,75c-3.979,0-7.794,1.581-10.607,4.394
|
||||
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 330 330" xml:space="preserve">
|
||||
<path id="XMLID_224_"
|
||||
d="M325.606,229.393l-150.004-150C172.79,76.58,168.974,75,164.996,75c-3.979,0-7.794,1.581-10.607,4.394
|
||||
l-149.996,150c-5.858,5.858-5.858,15.355,0,21.213c5.857,5.857,15.355,5.858,21.213,0l139.39-139.393l139.397,139.393
|
||||
C307.322,253.536,311.161,255,315,255c3.839,0,7.678-1.464,10.607-4.394C331.464,244.748,331.464,235.251,325.606,229.393z"/>
|
||||
</svg>
|
||||
</a>
|
||||
C307.322,253.536,311.161,255,315,255c3.839,0,7.678-1.464,10.607-4.394C331.464,244.748,331.464,235.251,325.606,229.393z" />
|
||||
</svg>
|
||||
</a>
|
||||
<div id="customMenu" class="custom-menu">
|
||||
<ul> </ul></div>
|
||||
<ul> </ul>
|
||||
</div>
|
||||
</div>
|
||||
+128
-42
@@ -4,30 +4,36 @@ let sbPosition = "left";
|
||||
let defaultSearchToggle = "fuzzy";
|
||||
let defaultSearchOrder = "comfyui";
|
||||
|
||||
async function getConfiguration(name) {
|
||||
async function getConfiguration(name,local = false) {
|
||||
//console.log("getStyles called " + name);
|
||||
try {
|
||||
const response = await fetch('/sidebar/settings', {
|
||||
cache: "no-store",
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action : "read",
|
||||
parameter: name
|
||||
|
||||
}),
|
||||
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (local) {
|
||||
return localStorage.getItem(name);
|
||||
} else {
|
||||
|
||||
|
||||
const response = await fetch('/sidebar/settings', {
|
||||
cache: "no-store",
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action : "read",
|
||||
parameter: name
|
||||
|
||||
}),
|
||||
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
return data["value"];
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return null;
|
||||
}
|
||||
return data["value"];
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function addConfiguration(name,value) {
|
||||
@@ -45,7 +51,11 @@ async function getConfiguration(name) {
|
||||
})
|
||||
}
|
||||
|
||||
function updateConfiguration(name,value) {
|
||||
function updateConfiguration(name,value,local = false) {
|
||||
if (local) {
|
||||
return localStorage.setItem(name,value)
|
||||
} else {
|
||||
|
||||
return fetch('/sidebar/settings', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -57,6 +67,8 @@ async function getConfiguration(name) {
|
||||
value: value
|
||||
}),
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function removeConfiguration(name) {
|
||||
@@ -91,9 +103,9 @@ function factoryResetSettings() {
|
||||
|
||||
|
||||
|
||||
function settingsSetup(app,$el) {
|
||||
async function settingsSetup(app,$el) {
|
||||
|
||||
|
||||
|
||||
app.ui.settings.addSetting({
|
||||
id: "0_sidebar",
|
||||
name: "[Sidebar] Better ComfyUI Settings Style",
|
||||
@@ -118,6 +130,33 @@ function settingsSetup(app,$el) {
|
||||
});
|
||||
|
||||
|
||||
addSBSetting( "sb_settingsDiv",{
|
||||
id: "workflow_preview",
|
||||
name: "Enable Workflow Node List",
|
||||
defaultValue: "false",
|
||||
type: "boolean",
|
||||
local: true,
|
||||
info: "This is disabled by default since workflows preview can be slow.",
|
||||
|
||||
|
||||
onChange(value) {
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
addSBSetting( "sb_settingsDiv",{
|
||||
id: "workflow_replace",
|
||||
name: "Workflow Replace Popup",
|
||||
defaultValue: "true",
|
||||
type: "boolean",
|
||||
local: true,
|
||||
|
||||
|
||||
onChange(value) {
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
addSBSetting( "sb_settingsDiv",{
|
||||
id: "font",
|
||||
name: "Font Size",
|
||||
@@ -147,7 +186,7 @@ function settingsSetup(app,$el) {
|
||||
addDynamicCSSRule('.sidebar li', 'padding', value + 'px');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
addSBSetting( "sb_settingsDiv", {
|
||||
id: "bartop",
|
||||
name: "Space Top",
|
||||
@@ -395,7 +434,7 @@ function settingsSetup(app,$el) {
|
||||
},
|
||||
});
|
||||
|
||||
addSBSetting( "sb_settingsDiv", {
|
||||
await addSBSetting( "sb_settingsDiv", {
|
||||
id: "order_type",
|
||||
name: "Nodes Order Type",
|
||||
defaultValue: "comfyui",
|
||||
@@ -416,6 +455,23 @@ function settingsSetup(app,$el) {
|
||||
});
|
||||
|
||||
|
||||
addSBSetting( "sb_settingsDiv", {
|
||||
id: "wf_path",
|
||||
name: "Workflow Paths",
|
||||
defaultValue: "",
|
||||
type: "textarea",
|
||||
info: "Paths must be row separated (only one per row).\nThe default ComfyUI workflows path has already been set.\nReboot ComfyUI to apply changes!",
|
||||
|
||||
onChange(value) {
|
||||
|
||||
NaN
|
||||
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -446,18 +502,22 @@ function settingsSetup(app,$el) {
|
||||
factoryReset();
|
||||
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
async function addSBSetting(fieldLocation, setting) {
|
||||
setting.id = "sb_" + setting.id; // Aggiunge il prefisso del campo
|
||||
setting.id = "sb_" + setting.id;
|
||||
|
||||
// Crea l'elemento HTML per il campo di impostazione
|
||||
|
||||
const settingElement = document.createElement("div");
|
||||
settingElement.classList.add("setting");
|
||||
|
||||
// Aggiungi il nome del campo
|
||||
|
||||
const nameLabel = document.createElement("label");
|
||||
nameLabel.textContent = setting.name;
|
||||
settingElement.appendChild(nameLabel);
|
||||
@@ -471,20 +531,27 @@ async function addSBSetting(fieldLocation, setting) {
|
||||
nameLabel.appendChild(infoIcon);
|
||||
}
|
||||
|
||||
// Aggiungi il tipo appropriato di input per il campo
|
||||
|
||||
let inputElement;
|
||||
if (setting.type === "boolean") {
|
||||
inputElement = document.createElement("input");
|
||||
inputElement.type = "checkbox";
|
||||
inputElement.checked = await getConfiguration(setting.id) || setting.defaultValue;
|
||||
|
||||
let configValue = await getConfiguration(setting.id, setting.local) || setting.defaultValue;
|
||||
if (configValue == "true") {
|
||||
inputElement.checked = true;
|
||||
} else if (configValue == "false") {
|
||||
inputElement.checked = false;
|
||||
}
|
||||
|
||||
setting.onChange(inputElement.checked);
|
||||
inputElement.addEventListener("change", function() {
|
||||
setting.onChange(inputElement.checked);
|
||||
updateConfiguration(setting.id,inputElement.checked)
|
||||
updateConfiguration(setting.id,inputElement.checked, setting.local)
|
||||
|
||||
});
|
||||
} else if (setting.type === "slider") {
|
||||
// Crea l'elemento input per lo slider
|
||||
|
||||
const sliderContainer = document.createElement("div");
|
||||
sliderContainer.classList.add("slider-container");
|
||||
|
||||
@@ -497,19 +564,20 @@ async function addSBSetting(fieldLocation, setting) {
|
||||
inputElement.value = await getConfiguration(setting.id) || setting.defaultValue || setting.defaultValue;
|
||||
setting.onChange(inputElement.value);
|
||||
inputElement.addEventListener("input", function() {
|
||||
// Aggiorna il valore del campo testuale quando lo slider viene spostato
|
||||
|
||||
valueText.textContent = inputElement.value;
|
||||
setting.onChange(inputElement.value);
|
||||
updateConfiguration(setting.id,inputElement.value)
|
||||
});
|
||||
|
||||
// Crea l'elemento per il valore testuale dello slider
|
||||
|
||||
const valueText = document.createElement("span");
|
||||
valueText.textContent = await getConfiguration(setting.id) || setting.defaultValue;
|
||||
valueText.id = setting.id+"_span";
|
||||
sliderContainer.appendChild(inputElement);
|
||||
sliderContainer.appendChild(valueText);
|
||||
settingElement.appendChild(sliderContainer);
|
||||
|
||||
} else if (setting.type === "text") {
|
||||
inputElement = document.createElement("input");
|
||||
inputElement.type = "text";
|
||||
@@ -519,7 +587,18 @@ async function addSBSetting(fieldLocation, setting) {
|
||||
setting.onChange(inputElement.value);
|
||||
updateConfiguration(setting.id,inputElement.value)
|
||||
});
|
||||
} else if (setting.type === "dropdown") {
|
||||
}
|
||||
else if (setting.type === "textarea") {
|
||||
inputElement = document.createElement("textarea");
|
||||
inputElement.rows = 3;
|
||||
inputElement.value = await getConfiguration(setting.id) || setting.defaultValue;
|
||||
setting.onChange(inputElement.value);
|
||||
inputElement.addEventListener("input", function() {
|
||||
setting.onChange(inputElement.value);
|
||||
updateConfiguration(setting.id,inputElement.value)
|
||||
});
|
||||
}
|
||||
else if (setting.type === "dropdown") {
|
||||
inputElement = document.createElement("select");
|
||||
const defaultValue = await getConfiguration(setting.id) || setting.defaultValue;
|
||||
setting.options.forEach(async (option) => {
|
||||
@@ -541,7 +620,7 @@ async function addSBSetting(fieldLocation, setting) {
|
||||
|
||||
settingElement.appendChild(inputElement);
|
||||
|
||||
// Aggiungi il campo di impostazione al luogo specificato
|
||||
|
||||
const targetElement = document.getElementById(fieldLocation);
|
||||
if (targetElement) {
|
||||
targetElement.appendChild(settingElement);
|
||||
@@ -552,12 +631,9 @@ async function addSBSetting(fieldLocation, setting) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function resetSettings() {
|
||||
let ok = confirm("This option will reset the following settings: \n-Search Type\n-Position\n-Nodes Order Type\n-Font Size\n-Node Size\n-Space Top\n-Space Bottom\n-Node Radius Border\n-Blur Intesity\n-Opacity\nAre you sure you want to reset these settings?");
|
||||
let ok = confirm("This option will reset the following settings: \n-Search Type\n-Position\n-Nodes Order Type\n-Font Size\n-Node Size\n-Space Top\n-Space Bottom\n-Node Radius Border\n-Blur Intesity\n-Opacity\nsidebarWidth\nsb_pinned_collapsed\nsb_minimized\nsb_current_tab\nsb_workflow_preview\nsb_workflow_replace\nAre you sure you want to reset these settings?");
|
||||
if (!ok) {
|
||||
return;
|
||||
}
|
||||
@@ -566,6 +642,16 @@ function resetSettings() {
|
||||
removeConfiguration(setting);
|
||||
});
|
||||
|
||||
const localSettings = ["sidebarWidth","sb_pinned_collapsed","sb_minimized","sb_current_tab","sb_workflow_preview","sb_workflow_replace"];
|
||||
|
||||
localSettings.forEach(setting => {
|
||||
try{
|
||||
removeVar(setting);
|
||||
}catch(err){
|
||||
console.log(err)
|
||||
}
|
||||
})
|
||||
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
@@ -577,7 +663,7 @@ function factoryReset() {
|
||||
}
|
||||
factoryResetSettings();
|
||||
|
||||
const localSettings = ["sidebarWidth","sb_pinned_collapsed","sb_minimized","sb_current_tab","sb_current_tab"];
|
||||
const localSettings = ["sidebarWidth","sb_pinned_collapsed","sb_minimized","sb_current_tab","sb_workflow_preview","sb_workflow_replace"];
|
||||
|
||||
localSettings.forEach(setting => {
|
||||
try{
|
||||
|
||||
@@ -93,7 +93,6 @@
|
||||
function addJavascriptVar(name, value) {
|
||||
const scripta = document.createElement('script');
|
||||
scripta.type = 'text/javascript';
|
||||
console.log("var "+name+" = "+value)
|
||||
scripta.innerHTML = "var "+name+" = "+value;
|
||||
|
||||
document.head.appendChild(scripta);
|
||||
@@ -212,16 +211,37 @@ function createContextMenu(event, subMenus,settingsData) {
|
||||
showSubMenu(subMenus[index], li);
|
||||
});
|
||||
try {
|
||||
|
||||
|
||||
|
||||
if (settingsData.menuctx_opt_callback[index].indexOf(".") !== -1) {
|
||||
|
||||
// Handle sub menu option
|
||||
var mainfunc = settingsData.menuctx_opt_callback[index].split(".")[0];
|
||||
var subfunc = settingsData.menuctx_opt_callback[index].split(".")[1];
|
||||
if (typeof (window[mainfunc][subfunc]) === 'function') {
|
||||
|
||||
|
||||
li.addEventListener('click', () => {
|
||||
// Handle sub menu click
|
||||
window[mainfunc][subfunc](event);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
else{
|
||||
|
||||
if (typeof (window[settingsData.menuctx_opt_callback[index]]) === 'function') {
|
||||
li.addEventListener('click', () => {
|
||||
// Handle main option click
|
||||
//alert(`Selected option: ${option}`);
|
||||
|
||||
|
||||
|
||||
window[settingsData.menuctx_opt_callback[index]](event);
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
@@ -368,9 +388,16 @@ window.addEventListener("click", function(event) {
|
||||
|
||||
|
||||
// Function to check for special characters
|
||||
function containsSpecialCharacters(name) {
|
||||
function containsSpecialCharacters(name, level=0) {
|
||||
// Define a regular expression pattern to match special characters
|
||||
var specialCharacters = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/;
|
||||
if (level == 0) {
|
||||
var specialCharacters = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/;
|
||||
} else if (level == 1) {
|
||||
var specialCharacters = /[\*':"\\|,<>\/?]/g;
|
||||
} else{
|
||||
var specialCharacters = /['"]/gi;
|
||||
}
|
||||
|
||||
// Return true if the name contains any special characters, false otherwise
|
||||
return specialCharacters.test(name);
|
||||
}
|
||||
@@ -442,7 +469,11 @@ function openModal(addon=null) {
|
||||
closeModalButton.addEventListener('click', closeModal);
|
||||
try{
|
||||
// Focus the input field
|
||||
document.getElementById('sb-categoryName').focus();
|
||||
inputElement = document.getElementById('sb-categoryName');
|
||||
inputElement.focus();
|
||||
const length = inputElement.value.length;
|
||||
inputElement.setSelectionRange(length, length);
|
||||
|
||||
}catch(err){
|
||||
|
||||
}
|
||||
@@ -454,12 +485,17 @@ try{
|
||||
function closeModal() {
|
||||
const modalBackdrop = document.querySelector('.sb-modal-backdrop');
|
||||
const modal = document.querySelector('.sb-category-dialog');
|
||||
|
||||
try{
|
||||
// Remove the modal from the DOM
|
||||
modalBackdrop.parentNode.removeChild(modalBackdrop);
|
||||
modal.parentNode.removeChild(modal);
|
||||
}
|
||||
catch(err){
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function rgbToHex(rgb) {
|
||||
// Verifica se il colore è nel formato "rgb()"
|
||||
if (rgb.indexOf('rgb') !== -1) {
|
||||
@@ -522,3 +558,10 @@ function isBottomEdgeVisible(el) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function convertCanvasToOffset(canvas, pos, out) {
|
||||
out = out || [0, 0];
|
||||
out[0] = pos[0] / canvas.scale - canvas.offset[0];
|
||||
out[1] = pos[1] / canvas.scale - canvas.offset[1];
|
||||
return out;
|
||||
};
|
||||
|
||||
+10
-16
@@ -3,7 +3,9 @@ import { api } from "../../../../scripts/api.js"
|
||||
import { app } from "../../../../scripts/app.js";
|
||||
import { $el } from "../../../../scripts/ui.js";
|
||||
import { fuzzyMatch } from "./fts_fuzzy_match.js";
|
||||
import { GroupNodeConfig, GroupNodeHandler } from "../../../../extensions/core/groupNode.js";
|
||||
|
||||
const gnc = GroupNodeConfig;
|
||||
//import {settingsSetup} from './functions/settings.jsb';
|
||||
console.time('execution time');
|
||||
const cnPath = "../extensions/ComfyUI-N-Sidebar/"
|
||||
@@ -93,7 +95,7 @@ function postPinned() {
|
||||
|
||||
previewDivTop = (itemPosition.top + this.offsetHeight) - previewDiv.offsetHeight;
|
||||
}
|
||||
let sidebar_width = parseInt(getVar("sidebarWidth")) || 300;
|
||||
let sidebar_width = parseInt(getVar("sidebarWidth")) || 500;
|
||||
previewDiv.style.top = `${previewDivTop}px`;
|
||||
const previewDivLeft = sidebar_width - sidebad_view_width;
|
||||
|
||||
@@ -112,14 +114,8 @@ function postPinned() {
|
||||
previewDiv.style.display = 'none';
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
reloadCtxMenu()
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
pinnedElement.addEventListener("dragover", function (event) {
|
||||
@@ -228,8 +224,11 @@ async function loadPinnedItemsAndAddToBookmarks() {
|
||||
|
||||
|
||||
if (item) {
|
||||
try{
|
||||
let addedItem = sidebarBookmarks.appendChild(item.cloneNode(true));
|
||||
addedItem.lastChild.lastChild.classList.add("pinned");
|
||||
|
||||
}catch(err){ }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -579,7 +578,7 @@ async function createCategoryList() {
|
||||
previewDivTop = (itemPosition.top + this.offsetHeight) - previewDiv.offsetHeight;
|
||||
}
|
||||
|
||||
let sidebar_width = parseInt(getVar("sidebarWidth")) || 300;
|
||||
let sidebar_width = parseInt(getVar("sidebarWidth")) || 500;
|
||||
|
||||
|
||||
previewDiv.style.top = `${previewDivTop}px`;
|
||||
@@ -755,13 +754,7 @@ async function addSidebar() {
|
||||
});
|
||||
|
||||
|
||||
function convertCanvasToOffset(canvas, pos, out) {
|
||||
out = out || [0, 0];
|
||||
out[0] = pos[0] / canvas.scale - canvas.offset[0];
|
||||
out[1] = pos[1] / canvas.scale - canvas.offset[1];
|
||||
return out;
|
||||
};
|
||||
|
||||
|
||||
|
||||
function handleDrop(event) {
|
||||
event.preventDefault();
|
||||
@@ -973,7 +966,7 @@ function processViews(viewsData, settingsData) {
|
||||
div_panel_title.classList = "panel_sidebar_title sb_label";
|
||||
div_panel_title.id = "panel_title_" + panel;
|
||||
|
||||
div_panel_title.innerHTML = panel.replace("_", " ");
|
||||
div_panel_title.innerHTML = view.id.replace("_", " ");
|
||||
|
||||
|
||||
|
||||
@@ -987,6 +980,7 @@ function processViews(viewsData, settingsData) {
|
||||
|
||||
div_view.insertAdjacentElement('beforeend', div_panel);
|
||||
jsloader(`${cnPath}panels/${panel}/${panel}.jsb`);
|
||||
//window.custom_templates();
|
||||
console.log("LOADING " + cnPath + `panels/${panel}/${panel}.js`)
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -512,6 +512,13 @@ async function renameCategory(oldCategoryName, newCategoryName) {
|
||||
}
|
||||
|
||||
let categoryNodeMap = await getNodeMap();
|
||||
|
||||
if (categoryNodeMap[newCategoryName]) {
|
||||
alert("Category already exists!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let categoryNodeStatus = getNodesStatus();
|
||||
if (categoryNodeMap[oldCategoryName]) {
|
||||
// Categoty Current Order
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<div id="custom_templates_header">
|
||||
<div class="h-header" id="h_search" data-content="panel_head_home">
|
||||
<input type="text" id="searchTemplateInput" oninput="custom_templates.searchT(this)" placeholder="Search..."
|
||||
autocomplete="off" class="">
|
||||
<span class="clearIconCustomTemplate">×</span>
|
||||
<span class="searchTemplateIconCustomTemplate">C</span>
|
||||
<button id="openModalButton" onclick="custom_templates.openModal()">+</button>
|
||||
<button id="refreshlButton" onclick="custom_templates.renderList('custom_templates_main')">⭮</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="custom_templates_main">
|
||||
</div>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,141 @@
|
||||
#custom_templates_main,#custom_templates_header {
|
||||
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
#custom_templates_main{
|
||||
|
||||
padding-top: 44px;
|
||||
}
|
||||
#custom_templates_header {
|
||||
margin: 10px 20px;
|
||||
font-size: 16px;
|
||||
|
||||
}
|
||||
#custom_templates_header #h_search {
|
||||
position: absolute;
|
||||
width: calc(100% - 115px);
|
||||
margin-top: 0px;
|
||||
|
||||
z-index: 400;
|
||||
|
||||
}
|
||||
|
||||
#custom_templates_header button {
|
||||
/* padding: 10px 20px; */
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
font-size: 16px;
|
||||
background: var(--comfy-input-bg);
|
||||
border: 2px solid var(--border-color);
|
||||
color: var(--input-text);
|
||||
border-radius: 5px;
|
||||
float: right;
|
||||
position: absolute;
|
||||
margin: 2px 2px 2px 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#custom_templates_header button:hover {
|
||||
border: 2px solid var(--descrip-text);
|
||||
|
||||
}
|
||||
.sb-template-dialog {
|
||||
outline: 0;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
background: var(--bg-color);
|
||||
color: #fff;
|
||||
box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.05), inset -1px -1px 0px rgba(0, 0, 0, 0.5), 2px 2px 20px rgb(0, 0, 0);
|
||||
max-width: 800px;
|
||||
min-width: 30rem;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||
font-size: 1rem;
|
||||
padding: 20px;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
#sb-template-form {
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sb-input {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
margin-top: 16px;
|
||||
background: var(--bg-color);
|
||||
color: var(--input-text);
|
||||
|
||||
}
|
||||
.sb-input:focus {
|
||||
outline: none;
|
||||
border: 2px solid var(--descrip-text);
|
||||
}
|
||||
|
||||
.sb-button {
|
||||
background-color: var(--comfy-menu-bg);
|
||||
color: var(--input-text);
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
margin-top: 10px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sb-button:hover {
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
#closeModalButton {
|
||||
background-color: var(--comfy-menu-bg);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#closeModalButton:hover {
|
||||
filter: brightness(120%);
|
||||
|
||||
}
|
||||
#searchTemplateInput {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
user-select: none;
|
||||
background: var(--comfy-input-bg);
|
||||
color: var(--input-text);
|
||||
line-height: 1.4;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
|
||||
#previewDiv .sb_table {
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sidebar #previewDiv .sidebarItem, #custom_templates_main .sidebarItem {
|
||||
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
#refreshlButton{
|
||||
margin-left: 48px !important;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<div id="custom_workflows_header">
|
||||
<div class="h-header" id="h_search" data-content="panel_head_home">
|
||||
<input type="text" id="searchWorkflowInput" oninput="custom_workflows.searchT(this)" placeholder="Search..."
|
||||
autocomplete="off" class="">
|
||||
<span class="clearIconCustomWorkflow">×</span>
|
||||
<span class="searchWorkflowIconCustomWorkflow">C</span>
|
||||
<button id="openModalButton" onclick="custom_workflows.openModal()">+</button>
|
||||
<button id="refreshlButton" onclick="custom_workflows.renderList('custom_workflows_main')">⭮</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="custom_workflows_main">
|
||||
</div>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,139 @@
|
||||
#custom_workflows_main,#custom_workflows_header {
|
||||
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
#custom_workflows_main{
|
||||
|
||||
padding-top: 44px;
|
||||
}
|
||||
#custom_workflows_header {
|
||||
margin: 10px 20px;
|
||||
font-size: 16px;
|
||||
|
||||
}
|
||||
#custom_workflows_header #h_search {
|
||||
position: absolute;
|
||||
width: calc(100% - 115px);
|
||||
margin-top: 0px;
|
||||
|
||||
z-index: 400;
|
||||
|
||||
}
|
||||
|
||||
#custom_workflows_header button {
|
||||
/* padding: 10px 20px; */
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
font-size: 16px;
|
||||
background: var(--comfy-input-bg);
|
||||
border: 2px solid var(--border-color);
|
||||
color: var(--input-text);
|
||||
border-radius: 5px;
|
||||
float: right;
|
||||
position: absolute;
|
||||
margin: 2px 2px 2px 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#custom_workflows_header button:hover {
|
||||
border: 2px solid var(--descrip-text);
|
||||
|
||||
}
|
||||
.sb-workflow-dialog {
|
||||
outline: 0;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
background: var(--bg-color);
|
||||
color: #fff;
|
||||
box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.05), inset -1px -1px 0px rgba(0, 0, 0, 0.5), 2px 2px 20px rgb(0, 0, 0);
|
||||
max-width: 800px;
|
||||
min-width: 30rem;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||
font-size: 1rem;
|
||||
padding: 20px;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
#sb-workflow-form {
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sb-input {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
margin-bottom: 10px;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid var(--border-color);
|
||||
border-radius: 4px;
|
||||
margin-top: 16px;
|
||||
background: var(--bg-color);
|
||||
color: var(--input-text);
|
||||
|
||||
}
|
||||
.sb-input:focus {
|
||||
outline: none;
|
||||
border: 2px solid var(--descrip-text);
|
||||
}
|
||||
|
||||
.sb-button {
|
||||
background-color: var(--comfy-menu-bg);
|
||||
color: var(--input-text);
|
||||
padding: 10px 20px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
margin-top: 10px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sb-button:hover {
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
#closeModalButton {
|
||||
background-color: var(--comfy-menu-bg);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#closeModalButton:hover {
|
||||
filter: brightness(120%);
|
||||
|
||||
}
|
||||
#searchWorkflowInput {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
user-select: none;
|
||||
background: var(--comfy-input-bg);
|
||||
color: var(--input-text);
|
||||
line-height: 1.4;
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
||||
|
||||
#previewDiv .sb_table {
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sidebar #previewDiv .sidebarItem, #custom_workflows_main .sidebarItem {
|
||||
|
||||
max-width: 100% !important;
|
||||
}
|
||||
#refreshlButton{
|
||||
margin-left: 48px !important;
|
||||
}
|
||||
+21
-1
@@ -1,11 +1,31 @@
|
||||
[
|
||||
{
|
||||
"id": "custom_view",
|
||||
"id": "custom_categories",
|
||||
"icon": "⧉",
|
||||
"description": "Custom Node Categories",
|
||||
"panels": [
|
||||
"custom_categories"
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "templates",
|
||||
"icon": "Τ",
|
||||
"description": "Custom Node templates",
|
||||
"panels": [
|
||||
"custom_templates"
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "workflows",
|
||||
"icon": "W",
|
||||
"description": "Custom Node workflows",
|
||||
"panels": [
|
||||
"custom_workflows"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 369 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 317 KiB |
+1
-1
@@ -1,7 +1,7 @@
|
||||
[project]
|
||||
name = "comfyui-n-sidebar"
|
||||
description = "A simple sidebar for ComfyUI."
|
||||
version = "1.0.1"
|
||||
version = "1.1.0"
|
||||
license = "LICENSE"
|
||||
|
||||
[project.urls]
|
||||
|
||||
Reference in New Issue
Block a user