Skip to content
This repository was archived by the owner on Jun 13, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 42 additions & 42 deletions apps/webapp/src/common/layouts/app-layout/bottom-bar.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
import React, { useState } from 'react';
import { Button } from '@tegonhq/ui/components/button';
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@tegonhq/ui/components/tooltip';
import { HelpLine } from '@tegonhq/ui/icons';
import React from 'react';

interface BottomBarButtonProps {
icon: React.ReactElement;
tooltip: string;
onClick: () => void;
isActive?: boolean;
}

const BottomBarButton: React.FC<BottomBarButtonProps> = ({
icon,
tooltip,
onClick,
isActive,
}) => (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="link"
onClick={onClick}
isActive={isActive}
className="px-3"
>
{icon}
</Button>
</TooltipTrigger>
<TooltipContent>
<p>{tooltip}</p>
</TooltipContent>
</Tooltip>
);
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@tegonhq/ui/components/dropdown-menu';
import { SlackIcon, DocumentLine, HelpLine } from '@tegonhq/ui/icons';
import { KeyboardShortcutsDialog } from './keyboard-shortcuts-layout';

export function BottomBar() {
const [shortcutsOpen, setShortcutsOpen] = useState(false);

return (
<div className="w-full flex justify-between px-6 py-4">
<BottomBarButton
icon={<HelpLine size={20} />}
tooltip="Help from docs"
onClick={() => {
window.open('https://docs.tegon.ai', '_blank');
}}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="link" className="px-3">
<HelpLine size={20} />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start" className="w-56">
<DropdownMenuItem
onClick={() => window.open('https://docs.tegon.ai', '_blank')}
>
<DocumentLine className="mr-2" size={16} />
Documentation
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setShortcutsOpen(true)}>
Keyboard Shortcuts
</DropdownMenuItem>
<DropdownMenuItem
onClick={() =>
window.open(
'https://join.slack.com/t/tegoncommunity/shared_invite/zt-2jvar8p1x-9wqFTL9PP5ICImb76qcjEA',
'_blank',
)
}
>
<SlackIcon className="mr-2" size={16} />
Slack Community
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<KeyboardShortcutsDialog
open={shortcutsOpen}
onOpenChange={setShortcutsOpen}
/>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
'use client';

import {
CommandDialog,
CommandInput,
CommandList,
CommandGroup,
CommandItem,
} from '@tegonhq/ui/components/command';
import * as React from 'react';

const shortcuts = {
navigation: [
{ title: 'Command menu', shortcut: '⌘ K' },
{ title: 'Submit issue', shortcut: '⌘ Enter' },
{ title: 'Back', shortcut: 'Esc' },
{ title: 'Search', shortcut: '⌘ /' },
],
common: [
{ title: 'Create issue', shortcut: 'C' },
{ title: 'Open shortcuts guide', shortcut: 'Shift /' },
{ title: 'Copy issue URL from the issue details page', shortcut: '⌘ C' }
]
};

interface KeyboardShortcutsDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}

export function KeyboardShortcutsDialog({
open,
onOpenChange
}: KeyboardShortcutsDialogProps) {
React.useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === '?' && e.shiftKey) {
e.preventDefault();
onOpenChange(!open);
}
};

document.addEventListener('keydown', down);
return () => document.removeEventListener('keydown', down);
}, [open, onOpenChange]);

return (
<CommandDialog open={open} onOpenChange={onOpenChange}>
<CommandInput placeholder="Search for shortcuts" />
<CommandList>
<CommandGroup heading="Navigation">
{shortcuts.navigation.map(({ title, shortcut }) => (
<CommandItem key={title}>
<div className="flex w-full justify-between">
<span>{title}</span>
<kbd className="bg-muted px-2 rounded">{shortcut}</kbd>
</div>
</CommandItem>
))}
</CommandGroup>
<CommandGroup heading="Common">
{shortcuts.common.map(({ title, shortcut }) => (
<CommandItem key={title}>
<div className="flex w-full justify-between">
<span>{title}</span>
<kbd className="bg-muted px-2 rounded">{shortcut}</kbd>
</div>
</CommandItem>
))}
</CommandGroup>
</CommandList>
</CommandDialog>
);
}