/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import "./dock.scss"; import React from "react"; import { observer } from "mobx-react"; import { cssNames } from "../../utils"; import { Icon } from "../icon"; import { MenuItem } from "../menu"; import { MenuActions } from "../menu/menu-actions"; import { ResizeDirection, ResizingAnchor } from "../resizing-anchor"; import { CreateResource } from "./create-resource/view"; import { DockTabs } from "./dock-tabs"; import type { DockStore, DockTab } from "./dock/store"; import { TabKind } from "./dock/store"; import { EditResource } from "./edit-resource/view"; import { InstallChart } from "./install-chart/view"; import { LogsDockTab } from "./logs/view"; import { TerminalWindow } from "./terminal/view"; import { UpgradeChart } from "./upgrade-chart/view"; import { withInjectables } from "@ogre-tools/injectable-react"; import createResourceTabInjectable from "./create-resource/create-resource-tab.injectable"; import dockStoreInjectable from "./dock/store.injectable"; import createTerminalTabInjectable from "./terminal/create-terminal-tab.injectable"; import { ErrorBoundary } from "../error-boundary"; export interface DockProps { className?: string; } interface Dependencies { createResourceTab: () => void; createTerminalTab: () => void; dockStore: DockStore; } enum Direction { NEXT = 1, PREV = -1, } @observer class NonInjectedDock extends React.Component { private readonly element = React.createRef(); componentDidMount() { document.addEventListener("keydown", this.onKeyDown); } componentWillUnmount() { document.removeEventListener("keydown", this.onKeyDown); } onKeyDown = (evt: KeyboardEvent) => { const { close, selectedTab, closeTab } = this.props.dockStore; const { code, ctrlKey, metaKey, shiftKey } = evt; // Determine if user working inside or using any other areas in app const dockIsFocused = this.element.current?.contains(document.activeElement); if (!selectedTab || !dockIsFocused) return; if (shiftKey && code === "Escape") { close(); } if ((ctrlKey && code === "KeyW") || (metaKey && code === "KeyW")) { closeTab(selectedTab.id); this.element.current?.focus(); // Avoid loosing focus when closing tab } if(ctrlKey && code === "Period") { this.switchToNextTab(selectedTab, Direction.NEXT); } if(ctrlKey && code === "Comma") { this.switchToNextTab(selectedTab, Direction.PREV); } }; onChangeTab = (tab: DockTab) => { const { open, selectTab } = this.props.dockStore; open(); selectTab(tab.id); this.element.current?.focus(); }; switchToNextTab = (selectedTab: DockTab, direction: Direction) => { const { tabs } = this.props.dockStore; const currentIndex = tabs.indexOf(selectedTab); const nextIndex = currentIndex + direction; // check if moving to the next or previous tab is possible. if (nextIndex >= tabs.length || nextIndex < 0) return; const nextElement = tabs[nextIndex]; this.onChangeTab(nextElement); }; renderTab(tab: DockTab) { switch (tab.kind) { case TabKind.CREATE_RESOURCE: return ; case TabKind.EDIT_RESOURCE: return ; case TabKind.INSTALL_CHART: return ; case TabKind.UPGRADE_CHART: return ; case TabKind.POD_LOGS: return ; case TabKind.TERMINAL: return ; } } renderTabContent() { const { isOpen, height, selectedTab } = this.props.dockStore; if (!isOpen || !selectedTab) return null; return (
{this.renderTab(selectedTab)}
); } render() { const { className, dockStore } = this.props; const { isOpen, toggle, tabs, toggleFillSize, selectedTab, hasTabs, fullSize } = this.props.dockStore; return (
dockStore.height} minExtent={dockStore.minHeight} maxExtent={dockStore.maxHeight} direction={ResizeDirection.VERTICAL} onStart={dockStore.open} onMinExtentSubceed={dockStore.close} onMinExtentExceed={dockStore.open} onDrag={extent => dockStore.height = extent} />
this.props.createTerminalTab()}> Terminal session this.props.createResourceTab()}> Create resource
{hasTabs() && ( <> )}
{this.renderTabContent()}
); } } export const Dock = withInjectables( NonInjectedDock, { getProps: (di, props) => ({ createResourceTab: di.inject(createResourceTabInjectable), dockStore: di.inject(dockStoreInjectable), createTerminalTab: di.inject(createTerminalTabInjectable), ...props, }), }, );