Skip to content

Commit 0f4057c

Browse files
christian-byrnepythongosssssgithub-actions
authored
[backport] Refactor app menu items and update side toolbar (#4665, #4946) (#5030)
* Refactor app menu items (#4665) * Restructures the application menu - rename Workflow to File - move new & template items to top level - add View menu and related sub items Commands - add "active" state getter shown as checkmark in the menu Node side panel - add refresh node defs - change reset view icon Help center - change to use store for visibility Fixes - Fix bug with mouse down where if you drag mouse out, mouse up wasn't caught - Fix issue with canvas info setting not triggering a redraw on change * Fix missing translation warnings * Add separator under new * tidy * Update locales [skip ci] * fix some tests * fix * Hide icon if there is an active state within the menu item group * Update locales [skip ci] * Fix tests * Implement feedback - Remove queue, node lib, model lib, workflows, manager, help center - Add minimap, link visibility * Update locales [skip ci] * Add plus icon on "New" menu item * Update locales [skip ci] * Fix test * Fix translations * Update locales [skip ci] * Update locales [skip ci] --------- Co-authored-by: github-actions <[email protected]> * Update side toolbar menu (#4946) Side toolbar menu UI updates - Currently the template modal is very hidden. Many users do not find it - The current icons are quite aleatory **What**: - Add templates shortcut button - Add item label in normal size - Use custom icon Critical design decisions or edge cases that need attention: - Sidebar tabs registered using custom icons will have their associated command registed with an undefined icon (currently only string icons are accepted, not components). I couldn't see anywhere directly using this icon, but we should consider autogenerating an icon font so we can use classes for our custom icons (or locating and updating locations to support both icon types) Normal mode: <img width="621" height="1034" alt="image" src="https://github.com/user-attachments/assets/c1d1cee2-004e-4ff8-b3fa-197329b0d2ae" /> Small mode: <img width="176" height="325" alt="image" src="https://github.com/user-attachments/assets/3824b8f6-bc96-4e62-aece-f0265113d2e3" /> ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-4946-Update-side-toolbar-menu-24d6d73d365081c5b2bdc0ee8b61dc50) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <[email protected]> --------- Co-authored-by: pythongosssss <[email protected]> Co-authored-by: github-actions <[email protected]>
1 parent 2ee5541 commit 0f4057c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1477
-155
lines changed

browser_tests/fixtures/components/Topbar.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class Topbar {
5050
workflowName: string,
5151
command: 'Save' | 'Save As' | 'Export'
5252
) {
53-
await this.triggerTopbarCommand(['Workflow', command])
53+
await this.triggerTopbarCommand(['File', command])
5454
await this.getSaveDialog().fill(workflowName)
5555
await this.page.keyboard.press('Enter')
5656

@@ -72,8 +72,8 @@ export class Topbar {
7272
}
7373

7474
async triggerTopbarCommand(path: string[]) {
75-
if (path.length < 2) {
76-
throw new Error('Path is too short')
75+
if (path.length < 1) {
76+
throw new Error('Path cannot be empty')
7777
}
7878

7979
const menu = await this.openTopbarMenu()
@@ -85,6 +85,13 @@ export class Topbar {
8585
.locator('.p-tieredmenu-item')
8686
.filter({ has: topLevelMenuItem })
8787
await topLevelMenu.waitFor({ state: 'visible' })
88+
89+
// Handle top-level commands (like "New")
90+
if (path.length === 1) {
91+
await topLevelMenuItem.click()
92+
return
93+
}
94+
8895
await topLevelMenu.hover()
8996

9097
let currentMenu = topLevelMenu

browser_tests/tests/groupNode.spec.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,7 @@ test.describe('Group Node', () => {
268268
await comfyPage.setSetting('Comfy.ConfirmClear', false)
269269

270270
// Clear workflow
271-
await comfyPage.menu.topbar.triggerTopbarCommand([
272-
'Edit',
273-
'Clear Workflow'
274-
])
271+
await comfyPage.executeCommand('Comfy.ClearWorkflow')
275272

276273
await comfyPage.ctrlV()
277274
await verifyNodeLoaded(comfyPage, 1)
@@ -280,7 +277,7 @@ test.describe('Group Node', () => {
280277
test('Copies and pastes group node into a newly created blank workflow', async ({
281278
comfyPage
282279
}) => {
283-
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
280+
await comfyPage.menu.topbar.triggerTopbarCommand(['New'])
284281
await comfyPage.ctrlV()
285282
await verifyNodeLoaded(comfyPage, 1)
286283
})
@@ -296,7 +293,7 @@ test.describe('Group Node', () => {
296293
test('Serializes group node after copy and paste across workflows', async ({
297294
comfyPage
298295
}) => {
299-
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
296+
await comfyPage.menu.topbar.triggerTopbarCommand(['New'])
300297
await comfyPage.ctrlV()
301298
const currentGraphState = await comfyPage.page.evaluate(() =>
302299
window['app'].graph.serialize()

browser_tests/tests/interaction.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ test.describe('Load workflow', () => {
684684
workflowA = generateUniqueFilename()
685685
await comfyPage.menu.topbar.saveWorkflow(workflowA)
686686
workflowB = generateUniqueFilename()
687-
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
687+
await comfyPage.menu.topbar.triggerTopbarCommand(['New'])
688688
await comfyPage.menu.topbar.saveWorkflow(workflowB)
689689

690690
// Wait for localStorage to persist the workflow paths before reloading

browser_tests/tests/menu.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ test.describe('Menu', () => {
7575

7676
test('Displays keybinding next to item', async ({ comfyPage }) => {
7777
await comfyPage.menu.topbar.openTopbarMenu()
78-
const workflowMenuItem = comfyPage.menu.topbar.getMenuItem('Workflow')
78+
const workflowMenuItem = comfyPage.menu.topbar.getMenuItem('File')
7979
await workflowMenuItem.hover()
8080
const exportTag = comfyPage.page.locator('.keybinding-tag', {
8181
hasText: 'Ctrl + s'

browser_tests/tests/rerouteNode.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test.describe('Reroute Node', () => {
1818
[workflowName]: workflowName
1919
})
2020
await comfyPage.setup()
21-
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
21+
await comfyPage.menu.topbar.triggerTopbarCommand(['New'])
2222

2323
// Insert the workflow
2424
const workflowsTab = comfyPage.menu.workflowsTab

browser_tests/tests/workflowTabThumbnail.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ test.describe('Workflow Tab Thumbnails', () => {
6363
test('Should show thumbnail when hovering over a non-active tab', async ({
6464
comfyPage
6565
}) => {
66-
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
66+
await comfyPage.menu.topbar.triggerTopbarCommand(['New'])
6767
const thumbnailImg = await getTabThumbnailImage(
6868
comfyPage,
6969
0,
@@ -73,7 +73,7 @@ test.describe('Workflow Tab Thumbnails', () => {
7373
})
7474

7575
test('Should not show thumbnail for active tab', async ({ comfyPage }) => {
76-
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
76+
await comfyPage.menu.topbar.triggerTopbarCommand(['New'])
7777
const thumbnailImg = await getTabThumbnailImage(
7878
comfyPage,
7979
1,
@@ -105,7 +105,7 @@ test.describe('Workflow Tab Thumbnails', () => {
105105
await comfyPage.nextFrame()
106106

107107
// Create a new workflow (tab 1) which will be empty
108-
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
108+
await comfyPage.menu.topbar.triggerTopbarCommand(['New'])
109109
await comfyPage.nextFrame()
110110

111111
// Now we have two tabs: tab 0 (default workflow with nodes) and tab 1 (empty)
Lines changed: 6 additions & 0 deletions
Loading

src/assets/icons/custom/node.svg

Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 5 additions & 0 deletions
Loading

src/components/sidebar/SideToolbar.vue

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
:icon-badge="tab.iconBadge"
99
:tooltip="tab.tooltip"
1010
:tooltip-suffix="getTabTooltipSuffix(tab)"
11+
:label="tab.label || tab.title"
12+
:is-small="isSmall"
1113
:selected="tab.id === selectedTab?.id"
1214
:class="tab.id + '-tab-button'"
1315
@click="onTabClick(tab)"
1416
/>
17+
<SidebarTemplatesButton />
1518
<div class="side-tool-bar-end">
1619
<SidebarLogoutIcon v-if="userStore.isMultiUserServer" />
1720
<SidebarHelpCenterIcon />
@@ -43,6 +46,7 @@ import type { SidebarTabExtension } from '@/types/extensionTypes'
4346
import SidebarHelpCenterIcon from './SidebarHelpCenterIcon.vue'
4447
import SidebarIcon from './SidebarIcon.vue'
4548
import SidebarLogoutIcon from './SidebarLogoutIcon.vue'
49+
import SidebarTemplatesButton from './SidebarTemplatesButton.vue'
4650
4751
const workspaceStore = useWorkspaceStore()
4852
const settingStore = useSettingStore()
@@ -86,7 +90,7 @@ const getTabTooltipSuffix = (tab: SidebarTabExtension) => {
8690
box-shadow: var(--bar-shadow);
8791
8892
--sidebar-width: 4rem;
89-
--sidebar-icon-size: 1.5rem;
93+
--sidebar-icon-size: 1rem;
9094
}
9195
9296
.side-tool-bar-container.small-sidebar {

0 commit comments

Comments
 (0)