Skip to content

Show active tab name in status bar#51108

Merged
gzdunek merged 19 commits intomasterfrom
gzdunek/active-document-status-bar
Jan 22, 2025
Merged

Show active tab name in status bar#51108
gzdunek merged 19 commits intomasterfrom
gzdunek/active-document-status-bar

Conversation

@gzdunek
Copy link
Copy Markdown
Contributor

@gzdunek gzdunek commented Jan 16, 2025

Currently, if you open multiple tabs, their titles may be truncated, making it difficult to see what is the resource name.
To improve this, we can show the document (resource) name in the status bar:

image

Other changes:

  • I thought it would also be nice to have resource icons on both the status bar and tabs to make them easier to locate visually.
    This extra icon unfortunately takes up valuable space in the tabs, so to avoid trimming the titles even further, I hid the close buttons. It is now only visible when the tab is active or when you hover over it. Thanks to this, we show ~the same amount of text as before.
  • I changed the title of db gateways (as discussed on Slack). Now it's “postgres-prod (alice)” instead of “alice@postgres-prod”. The database name seems more important than the username.

Problems

The document name in the status bar shouldn't always matches the title in the tabs. For example, we don't want to show cwd or shell name in the status bar for the terminal tabs. Because of that, we shouldn't blindly use the title of the documents, but instead build the name separately.
Unfortunately, there were some problems with this approach:

  • We would have another place where we generate a "name" for the document.
  • For doc.terminal_tsh_node only the document title contains the server name (in the fields we have ID). It's because we update the title asynchronously when we fetch the server name from the backend.
  • For doc.cluster we shouldn't show cluster name in the status bar, since it would look like (teleport-17-ent.asteroid.earth > teleport-17-ent.asteroid.earth).

These problems would be solved by getting rid of storing the document title on disk, and instead generating it dynamically using a function similar to getStaticNameAndIcon. That's quite a lot work to refactor this, so I decided to reuse the document title when possible, and when not, generate it from the document fields.

changelog: Teleport Connect now shows a resource name in the status bar

Copy link
Copy Markdown
Contributor

@avatus avatus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great for me locally, but I haven't finished looking at all the code yet. Ill return to this on monday

Comment thread web/packages/teleterm/src/ui/StatusBar/StatusBar.tsx
Copy link
Copy Markdown
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll continue the review tomorrow. I wanted to look around different documents and then got stuck at some weird errors related to access requests that I managed to solve. (I think some watchers got broken when my laptop woke up from sleep and I had to restart the cluster)

Comment thread web/packages/teleterm/src/ui/StatusBar/StatusBar.tsx
Comment thread web/packages/teleterm/src/ui/StatusBar/StatusBar.tsx Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on the optimized version of the hook?

Because hooks cannot be called conditionally, we can't do early returns. But in return (hehe) the component is indeed re-rendered only when necessary, instead on every change to workspaces, clusters and gateways.

Details
import { ComponentType, useCallback } from 'react';

import { IconProps } from 'design/Icon/Icon';

import {
  getResourceUri,
  getStaticNameAndIcon,
} from 'teleterm/ui/services/workspacesService';
import { routing } from 'teleterm/ui/uri';

import { useStoreSelector } from '../hooks/useStoreSelector';

interface Breadcrumb {
  name: string;
  Icon?: ComponentType<IconProps>;
}

