diff --git a/.gitignore b/.gitignore
index 38931e8..ebd586d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
# Config file
app/settings.json
+app/settings.json.bak
# Byte-compiled / optimized / DLL files
__pycache__/
diff --git a/README.md b/README.md
index 8dfb423..7062f73 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,25 @@ For what i know nobody did it, so i did it.
Maybe you don't need it. I need it >.<
# Updates
+
+- 04-06-2024
+ - Fixed some bugs
+ - Changed icon bar positioning to the border of the screen
+ - Implemented the DAMN subcategory view on the node panel!!! xD (you can disable it in the settings if you don't want it)
+ - Added the ability to disable the "Auto Show" feature
+ - Added the ability to view folders inside the workflow panel
+ - Added some tooltips for better UX
+ - Changed the Custom Node Categories icon (I didn't like the old one)
+ - Added a little icon in custom categories and folders/subcategories
+ - Added the ability to move workflows in custom categories via the context menu
+ - Added the ability to open workflows in another TAB
+
+NOTE: If you had some custom categories in the workflow panel, at the first start they will be migrated to the new system (since I did a full rewrite to support the folders). It is possible that you need to refresh the page more than once to see them again. Also, a backup of the settings.json will be created before the migration in case anything goes wrong.
+
+NOTE2: I hope I did not break anything T_T
+
+
+
- 25-05-2024
- Fixed some bugs
- Added Templates support**
@@ -66,6 +85,11 @@ NOTE: If you choose to use a different method to install the ComfyUI-N-Sidebar,
1. Navigate to the cloned repo e.g. `custom_nodes/ComfyUI-N-Sidebar`
2. `git pull`
+
+# Settings
+The most important settings are stored in `custom_nodes/ComfyUI-N-Sidebar/settings.json`
+
+
# Keyboard Shortcuts
- `Alt+Z` to toggle show/hide sidebar
@@ -129,6 +153,10 @@ PS: Workflow Path
- [x] Color integration with Jovimetrix
- [x] Better search
- [x] Custom Categories!!
+- [x] Workflows
+- [x] Templates
+- [ ] Custom Shortcuts
+- [ ] Export and Import Settings
diff --git a/__init__.py b/__init__.py
index 0341591..8e169f7 100644
--- a/__init__.py
+++ b/__init__.py
@@ -5,6 +5,8 @@ import os
import json
from collections import OrderedDict
from pathlib import Path
+import base64
+import shutil
@@ -53,6 +55,55 @@ class JSONConfigManager:
self.data[parameter_name] = value
self.write_json_file()
+def generate_id(file_path):
+
+ encoded_bytes = base64.b64encode(file_path.encode('utf-8'))
+ encoded_str = str(encoded_bytes, 'utf-8')
+ return encoded_str
+
+
+"""
+def scan_directory(directory, workflows_dict, existing_names, main_path = ''):
+ for entry in os.scandir(directory):
+ 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(directory)
+ # unique_name = f"{base_name} (from {folder_name})"
+
+ subfolder = entry.path.replace(main_path, '').replace(entry.name, '')
+
+ workflows_dict[base_name] = {"name": base_name,"path": entry.path, "subfolder": subfolder}
+ existing_names.add(base_name)
+ elif entry.is_dir():
+ scan_directory(entry.path, workflows_dict, existing_names,main_path)
+
+"""
+
+def scan_directory(directory, workflows_dict, existing_names, main_path=''):
+ for entry in os.scandir(directory):
+ if entry.is_file() and entry.name.endswith('.json'):
+ base_name = entry.name[:-5] # Remove the '.json' extension
+ subfolder = entry.path.replace(main_path, '').replace(entry.name, '')
+
+ unique_id = generate_id(entry.path)
+ workflows_dict[unique_id] = {
+ "name": base_name,
+ "path": entry.path,
+ "subfolder": subfolder
+ }
+ existing_names.add(base_name)
+ elif entry.is_dir():
+ scan_directory(entry.path, workflows_dict, existing_names, main_path)
+
+
+
+
+
+
+
# If is different from ComfyUISidebar, change it
if __package__ != "ComfyUI-N-Sidebar":
@@ -109,6 +160,21 @@ for folder in folders:
list_panels_array.append(folder)
+@server.PromptServer.instance.routes.get("/sidebar/backup" )
+async def s_get(request):
+ backup_path = file_path + ".bak"
+
+ try:
+ # Crea una copia di settings.json come settings.json.bak
+ shutil.copyfile(file_path, backup_path)
+ except Exception as e:
+ result = {"result": "ERROR", "message": str(e)}
+ return web.json_response(result, content_type='application/json')
+
+ result = {"result": "OK"}
+ return web.json_response(result, content_type='application/json')
+
+
@server.PromptServer.instance.routes.get("/sidebar/workflows" )
async def s_get(request):
@@ -116,18 +182,9 @@ async def s_get(request):
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()))
+ scan_directory(list_workflows, workflows_dict, existing_names, list_workflows)
+
+ sorted_workflows_dict = dict(sorted(workflows_dict.items(), key=lambda x: x[1]["name"].lower()))
return web.json_response(sorted_workflows_dict, content_type='application/json')
@@ -153,10 +210,10 @@ async def s_get(request):
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!"}
+ result = {"result": "File already exists!"}
else:
#rename
os.rename(path, new_path)
diff --git a/app/css/base_style.css b/app/css/base_style.css
index 6cbb667..666000f 100644
--- a/app/css/base_style.css
+++ b/app/css/base_style.css
@@ -25,9 +25,10 @@
padding-left: 5px;
padding-right: 5px;
- margin-bottom: 8px;
+ /*margin-bottom: 8px;*/
margin-top: 0;
padding-top: 5px;
+ width: 100%;
}
.sidebar li {
@@ -78,7 +79,7 @@
width: calc(100% - 75px);
margin-top: 5px;
margin-bottom: 10px;
- margin-left: 10px;
+ margin-left: 44px;
z-index: 400;
@@ -133,7 +134,10 @@
font-size: 15px;
padding-bottom: 8px;
}
-
+ .sidebarCategory {
+ border-bottom:var(--comfy-input-bg) solid 1px;
+ text-wrap: nowrap;
+ }
#sidebarCustomNodes {
list-style-type: none;
font-family: 'Open Sans', sans-serif;
@@ -165,9 +169,30 @@
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
- max-width: calc(100% - 39px);
+ /*max-width: calc(100% - 39px);*/
}
+ .displayName{
+ float: left;
+ width: 87%;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ /* margin: 2% auto;*/
+ /*display: flex;*/
+ align-items: center;
+ padding-left: 3%;
+ /*height: 14px;*/
+ }
+ .categoryName{
+
+ width: 100%;
+ text-overflow: ellipsis;
+ overflow: hidden;
+
+
+
+ }
.content_sidebar::-webkit-scrollbar {
margin-top: 0.5rem;
@@ -260,11 +285,15 @@
display: none;
}
- .sidebarCategory .pinButton {
+ .sidebarCategory .pinButton, .sidebarItem .pinButton {
background-color: transparent;
border: 0;
position: absolute;
- right: 0;
+ width: 10%;
+ float: left;
+ /* padding-top: 4px; */
+ /* font-size: 39px; */
+ height: 1.5em;
}
#sb_scrollToTopButton.closed {
@@ -276,8 +305,13 @@
background-color: transparent;
border: 0;
- position: absolute;
- right: 0;
+ /*position: absolute;
+ right: 0;*/
+
+ position: relative;
+ width: 10%;
+ float: left;
+
}
.previewButton {
@@ -294,12 +328,12 @@
.svg_class {
width: 24px;
- height: 24px;
+ height: 18px;
fill: var(--border-color);
cursor: pointer;
- /* hacky fix */
+ /* hacky fix
margin-top: -5px;
- margin-left: -25px;
+ margin-left: -25px;*/
}
.pin_normal {
diff --git a/app/html/sidebar.html b/app/html/sidebar.html
index 65dce86..2aa748c 100644
--- a/app/html/sidebar.html
+++ b/app/html/sidebar.html
@@ -4,13 +4,25 @@
×
C
+
-
+
diff --git a/app/js/functions/settings.js b/app/js/functions/settings.js
index b63369b..8f2a8a8 100644
--- a/app/js/functions/settings.js
+++ b/app/js/functions/settings.js
@@ -156,7 +156,39 @@ async function settingsSetup(app,$el) {
},
});
-
+ addSBSetting( "sb_settingsDiv",{
+ id: "auto_hide",
+ name: "Auto Show Sidebar",
+ defaultValue: "false",
+ type: "boolean",
+ local: true,
+
+
+ onChange(value) {
+
+ },
+ });
+
+ await addSBSetting( "sb_settingsDiv", {
+ id: "tree_view",
+ name: "Node Category Tree View",
+ defaultValue: "multi",
+ type: "dropdown",
+ info: "NOTE: The new view will be applied after a page refresh!",
+ options: [
+ { value: "mono", label: "MONO" },
+ { value: "multi", label: "MULTILEVEL" }
+
+
+ ],
+ onChange(value) {
+
+ defaultSearchOrder = value;
+
+
+ },
+ });
+
addSBSetting( "sb_settingsDiv",{
id: "font",
name: "Font Size",
@@ -168,7 +200,7 @@ async function settingsSetup(app,$el) {
step: 1,
},
onChange(value) {
- addDynamicCSSRule('.sidebarCategory, #sidebarBookmarks', 'font-size', value + 'px');
+ addDynamicCSSRule('.sidebarCategory, .sidebarFolder, #sidebarBookmarks', 'font-size', value + 'px');
},
});
@@ -337,7 +369,7 @@ async function settingsSetup(app,$el) {
step: 1,
},
onChange(value) {
- addDynamicCSSRule('.sidebarCategory, #sidebarBookmarks', 'border-radius', value + 'px');
+ addDynamicCSSRule('.sidebarCategory, .sidebarFolder, #sidebarBookmarks', 'border-radius', value + 'px');
addDynamicCSSRule('.sidebarItem', 'border-radius', value + 'px');
},
});
@@ -374,7 +406,7 @@ async function settingsSetup(app,$el) {
addDynamicCSSRule('.content_sidebar', 'background', 'rgb(from var(--comfy-menu-bg) r g b / ' + value_perc + '%)');
addDynamicCSSRule('#sidebar_views', 'background', 'rgb(from var(--comfy-menu-bg) r g b / ' + value_perc + '%)');
addDynamicCSSRule('#sidebar_views', 'border-left', '2px rgb(from var(--comfy-menu-bg) r g b / ' + (parseFloat(value) + 10) + '%)');
- addDynamicCSSRule('.sidebarCategory, #sidebarBookmarks', 'background-color', 'rgb(from var(--comfy-input-bg) r g b / ' + value_perc + '%)');
+ addDynamicCSSRule('.sidebarCategory, .sidebarFolder, #sidebarBookmarks', 'background-color', 'rgb(from var(--comfy-input-bg) r g b / ' + value_perc + '%)');
},
@@ -416,8 +448,8 @@ async function settingsSetup(app,$el) {
addDynamicCSSRule('.dragHandle', 'float', 'right');
addDynamicCSSRule('.sidebar', 'left', 'unset');
addDynamicCSSRule('.sidebar', 'right', '0');
- addDynamicCSSRule('.sidebar-header', 'right', '16px');
- addDynamicCSSRule('#sb_scrollToTopButton', 'right', '12px');
+ addDynamicCSSRule('.sidebar-header', 'right', '52px');
+ addDynamicCSSRule('#sb_scrollToTopButton', 'right', '48px');
}
if (value == "left") {
@@ -427,7 +459,7 @@ async function settingsSetup(app,$el) {
addDynamicCSSRule('.sidebar', 'left', '0');
addDynamicCSSRule('.sidebar', 'right', 'unset');
addDynamicCSSRule('.sidebar-header', 'right', 'unset');
- addDynamicCSSRule('#sb_scrollToTopButton', 'right', '56px');
+ addDynamicCSSRule('#sb_scrollToTopButton', 'right', '26px');
}
sbPosition = value;
@@ -642,7 +674,7 @@ function resetSettings() {
removeConfiguration(setting);
});
- const localSettings = ["sidebarWidth","sb_pinned_collapsed","sb_minimized","sb_current_tab","sb_workflow_preview","sb_workflow_replace"];
+ const localSettings = ["sidebarWidth","sb_pinned_collapsed","sb_minimized","sb_current_tab","sb_workflow_preview","sb_workflow_replace","sb_migrated"];
localSettings.forEach(setting => {
try{
@@ -663,7 +695,7 @@ function factoryReset() {
}
factoryResetSettings();
- const localSettings = ["sidebarWidth","sb_pinned_collapsed","sb_minimized","sb_current_tab","sb_workflow_preview","sb_workflow_replace"];
+ const localSettings = ["sidebarWidth","sb_pinned_collapsed","sb_minimized","sb_current_tab","sb_workflow_preview","sb_workflow_replace","sb_migrated"];
localSettings.forEach(setting => {
try{
diff --git a/app/js/functions/utils.js b/app/js/functions/utils.js
index 8b81e7b..9a41608 100644
--- a/app/js/functions/utils.js
+++ b/app/js/functions/utils.js
@@ -213,7 +213,6 @@ function createContextMenu(event, subMenus,settingsData) {
try {
-
if (settingsData.menuctx_opt_callback[index].indexOf(".") !== -1) {
// Handle sub menu option
@@ -234,9 +233,6 @@ function createContextMenu(event, subMenus,settingsData) {
if (typeof (window[settingsData.menuctx_opt_callback[index]]) === 'function') {
li.addEventListener('click', () => {
// Handle main option click
-
-
-
window[settingsData.menuctx_opt_callback[index]](event);
});
@@ -244,6 +240,7 @@ function createContextMenu(event, subMenus,settingsData) {
}
} catch (error) {
console.log(error);
+
}
menuOptions.appendChild(li);
});
@@ -334,17 +331,41 @@ async function setContextMenu(settingsData,class_menu_item,main=0,exluded_class=
subMenu.appendChild(li);
try {
- if (typeof (window[settingsData.menuctx_sub_opt_callback[i][j]]) === 'function') {
- li.addEventListener('click', () => {
- // Handle main option click
-
- //alert(`Selected option: ${settingsData.menuctx_subOptions[i][j]}`);
-
-
- window[settingsData.menuctx_sub_opt_callback[i][j]](lastTargetClicked,settingsData.menuctx_subOptions[i][j]);
-
- });
+ if (settingsData.menuctx_sub_opt_callback[i][j].indexOf(".") !== -1) {
+
+ // Handle sub menu option
+ var mainfunc = settingsData.menuctx_sub_opt_callback[i][j].split(".")[0];
+ var subfunc = settingsData.menuctx_sub_opt_callback[i][j].split(".")[1];
+ if (typeof (window[mainfunc][subfunc]) === 'function') {
+
+
+ li.addEventListener('click', () => {
+ // Handle sub menu click
+
+ window[mainfunc][subfunc](lastTargetClicked,settingsData.menuctx_subOptions[i][j]);
+
+ });
+
+ }
+ }
+ else{
+
+ if (typeof (window[settingsData.menuctx_sub_opt_callback[i][j]]) === 'function') {
+ li.addEventListener('click', () => {
+ // Handle main option click
+
+
+ window[settingsData.menuctx_sub_opt_callback[i][j]](lastTargetClicked,settingsData.menuctx_subOptions[i][j]);
+
+ });
+ }
}
+
+
+
+
+
+
} catch (error) {
console.log(error);
}
@@ -411,24 +432,24 @@ async function reloadCtxMenu() {
}
-function setNodeStatus(node,status) {
- try{
- const categoryNodeStatus = JSON.parse(localStorage.getItem('sb_categoryNodeStatus')) || {};
+function setNodeStatus(varname,node,status) {
+ try{//'sb_categoryNodeStatus'
+ const categoryNodeStatus = JSON.parse(localStorage.getItem(varname)) || {};
categoryNodeStatus[node] = [status];
- localStorage.setItem('sb_categoryNodeStatus', JSON.stringify(categoryNodeStatus));
+ localStorage.setItem(varname, JSON.stringify(categoryNodeStatus));
}catch(err){ }
}
-function getNodeStatus(node) {
+function getNodeStatus(varname,node) {
try{
- const categoryNodeStatus = JSON.parse(localStorage.getItem('sb_categoryNodeStatus')) || {};
+ const categoryNodeStatus = JSON.parse(localStorage.getItem(varname)) || {};
return categoryNodeStatus[node] || "none";
}catch(err){ }
return "none";
}
function getNodesStatus() {
- let categoryNodeStatus = JSON.parse(localStorage.getItem('sb_categoryNodeStatus')) || {};
+ let categoryNodeStatus = JSON.parse(localStorage.getItem(varname)) || {};
return categoryNodeStatus;
}
diff --git a/app/js/sidebar_node.js b/app/js/sidebar_node.js
index ab35bdb..3e1c01a 100644
--- a/app/js/sidebar_node.js
+++ b/app/js/sidebar_node.js
@@ -42,11 +42,6 @@ try {
let categorySearchToggle = false;
-
-
-
-
-
function getSidebarItemIds() {
const sidebarItems = document.querySelectorAll("#sidebarBookmarks .sidebarItem");
const itemIds = [];
@@ -98,8 +93,8 @@ function postPinned() {
}
let sidebar_width = parseInt(getVar("sidebarWidth")) || 500;
previewDiv.style.top = `${previewDivTop}px`;
- const previewDivLeft = sidebar_width - sidebad_view_width;
-
+ const previewDivLeft = sidebar_width - sidebad_view_width + correction_offset;
+
if (sbPosition == "left") {
previewDiv.style.left = `${previewDivLeft}px`;
} else {
@@ -288,8 +283,6 @@ async function createCategoryList() {
if (defaultSearchToggle == "original" && itemSearchInput.value != "") {
//search in all .sidebarItem
handleSearch(categorySearchToggle, "#content_sidebar_home", "searchInput")
-
-
}
else {
updateList();
@@ -445,98 +438,154 @@ async function createCategoryList() {
}
+ function buildTree(categories, useSubcategories = true) {
+ const tree = {};
+
+ for (const category in categories) {
+ const parts = useSubcategories ? category.split('/').filter(part => part !== '') : [category];
+
+ let current = tree;
+ if (parts.length > 0 || !useSubcategories) {
+
+
+ for (const part of parts) {
+ if (!current[part]) {
+ current[part] = {};
+ }
+ current = current[part];
+ }
+
+ if (!current.items) {
+ current.items = [];
+ }
+
+ categories[category].forEach(displayName => {
+ current.items.push(displayName);
+ });
+ }
+ }
+
+ return tree;
+ }
+
+ function createHtmlFromTree(tree, parentElement,pinnedItems) {
+ for (const key in tree) {
+ if (key !== 'items') {
+ const subfolderLi = document.createElement('li');
+ subfolderLi.textContent = "🗀 " + key;
+ subfolderLi.classList.add('sidebarCategory');
+ subfolderLi.dataset.nameworkflow = key;
+
+ const subfolderUl = document.createElement('ul');
+ subfolderUl.style.display = "none";
+ subfolderUl.classList.add('subfolder');
+ subfolderUl.dataset.subfolder = key;
+ subfolderUl.id = key + "_ul";
+ subfolderUl.classList.add("displayNamesList");
+
+ subfolderLi.appendChild(subfolderUl);
+ parentElement.appendChild(subfolderLi);
+
+ createHtmlFromTree(tree[key], subfolderUl,pinnedItems);
+ }
+ }
+
+ if (tree.items) {
+ tree.items.forEach(displayName => {
+ try {
+
+ const displayNameMain = document.createElement('div');
+ displayNameMain.classList.add('displayName');
+ displayNameMain.title = displayName.title;
+ displayNameMain.id = displayName.type;
+
+ displayNameMain.textContent = displayName.title;
+
+
+
+ const displayNameItem = document.createElement('li');
+ displayNameItem.classList.add('sidebarItem');
+ //displayNameItem.innerHTML = ""+displayName.title+"
";
+ displayNameItem.title = displayName.title;
+ displayNameItem.draggable = true;
+ displayNameItem.appendChild(displayNameMain);
+
+ // JOVIMETRIX CUT-OUT FOR CUSTOM COLORED NODES
+ if (CUSTOM_COLORS) {
+ let color = CUSTOM_COLORS[displayName.title];
+ const nodeData = displayName?.nodeData;
+ if (color === undefined) {
+ if (nodeData !== undefined) {
+ let k = nodeData.category;
+ while (k) {
+ color = CUSTOM_COLORS[k];
+ if (color) {
+ color = color.title;
+ break;
+ }
+ const last = k.lastIndexOf('/');
+ k = last !== -1 ? k.substring(0, last) : '';
+ }
+ }
+ } else {
+ color = color.title;
+ }
+ if (color) {
+ displayNameItem.style = `background: ${color}`;
+ }
+ }
+ //
+
+ displayNameItem.id = displayName.type;
+
+ /* Create Pin Button */
+
+ const pinButton = document.createElement('button');
+ pinButton.classList.add('pinButton');
+
+ let add_class = "";
+
+ if (pinnedItems.includes(displayName.type)) {
+ add_class = "pinned";
+ }
+ pinButton.innerHTML = ``;
+
+ displayNameItem.appendChild(pinButton);
+ /* End Pin Button */
+
+ parentElement.appendChild(displayNameItem);
+ } catch (err) {
+ console.log(err);
+ }
+ });
+ }
+ }
+
+
async function renderList() {
return new Promise(async (resolve, reject) => {
const pinnedItems = await loadPinnedItems();
//
const sidebarCustomNodes = document.getElementById("sidebarCustomNodes");
- for (const category in categories) {
- const categoryItem = document.createElement("li");
- categoryItem.classList.add("sidebarCategory");
- categoryItem.textContent = category;
-
- const displayNamesList = document.createElement("ul");
- displayNamesList.style.display = "none";
- categoryItem.appendChild(displayNamesList);
-
- categories[category].forEach(displayName => {
- try {
- const displayNameItem = document.createElement("li");
- displayNameItem.classList.add("sidebarItem");
- displayNameItem.textContent = displayName.title;
- displayNameItem.title = displayName.title;
- displayNameItem.draggable = true;
-
- // JOVIMETRIX CUT-OUT FOR CUSTOM COLORED NODES
- //
- if (CUSTOM_COLORS) {
- let color = CUSTOM_COLORS[displayName.title];
- const nodeData = displayName?.nodeData;
- if (color === undefined) {
- if (nodeData !== undefined) {
- let k = nodeData.category;
- while (k) {
- color = CUSTOM_COLORS[k];
- if (color) {
- color = color.title;
- break;
- }
- const last = k.lastIndexOf('/');
- k = last !== -1 ? k.substring(0, last) : '';
- }
- }
- } else {
- color = color.title;
- }
- if (color) {
- displayNameItem.style = `background: ${color}`;
- }
- }
- //
-
- displayNameItem.id = displayName.type;
-
- /* Create Pin Button */
- const pinButton = document.createElement("button");
- pinButton.classList.add("pinButton");
-
- let add_class = "";
-
- if (pinnedItems.includes(displayName.type)) {
- add_class = "pinned";
- }
- pinButton.innerHTML = ``;
-
-
- displayNameItem.appendChild(pinButton);
- /* End Pin Button */
-
-
- displayNamesList.appendChild(displayNameItem);
- } catch (err) {
- console.log(err);
- }
- });
-
- categoryItem.addEventListener("click", function (event) {
-
- if (event.target === event.currentTarget) {
-
- displayNamesList.style.display = displayNamesList.style.display === "none" ? "block" : "none";
- }
- });
-
-
-
- sidebarCustomNodes.appendChild(categoryItem);
-
-
+
+ let tree_view = await getConfiguration("sb_tree_view") || "multi";
+ if (tree_view=="multi" ) {
+ tree_view = true;
+ } else{
+ tree_view = false;
}
+ const tree = buildTree(categories,tree_view);
+
+
+ createHtmlFromTree(tree, sidebarCustomNodes,pinnedItems);
+
+
+
if (!categorySearchToggle && itemSearchInput.value != "") {
sdExpandAll(1);
@@ -585,7 +634,7 @@ async function createCategoryList() {
previewDiv.style.top = `${previewDivTop}px`;
- const previewDivLeft = sidebar_width - sidebad_view_width;
+ const previewDivLeft = sidebar_width - sidebad_view_width + correction_offset;
if (sbPosition == "left") {
previewDiv.style.left = `${previewDivLeft}px`;
@@ -615,6 +664,25 @@ async function createCategoryList() {
});
+ const categoryItems = document.querySelectorAll("#content_sidebar_home .sidebarCategory");
+ categoryItems.forEach(function (folderItem) {
+ folderItem.addEventListener("click", function (event) {
+
+ if (event.target === event.currentTarget) {
+ const displayNamesList = event.target.querySelector("ul");
+
+ displayNamesList.style.display = displayNamesList.style.display === "none" ? "block" : "none";
+
+ setNodeStatus('sb_categoryNodeStatus',displayNamesList.parentElement.dataset.nameworkflow, displayNamesList.style.display)
+ }
+ });
+
+
+
+ });
+
+
+
reloadCtxMenu()
resolve();
});
@@ -665,10 +733,6 @@ async function createCategoryList() {
-
-
-
-
}
@@ -833,16 +897,17 @@ function toggleSHSB(force = undefined) {
searchCategoryIcon.classList.add('closed');
search_bar.classList.add('closed');
scrollToTopButton.classList.add('closed');
+
} else {
side_bar.classList.remove('closed');
clearIcon.classList.remove('closed');
searchCategoryIcon.classList.remove('closed');
search_bar.classList.remove('closed');
scrollToTopButton.classList.remove('closed');
-
+ setVar("sb_minimized", "true");
}
} else {
-
+
if (side_bar.classList.contains('closed')) {
side_bar.classList.remove('closed');
clearIcon.classList.remove('closed');
@@ -869,30 +934,31 @@ function toggleSHSB(force = undefined) {
});
+
+
+ if (getVar("sb_minimized") == "false") {
- if (getVar("sb_minimized") == "false") {
-
- if (force == undefined) {
- setVar("sb_minimized", true);
- }
- main_sidebar.style.width = '45px';
- } else {
-
- if (force == undefined) {
- setVar("sb_minimized", false);
- main_sidebar.style.width = getVar("sidebarWidth") || '300px';
- } else if (force == true) {
-
- main_sidebar.style.width = '45px'; console.log("minimized")
-
+ if (force == undefined) {
+ setVar("sb_minimized", true);
+ }
+ main_sidebar.style.width = '45px';
} else {
- main_sidebar.style.width = getVar("sidebarWidth") || '300px';
+
+ if (force == undefined) {
+ setVar("sb_minimized", false);
+ main_sidebar.style.width = getVar("sidebarWidth") || '300px';
+ } else if (force == true) {
+
+ main_sidebar.style.width = '45px';
+
+ } else {
+ main_sidebar.style.width = getVar("sidebarWidth") || '300px';
+ }
+
}
- }
-
-
+
}
@@ -969,6 +1035,7 @@ function processViews(viewsData, settingsData) {
div_panel_title.id = "panel_title_" + panel;
div_panel_title.innerHTML = view.id.replace("_", " ");
+
@@ -1001,12 +1068,15 @@ function processViews(viewsData, settingsData) {
//inherit width from bsb
div_button.dataset.tab = view.id;
- div_button.alt = view.description;
+ div_button.title = description;
div_button.innerHTML += view.icon;
div_button.addEventListener('click', function () {
const tabId = "panel_" + this.getAttribute('data-tab');
switchTab(tabId)
+ if (getVar("sb_auto_hide") == "false" && getVar("sb_minimized") == "true") {
+ toggleSHSB(false);
+ }
});
sbv.appendChild(div_button);
});
@@ -1019,12 +1089,17 @@ function processViews(viewsData, settingsData) {
switchTab(getVar('sb_current_tab'));
const sidebar_view = document.getElementById('sidebar_views');
const sidebar = document.getElementById('sidebar');
+
+
+
sidebar_view.addEventListener('mouseover', function () {
- if (getVar('sb_minimized') == "true") {
- toggleSHSB(false);
+
+ if (getVar('sb_auto_hide') == "true") {
+ if (getVar('sb_minimized') == "true") {
+ toggleSHSB(false);
+ }
}
-
});
document.addEventListener('click', function (event) {
//if click is outside sidebar id element
@@ -1077,7 +1152,9 @@ async function SidebarPostBoot() {
//only for home
switch_home.addEventListener('click', function () {
switchTab("content_sidebar_home", 1)
-
+ if (getVar("sb_auto_hide") == "false" && getVar("sb_minimized") == "true") {
+ toggleSHSB(false);
+ }
});
diff --git a/app/panels/custom_categories/custom_categories.html b/app/panels/custom_categories/custom_categories.html
index 065dcc7..643de0c 100644
--- a/app/panels/custom_categories/custom_categories.html
+++ b/app/panels/custom_categories/custom_categories.html
@@ -12,9 +12,9 @@
-
+
diff --git a/app/panels/custom_categories/custom_categories.jsb b/app/panels/custom_categories/custom_categories.jsb
index a438c61..763d575 100644
--- a/app/panels/custom_categories/custom_categories.jsb
+++ b/app/panels/custom_categories/custom_categories.jsb
@@ -33,6 +33,7 @@ const panel_title_custom_categories = document.getElementById("panel_title_custo
const button_custom_categories = document.createElement("button");
button_custom_categories.classList = "expand_node";
+button_custom_categories.title = "Expand/Collapse";
button_custom_categories.innerHTML = `