mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-11 09:51:30 +00:00
Bugfix/workspace name case mismatch (#6560)
* fix: preserve workspace name casing in title bar (#6522) * fix: improve workspace display name handling in title bar --------- Co-authored-by: Uzairkazi695 <kaziuzair695@gmail.com>
This commit is contained in:
@@ -18,9 +18,9 @@ import ImportWorkspace from 'components/WorkspaceSidebar/ImportWorkspace';
|
||||
|
||||
import IconBottombarToggle from 'components/Icons/IconBottombarToggle/index';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import { toTitleCase } from 'utils/common/index';
|
||||
import ResponseLayoutToggle from 'components/ResponsePane/ResponseLayoutToggle';
|
||||
import { isMacOS, isWindowsOS, isLinuxOS } from 'utils/common/platform';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const getOsClass = () => {
|
||||
if (isMacOS()) return 'os-mac';
|
||||
@@ -29,6 +29,12 @@ const getOsClass = () => {
|
||||
return 'os-other';
|
||||
};
|
||||
|
||||
// Helper to get display name for workspace
|
||||
export const getWorkspaceDisplayName = (name) => {
|
||||
if (!name) return 'Untitled Workspace';
|
||||
return name;
|
||||
};
|
||||
|
||||
const AppTitleBar = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [isFullScreen, setIsFullScreen] = useState(false);
|
||||
@@ -115,7 +121,7 @@ const AppTitleBar = () => {
|
||||
const WorkspaceName = forwardRef((props, ref) => {
|
||||
return (
|
||||
<div ref={ref} className="workspace-name-container" {...props}>
|
||||
<span className="workspace-name">{toTitleCase(activeWorkspace?.name) || 'Default Workspace'}</span>
|
||||
<span data-testid="workspace-name" className={classNames('workspace-name', { 'italic text-muted': !activeWorkspace?.name })}>{getWorkspaceDisplayName(activeWorkspace?.name)}</span>
|
||||
<IconChevronDown size={14} stroke={1.5} className="chevron-icon" />
|
||||
</div>
|
||||
);
|
||||
@@ -127,7 +133,7 @@ const AppTitleBar = () => {
|
||||
|
||||
const handleWorkspaceSwitch = (workspaceUid) => {
|
||||
dispatch(switchWorkspace(workspaceUid));
|
||||
toast.success(`Switched to ${workspaces.find((w) => w.uid === workspaceUid)?.name}`);
|
||||
toast.success(`Switched to ${getWorkspaceDisplayName(workspaces.find((w) => w.uid === workspaceUid)?.name)}`);
|
||||
};
|
||||
|
||||
const handleOpenWorkspace = async () => {
|
||||
@@ -178,7 +184,7 @@ const AppTitleBar = () => {
|
||||
|
||||
return {
|
||||
id: workspace.uid,
|
||||
label: toTitleCase(workspace.name),
|
||||
label: getWorkspaceDisplayName(workspace.name),
|
||||
onClick: () => handleWorkspaceSwitch(workspace.uid),
|
||||
className: `workspace-item ${isActive ? 'active' : ''}`,
|
||||
rightSection: (
|
||||
@@ -190,11 +196,7 @@ const AppTitleBar = () => {
|
||||
label={isPinned ? 'Unpin workspace' : 'Pin workspace'}
|
||||
size="sm"
|
||||
>
|
||||
{isPinned ? (
|
||||
<IconPinned size={14} stroke={1.5} />
|
||||
) : (
|
||||
<IconPin size={14} stroke={1.5} />
|
||||
)}
|
||||
{isPinned ? <IconPinned size={14} stroke={1.5} /> : <IconPin size={14} stroke={1.5} />}
|
||||
</ActionIcon>
|
||||
)}
|
||||
{isActive && <IconCheck size={16} stroke={1.5} className="check-icon" />}
|
||||
@@ -247,12 +249,7 @@ const AppTitleBar = () => {
|
||||
<div className="titlebar-content">
|
||||
{/* Left section: Home + Workspace */}
|
||||
<div className="titlebar-left">
|
||||
<ActionIcon
|
||||
onClick={handleHomeClick}
|
||||
label="Home"
|
||||
size="lg"
|
||||
className="home-button"
|
||||
>
|
||||
<ActionIcon onClick={handleHomeClick} label="Home" size="lg" className="home-button">
|
||||
<IconHome size={16} stroke={1.5} />
|
||||
</ActionIcon>
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ import WorkspaceTabs from 'components/WorkspaceTabs';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import { getRevealInFolderLabel } from 'utils/common/platform';
|
||||
import { getWorkspaceDisplayName } from 'components/AppTitleBar';
|
||||
import classNames from 'classnames';
|
||||
|
||||
const WorkspaceHome = () => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -208,7 +210,7 @@ const WorkspaceHome = () => {
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<span>{activeWorkspace.name}</span>
|
||||
<span className={classNames('workspace-name', { 'italic text-muted': !activeWorkspace?.name })}>{getWorkspaceDisplayName(activeWorkspace.name)}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ const readWorkspaceConfig = (workspacePath) => {
|
||||
|
||||
const generateYamlContent = (config) => {
|
||||
const yamlLines = [];
|
||||
const workspaceName = config.info?.name || config.name || 'Unnamed Workspace';
|
||||
const workspaceName = config.info?.name || config.name || 'Untitled Workspace';
|
||||
const workspaceType = config.info?.type || config.type || WORKSPACE_TYPE;
|
||||
|
||||
yamlLines.push(`opencollection: ${config.opencollection || OPENCOLLECTION_VERSION}`);
|
||||
|
||||
@@ -12,8 +12,8 @@ test.describe('Default Workspace', () => {
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
// Verify the workspace name is "My Workspace" in the title bar
|
||||
const workspaceName = page.locator('.workspace-name');
|
||||
await expect(workspaceName).toContainText('My Workspace');
|
||||
const workspaceName = page.getByTestId('workspace-name');
|
||||
await expect(workspaceName).toHaveText('My Workspace');
|
||||
|
||||
await app.context().close();
|
||||
await app.close();
|
||||
@@ -28,7 +28,7 @@ test.describe('Default Workspace', () => {
|
||||
const app1 = await launchElectronApp({ userDataPath });
|
||||
const page1 = await app1.firstWindow();
|
||||
await page1.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
await expect(page1.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page1.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
await app1.close();
|
||||
|
||||
@@ -36,7 +36,7 @@ test.describe('Default Workspace', () => {
|
||||
const app2 = await launchElectronApp({ userDataPath });
|
||||
const page2 = await app2.firstWindow();
|
||||
await page2.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
await expect(page2.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page2.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
await app2.context().close();
|
||||
await app2.close();
|
||||
@@ -69,7 +69,7 @@ test.describe('Default Workspace', () => {
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
// Should show "My Workspace"
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Old directory should still exist (never deleted)
|
||||
expect(fs.existsSync(defaultWorkspacePath)).toBe(true);
|
||||
@@ -106,7 +106,7 @@ test.describe('Default Workspace', () => {
|
||||
const page = await app.firstWindow();
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Old corrupted file should still exist (never deleted)
|
||||
const oldContent = fs.readFileSync(path.join(defaultWorkspacePath, 'workspace.yml'), 'utf8');
|
||||
@@ -150,7 +150,7 @@ docs: ''
|
||||
const page = await app.firstWindow();
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// New workspace should have been created
|
||||
const newWorkspacePath = path.join(userDataPath, 'default-workspace-1');
|
||||
@@ -179,7 +179,7 @@ docs: ''
|
||||
const page = await app.firstWindow();
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// New workspace should have been created (default-workspace since non-existent doesn't block)
|
||||
const newWorkspacePath = path.join(userDataPath, 'default-workspace');
|
||||
|
||||
@@ -35,7 +35,7 @@ test.describe('Default Workspace Migration', () => {
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await test.step('Verify workspace UI', async () => {
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
});
|
||||
|
||||
await test.step('Verify workspace filesystem artifacts', async () => {
|
||||
@@ -87,7 +87,7 @@ test.describe('Default Workspace Migration', () => {
|
||||
const page = await app.firstWindow();
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Verify workspace.yml has both collections
|
||||
const workspacePath = path.join(userDataPath, 'default-workspace');
|
||||
@@ -132,7 +132,7 @@ test.describe('Default Workspace Migration', () => {
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
// Verify default workspace is created
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Sample collection should NOT be created (because user has existing collections)
|
||||
const sampleCollection = page.locator('#sidebar-collection-name').getByText('Sample API Collection');
|
||||
@@ -151,7 +151,7 @@ test.describe('Default Workspace Migration', () => {
|
||||
const app1 = await launchElectronApp({ userDataPath });
|
||||
const page1 = await app1.firstWindow();
|
||||
await page1.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
await expect(page1.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page1.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Verify initial workspace was created
|
||||
const workspacePath = path.join(userDataPath, 'default-workspace');
|
||||
@@ -165,7 +165,7 @@ test.describe('Default Workspace Migration', () => {
|
||||
const app2 = await launchElectronApp({ userDataPath });
|
||||
const page2 = await app2.firstWindow();
|
||||
await page2.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
await expect(page2.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page2.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// workspace.yml should NOT have been modified
|
||||
const currentYmlContent = fs.readFileSync(path.join(workspacePath, 'workspace.yml'), 'utf8');
|
||||
@@ -188,7 +188,7 @@ test.describe('Default Workspace Migration', () => {
|
||||
const page = await app.firstWindow();
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Verify workspace was created
|
||||
const workspacePath = path.join(userDataPath, 'default-workspace');
|
||||
|
||||
@@ -183,7 +183,7 @@ docs: ''
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
// UI always shows "My Workspace"
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Should NOT create a new workspace
|
||||
expect(fs.existsSync(path.join(userDataPath, 'default-workspace-1'))).toBe(false);
|
||||
@@ -231,7 +231,7 @@ docs: ''
|
||||
const page = await app.firstWindow();
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Verify the correct workspace was selected (workspace-2)
|
||||
const prefs = JSON.parse(fs.readFileSync(path.join(userDataPath, 'preferences.json'), 'utf8'));
|
||||
@@ -295,7 +295,7 @@ docs: ''
|
||||
const page = await app.firstWindow();
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Verify workspace-1 was selected (not workspace-2 which is broken)
|
||||
const prefs = JSON.parse(fs.readFileSync(path.join(userDataPath, 'preferences.json'), 'utf8'));
|
||||
@@ -521,7 +521,7 @@ docs: ''
|
||||
const page = await app.firstWindow();
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Since path doesn't exist but we have a valid workspace, it should use it
|
||||
// OR create a new one recovering from the existing one
|
||||
@@ -603,7 +603,7 @@ docs: ''
|
||||
const page = await app.firstWindow();
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
await expect(page.locator('.workspace-name')).toContainText('My Workspace');
|
||||
await expect(page.getByTestId('workspace-name')).toHaveText('My Workspace');
|
||||
|
||||
// Verify workspace-1 was used (or workspace-2 was created recovering from workspace-1)
|
||||
const prefs = JSON.parse(fs.readFileSync(path.join(userDataPath, 'preferences.json'), 'utf8'));
|
||||
|
||||
Reference in New Issue
Block a user