-
Notifications
You must be signed in to change notification settings - Fork 965
feat(desktop): support big and compact terminal add buttons #1757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
42052f3
62cb2c8
8b34389
d7e6682
3be486f
2d4c053
ab1aca1
b451075
566091f
8d69fc5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,15 +1,7 @@ | ||||||||||||||||||||||||||||||
| import type { TerminalPreset } from "@superset/local-db"; | ||||||||||||||||||||||||||||||
| import { FEATURE_FLAGS } from "@superset/shared/constants"; | ||||||||||||||||||||||||||||||
| import { Button } from "@superset/ui/button"; | ||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||
| DropdownMenu, | ||||||||||||||||||||||||||||||
| DropdownMenuCheckboxItem, | ||||||||||||||||||||||||||||||
| DropdownMenuContent, | ||||||||||||||||||||||||||||||
| DropdownMenuItem, | ||||||||||||||||||||||||||||||
| DropdownMenuSeparator, | ||||||||||||||||||||||||||||||
| DropdownMenuTrigger, | ||||||||||||||||||||||||||||||
| } from "@superset/ui/dropdown-menu"; | ||||||||||||||||||||||||||||||
| import { useLiveQuery } from "@tanstack/react-db"; | ||||||||||||||||||||||||||||||
| import { useParams } from "@tanstack/react-router"; | ||||||||||||||||||||||||||||||
| import { useNavigate, useParams } from "@tanstack/react-router"; | ||||||||||||||||||||||||||||||
| import { useFeatureFlagEnabled } from "posthog-js/react"; | ||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||
| useCallback, | ||||||||||||||||||||||||||||||
|
|
@@ -19,21 +11,22 @@ import { | |||||||||||||||||||||||||||||
| useRef, | ||||||||||||||||||||||||||||||
| useState, | ||||||||||||||||||||||||||||||
| } from "react"; | ||||||||||||||||||||||||||||||
| import { BsTerminalPlus } from "react-icons/bs"; | ||||||||||||||||||||||||||||||
| import { LuPlus } from "react-icons/lu"; | ||||||||||||||||||||||||||||||
| import { TbMessageCirclePlus, TbWorld } from "react-icons/tb"; | ||||||||||||||||||||||||||||||
| import { HotkeyMenuShortcut } from "renderer/components/HotkeyMenuShortcut"; | ||||||||||||||||||||||||||||||
| import { electronTrpc } from "renderer/lib/electron-trpc"; | ||||||||||||||||||||||||||||||
| import { usePresets } from "renderer/react-query/presets"; | ||||||||||||||||||||||||||||||
| import { useCollections } from "renderer/routes/_authenticated/providers/CollectionsProvider"; | ||||||||||||||||||||||||||||||
| import { useTabsStore } from "renderer/stores/tabs/store"; | ||||||||||||||||||||||||||||||
| import { useTabsWithPresets } from "renderer/stores/tabs/useTabsWithPresets"; | ||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||
| isLastPaneInTab, | ||||||||||||||||||||||||||||||
| resolveActiveTabIdForWorkspace, | ||||||||||||||||||||||||||||||
| } from "renderer/stores/tabs/utils"; | ||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||
| DEFAULT_SHOW_PRESETS_BAR, | ||||||||||||||||||||||||||||||
| DEFAULT_USE_COMPACT_TERMINAL_ADD_BUTTON, | ||||||||||||||||||||||||||||||
| } from "shared/constants"; | ||||||||||||||||||||||||||||||
| import { type ActivePaneStatus, pickHigherStatus } from "shared/tabs-types"; | ||||||||||||||||||||||||||||||
| import { AddTabButton } from "./components/AddTabButton"; | ||||||||||||||||||||||||||||||
| import { GroupItem } from "./GroupItem"; | ||||||||||||||||||||||||||||||
| import { NewTabDropZone } from "./NewTabDropZone"; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| export function GroupStrip() { | ||||||||||||||||||||||||||||||
| const { workspaceId: activeWorkspaceId } = useParams({ strict: false }); | ||||||||||||||||||||||||||||||
|
|
@@ -42,7 +35,7 @@ export function GroupStrip() { | |||||||||||||||||||||||||||||
| const panes = useTabsStore((s) => s.panes); | ||||||||||||||||||||||||||||||
| const activeTabIds = useTabsStore((s) => s.activeTabIds); | ||||||||||||||||||||||||||||||
| const tabHistoryStacks = useTabsStore((s) => s.tabHistoryStacks); | ||||||||||||||||||||||||||||||
| const { addTab } = useTabsWithPresets(); | ||||||||||||||||||||||||||||||
| const { addTab, openPreset } = useTabsWithPresets(); | ||||||||||||||||||||||||||||||
| const addChatMastraTab = useTabsStore((s) => s.addChatMastraTab); | ||||||||||||||||||||||||||||||
| const addBrowserTab = useTabsStore((s) => s.addBrowserTab); | ||||||||||||||||||||||||||||||
| const renameTab = useTabsStore((s) => s.renameTab); | ||||||||||||||||||||||||||||||
|
|
@@ -53,6 +46,8 @@ export function GroupStrip() { | |||||||||||||||||||||||||||||
| const reorderTabs = useTabsStore((s) => s.reorderTabs); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const setTabAutoTitle = useTabsStore((s) => s.setTabAutoTitle); | ||||||||||||||||||||||||||||||
| const { presets } = usePresets(); | ||||||||||||||||||||||||||||||
| const navigate = useNavigate(); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const hasAiChat = useFeatureFlagEnabled(FEATURE_FLAGS.AI_CHAT); | ||||||||||||||||||||||||||||||
| const scrollContainerRef = useRef<HTMLDivElement>(null); | ||||||||||||||||||||||||||||||
|
|
@@ -61,6 +56,8 @@ export function GroupStrip() { | |||||||||||||||||||||||||||||
| const utils = electronTrpc.useUtils(); | ||||||||||||||||||||||||||||||
| const { data: showPresetsBar } = | ||||||||||||||||||||||||||||||
| electronTrpc.settings.getShowPresetsBar.useQuery(); | ||||||||||||||||||||||||||||||
| const { data: useCompactTerminalAddButton } = | ||||||||||||||||||||||||||||||
| electronTrpc.settings.getUseCompactTerminalAddButton.useQuery(); | ||||||||||||||||||||||||||||||
| const setShowPresetsBar = electronTrpc.settings.setShowPresetsBar.useMutation( | ||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||
| onMutate: async ({ enabled }) => { | ||||||||||||||||||||||||||||||
|
|
@@ -79,6 +76,30 @@ export function GroupStrip() { | |||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| const setUseCompactTerminalAddButton = | ||||||||||||||||||||||||||||||
| electronTrpc.settings.setUseCompactTerminalAddButton.useMutation({ | ||||||||||||||||||||||||||||||
| onMutate: async ({ enabled }) => { | ||||||||||||||||||||||||||||||
| await utils.settings.getUseCompactTerminalAddButton.cancel(); | ||||||||||||||||||||||||||||||
| const previous = | ||||||||||||||||||||||||||||||
| utils.settings.getUseCompactTerminalAddButton.getData(); | ||||||||||||||||||||||||||||||
| utils.settings.getUseCompactTerminalAddButton.setData( | ||||||||||||||||||||||||||||||
| undefined, | ||||||||||||||||||||||||||||||
| enabled, | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| return { previous }; | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| onError: (_err, _vars, context) => { | ||||||||||||||||||||||||||||||
| if (context?.previous !== undefined) { | ||||||||||||||||||||||||||||||
| utils.settings.getUseCompactTerminalAddButton.setData( | ||||||||||||||||||||||||||||||
| undefined, | ||||||||||||||||||||||||||||||
| context.previous, | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| onSettled: () => { | ||||||||||||||||||||||||||||||
| utils.settings.getUseCompactTerminalAddButton.invalidate(); | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const tabs = useMemo( | ||||||||||||||||||||||||||||||
| () => | ||||||||||||||||||||||||||||||
|
|
@@ -160,6 +181,18 @@ export function GroupStrip() { | |||||||||||||||||||||||||||||
| addBrowserTab(activeWorkspaceId); | ||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const handleOpenPreset = useCallback( | ||||||||||||||||||||||||||||||
| (preset: TerminalPreset) => { | ||||||||||||||||||||||||||||||
| if (!activeWorkspaceId) return; | ||||||||||||||||||||||||||||||
| openPreset(activeWorkspaceId, preset, { target: "active-tab" }); | ||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||
| [activeWorkspaceId, openPreset], | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
|
Comment on lines
+184
to
+190
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Preset selection currently targets the active tab instead of creating a new tab. At Line 180, Proposed fix- openPreset(activeWorkspaceId, preset, { target: "active-tab" });
+ openPreset(activeWorkspaceId, preset, { target: "new-tab" });📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const handleOpenPresetsSettings = useCallback(() => { | ||||||||||||||||||||||||||||||
| navigate({ to: "/settings/presets" }); | ||||||||||||||||||||||||||||||
| }, [navigate]); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const handleSelectGroup = (tabId: string) => { | ||||||||||||||||||||||||||||||
| if (activeWorkspaceId) { | ||||||||||||||||||||||||||||||
| setActiveTab(activeWorkspaceId, tabId); | ||||||||||||||||||||||||||||||
|
|
@@ -219,52 +252,29 @@ export function GroupStrip() { | |||||||||||||||||||||||||||||
| requestAnimationFrame(updateOverflow); | ||||||||||||||||||||||||||||||
| }, [updateOverflow]); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const useCompactAddButton = | ||||||||||||||||||||||||||||||
| useCompactTerminalAddButton ?? DEFAULT_USE_COMPACT_TERMINAL_ADD_BUTTON; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| const plusControl = ( | ||||||||||||||||||||||||||||||
| <NewTabDropZone | ||||||||||||||||||||||||||||||
| onDrop={(paneId) => movePaneToNewTab(paneId)} | ||||||||||||||||||||||||||||||
| <AddTabButton | ||||||||||||||||||||||||||||||
| hasAiChat={hasAiChat === true} | ||||||||||||||||||||||||||||||
| useCompactAddButton={useCompactAddButton} | ||||||||||||||||||||||||||||||
| showPresetsBar={showPresetsBar ?? DEFAULT_SHOW_PRESETS_BAR} | ||||||||||||||||||||||||||||||
| presets={presets} | ||||||||||||||||||||||||||||||
| onDropToNewTab={movePaneToNewTab} | ||||||||||||||||||||||||||||||
| isLastPaneInTab={checkIsLastPaneInTab} | ||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||
| <DropdownMenu> | ||||||||||||||||||||||||||||||
| <DropdownMenuTrigger asChild> | ||||||||||||||||||||||||||||||
| <Button | ||||||||||||||||||||||||||||||
| variant="ghost" | ||||||||||||||||||||||||||||||
| size="icon" | ||||||||||||||||||||||||||||||
| className="size-7 px-1 shrink-0 rounded-md border border-border/60 bg-muted/30 text-muted-foreground hover:bg-accent/60 hover:text-foreground" | ||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||
| <LuPlus className="size-3.5" strokeWidth={1.8} /> | ||||||||||||||||||||||||||||||
| </Button> | ||||||||||||||||||||||||||||||
| </DropdownMenuTrigger> | ||||||||||||||||||||||||||||||
| <DropdownMenuContent align="end" className="w-56"> | ||||||||||||||||||||||||||||||
| <DropdownMenuItem onClick={handleAddGroup} className="gap-2"> | ||||||||||||||||||||||||||||||
| <BsTerminalPlus className="size-4" /> | ||||||||||||||||||||||||||||||
| <span>Terminal</span> | ||||||||||||||||||||||||||||||
| <HotkeyMenuShortcut hotkeyId="NEW_GROUP" /> | ||||||||||||||||||||||||||||||
| </DropdownMenuItem> | ||||||||||||||||||||||||||||||
| {hasAiChat && ( | ||||||||||||||||||||||||||||||
| <DropdownMenuItem onClick={handleAddChat} className="gap-2"> | ||||||||||||||||||||||||||||||
| <TbMessageCirclePlus className="size-4" /> | ||||||||||||||||||||||||||||||
| <span>Chat</span> | ||||||||||||||||||||||||||||||
| <HotkeyMenuShortcut hotkeyId="NEW_CHAT" /> | ||||||||||||||||||||||||||||||
| </DropdownMenuItem> | ||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||
| <DropdownMenuItem onClick={handleAddBrowser} className="gap-2"> | ||||||||||||||||||||||||||||||
| <TbWorld className="size-4" /> | ||||||||||||||||||||||||||||||
| <span>Browser</span> | ||||||||||||||||||||||||||||||
| <HotkeyMenuShortcut hotkeyId="NEW_BROWSER" /> | ||||||||||||||||||||||||||||||
| </DropdownMenuItem> | ||||||||||||||||||||||||||||||
| <DropdownMenuSeparator /> | ||||||||||||||||||||||||||||||
| <DropdownMenuCheckboxItem | ||||||||||||||||||||||||||||||
| checked={showPresetsBar ?? false} | ||||||||||||||||||||||||||||||
| onCheckedChange={(checked) => | ||||||||||||||||||||||||||||||
| setShowPresetsBar.mutate({ enabled: checked }) | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| onSelect={(e) => e.preventDefault()} | ||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||
| Show Preset Bar | ||||||||||||||||||||||||||||||
| </DropdownMenuCheckboxItem> | ||||||||||||||||||||||||||||||
| </DropdownMenuContent> | ||||||||||||||||||||||||||||||
| </DropdownMenu> | ||||||||||||||||||||||||||||||
| </NewTabDropZone> | ||||||||||||||||||||||||||||||
| onAddTerminal={handleAddGroup} | ||||||||||||||||||||||||||||||
| onAddChat={handleAddChat} | ||||||||||||||||||||||||||||||
| onAddBrowser={handleAddBrowser} | ||||||||||||||||||||||||||||||
| onOpenPreset={handleOpenPreset} | ||||||||||||||||||||||||||||||
| onConfigurePresets={handleOpenPresetsSettings} | ||||||||||||||||||||||||||||||
| onToggleShowPresetsBar={(enabled) => | ||||||||||||||||||||||||||||||
| setShowPresetsBar.mutate({ enabled }) | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| onToggleCompactAddButton={(enabled) => | ||||||||||||||||||||||||||||||
| setUseCompactTerminalAddButton.mutate({ enabled }) | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||
|
|
@@ -301,7 +311,15 @@ export function GroupStrip() { | |||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||
| {hasHorizontalOverflow ? ( | ||||||||||||||||||||||||||||||
| <div className="h-full w-10 shrink-0" /> | ||||||||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||||||||
| className={`h-full shrink-0 ${ | ||||||||||||||||||||||||||||||
| !useCompactAddButton | ||||||||||||||||||||||||||||||
| ? hasAiChat | ||||||||||||||||||||||||||||||
| ? "w-[220px]" | ||||||||||||||||||||||||||||||
| : "w-[170px]" | ||||||||||||||||||||||||||||||
| : "w-10" | ||||||||||||||||||||||||||||||
| }`} | ||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||
| ) : ( | ||||||||||||||||||||||||||||||
| <div className="shrink-0">{plusControl}</div> | ||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 3226
🏁 Script executed:
Repository: superset-sh/superset
Length of output: 6055
Add
mastracodeand@ast-grep/napito electron-builder packaging rules.These modules are externalized in
rollupOptions.externalbut are not included in thefilesconfiguration inelectron-builder.ts. They will not be copied to the packaged application, causing runtime failures when the app attempts to load them.Add both modules to the
filesconfiguration inelectron-builder.ts(alongsidebetter-sqlite3,node-pty, andfriendly-words):Example addition to electron-builder.ts files config
If either module contains native binaries, also add them to the
asarUnpackconfiguration so electron-builder unpacks them outside the asar archive.🤖 Prompt for AI Agents