export function useActiveDocumentClusterBreadcrumbs(): Breadcrumb[] {
  const activeDocument = useStoreSelector(
    'workspacesService',
    useCallback(state => {
      const workspace = state.workspaces[state.rootClusterUri];
      return workspace?.documents.find(d => d.uri === workspace?.location);
    }, [])
  );
  const resourceUri = activeDocument && getResourceUri(activeDocument);
  const staticNameAndIcon =
    activeDocument && getStaticNameAndIcon(activeDocument);
  const clusterUri = resourceUri && routing.ensureClusterUri(resourceUri);
  const rootClusterUri =
    resourceUri && routing.ensureRootClusterUri(resourceUri);

  const cluster = useStoreSelector(
    'clustersService',
    useCallback(state => state.clusters.get(clusterUri), [clusterUri])
  );
  const rootCluster = useStoreSelector(
    'clustersService',
    useCallback(state => state.clusters.get(rootClusterUri), [rootClusterUri])
  );

  if (!cluster || !rootCluster || !staticNameAndIcon) {
    return;
  }

  return [
    { name: rootCluster.name },
    clusterUri !== rootClusterUri && { name: cluster.name },
    {
      name: staticNameAndIcon.name,
      Icon: staticNameAndIcon.Icon,
    },
  ].filter(Boolean);
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much better, thank you!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, I'm not sure if I'm a fan of this style of writing hooks/components. But it's hard to argue against the performance implications of it.

Maybe that's what people arguing in favor of signals mean, idk. As in, maybe in another paradigm we wouldn't have to worry not being able to return early.

@ravicious ravicious self-requested a review January 20, 2025 17:34
Copy link
Copy Markdown
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty slick! And the icons don't make the UI look busy, now that I used it myself. I think the demo looked busy mostly because it had a small window and a lot of tabs to show how you solved the problem of showing/hiding the close button. But in a "real" app it looks pretty cool.

Comment thread web/packages/teleterm/src/ui/StatusBar/StatusBar.tsx Outdated
Comment thread web/packages/teleterm/src/ui/Tabs/TabItem.tsx Outdated
Comment thread web/packages/teleterm/src/ui/Tabs/Tabs.story.tsx Outdated
# Conflicts:
#	web/packages/teleterm/src/ui/services/connectionTracker/connectionTrackerService.ts
#	web/packages/teleterm/src/ui/services/workspacesService/documentsService/documentsService.ts
#	web/packages/teleterm/src/ui/services/workspacesService/documentsService/documentsUtils.ts
@gzdunek gzdunek requested a review from ravicious January 22, 2025 15:51
@gzdunek
Copy link
Copy Markdown
Contributor Author

gzdunek commented Jan 22, 2025

Ah, I forgot to re-request the review!

@ravicious
Copy link
Copy Markdown
Member

I wouldn't have time to re-review it earlier anyway. 😂 😭

const newItem = createGatewayConnection(doc);
draft.connections.push(newItem);
} else {
// In case the document changes, update the gateway title.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is specific enough. IIRC this was to specifically address a case where over time we've decided to change the title for db gateways and we wanted this change to be reflected in already created connections, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I mentioned it now it the comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol ok, when I was suggesting this, I completely forgot that TabHost renders tabs and documents. I'm glad adding this wasn't much of a problem and it's indeed pretty cool to see those docs rendered in the browser.

@gzdunek gzdunek enabled auto-merge January 22, 2025 17:11
@gzdunek gzdunek added this pull request to the merge queue Jan 22, 2025
Merged via the queue into master with commit d1862f3 Jan 22, 2025
@gzdunek gzdunek deleted the gzdunek/active-document-status-bar branch January 22, 2025 17:28
@public-teleport-github-review-bot
Copy link
Copy Markdown

@gzdunek See the table below for backport results.

Branch Result
branch/v17 Failed

gzdunek added a commit that referenced this pull request Jan 22, 2025
* Show active document in the status bar

* Update reading breadcrumbs value in tests

* Show db name first and then username

* Add helpers for making documents

* Show document icon in tabs and adjust styling

* Update gateway title from the document title

* Fix document helpers

* Put breadcrumbs in title

* Simplify breadcrumb key

* Optimize `useActiveDocumentClusterBreadcrumbs`

* Deprecate `isDocumentTshNodeWithLoginHost` and `isDocumentTshNodeWithServerId`

* Remove `aria-label="breadcrumbs"`

* Replace id with class

* Reuse `makeAppGateway`, `makeDatabaseGateway` and `makeKubeGateway` helpers in docs helpers

* Add a comment about updating gateway title

* Re-update the format of db gateways title

* Render entire TabHost instead of only tabs

* Make comment more specific

(cherry picked from commit d1862f3)
github-merge-queue Bot pushed a commit that referenced this pull request Jan 22, 2025
* Show active document in the status bar

* Update reading breadcrumbs value in tests

* Show db name first and then username

* Add helpers for making documents

* Show document icon in tabs and adjust styling

* Update gateway title from the document title

* Fix document helpers

* Put breadcrumbs in title

* Simplify breadcrumb key

* Optimize `useActiveDocumentClusterBreadcrumbs`

* Deprecate `isDocumentTshNodeWithLoginHost` and `isDocumentTshNodeWithServerId`

* Remove `aria-label="breadcrumbs"`

* Replace id with class

* Reuse `makeAppGateway`, `makeDatabaseGateway` and `makeKubeGateway` helpers in docs helpers

* Add a comment about updating gateway title

* Re-update the format of db gateways title

* Render entire TabHost instead of only tabs

* Make comment more specific

(cherry picked from commit d1862f3)
carloscastrojumo pushed a commit to carloscastrojumo/teleport that referenced this pull request Feb 19, 2025
* Show active document in the status bar

* Update reading breadcrumbs value in tests

* Show db name first and then username

* Add helpers for making documents

* Show document icon in tabs and adjust styling

* Update gateway title from the document title

* Fix document helpers

* Put breadcrumbs in title

* Simplify breadcrumb key

* Optimize `useActiveDocumentClusterBreadcrumbs`

* Deprecate `isDocumentTshNodeWithLoginHost` and `isDocumentTshNodeWithServerId`

* Remove `aria-label="breadcrumbs"`

* Replace id with class

* Reuse `makeAppGateway`, `makeDatabaseGateway` and `makeKubeGateway` helpers in docs helpers

* Add a comment about updating gateway title

* Re-update the format of db gateways title

* Render entire TabHost instead of only tabs

* Make comment more specific
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants