Revert "Rename terminals, add welcome card for the survey, add buttons to make it clear how to open the sidebar/topbar after closing."
This reverts commit b27916852f.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React from "react"
|
||||
|
||||
import {Homepage} from "@/apps/Homepage/Homepage.tsx"
|
||||
import {Terminal} from "@/apps/SSH/Terminal/Terminal.tsx"
|
||||
import {SSH} from "@/apps/SSH/Terminal/SSH.tsx"
|
||||
import {SSHTunnel} from "@/apps/SSH/Tunnel/SSHTunnel.tsx";
|
||||
import {ConfigEditor} from "@/apps/SSH/Config Editor/ConfigEditor.tsx";
|
||||
import {SSHManager} from "@/apps/SSH/Manager/SSHManager.tsx"
|
||||
@@ -35,7 +35,7 @@ function App() {
|
||||
)}
|
||||
{mountedViews.has("terminal") && (
|
||||
<div style={{display: view === "terminal" ? "block" : "none"}}>
|
||||
<Terminal onSelectView={handleSelectView} />
|
||||
<SSH onSelectView={handleSelectView} />
|
||||
</div>
|
||||
)}
|
||||
{mountedViews.has("tunnel") && (
|
||||
|
||||
@@ -3,7 +3,6 @@ import React, {useEffect, useState} from "react";
|
||||
import {HomepageAuth} from "@/apps/Homepage/HomepageAuth.tsx";
|
||||
import axios from "axios";
|
||||
import {HomepageUpdateLog} from "@/apps/Homepage/HompageUpdateLog.tsx";
|
||||
import {HomepageWelcomeCard} from "@/apps/Homepage/HomepageWelcomeCard.tsx";
|
||||
|
||||
interface HomepageProps {
|
||||
onSelectView: (view: string) => void;
|
||||
@@ -33,12 +32,9 @@ export function Homepage({onSelectView}: HomepageProps): React.ReactElement {
|
||||
const [username, setUsername] = useState<string | null>(null);
|
||||
const [authLoading, setAuthLoading] = useState(true);
|
||||
const [dbError, setDbError] = useState<string | null>(null);
|
||||
const [showWelcomeCard, setShowWelcomeCard] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const jwt = getCookie("jwt");
|
||||
const welcomeHidden = getCookie("welcome_hidden");
|
||||
|
||||
if (jwt) {
|
||||
setAuthLoading(true);
|
||||
Promise.all([
|
||||
@@ -50,7 +46,6 @@ export function Homepage({onSelectView}: HomepageProps): React.ReactElement {
|
||||
setIsAdmin(!!meRes.data.is_admin);
|
||||
setUsername(meRes.data.username || null);
|
||||
setDbError(null);
|
||||
setShowWelcomeCard(welcomeHidden !== "true");
|
||||
})
|
||||
.catch((err) => {
|
||||
setLoggedIn(false);
|
||||
@@ -69,11 +64,6 @@ export function Homepage({onSelectView}: HomepageProps): React.ReactElement {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleHideWelcomeCard = () => {
|
||||
setShowWelcomeCard(false);
|
||||
setCookie("welcome_hidden", "true", 365 * 10);
|
||||
};
|
||||
|
||||
return (
|
||||
<HomepageSidebar
|
||||
onSelectView={onSelectView}
|
||||
@@ -96,13 +86,6 @@ export function Homepage({onSelectView}: HomepageProps): React.ReactElement {
|
||||
loggedIn={loggedIn}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{loggedIn && !authLoading && showWelcomeCard && (
|
||||
<div
|
||||
className="absolute inset-0 flex items-center justify-center bg-background/80 backdrop-blur-sm z-10">
|
||||
<HomepageWelcomeCard onHidePermanently={handleHideWelcomeCard}/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</HomepageSidebar>
|
||||
);
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import React from "react";
|
||||
import {Card, CardContent, CardFooter, CardHeader, CardTitle} from "@/components/ui/card";
|
||||
import {Button} from "@/components/ui/button";
|
||||
|
||||
interface HomepageWelcomeCardProps {
|
||||
onHidePermanently: () => void;
|
||||
}
|
||||
|
||||
export function HomepageWelcomeCard({onHidePermanently}: HomepageWelcomeCardProps): React.ReactElement {
|
||||
return (
|
||||
<Card className="w-full max-w-2xl mx-auto">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-2xl font-bold text-center">
|
||||
The Future of Termix
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="text-muted-foreground text-center leading-relaxed">
|
||||
Please checkout the linked survey{" "}
|
||||
<a
|
||||
href="https://docs.google.com/forms/d/e/1FAIpQLSeGvnQODFtnpjmJsMKgASbaQ87CLQEBCcnzK_Vuw5TdfbfIyA/viewform?usp=sharing&ouid=107601685503825301492"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary hover:underline hover:text-primary/80 transition-colors"
|
||||
>
|
||||
here
|
||||
</a>
|
||||
. The purpose of this survey is to gather feedback from users on what the future UI of Termix could
|
||||
look like to optimize server management. Please take a minute or two to read the survey questions
|
||||
and answer them to the best of your ability. Thank you!
|
||||
</p>
|
||||
<p className="text-muted-foreground text-center leading-relaxed mt-6">
|
||||
A special thanks to those in Asia who recently joined Termix through various forum posts, keep
|
||||
sharing it! A Chinese translation is planned for Termix, but since I don’t speak Chinese, I’ll need
|
||||
to hire someone to help with the translation. If you’d like to support me financially, you can do
|
||||
so{" "}
|
||||
<a
|
||||
href="https://github.com/sponsors/LukeGus"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-primary hover:underline hover:text-primary/80 transition-colors"
|
||||
>
|
||||
here.
|
||||
</a>
|
||||
</p>
|
||||
</CardContent>
|
||||
<CardFooter className="justify-center">
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={onHidePermanently}
|
||||
className="w-full max-w-xs"
|
||||
>
|
||||
Hide Permanently
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import React, {useState, useRef, useEffect} from "react";
|
||||
import {TerminalSidebar} from "@/apps/SSH/Terminal/TerminalSidebar.tsx";
|
||||
import {TerminalComponent} from "./TerminalComponent.tsx";
|
||||
import {TerminalTopbar} from "@/apps/SSH/Terminal/TerminalTopbar.tsx";
|
||||
import {SSHSidebar} from "@/apps/SSH/Terminal/SSHSidebar.tsx";
|
||||
import {SSHTerminal} from "./SSHTerminal.tsx";
|
||||
import {SSHTopbar} from "@/apps/SSH/Terminal/SSHTopbar.tsx";
|
||||
import {ResizablePanelGroup, ResizablePanel, ResizableHandle} from '@/components/ui/resizable.tsx';
|
||||
import * as ResizablePrimitive from "react-resizable-panels";
|
||||
import {ChevronDown, ChevronRight} from "lucide-react";
|
||||
|
||||
interface ConfigEditorProps {
|
||||
onSelectView: (view: string) => void;
|
||||
@@ -17,7 +16,7 @@ type Tab = {
|
||||
terminalRef: React.RefObject<any>;
|
||||
};
|
||||
|
||||
export function Terminal({onSelectView}: ConfigEditorProps): React.ReactElement {
|
||||
export function SSH({onSelectView}: ConfigEditorProps): React.ReactElement {
|
||||
const [allTabs, setAllTabs] = useState<Tab[]>([]);
|
||||
const [currentTab, setCurrentTab] = useState<number | null>(null);
|
||||
const [allSplitScreenTab, setAllSplitScreenTab] = useState<number[]>([]);
|
||||
@@ -26,7 +25,7 @@ export function Terminal({onSelectView}: ConfigEditorProps): React.ReactElement
|
||||
const [isSidebarOpen, setIsSidebarOpen] = useState<boolean>(true);
|
||||
const [isTopbarOpen, setIsTopbarOpen] = useState<boolean>(true);
|
||||
const SIDEBAR_WIDTH = 256;
|
||||
const HANDLE_THICKNESS = 10;
|
||||
const HANDLE_THICKNESS = 6;
|
||||
|
||||
const [panelRects, setPanelRects] = useState<Record<string, DOMRect | null>>({});
|
||||
const panelRefs = useRef<Record<string, HTMLDivElement | null>>({});
|
||||
@@ -161,7 +160,7 @@ export function Terminal({onSelectView}: ConfigEditorProps): React.ReactElement
|
||||
const isVisible = !!layoutStyles[tab.id];
|
||||
return (
|
||||
<div key={tab.id} style={style} data-terminal-id={tab.id}>
|
||||
<TerminalComponent
|
||||
<SSHTerminal
|
||||
key={tab.id}
|
||||
ref={tab.terminalRef}
|
||||
hostConfig={tab.hostConfig}
|
||||
@@ -594,6 +593,7 @@ export function Terminal({onSelectView}: ConfigEditorProps): React.ReactElement
|
||||
|
||||
return (
|
||||
<div style={{display: 'flex', width: '100vw', height: '100vh', overflow: 'hidden', position: 'relative'}}>
|
||||
{/* Sidebar (collapsible) */}
|
||||
<div
|
||||
style={{
|
||||
width: isSidebarOpen ? SIDEBAR_WIDTH : 0,
|
||||
@@ -609,7 +609,7 @@ export function Terminal({onSelectView}: ConfigEditorProps): React.ReactElement
|
||||
willChange: 'width',
|
||||
}}
|
||||
>
|
||||
<TerminalSidebar
|
||||
<SSHSidebar
|
||||
onSelectView={onSelectView}
|
||||
onHostConnect={onHostConnect}
|
||||
allTabs={allTabs}
|
||||
@@ -655,7 +655,7 @@ export function Terminal({onSelectView}: ConfigEditorProps): React.ReactElement
|
||||
willChange: 'height',
|
||||
}}
|
||||
>
|
||||
<TerminalTopbar
|
||||
<SSHTopbar
|
||||
allTabs={allTabs}
|
||||
currentTab={currentTab ?? -1}
|
||||
setActiveTab={setActiveTab}
|
||||
@@ -677,15 +677,12 @@ export function Terminal({onSelectView}: ConfigEditorProps): React.ReactElement
|
||||
background: '#222224',
|
||||
cursor: 'pointer',
|
||||
zIndex: 12,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
title="Show top bar">
|
||||
<ChevronDown size={HANDLE_THICKNESS} />
|
||||
</div>
|
||||
title="Show top bar"
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Main terminal area (height adapts to topbar) */}
|
||||
<div
|
||||
style={{
|
||||
height: isTopbarOpen ? 'calc(100% - 46px)' : '100%',
|
||||
@@ -759,6 +756,7 @@ export function Terminal({onSelectView}: ConfigEditorProps): React.ReactElement
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sidebar reopen handle */}
|
||||
{!isSidebarOpen && (
|
||||
<div
|
||||
onClick={() => setIsSidebarOpen(true)}
|
||||
@@ -771,13 +769,9 @@ export function Terminal({onSelectView}: ConfigEditorProps): React.ReactElement
|
||||
background: '#222224',
|
||||
cursor: 'pointer',
|
||||
zIndex: 20,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
title="Show sidebar">
|
||||
<ChevronRight size={HANDLE_THICKNESS} />
|
||||
</div>
|
||||
title="Show sidebar"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
@@ -74,7 +74,7 @@ export interface SidebarProps {
|
||||
onOpenChange?: (open: boolean) => void;
|
||||
}
|
||||
|
||||
export function TerminalSidebar({
|
||||
export function SSHSidebar({
|
||||
onSelectView,
|
||||
onHostConnect,
|
||||
allTabs,
|
||||
@@ -16,7 +16,7 @@ interface SSHTabListProps {
|
||||
setCloseTab: (tab: number) => void;
|
||||
}
|
||||
|
||||
export function TerminalTabList({
|
||||
export function SSHTabList({
|
||||
allTabs,
|
||||
currentTab,
|
||||
setActiveTab,
|
||||
@@ -13,7 +13,7 @@ interface SSHTerminalProps {
|
||||
splitScreen?: boolean;
|
||||
}
|
||||
|
||||
export const TerminalComponent = forwardRef<any, SSHTerminalProps>(function SSHTerminal(
|
||||
export const SSHTerminal = forwardRef<any, SSHTerminalProps>(function SSHTerminal(
|
||||
{hostConfig, isVisible, splitScreen = false},
|
||||
ref
|
||||
) {
|
||||
@@ -1,4 +1,4 @@
|
||||
import {TerminalTabList} from "@/apps/SSH/Terminal/TerminalTabList.tsx";
|
||||
import {SSHTabList} from "@/apps/SSH/Terminal/SSHTabList.tsx";
|
||||
import React from "react";
|
||||
import {ChevronUp} from "lucide-react";
|
||||
|
||||
@@ -17,7 +17,7 @@ interface SSHTopbarProps {
|
||||
onHideTopbar?: () => void;
|
||||
}
|
||||
|
||||
export function TerminalTopbar({
|
||||
export function SSHTopbar({
|
||||
allTabs,
|
||||
currentTab,
|
||||
setActiveTab,
|
||||
@@ -38,7 +38,7 @@ export function TerminalTopbar({
|
||||
}}>
|
||||
<div style={{flex: 1, minWidth: 0, height: '100%', overflowX: 'auto'}}>
|
||||
<div style={{minWidth: 'max-content', height: '100%', paddingLeft: 8, overflowY: 'hidden'}}>
|
||||
<TerminalTabList
|
||||
<SSHTabList
|
||||
allTabs={allTabs}
|
||||
currentTab={currentTab}
|
||||
setActiveTab={setActiveTab}
|
||||
Reference in New Issue
Block a user