diff --git a/web/packages/teleterm/src/ui/TopBar/AdditionalActions.story.tsx b/web/packages/teleterm/src/ui/TopBar/AdditionalActions.story.tsx
new file mode 100644
index 0000000000000..701de28792529
--- /dev/null
+++ b/web/packages/teleterm/src/ui/TopBar/AdditionalActions.story.tsx
@@ -0,0 +1,96 @@
+/**
+ * Copyright 2023 Gravitational, Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import * as icons from 'design/Icon';
+
+import { MockAppContextProvider } from 'teleterm/ui/fixtures/MockAppContextProvider';
+
+import { Menu, MenuItem } from './AdditionalActions';
+
+export default {
+ title: 'Teleterm/AdditionalActions',
+};
+
+export const MenuItems = () => {
+ return (
+
+
+
+ );
+};
+
+const noop = () => {};
diff --git a/web/packages/teleterm/src/ui/TopBar/AdditionalActions.tsx b/web/packages/teleterm/src/ui/TopBar/AdditionalActions.tsx
index 793d716d9f078..1d1f2d0b07205 100644
--- a/web/packages/teleterm/src/ui/TopBar/AdditionalActions.tsx
+++ b/web/packages/teleterm/src/ui/TopBar/AdditionalActions.tsx
@@ -32,11 +32,14 @@ import { useNewTabOpener } from 'teleterm/ui/TabHost';
type MenuItem = {
title: string;
isVisible: boolean;
- Icon: React.ComponentType<{ fontSize: number }>;
+ Icon: React.ElementType;
onNavigate: () => void;
prependSeparator?: boolean;
keyboardShortcutAction?: KeyboardShortcutAction;
-};
+} & (MenuItemAlwaysEnabled | MenuItemConditionallyDisabled);
+
+type MenuItemAlwaysEnabled = { isDisabled?: false };
+type MenuItemConditionallyDisabled = { isDisabled: true; disabledText: string };
function useMenuItems(): MenuItem[] {
const ctx = useAppContext();
@@ -51,6 +54,7 @@ function useMenuItems(): MenuItem[] {
localClusterUri: workspacesService.getActiveWorkspace()?.localClusterUri,
});
+ const hasNoActiveWorkspace = !documentsService;
const areAccessRequestsSupported =
!!activeRootCluster?.features?.advancedAccessWorkflows;
@@ -61,6 +65,9 @@ function useMenuItems(): MenuItem[] {
{
title: 'Open new terminal',
isVisible: true,
+ isDisabled: hasNoActiveWorkspace,
+ disabledText:
+ 'You need to be logged in to a cluster to open new terminals.',
Icon: icons.Terminal,
keyboardShortcutAction: 'newTerminalTab',
onNavigate: openTerminalTab,
@@ -137,10 +144,11 @@ export function AdditionalActions() {
const items = useMenuItems().map(item => {
return (
-
- {item.prependSeparator && }
-
+