From cc2d478c72796bf97a6add770778fed4e9f51dcb Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 26 Feb 2025 22:57:37 +0530 Subject: [PATCH 01/23] Initial commit for Sidebar changes --- apps/gitness/src/components-v2/app-shell.tsx | 23 +- packages/ui/src/components/icon.tsx | 2 + packages/ui/src/components/index.ts | 1 + .../language-selector/language-dialog.tsx | 13 +- .../src/components/navbar-new/app-sidebar.tsx | 277 ++++++++++++++ .../navbar-new/data/navbar-menu-data.ts | 342 ++++++++++++++++++ .../ui/src/components/navbar-new/index.ts | 1 + .../components/navbar-new/sidebar-item.tsx | 131 +++++++ .../components/navbar-new/sidebar-search.tsx | 61 ++++ .../components/navbar-new/sidebar-user.tsx | 148 ++++++++ .../ui/src/components/navbar-new/types.ts | 50 +++ packages/ui/src/components/select.tsx | 5 +- .../ui/src/components/sidebar/sidebar.tsx | 2 +- packages/ui/src/icons/chevron-up-down.svg | 3 + 14 files changed, 1052 insertions(+), 7 deletions(-) create mode 100644 packages/ui/src/components/navbar-new/app-sidebar.tsx create mode 100644 packages/ui/src/components/navbar-new/data/navbar-menu-data.ts create mode 100644 packages/ui/src/components/navbar-new/index.ts create mode 100644 packages/ui/src/components/navbar-new/sidebar-item.tsx create mode 100644 packages/ui/src/components/navbar-new/sidebar-search.tsx create mode 100644 packages/ui/src/components/navbar-new/sidebar-user.tsx create mode 100644 packages/ui/src/components/navbar-new/types.ts create mode 100644 packages/ui/src/icons/chevron-up-down.svg diff --git a/apps/gitness/src/components-v2/app-shell.tsx b/apps/gitness/src/components-v2/app-shell.tsx index 832416eb6c..7fe00b4a24 100644 --- a/apps/gitness/src/components-v2/app-shell.tsx +++ b/apps/gitness/src/components-v2/app-shell.tsx @@ -3,13 +3,15 @@ import { Outlet, useLocation, useNavigate, useParams } from 'react-router-dom' import { cn } from '@harnessio/canary' import { + AppSidebar, ManageNavigation, MenuGroupType, MenuGroupTypes, MoreSubmenu, Navbar, NavbarItemType, - SettingsMenu + SettingsMenu, + Sidebar } from '@harnessio/ui/components' import { SandboxLayout } from '@harnessio/ui/views' @@ -177,7 +179,7 @@ export const AppShell = () => { return ( - { handleRemoveRecentMenuItem={handleRemoveRecentMenuItem} useThemeStore={useThemeStore} useTranslationStore={useTranslationStore} - /> + /> */} + + + diff --git a/packages/ui/src/components/icon.tsx b/packages/ui/src/components/icon.tsx index 8eab0fc1e6..1547c7a283 100644 --- a/packages/ui/src/components/icon.tsx +++ b/packages/ui/src/components/icon.tsx @@ -35,6 +35,7 @@ import Checks from '../icons/checks.svg' import ChevronDown from '../icons/chevron-down.svg' import ChevronFillDown from '../icons/chevron-fill-down.svg' import ChevronRight from '../icons/chevron-right.svg' +import ChevronUpDown from '../icons/chevron-up-down.svg' import ChevronUp from '../icons/chevron-up.svg' import CircleArrowTopRight from '../icons/circle-arrow-top-right.svg' import CircleArrowTop from '../icons/circle-arrow-top.svg' @@ -210,6 +211,7 @@ const IconNameMap = { 'chevron-down': ChevronDown, 'chevron-right': ChevronRight, 'chevron-up': ChevronUp, + 'chevron-up-down': ChevronUpDown, 'filter-list': FilterList, 'info-circle': InfoCircle, 'double-tick': DoubleTick, diff --git a/packages/ui/src/components/index.ts b/packages/ui/src/components/index.ts index 0d529ce4b9..8dfd3d083c 100644 --- a/packages/ui/src/components/index.ts +++ b/packages/ui/src/components/index.ts @@ -16,6 +16,7 @@ export * from './alert-dialog' export * from './popover' export * from './avatar' export * from './navbar' +export * from './navbar-new' export * from './navbar-skeleton' export * from './theme-selector' export * from './theme-selector/types' diff --git a/packages/ui/src/components/language-selector/language-dialog.tsx b/packages/ui/src/components/language-selector/language-dialog.tsx index 32569c9ee8..0a10bf8205 100644 --- a/packages/ui/src/components/language-selector/language-dialog.tsx +++ b/packages/ui/src/components/language-selector/language-dialog.tsx @@ -3,7 +3,18 @@ import { FC, useEffect, useState } from 'react' import { Dialog, Icon } from '@/components' import { cn } from '@utils/cn' -import { LanguageCode, LanguageDialogProps } from './types' +import { Language, LanguageCode, LanguageDialogProps, LanguageInterface } from './types' + +export const languages: LanguageInterface[] = [ + { code: LanguageCode.EN, name: Language.English }, + { code: LanguageCode.БГ, name: Language.Bulgarian }, + { code: LanguageCode.HR, name: Language.Croatian }, + { code: LanguageCode.CZ, name: Language.Czech }, + { code: LanguageCode.FR, name: Language.French }, + { code: LanguageCode.DE, name: Language.German }, + { code: LanguageCode.IE, name: Language.Irish }, + { code: LanguageCode.LA, name: Language.LatinAmerican } +] const LanguageDialog: FC = ({ defaultLanguage = LanguageCode.EN, diff --git a/packages/ui/src/components/navbar-new/app-sidebar.tsx b/packages/ui/src/components/navbar-new/app-sidebar.tsx new file mode 100644 index 0000000000..1501c7fb6d --- /dev/null +++ b/packages/ui/src/components/navbar-new/app-sidebar.tsx @@ -0,0 +1,277 @@ +// @ts-nocheck + +import { useCallback, useEffect, useMemo, useState } from 'react' +import { NavLink, useLocation, useNavigate } from 'react-router-dom' + +import { Icon } from '@components/icon' +import { LanguageDialog, languages } from '@components/language-selector' +import { ManageNavigation } from '@components/manage-navigation' +import { MoreSubmenu } from '@components/more-submenu' +import { SettingsMenu } from '@components/settings-menu' +import { Sidebar } from '@components/sidebar/sidebar' +import { Spacer } from '@components/spacer' +import { ThemeDialog } from '@components/theme-selector-v2' + +import { getNavbarMenuData } from './data/navbar-menu-data' +import { SidebarItem } from './sidebar-item' +import { SidebarSearch } from './sidebar-search' +import { User } from './sidebar-user' +import { MenuGroupTypes } from './types' + +const getData = t => ({ + user: { + name: 'Jane Citizen', + email: 'jane@harness.io', + avatar: + 'https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?&w=256&h=256&q=70&crop=focalpoint&fp-x=0.5&fp-y=0.3&fp-z=1&fit=crop' + } +}) + +export const AppSidebar = ({ + useThemeStore, + useTranslationStore, + handleChangePinnedMenuItem, + handleRemoveRecentMenuItem, + pinnedMenuItems, + recentMenuItems, + currentUser, + showMoreMenu, + showSettingMenu, + handleMoreMenu, + handleSettingsMenu +}) => { + const location = useLocation() + const { setTheme } = useThemeStore() + + // const [showMoreMenu, setShowMoreMenu] = useState(false) + // const [showSettingMenu, setShowSettingMenu] = useState(false) + const [showCustomNav, setShowCustomNav] = useState(false) + const [openThemeDialog, setOpenThemeDialog] = useState(false) + const [openLanguageDialog, setOpenLanguageDialog] = useState(false) + + const { t, changeLanguage } = useTranslationStore() + const data = getData(t) + + const { moreMenu, settingsMenu } = useMemo(() => { + const navbarMenuData = getNavbarMenuData(t) + + return navbarMenuData.reduce( + (acc, item) => { + if (item.type === MenuGroupTypes.SETTINGS) { + acc.settingsMenu.push(item) + } else { + acc.moreMenu.push(item) + } + return acc + }, + { moreMenu: [], settingsMenu: [] } + ) + }, [t, changeLanguage]) + + /** + * Toggle show more menu + */ + // const handleMoreMenu = useCallback(() => { + // setShowSettingMenu(false) + // setShowMoreMenu(prevState => !prevState) + // }, []) + + /** + * Toggle system settings menu + */ + // const handleSettingsMenu = useCallback(() => { + // setShowMoreMenu(false) + // setShowSettingMenu(prevState => !prevState) + // }, []) + + /** + * Toggle custom navigation modal + */ + const handleCustomNav = useCallback(() => { + setShowCustomNav(prevState => !prevState) + }, []) + + /** + * Close all menu when location changed + */ + // useEffect(() => { + // setShowMoreMenu(false) + // setShowSettingMenu(false) + // setShowCustomNav(false) + // }, [location]) + + /** + * Handle save recent and pinned items + */ + const handleSave = (nextRecentItems, nextPinnedItems) => { + // setNavLinks({ + // pinnedMenu: nextPinnedItems, + // recentMenu: nextRecentItems + // }) + } + + const handleThemeChange = theme => { + setTheme(theme) + } + + const handleLanguageChange = language => { + changeLanguage(language.code.toLowerCase()) + } + + const handleLanguageSave = language => { + changeLanguage(language.code.toLowerCase()) + setOpenLanguageDialog(false) + } + + const handleLanguageCancel = () => { + setOpenLanguageDialog(false) + } + + const navigate = useNavigate() + + return ( + <> + + +
+ + + + +
+ +
+ + + + + {pinnedMenuItems.map((item, index) => ( + + ))} + + + +
+ + More +
+
+
+
+
+
+ + {!!recentMenuItems.length && ( + + Recent + + + + {recentMenuItems.map(item => ( + + ))} + + + + )} + + + + + {!!currentUser?.admin && ( + + navigate('/admin/default-settings')} + > +
+ + + User Management + +
+
+
+ )} + + +
+ + + {t('component:navbar.settings')} + +
+
+
+
+
+
+
+ + setOpenThemeDialog(true)} + openLanguageDialog={() => setOpenLanguageDialog(true)} + t={t} + /> + + +
+ + + + setOpenThemeDialog(false)} + onChange={handleThemeChange} + // onCancel={handleThemeCancel} + // onSave={handleThemeSave} + /> + setOpenLanguageDialog(false)} + onChange={handleLanguageChange} + onCancel={handleLanguageCancel} + onSave={handleLanguageSave} + /> + + ) +} diff --git a/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts b/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts new file mode 100644 index 0000000000..34e48220b5 --- /dev/null +++ b/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts @@ -0,0 +1,342 @@ +import { TFunction } from 'i18next' + +import { MenuGroupType, MenuGroupTypes } from '@harnessio/ui/components' + +const PREFIX_ROUTE = '/canary/repos/canary' + +export const getNavbarMenuData = (t: TFunction): MenuGroupType[] => [ + { + groupId: 0, + title: 'Devops', + type: MenuGroupTypes.GENERAL, + items: [ + { + id: 0, + iconName: 'repositories-gradient', + title: t('component:navbar.repositories'), + description: t('component:navbar.repoDesc', 'Integrated & familiar git experience.'), + to: `${PREFIX_ROUTE}/repositories` + }, + { + id: 1, + iconName: 'pipelines-gradient', + title: t('component:navbar.pipelines'), + description: t('component:navbar.pipelineDesc', 'Up to 4X faster than other solutions.'), + to: `${PREFIX_ROUTE}/pipelines` + }, + { + id: 40, + iconName: 'execution-gradient', + title: t('component:navbar.executions'), + description: t('component:navbar.executionDesc', 'Optimize feature rollout velocity.'), + to: `${PREFIX_ROUTE}/executions` + }, + { + id: 41, + iconName: 'database-gradient', + title: t('component:navbar.databases'), + description: t('component:navbar.databaseDesc', 'Manage all your infrastructure.'), + to: `${PREFIX_ROUTE}/databases` + }, + { + id: 42, + iconName: 'artifacts-gradient', + title: t('component:navbar.artifacts'), + description: t('component:navbar.artifactDesc', 'Validate service resilience.'), + to: `${PREFIX_ROUTE}/artifacts` + }, + { + id: 5, + iconName: 'infrastructure-gradient', + title: t('component:navbar.infrastructure'), + description: t('component:navbar.infrastructureDesc', 'Manage all your infrastructure.'), + to: `${PREFIX_ROUTE}/infrastructure` + }, + { + id: 6, + iconName: 'flag-gradient', + title: t('component:navbar.feature-flags'), + description: t('component:navbar.featureFlagsDesc', 'Optimize feature rollout velocity.'), + to: `${PREFIX_ROUTE}/feature-flags` + } + ] + }, + { + groupId: 1, + title: 'Devex', + type: MenuGroupTypes.GENERAL, + items: [ + { + id: 7, + iconName: 'dev-portal-gradient', + title: t('component:navbar.developer-portal'), + description: t('component:navbar.devPortalDesc', 'Built for developers, onboard in minutes.'), + to: `${PREFIX_ROUTE}/dev-portal` + }, + { + id: 8, + iconName: 'dev-envs-gradient', + title: t('component:navbar.developer-environments'), + description: t('component:navbar.devEnvsDesc', 'Integrated & familiar git experience.'), + to: `${PREFIX_ROUTE}/dev-environments` + }, + { + id: 9, + iconName: 'dev-insights-gradient', + title: t('component:navbar.developer-insights'), + description: t('component:navbar.devInsightsDesc', 'Actionable insights on SDLC.'), + to: `${PREFIX_ROUTE}/dev-insights` + } + ] + }, + { + groupId: 2, + title: t('component:navbar.secops'), + type: MenuGroupTypes.GENERAL, + items: [ + { + id: 10, + iconName: 'security-tests-gradient', + title: t('component:navbar.security-tests'), + description: t('component:navbar.securityTestsDesc', 'Shift left security testing.'), + to: `${PREFIX_ROUTE}/security-tests` + }, + { + id: 11, + iconName: 'supply-chain-gradient', + title: t('component:navbar.supply-chain'), + description: t('component:navbar.supplyChainDesc', 'Artifact integrity and governance.'), + to: `${PREFIX_ROUTE}/supply-chain` + } + ] + }, + { + groupId: 3, + title: t('component:navbar.finops'), + type: MenuGroupTypes.GENERAL, + items: [ + { + id: 12, + iconName: 'cloud-costs-gradient', + title: t('component:navbar.cloud-costs'), + description: t('component:navbar.cloudCostsDesc', 'Intelligent cost management.'), + to: `${PREFIX_ROUTE}/cloud-costs` + } + ] + }, + { + groupId: 4, + title: t('component:navbar.reliability'), + type: MenuGroupTypes.GENERAL, + items: [ + { + id: 13, + iconName: 'incidents-gradient', + title: t('component:navbar.incidents'), + description: t('component:navbar.incidentsDesc', 'Shift left security testing.'), + to: `${PREFIX_ROUTE}/incidents` + }, + { + id: 14, + iconName: 'chaos-engineering-gradient', + title: t('component:navbar.chaos-engineering'), + description: t('component:navbar.chaosEngineeringDesc', 'Validate service resilience.'), + to: `${PREFIX_ROUTE}/chaos` + } + ] + }, + + { + groupId: 5, + title: t('component:navbar.platform'), + type: MenuGroupTypes.GENERAL, + items: [ + { + id: 15, + iconName: 'dashboards-gradient', + title: t('component:navbar.dashboards'), + description: 'Intelligent cost management.', + to: `${PREFIX_ROUTE}/dashboards` + } + ] + }, + { + groupId: 6, + title: t('component:navbar.general'), + type: MenuGroupTypes.SETTINGS, + items: [ + { + id: 16, + iconName: 'settings-2', + title: t('component:navbar.settings'), + to: `${PREFIX_ROUTE}/settings` + }, + { + id: 17, + iconName: 'notification', + title: t('component:navbar.notifications'), + to: `${PREFIX_ROUTE}/notifications` + } + ] + }, + { + groupId: 7, + title: t('component:navbar.resources'), + type: MenuGroupTypes.SETTINGS, + items: [ + { + id: 18, + iconName: 'wrench', + title: t('component:navbar.services'), + to: `${PREFIX_ROUTE}/resources` + }, + { + id: 19, + iconName: 'environment', + title: t('component:navbar.environments'), + to: `${PREFIX_ROUTE}/environments` + }, + { + id: 20, + iconName: 'connectors', + title: t('component:navbar.connectors'), + to: `${PREFIX_ROUTE}/connectors` + }, + { + id: 21, + iconName: 'hierarchy', + title: t('component:navbar.delegates'), + to: `${PREFIX_ROUTE}/delegates` + }, + { + id: 22, + iconName: 'key', + title: t('component:navbar.secrets'), + to: `${PREFIX_ROUTE}/secrets` + }, + { + id: 23, + iconName: 'file-icon', + title: t('component:navbar.file-store'), + to: `${PREFIX_ROUTE}/file-store` + }, + { + id: 24, + iconName: 'sidebar-icon', + title: t('component:navbar.templates'), + to: `${PREFIX_ROUTE}/templates` + }, + { + id: 25, + iconName: 'variable', + title: t('component:navbar.variables'), + to: `${PREFIX_ROUTE}/variables` + }, + { + id: 26, + iconName: 'clock-icon', + title: t('component:navbar.slo-downtime'), + to: `${PREFIX_ROUTE}/slo-downtime` + }, + { + id: 27, + iconName: 'search', + title: t('component:navbar.discovery'), + to: `${PREFIX_ROUTE}/discovery` + }, + { + id: 28, + iconName: 'eye', + title: t('component:navbar.monitored-services'), + to: `${PREFIX_ROUTE}/monitored-services` + }, + { + id: 29, + iconName: 'stack', + title: t('component:navbar.overrides'), + to: `${PREFIX_ROUTE}/overrides` + }, + { + id: 30, + iconName: 'bookmark-icon', + title: t('component:navbar.certificates'), + to: `${PREFIX_ROUTE}/certificates` + }, + { + id: 31, + iconName: 'webhook', + title: t('component:navbar.webhooks'), + to: `${PREFIX_ROUTE}/webhooks` + } + ] + }, + { + groupId: 8, + title: t('component:navbar.access-control'), + type: MenuGroupTypes.SETTINGS, + items: [ + { + id: 32, + iconName: 'user', + title: t('component:navbar.users'), + to: `${PREFIX_ROUTE}/users` + }, + { + id: 33, + iconName: 'users', + title: t('component:navbar.user-groups'), + to: `${PREFIX_ROUTE}/user-groups` + }, + { + id: 34, + iconName: 'account-icon', + title: t('component:navbar.service-accounts'), + to: `${PREFIX_ROUTE}/service-accounts` + }, + { + id: 35, + iconName: 'folder-icon', + title: t('component:navbar.resource-groups'), + to: `${PREFIX_ROUTE}/resource-groups` + }, + { + id: 36, + iconName: 'briefcase', + title: t('component:navbar.roles'), + to: `${PREFIX_ROUTE}/roles` + } + ] + }, + { + groupId: 9, + title: t('component:navbar.security-and-governance'), + type: MenuGroupTypes.SETTINGS, + items: [ + { + id: 37, + iconName: 'shield', + title: t('component:navbar.policies'), + to: `${PREFIX_ROUTE}/policies` + }, + { + id: 38, + iconName: 'snow', + title: t('component:navbar.freeze-windows'), + to: `${PREFIX_ROUTE}/freeze-windows` + } + ] + }, + { + groupId: 10, + title: t('component:navbar.external-tickets'), + type: MenuGroupTypes.SETTINGS, + items: [ + { + id: 39, + iconName: 'ticket', + title: t('component:navbar.external-tickets'), + to: `${PREFIX_ROUTE}/external-tickets` + } + ] + } +] diff --git a/packages/ui/src/components/navbar-new/index.ts b/packages/ui/src/components/navbar-new/index.ts new file mode 100644 index 0000000000..99ab33805f --- /dev/null +++ b/packages/ui/src/components/navbar-new/index.ts @@ -0,0 +1 @@ +export * from './app-sidebar' diff --git a/packages/ui/src/components/navbar-new/sidebar-item.tsx b/packages/ui/src/components/navbar-new/sidebar-item.tsx new file mode 100644 index 0000000000..f5965d73e2 --- /dev/null +++ b/packages/ui/src/components/navbar-new/sidebar-item.tsx @@ -0,0 +1,131 @@ +import { NavLink } from 'react-router-dom' + +import { Button } from '@components/button' +import { DropdownMenu } from '@components/dropdown-menu' +import { Icon, IconProps } from '@components/icon' +import { Sidebar } from '@components/sidebar/sidebar' +import { Text } from '@components/text' +import { cn } from '@utils/cn' +import { TFunction } from 'i18next' + +interface NavbarItemType { + id: number | string + title: string + iconName?: IconProps['name'] + description?: string + to: string + permanentlyPinned?: boolean +} + +interface NavbarItemProps { + item: NavbarItemType + isRecent?: boolean + handleChangePinnedMenuItem: (item: NavbarItemType, pin: boolean) => void + handleRemoveRecentMenuItem: (item: NavbarItemType) => void + handleCustomNav: () => void + t: TFunction +} + +export const SidebarItem = ({ + item, + isRecent = false, + handleChangePinnedMenuItem, + handleRemoveRecentMenuItem, + handleCustomNav, + t +}: // t, +NavbarItemProps) => { + const iconName = item.iconName && (item.iconName.replace('-gradient', '') as IconProps['name']) + + const handlePin = () => { + handleChangePinnedMenuItem(item, isRecent) + } + + const handleRemoveRecent = () => { + handleRemoveRecentMenuItem(item) + } + + const dropdownItems = isRecent ? ( + <> + + + + {t('component:navbar.pin')} + + + + + + {t('component:navbar.remove')} + + + + ) : ( + <> + + + + {t('component:navbar.reorder')} + + + + {!item.permanentlyPinned ? ( + + + + {t('component:navbar.unpin')} + + + ) : null} + + ) + + return ( +
+ + {({ isActive }) => ( + + +
+ + + {item.title} + +
+
+
+ )} +
+ + + + + + + + {dropdownItems} + + +
+ ) +} diff --git a/packages/ui/src/components/navbar-new/sidebar-search.tsx b/packages/ui/src/components/navbar-new/sidebar-search.tsx new file mode 100644 index 0000000000..161dfb822c --- /dev/null +++ b/packages/ui/src/components/navbar-new/sidebar-search.tsx @@ -0,0 +1,61 @@ +// import { Search } from "lucide-react"; + +import { FormHTMLAttributes } from 'react' + +import { Button } from '@components/button' +import { Label } from '@components/form-primitives' +// import { useSearch } from '@/context/SearchContext' +import { Icon } from '@components/icon' +import { Input } from '@components/input' +import { Sidebar } from '@components/sidebar/sidebar' +import { TFunction } from 'i18next' + +// import { Button, Command, Input, Label } from '@harnessio/ui/components' + +interface SidebarSearchProps extends FormHTMLAttributes { + t: TFunction +} + +export function SidebarSearch(props: SidebarSearchProps) { + // const searchContext = useSearch() + + // if (!searchContext) { + // console.warn('⚠️ Search context is null, returning early.') + // return null + // } + + // const { setIsOpen } = searchContext + + return ( +
+ + + + e.target.blur()} + /> + + + + +
+ ) +} diff --git a/packages/ui/src/components/navbar-new/sidebar-user.tsx b/packages/ui/src/components/navbar-new/sidebar-user.tsx new file mode 100644 index 0000000000..19f30f7a66 --- /dev/null +++ b/packages/ui/src/components/navbar-new/sidebar-user.tsx @@ -0,0 +1,148 @@ +import { Avatar } from '@components/avatar' +import { DropdownMenu } from '@components/dropdown-menu' +import { Icon } from '@components/icon' +import { Sidebar } from '@components/sidebar/sidebar' +import { getInitials } from '@utils/stringUtils' +import { TFunction } from 'i18next' + +interface UserProps { + user: { + display_name?: string + uid?: string + url: string + email: string + // avatar: string + } + openThemeDialog: () => void + openLanguageDialog: () => void + t: TFunction +} + +export function User({ user, openThemeDialog, openLanguageDialog, t }: UserProps) { + const userName = user?.display_name || user?.uid || '' + return ( + + + + + + + + {getInitials(userName)} + +
+ {userName} + {user.email} +
+ +
+
+ + +
+ + + SM + +
+ {userName} + {user.email} +
+
+
+ + + + +   {t('component:navbar.settings', 'Settings')} + + + +   {t('component:navbar.appearence', 'Appearance')} + + + +   {t('component:navbar.language', 'Language')} + + + + +   {t('component:navbar.logout', 'Logout')} + + +
+
+
+
+ ) +} + +const LanguageIcon = () => ( + + + + + + + + +) diff --git a/packages/ui/src/components/navbar-new/types.ts b/packages/ui/src/components/navbar-new/types.ts new file mode 100644 index 0000000000..6bd3aafb90 --- /dev/null +++ b/packages/ui/src/components/navbar-new/types.ts @@ -0,0 +1,50 @@ +import { IconProps } from '@/components' + +export enum MenuGroupTypes { + GENERAL = 'general', + SETTINGS = 'settings' +} + +interface MenuGroupType { + groupId: number | string + title: string + type: MenuGroupTypes + items: NavbarItemType[] +} + +type NavbarItemIdType = number | string + +interface NavbarItemType { + id: NavbarItemIdType + title: string + iconName?: IconProps['name'] + description?: string + to: string + permanentlyPinned?: boolean +} + +export enum UserMenuKeys { + ACCOUNT = 'account', + THEME = 'theme', + CUSTOM_NAV = 'customNavigation', + ADMINISTRATION = 'administration', + LOG_OUT = 'logOut' +} + +interface UserMenuItemType { + key: UserMenuKeys + iconName: IconProps['name'] + title: string + to: string | null + isSeparated: boolean +} + +interface NavState { + pinnedMenu: NavbarItemType[] + recentMenu: NavbarItemType[] + setPinned: (items: NavbarItemType, pin: boolean) => void + setRecent: (items: NavbarItemType, remove?: boolean) => void + setNavLinks: (links: { pinnedMenu?: NavbarItemType[]; recentMenu?: NavbarItemType[] }) => void +} + +export type { MenuGroupType, NavbarItemType, UserMenuItemType, NavbarItemIdType, NavState } diff --git a/packages/ui/src/components/select.tsx b/packages/ui/src/components/select.tsx index 17dea81556..ab74465aff 100644 --- a/packages/ui/src/components/select.tsx +++ b/packages/ui/src/components/select.tsx @@ -16,8 +16,9 @@ import * as SelectPrimitive from '@radix-ui/react-select' import { cn } from '@utils/cn' interface SelectRootProps - extends Omit>, 'defaultValue'>, 'dir'>, - SelectPrimitive.SelectProps { + extends Omit, 'defaultValue'>, 'dir'>, + Omit { + children?: ReactNode label?: string error?: string caption?: ReactNode diff --git a/packages/ui/src/components/sidebar/sidebar.tsx b/packages/ui/src/components/sidebar/sidebar.tsx index 1cee9287ce..b2c8342847 100644 --- a/packages/ui/src/components/sidebar/sidebar.tsx +++ b/packages/ui/src/components/sidebar/sidebar.tsx @@ -23,7 +23,7 @@ import { useIsMobile } from './use-is-mobile' const SIDEBAR_COOKIE_NAME = 'sidebar:state' const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 -const SIDEBAR_WIDTH = '16rem' +const SIDEBAR_WIDTH = '220px' const SIDEBAR_WIDTH_MOBILE = '18rem' const SIDEBAR_WIDTH_ICON = '3rem' const SIDEBAR_KEYBOARD_SHORTCUT = 'b' diff --git a/packages/ui/src/icons/chevron-up-down.svg b/packages/ui/src/icons/chevron-up-down.svg new file mode 100644 index 0000000000..44cea80627 --- /dev/null +++ b/packages/ui/src/icons/chevron-up-down.svg @@ -0,0 +1,3 @@ + + + From f25ee41a9107d51b861d859be95d25671dbe8284 Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 26 Feb 2025 23:30:09 +0530 Subject: [PATCH 02/23] Fix self import error --- packages/ui/src/components/navbar-new/data/navbar-menu-data.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts b/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts index 34e48220b5..38006067ad 100644 --- a/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts +++ b/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts @@ -1,7 +1,6 @@ +import { MenuGroupType, MenuGroupTypes } from '@components/navbar' import { TFunction } from 'i18next' -import { MenuGroupType, MenuGroupTypes } from '@harnessio/ui/components' - const PREFIX_ROUTE = '/canary/repos/canary' export const getNavbarMenuData = (t: TFunction): MenuGroupType[] => [ From fb93d16e1738334e4117f6cef74618c5df5c490a Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 26 Feb 2025 23:32:12 +0530 Subject: [PATCH 03/23] changed import from navbar to types --- packages/ui/src/components/navbar-new/data/navbar-menu-data.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts b/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts index 38006067ad..8f5fd214ea 100644 --- a/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts +++ b/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts @@ -1,6 +1,7 @@ -import { MenuGroupType, MenuGroupTypes } from '@components/navbar' import { TFunction } from 'i18next' +import { MenuGroupType, MenuGroupTypes } from '../types' + const PREFIX_ROUTE = '/canary/repos/canary' export const getNavbarMenuData = (t: TFunction): MenuGroupType[] => [ From 5dd23ded6aecb2d2e1ae9d70a0b55b384b607762 Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 18:40:28 +0530 Subject: [PATCH 04/23] Sidebar integration changes --- apps/gitness/src/components-v2/app-shell.tsx | 1 + .../language-selector/language-dialog.tsx | 10 +- .../src/components/language-selector/types.ts | 20 +- .../src/components/navbar-new/app-sidebar.tsx | 178 +++------ .../navbar-new/data/navbar-menu-data.ts | 342 ------------------ .../navbar-new/sidebar-search-new.tsx | 62 ++++ .../components/navbar-new/sidebar-search.tsx | 92 +++-- .../components/navbar-new/sidebar-user.tsx | 17 +- .../theme-selector-v2/theme-dialog.tsx | 105 +++--- .../src/components/theme-selector-v2/types.ts | 43 ++- 10 files changed, 257 insertions(+), 613 deletions(-) delete mode 100644 packages/ui/src/components/navbar-new/data/navbar-menu-data.ts create mode 100644 packages/ui/src/components/navbar-new/sidebar-search-new.tsx diff --git a/apps/gitness/src/components-v2/app-shell.tsx b/apps/gitness/src/components-v2/app-shell.tsx index 7fe00b4a24..48231405ce 100644 --- a/apps/gitness/src/components-v2/app-shell.tsx +++ b/apps/gitness/src/components-v2/app-shell.tsx @@ -207,6 +207,7 @@ export const AppShell = () => { handleMoreMenu={handleMoreMenu} showSettingMenu={showSettingMenu} handleSettingsMenu={handleSettingsMenu} + handleCustomNav={handleCustomNav} /> diff --git a/packages/ui/src/components/language-selector/language-dialog.tsx b/packages/ui/src/components/language-selector/language-dialog.tsx index 0a10bf8205..85c1b94787 100644 --- a/packages/ui/src/components/language-selector/language-dialog.tsx +++ b/packages/ui/src/components/language-selector/language-dialog.tsx @@ -7,13 +7,7 @@ import { Language, LanguageCode, LanguageDialogProps, LanguageInterface } from ' export const languages: LanguageInterface[] = [ { code: LanguageCode.EN, name: Language.English }, - { code: LanguageCode.БГ, name: Language.Bulgarian }, - { code: LanguageCode.HR, name: Language.Croatian }, - { code: LanguageCode.CZ, name: Language.Czech }, - { code: LanguageCode.FR, name: Language.French }, - { code: LanguageCode.DE, name: Language.German }, - { code: LanguageCode.IE, name: Language.Irish }, - { code: LanguageCode.LA, name: Language.LatinAmerican } + { code: LanguageCode.FR, name: Language.French } ] const LanguageDialog: FC = ({ @@ -51,7 +45,7 @@ const LanguageDialog: FC = ({ }} >
-
+
{lang.code}
({ - user: { - name: 'Jane Citizen', - email: 'jane@harness.io', - avatar: - 'https://images.unsplash.com/photo-1502823403499-6ccfcf4fb453?&w=256&h=256&q=70&crop=focalpoint&fp-x=0.5&fp-y=0.3&fp-z=1&fit=crop' - } -}) +import { NavbarItemType } from './types' + +interface SidebarProps { + recentMenuItems: NavbarItemType[] + pinnedMenuItems: NavbarItemType[] + showMoreMenu: boolean + showSettingMenu: boolean + handleMoreMenu: () => void + handleSettingsMenu: () => void + currentUser: TypesUser | undefined + handleCustomNav: () => void + handleLogOut: () => void + handleChangePinnedMenuItem: (item: NavbarItemType, pin: boolean) => void + handleRemoveRecentMenuItem: (item: NavbarItemType) => void + useThemeStore: () => IThemeStore + useTranslationStore: () => TranslationStore +} export const AppSidebar = ({ useThemeStore, @@ -35,90 +39,27 @@ export const AppSidebar = ({ pinnedMenuItems, recentMenuItems, currentUser, - showMoreMenu, - showSettingMenu, handleMoreMenu, - handleSettingsMenu -}) => { - const location = useLocation() - const { setTheme } = useThemeStore() + handleSettingsMenu, + handleCustomNav +}: SidebarProps) => { + const { t, i18n, changeLanguage } = useTranslationStore() + console.log('i18n.language', i18n.language) + const { theme, setTheme } = useThemeStore() + const navigate = useNavigate() - // const [showMoreMenu, setShowMoreMenu] = useState(false) - // const [showSettingMenu, setShowSettingMenu] = useState(false) - const [showCustomNav, setShowCustomNav] = useState(false) const [openThemeDialog, setOpenThemeDialog] = useState(false) const [openLanguageDialog, setOpenLanguageDialog] = useState(false) - const { t, changeLanguage } = useTranslationStore() - const data = getData(t) - - const { moreMenu, settingsMenu } = useMemo(() => { - const navbarMenuData = getNavbarMenuData(t) - - return navbarMenuData.reduce( - (acc, item) => { - if (item.type === MenuGroupTypes.SETTINGS) { - acc.settingsMenu.push(item) - } else { - acc.moreMenu.push(item) - } - return acc - }, - { moreMenu: [], settingsMenu: [] } - ) - }, [t, changeLanguage]) - - /** - * Toggle show more menu - */ - // const handleMoreMenu = useCallback(() => { - // setShowSettingMenu(false) - // setShowMoreMenu(prevState => !prevState) - // }, []) - - /** - * Toggle system settings menu - */ - // const handleSettingsMenu = useCallback(() => { - // setShowMoreMenu(false) - // setShowSettingMenu(prevState => !prevState) - // }, []) - - /** - * Toggle custom navigation modal - */ - const handleCustomNav = useCallback(() => { - setShowCustomNav(prevState => !prevState) - }, []) + // const handleThemeChange = (theme: ThemeInterface) => { + // setTheme(`${theme.mode}-${theme.colorAdjustment}-${theme.contrast}`) + // } - /** - * Close all menu when location changed - */ - // useEffect(() => { - // setShowMoreMenu(false) - // setShowSettingMenu(false) - // setShowCustomNav(false) - // }, [location]) - - /** - * Handle save recent and pinned items - */ - const handleSave = (nextRecentItems, nextPinnedItems) => { - // setNavLinks({ - // pinnedMenu: nextPinnedItems, - // recentMenu: nextRecentItems - // }) - } - - const handleThemeChange = theme => { - setTheme(theme) - } - - const handleLanguageChange = language => { + const handleLanguageChange = (language: LanguageInterface) => { changeLanguage(language.code.toLowerCase()) } - const handleLanguageSave = language => { + const handleLanguageSave = (language: LanguageInterface) => { changeLanguage(language.code.toLowerCase()) setOpenLanguageDialog(false) } @@ -127,19 +68,28 @@ export const AppSidebar = ({ setOpenLanguageDialog(false) } - const navigate = useNavigate() - return ( <> -
- - - - -
- + {/* + + + + } + /> */} + + + + + + } + t={t} + />
@@ -245,27 +195,15 @@ export const AppSidebar = ({
- - - setOpenThemeDialog(false)} - onChange={handleThemeChange} - // onCancel={handleThemeCancel} - // onSave={handleThemeSave} /> setOpenLanguageDialog(false)} onChange={handleLanguageChange} diff --git a/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts b/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts deleted file mode 100644 index 8f5fd214ea..0000000000 --- a/packages/ui/src/components/navbar-new/data/navbar-menu-data.ts +++ /dev/null @@ -1,342 +0,0 @@ -import { TFunction } from 'i18next' - -import { MenuGroupType, MenuGroupTypes } from '../types' - -const PREFIX_ROUTE = '/canary/repos/canary' - -export const getNavbarMenuData = (t: TFunction): MenuGroupType[] => [ - { - groupId: 0, - title: 'Devops', - type: MenuGroupTypes.GENERAL, - items: [ - { - id: 0, - iconName: 'repositories-gradient', - title: t('component:navbar.repositories'), - description: t('component:navbar.repoDesc', 'Integrated & familiar git experience.'), - to: `${PREFIX_ROUTE}/repositories` - }, - { - id: 1, - iconName: 'pipelines-gradient', - title: t('component:navbar.pipelines'), - description: t('component:navbar.pipelineDesc', 'Up to 4X faster than other solutions.'), - to: `${PREFIX_ROUTE}/pipelines` - }, - { - id: 40, - iconName: 'execution-gradient', - title: t('component:navbar.executions'), - description: t('component:navbar.executionDesc', 'Optimize feature rollout velocity.'), - to: `${PREFIX_ROUTE}/executions` - }, - { - id: 41, - iconName: 'database-gradient', - title: t('component:navbar.databases'), - description: t('component:navbar.databaseDesc', 'Manage all your infrastructure.'), - to: `${PREFIX_ROUTE}/databases` - }, - { - id: 42, - iconName: 'artifacts-gradient', - title: t('component:navbar.artifacts'), - description: t('component:navbar.artifactDesc', 'Validate service resilience.'), - to: `${PREFIX_ROUTE}/artifacts` - }, - { - id: 5, - iconName: 'infrastructure-gradient', - title: t('component:navbar.infrastructure'), - description: t('component:navbar.infrastructureDesc', 'Manage all your infrastructure.'), - to: `${PREFIX_ROUTE}/infrastructure` - }, - { - id: 6, - iconName: 'flag-gradient', - title: t('component:navbar.feature-flags'), - description: t('component:navbar.featureFlagsDesc', 'Optimize feature rollout velocity.'), - to: `${PREFIX_ROUTE}/feature-flags` - } - ] - }, - { - groupId: 1, - title: 'Devex', - type: MenuGroupTypes.GENERAL, - items: [ - { - id: 7, - iconName: 'dev-portal-gradient', - title: t('component:navbar.developer-portal'), - description: t('component:navbar.devPortalDesc', 'Built for developers, onboard in minutes.'), - to: `${PREFIX_ROUTE}/dev-portal` - }, - { - id: 8, - iconName: 'dev-envs-gradient', - title: t('component:navbar.developer-environments'), - description: t('component:navbar.devEnvsDesc', 'Integrated & familiar git experience.'), - to: `${PREFIX_ROUTE}/dev-environments` - }, - { - id: 9, - iconName: 'dev-insights-gradient', - title: t('component:navbar.developer-insights'), - description: t('component:navbar.devInsightsDesc', 'Actionable insights on SDLC.'), - to: `${PREFIX_ROUTE}/dev-insights` - } - ] - }, - { - groupId: 2, - title: t('component:navbar.secops'), - type: MenuGroupTypes.GENERAL, - items: [ - { - id: 10, - iconName: 'security-tests-gradient', - title: t('component:navbar.security-tests'), - description: t('component:navbar.securityTestsDesc', 'Shift left security testing.'), - to: `${PREFIX_ROUTE}/security-tests` - }, - { - id: 11, - iconName: 'supply-chain-gradient', - title: t('component:navbar.supply-chain'), - description: t('component:navbar.supplyChainDesc', 'Artifact integrity and governance.'), - to: `${PREFIX_ROUTE}/supply-chain` - } - ] - }, - { - groupId: 3, - title: t('component:navbar.finops'), - type: MenuGroupTypes.GENERAL, - items: [ - { - id: 12, - iconName: 'cloud-costs-gradient', - title: t('component:navbar.cloud-costs'), - description: t('component:navbar.cloudCostsDesc', 'Intelligent cost management.'), - to: `${PREFIX_ROUTE}/cloud-costs` - } - ] - }, - { - groupId: 4, - title: t('component:navbar.reliability'), - type: MenuGroupTypes.GENERAL, - items: [ - { - id: 13, - iconName: 'incidents-gradient', - title: t('component:navbar.incidents'), - description: t('component:navbar.incidentsDesc', 'Shift left security testing.'), - to: `${PREFIX_ROUTE}/incidents` - }, - { - id: 14, - iconName: 'chaos-engineering-gradient', - title: t('component:navbar.chaos-engineering'), - description: t('component:navbar.chaosEngineeringDesc', 'Validate service resilience.'), - to: `${PREFIX_ROUTE}/chaos` - } - ] - }, - - { - groupId: 5, - title: t('component:navbar.platform'), - type: MenuGroupTypes.GENERAL, - items: [ - { - id: 15, - iconName: 'dashboards-gradient', - title: t('component:navbar.dashboards'), - description: 'Intelligent cost management.', - to: `${PREFIX_ROUTE}/dashboards` - } - ] - }, - { - groupId: 6, - title: t('component:navbar.general'), - type: MenuGroupTypes.SETTINGS, - items: [ - { - id: 16, - iconName: 'settings-2', - title: t('component:navbar.settings'), - to: `${PREFIX_ROUTE}/settings` - }, - { - id: 17, - iconName: 'notification', - title: t('component:navbar.notifications'), - to: `${PREFIX_ROUTE}/notifications` - } - ] - }, - { - groupId: 7, - title: t('component:navbar.resources'), - type: MenuGroupTypes.SETTINGS, - items: [ - { - id: 18, - iconName: 'wrench', - title: t('component:navbar.services'), - to: `${PREFIX_ROUTE}/resources` - }, - { - id: 19, - iconName: 'environment', - title: t('component:navbar.environments'), - to: `${PREFIX_ROUTE}/environments` - }, - { - id: 20, - iconName: 'connectors', - title: t('component:navbar.connectors'), - to: `${PREFIX_ROUTE}/connectors` - }, - { - id: 21, - iconName: 'hierarchy', - title: t('component:navbar.delegates'), - to: `${PREFIX_ROUTE}/delegates` - }, - { - id: 22, - iconName: 'key', - title: t('component:navbar.secrets'), - to: `${PREFIX_ROUTE}/secrets` - }, - { - id: 23, - iconName: 'file-icon', - title: t('component:navbar.file-store'), - to: `${PREFIX_ROUTE}/file-store` - }, - { - id: 24, - iconName: 'sidebar-icon', - title: t('component:navbar.templates'), - to: `${PREFIX_ROUTE}/templates` - }, - { - id: 25, - iconName: 'variable', - title: t('component:navbar.variables'), - to: `${PREFIX_ROUTE}/variables` - }, - { - id: 26, - iconName: 'clock-icon', - title: t('component:navbar.slo-downtime'), - to: `${PREFIX_ROUTE}/slo-downtime` - }, - { - id: 27, - iconName: 'search', - title: t('component:navbar.discovery'), - to: `${PREFIX_ROUTE}/discovery` - }, - { - id: 28, - iconName: 'eye', - title: t('component:navbar.monitored-services'), - to: `${PREFIX_ROUTE}/monitored-services` - }, - { - id: 29, - iconName: 'stack', - title: t('component:navbar.overrides'), - to: `${PREFIX_ROUTE}/overrides` - }, - { - id: 30, - iconName: 'bookmark-icon', - title: t('component:navbar.certificates'), - to: `${PREFIX_ROUTE}/certificates` - }, - { - id: 31, - iconName: 'webhook', - title: t('component:navbar.webhooks'), - to: `${PREFIX_ROUTE}/webhooks` - } - ] - }, - { - groupId: 8, - title: t('component:navbar.access-control'), - type: MenuGroupTypes.SETTINGS, - items: [ - { - id: 32, - iconName: 'user', - title: t('component:navbar.users'), - to: `${PREFIX_ROUTE}/users` - }, - { - id: 33, - iconName: 'users', - title: t('component:navbar.user-groups'), - to: `${PREFIX_ROUTE}/user-groups` - }, - { - id: 34, - iconName: 'account-icon', - title: t('component:navbar.service-accounts'), - to: `${PREFIX_ROUTE}/service-accounts` - }, - { - id: 35, - iconName: 'folder-icon', - title: t('component:navbar.resource-groups'), - to: `${PREFIX_ROUTE}/resource-groups` - }, - { - id: 36, - iconName: 'briefcase', - title: t('component:navbar.roles'), - to: `${PREFIX_ROUTE}/roles` - } - ] - }, - { - groupId: 9, - title: t('component:navbar.security-and-governance'), - type: MenuGroupTypes.SETTINGS, - items: [ - { - id: 37, - iconName: 'shield', - title: t('component:navbar.policies'), - to: `${PREFIX_ROUTE}/policies` - }, - { - id: 38, - iconName: 'snow', - title: t('component:navbar.freeze-windows'), - to: `${PREFIX_ROUTE}/freeze-windows` - } - ] - }, - { - groupId: 10, - title: t('component:navbar.external-tickets'), - type: MenuGroupTypes.SETTINGS, - items: [ - { - id: 39, - iconName: 'ticket', - title: t('component:navbar.external-tickets'), - to: `${PREFIX_ROUTE}/external-tickets` - } - ] - } -] diff --git a/packages/ui/src/components/navbar-new/sidebar-search-new.tsx b/packages/ui/src/components/navbar-new/sidebar-search-new.tsx new file mode 100644 index 0000000000..9d896fe39c --- /dev/null +++ b/packages/ui/src/components/navbar-new/sidebar-search-new.tsx @@ -0,0 +1,62 @@ +// import { Search } from "lucide-react"; + +import { FormHTMLAttributes, ReactNode } from 'react' + +import { Button } from '@components/button' +// import { useSearch } from '@/context/SearchContext' +import { Icon } from '@components/icon' +import { Input } from '@components/input' +import { Sidebar } from '@components/sidebar/sidebar' +import { TFunction } from 'i18next' + +import { Label } from '..' + +interface SidebarSearchNewProps extends FormHTMLAttributes { + logo: ReactNode + t: TFunction +} + +export function SidebarSearchNew(props: SidebarSearchNewProps) { + // const searchContext = useSearch() + + // if (!searchContext) { + // console.warn('⚠️ Search context is null, returning early.') + // return null + // } + + // const { setIsOpen } = searchContext + + return ( +
+ {props.logo} + + + + e.target.blur()} + /> + + + + +
+ ) +} diff --git a/packages/ui/src/components/navbar-new/sidebar-search.tsx b/packages/ui/src/components/navbar-new/sidebar-search.tsx index 161dfb822c..f90092a836 100644 --- a/packages/ui/src/components/navbar-new/sidebar-search.tsx +++ b/packages/ui/src/components/navbar-new/sidebar-search.tsx @@ -1,61 +1,51 @@ -// import { Search } from "lucide-react"; +import { FormEvent, ReactNode, useState } from 'react' -import { FormHTMLAttributes } from 'react' +import { Dialog, SearchBox, Spacer } from '..' -import { Button } from '@components/button' -import { Label } from '@components/form-primitives' -// import { useSearch } from '@/context/SearchContext' -import { Icon } from '@components/icon' -import { Input } from '@components/input' -import { Sidebar } from '@components/sidebar/sidebar' -import { TFunction } from 'i18next' - -// import { Button, Command, Input, Label } from '@harnessio/ui/components' - -interface SidebarSearchProps extends FormHTMLAttributes { - t: TFunction +interface ProjectProps { + logo: ReactNode } -export function SidebarSearch(props: SidebarSearchProps) { - // const searchContext = useSearch() +function SidebarSearch({ logo }: ProjectProps) { + const [isSearchDialogOpen, setSearchDialogOpen] = useState(false) - // if (!searchContext) { - // console.warn('⚠️ Search context is null, returning early.') - // return null - // } + const openSearchDialog = (e?: FormEvent) => { + e?.preventDefault() + e?.stopPropagation() - // const { setIsOpen } = searchContext + setSearchDialogOpen(true) + } + + const closeSearchDialog = () => { + setSearchDialogOpen(false) + } return ( -
- - - - e.target.blur()} - /> - - - - -
+
+
{logo}
+ + + + + Search + + + + + + + +
) } + +export { SidebarSearch } diff --git a/packages/ui/src/components/navbar-new/sidebar-user.tsx b/packages/ui/src/components/navbar-new/sidebar-user.tsx index 19f30f7a66..664ac7def5 100644 --- a/packages/ui/src/components/navbar-new/sidebar-user.tsx +++ b/packages/ui/src/components/navbar-new/sidebar-user.tsx @@ -1,3 +1,4 @@ +import { TypesUser } from '@/types' import { Avatar } from '@components/avatar' import { DropdownMenu } from '@components/dropdown-menu' import { Icon } from '@components/icon' @@ -6,13 +7,7 @@ import { getInitials } from '@utils/stringUtils' import { TFunction } from 'i18next' interface UserProps { - user: { - display_name?: string - uid?: string - url: string - email: string - // avatar: string - } + user?: TypesUser openThemeDialog: () => void openLanguageDialog: () => void t: TFunction @@ -30,12 +25,12 @@ export function User({ user, openThemeDialog, openLanguageDialog, t }: UserProps className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground" > - + {getInitials(userName)}
{userName} - {user.email} + {user?.email}
@@ -49,12 +44,12 @@ export function User({ user, openThemeDialog, openLanguageDialog, t }: UserProps
- + SM
{userName} - {user.email} + {user?.email}
diff --git a/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx b/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx index fcabce90cd..d376042215 100644 --- a/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx +++ b/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx @@ -1,34 +1,40 @@ import { FC, useEffect, useState } from 'react' -import { Dialog, Icon, Select, Separator } from '@/components' +import { + ColorType, + ContrastType, + Dialog, + getModeColorContrastFromFullTheme, + Icon, + ModeType, + Select, + Separator +} from '@/components' import darkModeImage from '@/svgs/theme-dark.png' import lightModeImage from '@/svgs/theme-light.png' import { cn } from '@/utils/cn' -import { AccentColor, ColorAdjustment, Contrast, GrayColor, Mode, ThemeDialogProps } from './types' +import { AccentColor, GrayColor, ThemeDialogProps } from './types' -const ThemeDialog: FC = ({ defaultTheme, theme, open, onOpenChange, onChange, children }) => { - const [mode, setMode] = useState(Mode.Dark) - const [contrast, setContrast] = useState(Contrast.Default) - const [colorAdjustment, setColorAdjustment] = useState(ColorAdjustment.Default) +const ThemeDialog: FC = ({ theme, setTheme, open, onOpenChange, children }) => { const [accentColor, setAccentColor] = useState(AccentColor.Blue) const [grayColor, setGrayColor] = useState(GrayColor.First) + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)') + const [systemMode, setSystemMode] = useState(mediaQuery.matches ? ModeType.Dark : ModeType.Light) useEffect(() => { - if (theme) { - setMode(theme.mode) - setContrast(theme.contrast) - setColorAdjustment(theme.colorAdjustment) - setAccentColor(theme.accentColor) - setGrayColor(theme.grayColor) - } else if (defaultTheme) { - setMode(defaultTheme.mode) - setContrast(defaultTheme.contrast) - setColorAdjustment(defaultTheme.colorAdjustment) - setAccentColor(defaultTheme.accentColor) - setGrayColor(defaultTheme.grayColor) + const updateSystemTheme = () => { + setSystemMode(mediaQuery.matches ? ModeType.Dark : ModeType.Light) } - }, [defaultTheme, theme]) + + mediaQuery.addEventListener('change', updateSystemTheme) + + return () => { + mediaQuery.removeEventListener('change', updateSystemTheme) + } + }, []) + + const { mode, color: colorAdjustment, contrast } = getModeColorContrastFromFullTheme(theme) return ( @@ -42,27 +48,36 @@ const ThemeDialog: FC = ({ defaultTheme, theme, open, onOpenCh

Choose Dark mode for low light or Light mode for bright spaces.

-
- {Object.values(Mode).map(item => { +
+ {Object.entries(ModeType).map(([key, value]) => { return ( ) })} @@ -98,16 +113,17 @@ const ThemeDialog: FC = ({ defaultTheme, theme, open, onOpenCh { - setContrast(value) - onChange({ contrast: value, mode, colorAdjustment, accentColor, grayColor }) + onValueChange={(value: ContrastType) => { + setTheme(`${mode}-${colorAdjustment}-${value}`) + // setContrast(value) + // onChange({ contrast: value, mode, colorAdjustment, accentColor, grayColor }) }} placeholder="Select" > - {Object.values(Contrast).map(item => ( - - {item} + {Object.entries(ContrastType).map(([key, value]) => ( + + {key} ))} @@ -127,16 +143,17 @@ const ThemeDialog: FC = ({ defaultTheme, theme, open, onOpenCh { - setColorAdjustment(value) - onChange({ colorAdjustment: value, mode, contrast, accentColor, grayColor }) + onValueChange={(value: ColorType) => { + setTheme(`${mode}-${value}-${contrast}`) + // setColorAdjustment(value) + // onChange({ colorAdjustment: value, mode, contrast, accentColor, grayColor }) }} placeholder="Select" > - {Object.values(ColorAdjustment).map(item => ( - - {item} + {Object.entries(ColorType).map(([key, value]) => ( + + {key} ))} @@ -161,13 +178,13 @@ const ThemeDialog: FC = ({ defaultTheme, theme, open, onOpenCh )} onClick={() => { setAccentColor(item) - onChange({ accentColor: item, mode, contrast, colorAdjustment, grayColor }) + // onChange({ accentColor: item, mode, contrast, colorAdjustment, grayColor }) }} > @@ -194,7 +211,7 @@ const ThemeDialog: FC = ({ defaultTheme, theme, open, onOpenCh )} onClick={() => { setGrayColor(item) - onChange({ grayColor: item, mode, contrast, colorAdjustment, accentColor }) + // onChange({ grayColor: item, mode, contrast, colorAdjustment, accentColor }) }} > diff --git a/packages/ui/src/components/theme-selector-v2/types.ts b/packages/ui/src/components/theme-selector-v2/types.ts index 3536aacde1..9fd1f78a47 100644 --- a/packages/ui/src/components/theme-selector-v2/types.ts +++ b/packages/ui/src/components/theme-selector-v2/types.ts @@ -1,28 +1,30 @@ +import { ColorType, ContrastType, FullTheme, IThemeStore, ModeType } from '@components/theme-selector/types' + export interface ThemeInterface { - mode: Mode - contrast: Contrast - colorAdjustment: ColorAdjustment + mode: ModeType + contrast: ContrastType + colorAdjustment: ColorType accentColor: AccentColor grayColor: GrayColor } -export enum Mode { - Dark = 'Dark', - Light = 'Light' -} +// export enum Mode { +// Dark = 'Dark', +// Light = 'Light' +// } -export enum Contrast { - Default = 'Default', - HighContrast = 'High Contrast', - Dimmer = 'Dimmer' -} +// export enum Contrast { +// Default = 'Default', +// HighContrast = 'High Contrast', +// Dimmer = 'Dimmer' +// } -export enum ColorAdjustment { - Default = 'Default', - Protanopia = 'Protanopia', - Deuteranopia = 'Deuteranopia', - Tritanopia = 'Tritanopia' -} +// export enum ColorAdjustment { +// Default = 'Default', +// Protanopia = 'Protanopia', +// Deuteranopia = 'Deuteranopia', +// Tritanopia = 'Tritanopia' +// } export enum AccentColor { Red = '#FF4D4D', @@ -53,9 +55,10 @@ export enum GrayColor { export interface ThemeDialogProps { defaultTheme?: ThemeInterface - theme?: ThemeInterface + theme?: FullTheme + setTheme: (theme: FullTheme) => void open: boolean onOpenChange: (open: boolean) => void - onChange: (language: ThemeInterface) => void + // onChange: (theme: ThemeInterface) => void children?: React.ReactNode } From 868920c143440fbc2008b389cc2b9fbecaeb5baf Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 18:58:13 +0530 Subject: [PATCH 05/23] Fixed lint errors --- apps/gitness/src/components-v2/app-shell.tsx | 3 ++- .../src/components/navbar-new/app-sidebar.tsx | 18 +++++++++-------- .../components/navbar-new/sidebar-user.tsx | 5 +++-- packages/ui/src/components/select.tsx | 5 ++--- .../src/components/theme-selector-v2/types.ts | 20 +------------------ 5 files changed, 18 insertions(+), 33 deletions(-) diff --git a/apps/gitness/src/components-v2/app-shell.tsx b/apps/gitness/src/components-v2/app-shell.tsx index 48231405ce..2fb6dcd739 100644 --- a/apps/gitness/src/components-v2/app-shell.tsx +++ b/apps/gitness/src/components-v2/app-shell.tsx @@ -8,7 +8,7 @@ import { MenuGroupType, MenuGroupTypes, MoreSubmenu, - Navbar, + // Navbar, NavbarItemType, SettingsMenu, Sidebar @@ -208,6 +208,7 @@ export const AppShell = () => { showSettingMenu={showSettingMenu} handleSettingsMenu={handleSettingsMenu} handleCustomNav={handleCustomNav} + handleLogOut={handleLogOut} /> diff --git a/packages/ui/src/components/navbar-new/app-sidebar.tsx b/packages/ui/src/components/navbar-new/app-sidebar.tsx index cee96ae7f0..bd22b688cf 100644 --- a/packages/ui/src/components/navbar-new/app-sidebar.tsx +++ b/packages/ui/src/components/navbar-new/app-sidebar.tsx @@ -8,10 +8,11 @@ import { Icon } from '@components/icon' import { LanguageCode, LanguageDialog, LanguageInterface, languages } from '@components/language-selector' import { Sidebar } from '@components/sidebar/sidebar' import { Spacer } from '@components/spacer' -import { ThemeDialog, ThemeInterface } from '@components/theme-selector-v2' +import { ThemeDialog } from '@components/theme-selector-v2' import { SidebarItem } from './sidebar-item' -import { SidebarSearchNew } from './sidebar-search-new' +import { SidebarSearch } from './sidebar-search' +// import { SidebarSearchNew } from './sidebar-search-new' import { User } from './sidebar-user' import { NavbarItemType } from './types' @@ -41,7 +42,8 @@ export const AppSidebar = ({ currentUser, handleMoreMenu, handleSettingsMenu, - handleCustomNav + handleCustomNav, + handleLogOut }: SidebarProps) => { const { t, i18n, changeLanguage } = useTranslationStore() console.log('i18n.language', i18n.language) @@ -72,16 +74,15 @@ export const AppSidebar = ({ <> - {/* } - /> */} - - + {/* @@ -89,7 +90,7 @@ export const AppSidebar = ({ } t={t} - /> + /> */} @@ -190,6 +191,7 @@ export const AppSidebar = ({ user={currentUser} openThemeDialog={() => setOpenThemeDialog(true)} openLanguageDialog={() => setOpenLanguageDialog(true)} + handleLogOut={handleLogOut} t={t} /> diff --git a/packages/ui/src/components/navbar-new/sidebar-user.tsx b/packages/ui/src/components/navbar-new/sidebar-user.tsx index 664ac7def5..535ce748ee 100644 --- a/packages/ui/src/components/navbar-new/sidebar-user.tsx +++ b/packages/ui/src/components/navbar-new/sidebar-user.tsx @@ -10,10 +10,11 @@ interface UserProps { user?: TypesUser openThemeDialog: () => void openLanguageDialog: () => void + handleLogOut: () => void t: TFunction } -export function User({ user, openThemeDialog, openLanguageDialog, t }: UserProps) { +export function User({ user, openThemeDialog, openLanguageDialog, handleLogOut, t }: UserProps) { const userName = user?.display_name || user?.uid || '' return ( @@ -68,7 +69,7 @@ export function User({ user, openThemeDialog, openLanguageDialog, t }: UserProps   {t('component:navbar.language', 'Language')} - +   {t('component:navbar.logout', 'Logout')} diff --git a/packages/ui/src/components/select.tsx b/packages/ui/src/components/select.tsx index ab74465aff..17dea81556 100644 --- a/packages/ui/src/components/select.tsx +++ b/packages/ui/src/components/select.tsx @@ -16,9 +16,8 @@ import * as SelectPrimitive from '@radix-ui/react-select' import { cn } from '@utils/cn' interface SelectRootProps - extends Omit, 'defaultValue'>, 'dir'>, - Omit { - children?: ReactNode + extends Omit>, 'defaultValue'>, 'dir'>, + SelectPrimitive.SelectProps { label?: string error?: string caption?: ReactNode diff --git a/packages/ui/src/components/theme-selector-v2/types.ts b/packages/ui/src/components/theme-selector-v2/types.ts index 9fd1f78a47..b70e4f3d82 100644 --- a/packages/ui/src/components/theme-selector-v2/types.ts +++ b/packages/ui/src/components/theme-selector-v2/types.ts @@ -1,4 +1,4 @@ -import { ColorType, ContrastType, FullTheme, IThemeStore, ModeType } from '@components/theme-selector/types' +import { ColorType, ContrastType, FullTheme, ModeType } from '@components/theme-selector/types' export interface ThemeInterface { mode: ModeType @@ -8,24 +8,6 @@ export interface ThemeInterface { grayColor: GrayColor } -// export enum Mode { -// Dark = 'Dark', -// Light = 'Light' -// } - -// export enum Contrast { -// Default = 'Default', -// HighContrast = 'High Contrast', -// Dimmer = 'Dimmer' -// } - -// export enum ColorAdjustment { -// Default = 'Default', -// Protanopia = 'Protanopia', -// Deuteranopia = 'Deuteranopia', -// Tritanopia = 'Tritanopia' -// } - export enum AccentColor { Red = '#FF4D4D', Green = '#63E979', From a40d379064130ce9251c96c74efc240ede2805f9 Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 19:15:51 +0530 Subject: [PATCH 06/23] Added user profile settings in sidebar --- packages/ui/src/components/navbar-new/sidebar-user.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/components/navbar-new/sidebar-user.tsx b/packages/ui/src/components/navbar-new/sidebar-user.tsx index 535ce748ee..be6469d77e 100644 --- a/packages/ui/src/components/navbar-new/sidebar-user.tsx +++ b/packages/ui/src/components/navbar-new/sidebar-user.tsx @@ -1,3 +1,5 @@ +import { Link } from 'react-router-dom' + import { TypesUser } from '@/types' import { Avatar } from '@components/avatar' import { DropdownMenu } from '@components/dropdown-menu' @@ -56,9 +58,11 @@ export function User({ user, openThemeDialog, openLanguageDialog, handleLogOut, - - -   {t('component:navbar.settings', 'Settings')} + + + +   {t('component:navbar.settings', 'Settings')} + From f100d488c1b1cd4b6cb3661baf33cff47d6ebbf9 Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 19:37:03 +0530 Subject: [PATCH 07/23] App sidebar change --- packages/ui/src/components/navbar-new/app-sidebar.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/ui/src/components/navbar-new/app-sidebar.tsx b/packages/ui/src/components/navbar-new/app-sidebar.tsx index bd22b688cf..1d577e0888 100644 --- a/packages/ui/src/components/navbar-new/app-sidebar.tsx +++ b/packages/ui/src/components/navbar-new/app-sidebar.tsx @@ -46,7 +46,6 @@ export const AppSidebar = ({ handleLogOut }: SidebarProps) => { const { t, i18n, changeLanguage } = useTranslationStore() - console.log('i18n.language', i18n.language) const { theme, setTheme } = useThemeStore() const navigate = useNavigate() From b8687ae0ce7a3b4f3cc500e97fe80e0d5262629f Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 19:37:50 +0530 Subject: [PATCH 08/23] Removed commented code --- packages/ui/src/components/navbar-new/app-sidebar.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/ui/src/components/navbar-new/app-sidebar.tsx b/packages/ui/src/components/navbar-new/app-sidebar.tsx index 1d577e0888..e4ecc582a8 100644 --- a/packages/ui/src/components/navbar-new/app-sidebar.tsx +++ b/packages/ui/src/components/navbar-new/app-sidebar.tsx @@ -52,10 +52,6 @@ export const AppSidebar = ({ const [openThemeDialog, setOpenThemeDialog] = useState(false) const [openLanguageDialog, setOpenLanguageDialog] = useState(false) - // const handleThemeChange = (theme: ThemeInterface) => { - // setTheme(`${theme.mode}-${theme.colorAdjustment}-${theme.contrast}`) - // } - const handleLanguageChange = (language: LanguageInterface) => { changeLanguage(language.code.toLowerCase()) } From d087f77b7f10faac1a62ba7c2e758477ad47c0b9 Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 19:46:31 +0530 Subject: [PATCH 09/23] Added language icon --- packages/ui/src/components/icon.tsx | 2 + .../src/components/navbar-new/app-sidebar.tsx | 10 --- .../navbar-new/sidebar-search-new.tsx | 62 ------------------ .../components/navbar-new/sidebar-user.tsx | 64 +------------------ packages/ui/src/icons/language.svg | 59 +++++++++++++++++ 5 files changed, 62 insertions(+), 135 deletions(-) delete mode 100644 packages/ui/src/components/navbar-new/sidebar-search-new.tsx create mode 100644 packages/ui/src/icons/language.svg diff --git a/packages/ui/src/components/icon.tsx b/packages/ui/src/components/icon.tsx index 1547c7a283..0a06c1239a 100644 --- a/packages/ui/src/components/icon.tsx +++ b/packages/ui/src/components/icon.tsx @@ -109,6 +109,7 @@ import InfrastructureGradient from '../icons/infrastructure-gradient.svg' import Infrastructure from '../icons/infrastructure-icon.svg' import Italicize from '../icons/italicize.svg' import Key from '../icons/key-icon.svg' +import Language from '../icons/language.svg' import Lightning from '../icons/lightning.svg' import List from '../icons/list.svg' import NoDataBranches from '../icons/lists-data-icons/no-data-branches.svg' @@ -215,6 +216,7 @@ const IconNameMap = { 'filter-list': FilterList, 'info-circle': InfoCircle, 'double-tick': DoubleTick, + language: Language, play: Play, download: Download, clock: Clock, diff --git a/packages/ui/src/components/navbar-new/app-sidebar.tsx b/packages/ui/src/components/navbar-new/app-sidebar.tsx index e4ecc582a8..575e7ccad5 100644 --- a/packages/ui/src/components/navbar-new/app-sidebar.tsx +++ b/packages/ui/src/components/navbar-new/app-sidebar.tsx @@ -12,7 +12,6 @@ import { ThemeDialog } from '@components/theme-selector-v2' import { SidebarItem } from './sidebar-item' import { SidebarSearch } from './sidebar-search' -// import { SidebarSearchNew } from './sidebar-search-new' import { User } from './sidebar-user' import { NavbarItemType } from './types' @@ -77,15 +76,6 @@ export const AppSidebar = ({ } /> - {/* - - - - } - t={t} - /> */} diff --git a/packages/ui/src/components/navbar-new/sidebar-search-new.tsx b/packages/ui/src/components/navbar-new/sidebar-search-new.tsx deleted file mode 100644 index 9d896fe39c..0000000000 --- a/packages/ui/src/components/navbar-new/sidebar-search-new.tsx +++ /dev/null @@ -1,62 +0,0 @@ -// import { Search } from "lucide-react"; - -import { FormHTMLAttributes, ReactNode } from 'react' - -import { Button } from '@components/button' -// import { useSearch } from '@/context/SearchContext' -import { Icon } from '@components/icon' -import { Input } from '@components/input' -import { Sidebar } from '@components/sidebar/sidebar' -import { TFunction } from 'i18next' - -import { Label } from '..' - -interface SidebarSearchNewProps extends FormHTMLAttributes { - logo: ReactNode - t: TFunction -} - -export function SidebarSearchNew(props: SidebarSearchNewProps) { - // const searchContext = useSearch() - - // if (!searchContext) { - // console.warn('⚠️ Search context is null, returning early.') - // return null - // } - - // const { setIsOpen } = searchContext - - return ( -
- {props.logo} - - - - e.target.blur()} - /> - - - - -
- ) -} diff --git a/packages/ui/src/components/navbar-new/sidebar-user.tsx b/packages/ui/src/components/navbar-new/sidebar-user.tsx index be6469d77e..720745fecc 100644 --- a/packages/ui/src/components/navbar-new/sidebar-user.tsx +++ b/packages/ui/src/components/navbar-new/sidebar-user.tsx @@ -69,7 +69,7 @@ export function User({ user, openThemeDialog, openLanguageDialog, handleLogOut,   {t('component:navbar.appearence', 'Appearance')}
- +   {t('component:navbar.language', 'Language')} @@ -84,65 +84,3 @@ export function User({ user, openThemeDialog, openLanguageDialog, handleLogOut,
) } - -const LanguageIcon = () => ( - - - - - - - - -) diff --git a/packages/ui/src/icons/language.svg b/packages/ui/src/icons/language.svg new file mode 100644 index 0000000000..7a0bc11fa4 --- /dev/null +++ b/packages/ui/src/icons/language.svg @@ -0,0 +1,59 @@ + + + + + + + + \ No newline at end of file From 3c437e54cedc79453084017aa408a99206433430 Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 19:56:41 +0530 Subject: [PATCH 10/23] Removed old Navbar integration --- apps/gitness/src/components-v2/app-shell.tsx | 32 +++++--------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/apps/gitness/src/components-v2/app-shell.tsx b/apps/gitness/src/components-v2/app-shell.tsx index 2fb6dcd739..c348a1be3d 100644 --- a/apps/gitness/src/components-v2/app-shell.tsx +++ b/apps/gitness/src/components-v2/app-shell.tsx @@ -8,7 +8,6 @@ import { MenuGroupType, MenuGroupTypes, MoreSubmenu, - // Navbar, NavbarItemType, SettingsMenu, Sidebar @@ -179,36 +178,21 @@ export const AppShell = () => { return ( - {/* */} From 0d7c57c76f7c18f87ee604633c306304b15739b5 Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 19:59:05 +0530 Subject: [PATCH 11/23] Removed commented code --- .../ui/src/components/theme-selector-v2/theme-dialog.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx b/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx index d376042215..a758cbae9c 100644 --- a/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx +++ b/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx @@ -56,8 +56,6 @@ const ThemeDialog: FC = ({ theme, setTheme, open, onOpenChange key={key} onClick={() => { setTheme(`${value}-${colorAdjustment}-${contrast}`) - // setMode(value) - // onChange({ mode: value, contrast, colorAdjustment, accentColor, grayColor }) }} >
@@ -115,8 +113,6 @@ const ThemeDialog: FC = ({ theme, setTheme, open, onOpenChange value={contrast} onValueChange={(value: ContrastType) => { setTheme(`${mode}-${colorAdjustment}-${value}`) - // setContrast(value) - // onChange({ contrast: value, mode, colorAdjustment, accentColor, grayColor }) }} placeholder="Select" > @@ -145,8 +141,6 @@ const ThemeDialog: FC = ({ theme, setTheme, open, onOpenChange value={colorAdjustment} onValueChange={(value: ColorType) => { setTheme(`${mode}-${value}-${contrast}`) - // setColorAdjustment(value) - // onChange({ colorAdjustment: value, mode, contrast, accentColor, grayColor }) }} placeholder="Select" > @@ -178,7 +172,6 @@ const ThemeDialog: FC = ({ theme, setTheme, open, onOpenChange )} onClick={() => { setAccentColor(item) - // onChange({ accentColor: item, mode, contrast, colorAdjustment, grayColor }) }} > = ({ theme, setTheme, open, onOpenChange )} onClick={() => { setGrayColor(item) - // onChange({ grayColor: item, mode, contrast, colorAdjustment, accentColor }) }} > From d290304100e14a86e4a221e6caf7d919cc125381 Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 20:29:51 +0530 Subject: [PATCH 12/23] Fixed language svg --- packages/ui/src/icons/language.svg | 60 +----------------------------- 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/packages/ui/src/icons/language.svg b/packages/ui/src/icons/language.svg index 7a0bc11fa4..72ed7aeee7 100644 --- a/packages/ui/src/icons/language.svg +++ b/packages/ui/src/icons/language.svg @@ -1,59 +1 @@ - - - - - - - - \ No newline at end of file + \ No newline at end of file From 8165c252ce52f1966fdc6e609b840ba56b1e6c40 Mon Sep 17 00:00:00 2001 From: Vivek Date: Thu, 27 Feb 2025 22:58:42 +0530 Subject: [PATCH 13/23] Removed commented code --- packages/ui/src/components/theme-selector-v2/types.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/ui/src/components/theme-selector-v2/types.ts b/packages/ui/src/components/theme-selector-v2/types.ts index b70e4f3d82..74a75c91d4 100644 --- a/packages/ui/src/components/theme-selector-v2/types.ts +++ b/packages/ui/src/components/theme-selector-v2/types.ts @@ -41,6 +41,5 @@ export interface ThemeDialogProps { setTheme: (theme: FullTheme) => void open: boolean onOpenChange: (open: boolean) => void - // onChange: (theme: ThemeInterface) => void children?: React.ReactNode } From 992e5875443b42211227513d194243a56fce846f Mon Sep 17 00:00:00 2001 From: Vivek Date: Fri, 28 Feb 2025 13:55:02 +0530 Subject: [PATCH 14/23] Fixed style issues --- .../ui/src/components/language-selector/language-dialog.tsx | 4 ++-- packages/ui/src/components/navbar-new/sidebar-item.tsx | 2 +- packages/ui/src/components/navbar-new/sidebar-user.tsx | 2 +- packages/ui/src/components/sidebar/sidebar.tsx | 5 +++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/ui/src/components/language-selector/language-dialog.tsx b/packages/ui/src/components/language-selector/language-dialog.tsx index 85c1b94787..0e4f26a45c 100644 --- a/packages/ui/src/components/language-selector/language-dialog.tsx +++ b/packages/ui/src/components/language-selector/language-dialog.tsx @@ -38,7 +38,7 @@ const LanguageDialog: FC = ({ {supportedLanguages.map(lang => ( From 8005ccd9835ed70e7753fdae56f818da86818f41 Mon Sep 17 00:00:00 2001 From: Vivek Date: Fri, 28 Feb 2025 16:02:19 +0530 Subject: [PATCH 17/23] Hide System Mode, accent color and gray scale by default --- .../theme-selector-v2/theme-dialog.tsx | 126 ++++++++++-------- .../src/components/theme-selector-v2/types.ts | 3 + 2 files changed, 74 insertions(+), 55 deletions(-) diff --git a/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx b/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx index a758cbae9c..cd7f485831 100644 --- a/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx +++ b/packages/ui/src/components/theme-selector-v2/theme-dialog.tsx @@ -16,7 +16,16 @@ import { cn } from '@/utils/cn' import { AccentColor, GrayColor, ThemeDialogProps } from './types' -const ThemeDialog: FC = ({ theme, setTheme, open, onOpenChange, children }) => { +const ThemeDialog: FC = ({ + theme, + setTheme, + open, + onOpenChange, + children, + showSystemMode, + showAccentColor, + showGrayColor +}) => { const [accentColor, setAccentColor] = useState(AccentColor.Blue) const [grayColor, setGrayColor] = useState(GrayColor.First) @@ -50,6 +59,7 @@ const ThemeDialog: FC = ({ theme, setTheme, open, onOpenChange

{Object.entries(ModeType).map(([key, value]) => { + if (!showSystemMode && value === ModeType.System) return null return (
- - {/* Accent Color */} -
-
- Accent color -

Select your application accent color.

-
-
- {Object.values(AccentColor).map(item => ( - - ))} -
-
- - + {showAccentColor ? ( + <> + +
+
+ Accent color +

Select your application accent color.

+
+
+ {Object.values(AccentColor).map(item => ( + + ))} +
+
+ + ) : null} {/* Gray Color */} -
-
- Gray color -

Select your application gray color.

-
-
- {Object.values(GrayColor).map(item => ( - - ))} -
-
+ {showGrayColor ? ( + <> + +
+
+ Gray color +

Select your application gray color.

+
+
+ {Object.values(GrayColor).map(item => ( + + ))} +
+
+ + ) : null}
diff --git a/packages/ui/src/components/theme-selector-v2/types.ts b/packages/ui/src/components/theme-selector-v2/types.ts index 74a75c91d4..286bbe1f89 100644 --- a/packages/ui/src/components/theme-selector-v2/types.ts +++ b/packages/ui/src/components/theme-selector-v2/types.ts @@ -42,4 +42,7 @@ export interface ThemeDialogProps { open: boolean onOpenChange: (open: boolean) => void children?: React.ReactNode + showSystemMode?: boolean + showAccentColor?: boolean + showGrayColor?: boolean } From 32412d3538d53d29bcb950676faf1b3d8de1de99 Mon Sep 17 00:00:00 2001 From: Vivek Date: Fri, 28 Feb 2025 17:46:22 +0530 Subject: [PATCH 18/23] Added new search functionality --- .../src/components/navbar-new/app-sidebar.tsx | 35 +++- .../command-palette-wrapper.tsx | 191 ++++++++++++++++++ .../sidebar-search-new/command-palette.tsx | 153 ++++++++++++++ .../sidebar-search-new/search-context.tsx | 64 ++++++ .../sidebar-search-new/sidebar-search-new.tsx | 56 +++++ 5 files changed, 490 insertions(+), 9 deletions(-) create mode 100644 packages/ui/src/components/navbar-new/sidebar-search-new/command-palette-wrapper.tsx create mode 100644 packages/ui/src/components/navbar-new/sidebar-search-new/command-palette.tsx create mode 100644 packages/ui/src/components/navbar-new/sidebar-search-new/search-context.tsx create mode 100644 packages/ui/src/components/navbar-new/sidebar-search-new/sidebar-search-new.tsx diff --git a/packages/ui/src/components/navbar-new/app-sidebar.tsx b/packages/ui/src/components/navbar-new/app-sidebar.tsx index 575e7ccad5..c0c5651509 100644 --- a/packages/ui/src/components/navbar-new/app-sidebar.tsx +++ b/packages/ui/src/components/navbar-new/app-sidebar.tsx @@ -12,6 +12,8 @@ import { ThemeDialog } from '@components/theme-selector-v2' import { SidebarItem } from './sidebar-item' import { SidebarSearch } from './sidebar-search' +import { SearchProvider } from './sidebar-search-new/search-context' +import { SidebarSearchNew } from './sidebar-search-new/sidebar-search-new' import { User } from './sidebar-user' import { NavbarItemType } from './types' @@ -29,6 +31,7 @@ interface SidebarProps { handleRemoveRecentMenuItem: (item: NavbarItemType) => void useThemeStore: () => IThemeStore useTranslationStore: () => TranslationStore + showNewSearch?: boolean } export const AppSidebar = ({ @@ -42,7 +45,8 @@ export const AppSidebar = ({ handleMoreMenu, handleSettingsMenu, handleCustomNav, - handleLogOut + handleLogOut, + showNewSearch }: SidebarProps) => { const { t, i18n, changeLanguage } = useTranslationStore() const { theme, setTheme } = useThemeStore() @@ -68,14 +72,27 @@ export const AppSidebar = ({ <> - - - - - } - /> + {showNewSearch ? ( + + + + + + } + /> + + ) : ( + + + + + } + /> + )} diff --git a/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette-wrapper.tsx b/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette-wrapper.tsx new file mode 100644 index 0000000000..55dad26559 --- /dev/null +++ b/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette-wrapper.tsx @@ -0,0 +1,191 @@ +import { useEffect, useState } from 'react' + +import { Icon } from '@components/icon' + +import { CommandPalette } from './command-palette' +import { useSearch } from './search-context' + +enum PageKey { + REPOSITORIES = 'repositories', + PROJECTS = 'projects', + PIPELINES = 'pipelines' +} + +interface CommandOption { + label: string + key?: PageKey + shortcut?: [string, string] // Symbol + Key (e.g., ["⇧", "R"]) + url?: string + action?: () => void + icon?: () => JSX.Element +} + +export function CommandPaletteWrapper() { + const { isOpen, setIsOpen } = useSearch() + const [search, setSearch] = useState('') + const [pages, setPages] = useState([]) + const page = pages[pages.length - 1] + + const DEFAULT = { + placeholder: 'What do you need?' + } + + const [placeholder, setPlaceholder] = useState(DEFAULT.placeholder) + + useEffect(() => { + setPlaceholder(page ? `Search ${page}...` : DEFAULT.placeholder) + }, [page]) + + function onItemClick(target: PageKey) { + setPages([...pages, target]) + setSearch('') + } + + const MENU_OPTIONS: Record = { + [PageKey.REPOSITORIES]: [ + { + label: 'Search repositories...', + key: PageKey.REPOSITORIES, + shortcut: ['⇧', 'R'], + icon: () => + }, + { + label: 'Create repository', + action: () => alert('Create Repository'), + icon: () => + }, + { + label: 'Import repository', + action: () => alert('Import Repository'), + icon: () => + } + ], + [PageKey.PROJECTS]: [ + { + label: 'Search projects...', + key: PageKey.PROJECTS, + shortcut: ['⇧', 'P'], + icon: () => + }, + { + label: 'Create project', + action: () => alert('Create Project'), + icon: () => + }, + { + label: 'Import project', + action: () => alert('Import Project'), + icon: () => + } + ], + [PageKey.PIPELINES]: [ + { + label: 'Search pipelines...', + key: PageKey.PIPELINES, + shortcut: ['⇧', 'L'], + icon: () => + }, + { + label: 'Create pipeline', + action: () => alert('Create Pipeline'), + icon: () => + } + ] + } + + const SUB_ITEMS: Record = { + [PageKey.REPOSITORIES]: [ + { + label: 'petstore-app', + url: '/canary/repos/petstore-app/summary', + icon: () => + }, + { + label: 'RealWorld', + url: '/canary/repos/real-world/summary', + icon: () => + }, + { + label: 'sock shop', + url: '/canary/repos/sock-shop/summary', + icon: () => + }, + { + label: 'anthos', + url: '/canary/repos/anthos/summary', + icon: () => + }, + { + label: 'acme-web', + url: '/canary/repos/acme-web/summary', + icon: () => + } + ], + [PageKey.PROJECTS]: [ + { + label: 'Canary', + url: '/canary/repos/petstore-app/summary', + icon: () => + }, + { + label: 'Paypal', + url: '/canary/repos/real-world/summary', + icon: () => + } + ], + [PageKey.PIPELINES]: [ + { + label: 'build-pipeline', + url: '/canary/pipelines/build-pipeline/studio', + icon: () => + } + ] + } + + return ( + + { + if (e.key === 'Escape' || (e.key === 'Backspace' && !search)) { + e.preventDefault() + setPages(pages => pages.slice(0, -1)) + } + }} + > + + + Nothing found + + {!page ? ( + Object.entries(MENU_OPTIONS).map(([key, items]) => ( + + {items.map(({ label, key, action, icon, shortcut }) => ( + (key ? onItemClick(key) : action?.())}> +
{icon && icon()}
+
{label}
+ {shortcut && ( + + {shortcut[0]} + {shortcut[1]} + + )} +
+ ))} +
+ )) + ) : ( + + {SUB_ITEMS[page]?.map(({ label, url, icon }) => ( + (window.location.href = url!)}> +
{icon && icon()}
+
{label}
+
+ ))} +
+ )} +
+
+
+ ) +} diff --git a/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette.tsx b/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette.tsx new file mode 100644 index 0000000000..e52a414b7f --- /dev/null +++ b/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette.tsx @@ -0,0 +1,153 @@ +import React, { PropsWithChildren } from 'react' + +import { Dialog as RadixDialog } from '@components/dialog' +import { Overlay } from '@radix-ui/react-dialog' +import { cn } from '@utils/cn' +import { Command as CommandPrimitive } from 'cmdk' + +interface DialogProps { + className?: string + open: boolean + onOpenChange: (open: boolean) => void +} + +const Root = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +const Dialog = ({ children, className, open, onOpenChange }: PropsWithChildren) => ( + + + + + {children} + + + +) + +const Dropdown = ({ children, className, open, onOpenChange }: PropsWithChildren) => ( + + + + + {children} + + + +) + +const Input = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ + + ESC + +
+)) + +const List = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +const Empty = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>((props, ref) => ) + +const Group = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +const Item = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +const Separator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +const Shortcut = ({ className, ...props }: React.HTMLAttributes) => { + return ( + + ) +} + +export const CommandPalette = { + Root, + Dialog, + Dropdown, + Input, + Empty, + Group, + List, + Item, + Separator, + Shortcut +} diff --git a/packages/ui/src/components/navbar-new/sidebar-search-new/search-context.tsx b/packages/ui/src/components/navbar-new/sidebar-search-new/search-context.tsx new file mode 100644 index 0000000000..9e515e26e3 --- /dev/null +++ b/packages/ui/src/components/navbar-new/sidebar-search-new/search-context.tsx @@ -0,0 +1,64 @@ +import { createContext, ReactNode, useContext, useEffect, useState } from 'react' + +import { CommandPaletteWrapper } from './CommandPaletteWrapper' + +interface SearchContextType { + isOpen: boolean + setIsOpen: (open: boolean) => void + searchTerm: string + setSearchTerm: (term: string) => void + selectedIndex: number + setSelectedIndex: (index: number) => void +} + +const SearchContext = createContext(null) + +interface SearchProviderProps { + children: ReactNode +} + +export function SearchProvider({ children }: SearchProviderProps) { + const [isOpen, setIsOpen] = useState(false) + const [searchTerm, setSearchTerm] = useState('') + const [selectedIndex, setSelectedIndex] = useState(0) + + const toggleSearch = () => { + setIsOpen(prev => !prev) + } + + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === 'k') { + event.preventDefault() + toggleSearch() + } + } + + document.addEventListener('keydown', handleKeyDown) + return () => document.removeEventListener('keydown', handleKeyDown) + }, []) + + return ( + + {children} + + + ) +} + +export function useSearch(): SearchContextType { + const context = useContext(SearchContext) + if (!context) { + throw new Error('useSearch must be used within a SearchProvider') + } + return context +} diff --git a/packages/ui/src/components/navbar-new/sidebar-search-new/sidebar-search-new.tsx b/packages/ui/src/components/navbar-new/sidebar-search-new/sidebar-search-new.tsx new file mode 100644 index 0000000000..f93011a32e --- /dev/null +++ b/packages/ui/src/components/navbar-new/sidebar-search-new/sidebar-search-new.tsx @@ -0,0 +1,56 @@ +import { FormHTMLAttributes, ReactNode } from 'react' + +import { Icon } from '@components/icon' +import { Sidebar } from '@components/sidebar/sidebar' + +import { Button, Input, Label } from '@harnessio/ui/components' + +import { useSearch } from './search-context' + +interface SidebarSearchProps extends FormHTMLAttributes { + logo: ReactNode +} + +export function SidebarSearchNew(props: SidebarSearchProps) { + const searchContext = useSearch() + + if (!searchContext) { + console.warn('⚠️ Search context is null, returning early.') + return null + } + + const { setIsOpen } = searchContext + + return ( +
+ {props.logo} + + + + setIsOpen(true)} + autoComplete="off" + spellCheck={false} + onFocus={e => e.target.blur()} + /> + + + + +
+ ) +} From 17226a5c213c671758054208308078fa13dacd83 Mon Sep 17 00:00:00 2001 From: Vivek Date: Fri, 28 Feb 2025 17:48:29 +0530 Subject: [PATCH 19/23] Search context changes --- .../components/navbar-new/sidebar-search-new/search-context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/src/components/navbar-new/sidebar-search-new/search-context.tsx b/packages/ui/src/components/navbar-new/sidebar-search-new/search-context.tsx index 9e515e26e3..71ccb409b0 100644 --- a/packages/ui/src/components/navbar-new/sidebar-search-new/search-context.tsx +++ b/packages/ui/src/components/navbar-new/sidebar-search-new/search-context.tsx @@ -1,6 +1,6 @@ import { createContext, ReactNode, useContext, useEffect, useState } from 'react' -import { CommandPaletteWrapper } from './CommandPaletteWrapper' +import { CommandPaletteWrapper } from './command-palette-wrapper' interface SearchContextType { isOpen: boolean From b3da01fcefba484d53e1cf4537a371efef4178f6 Mon Sep 17 00:00:00 2001 From: Vivek Date: Fri, 28 Feb 2025 20:26:28 +0530 Subject: [PATCH 20/23] Added sidebar toggle --- apps/gitness/src/components-v2/app-shell.tsx | 73 +++++++++---------- .../components-v2/breadcrumbs/breadcrumbs.tsx | 10 ++- .../ui/src/components/sidebar/sidebar.tsx | 4 +- 3 files changed, 46 insertions(+), 41 deletions(-) diff --git a/apps/gitness/src/components-v2/app-shell.tsx b/apps/gitness/src/components-v2/app-shell.tsx index c348a1be3d..fcfad4b7d9 100644 --- a/apps/gitness/src/components-v2/app-shell.tsx +++ b/apps/gitness/src/components-v2/app-shell.tsx @@ -12,7 +12,6 @@ import { SettingsMenu, Sidebar } from '@harnessio/ui/components' -import { SandboxLayout } from '@harnessio/ui/views' import { useNav } from '../components/stores/recent-pinned-nav-links.store' import { getNavbarMenuData } from '../data/navbar-menu-data' @@ -176,43 +175,41 @@ export const AppShell = () => { useRepoImportEvents() return ( - - - - - - - - - - - - + - - + + + + + + + + + + ) } @@ -224,7 +221,7 @@ function BreadcrumbsAndOutlet({ className }: { className?: string }) { useRepoImportEvents() return ( -
+
diff --git a/apps/gitness/src/components-v2/breadcrumbs/breadcrumbs.tsx b/apps/gitness/src/components-v2/breadcrumbs/breadcrumbs.tsx index 6bebd47a4d..62fa6aa6d4 100644 --- a/apps/gitness/src/components-v2/breadcrumbs/breadcrumbs.tsx +++ b/apps/gitness/src/components-v2/breadcrumbs/breadcrumbs.tsx @@ -1,16 +1,24 @@ import { Link, useMatches } from 'react-router-dom' -import { Breadcrumb, Topbar } from '@harnessio/ui/components' +import { Breadcrumb, Separator, Sidebar, Topbar } from '@harnessio/ui/components' +import { useIsMFE } from '../../framework/hooks/useIsMFE' import { CustomHandle } from '../../framework/routing/types' function Breadcrumbs() { const matches = useMatches() const matchesWithBreadcrumb = matches.filter(match => (match.handle as CustomHandle)?.breadcrumb) + const isMFE = useIsMFE() return ( + {!isMFE ? ( + <> + + + + ) : null} {matchesWithBreadcrumb.map((match, index) => { diff --git a/packages/ui/src/components/sidebar/sidebar.tsx b/packages/ui/src/components/sidebar/sidebar.tsx index bc7427e014..4c78a093d0 100644 --- a/packages/ui/src/components/sidebar/sidebar.tsx +++ b/packages/ui/src/components/sidebar/sidebar.tsx @@ -235,7 +235,7 @@ const SidebarTrigger = forwardRef, ComponentProps { onClick?.(event) toggleSidebar() @@ -281,7 +281,7 @@ const SidebarInset = forwardRef>(({ class
Date: Fri, 28 Feb 2025 21:10:57 +0530 Subject: [PATCH 21/23] Fixed lint erros --- .../navbar-new/sidebar-search-new/command-palette.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette.tsx b/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette.tsx index e52a414b7f..55a8261ffe 100644 --- a/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette.tsx +++ b/packages/ui/src/components/navbar-new/sidebar-search-new/command-palette.tsx @@ -24,6 +24,7 @@ const Root = React.forwardRef< {...props} /> )) +Root.displayName = 'Root' const Dialog = ({ children, className, open, onOpenChange }: PropsWithChildren) => ( @@ -40,6 +41,7 @@ const Dialog = ({ children, className, open, onOpenChange }: PropsWithChildren ) +Dialog.displayName = 'Dialog' const Dropdown = ({ children, className, open, onOpenChange }: PropsWithChildren) => ( @@ -56,6 +58,7 @@ const Dropdown = ({ children, className, open, onOpenChange }: PropsWithChildren ) +Dropdown.displayName = 'Dropdown' const Input = React.forwardRef< React.ElementRef, @@ -75,6 +78,7 @@ const Input = React.forwardRef<
)) +Input.displayName = 'Input' const List = React.forwardRef< React.ElementRef, @@ -86,11 +90,13 @@ const List = React.forwardRef< {...props} /> )) +List.displayName = 'List' const Empty = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >((props, ref) => ) +Empty.displayName = 'Empty' const Group = React.forwardRef< React.ElementRef, @@ -105,6 +111,7 @@ const Group = React.forwardRef< {...props} /> )) +Group.displayName = 'Group' const Item = React.forwardRef< React.ElementRef, @@ -119,6 +126,7 @@ const Item = React.forwardRef< {...props} /> )) +Item.displayName = 'Item' const Separator = React.forwardRef< React.ElementRef, @@ -126,6 +134,7 @@ const Separator = React.forwardRef< >(({ className, ...props }, ref) => ( )) +Separator.displayName = 'Separator' const Shortcut = ({ className, ...props }: React.HTMLAttributes) => { return ( @@ -138,6 +147,7 @@ const Shortcut = ({ className, ...props }: React.HTMLAttributes /> ) } +Shortcut.displayName = 'Shortcut' export const CommandPalette = { Root, From 18d68cdf1a7e83d41ffda34faf174587096a2212 Mon Sep 17 00:00:00 2001 From: Vivek Date: Fri, 28 Feb 2025 21:48:16 +0530 Subject: [PATCH 22/23] Fixed user initials --- packages/ui/src/components/navbar-new/sidebar-user.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ui/src/components/navbar-new/sidebar-user.tsx b/packages/ui/src/components/navbar-new/sidebar-user.tsx index f2b6457844..381b527e70 100644 --- a/packages/ui/src/components/navbar-new/sidebar-user.tsx +++ b/packages/ui/src/components/navbar-new/sidebar-user.tsx @@ -48,7 +48,7 @@ export function User({ user, openThemeDialog, openLanguageDialog, handleLogOut,
- SM + {getInitials(userName)}
{userName} From f3755e0566b195e152a235ddfe1ebd71a04203af Mon Sep 17 00:00:00 2001 From: Vivek Date: Fri, 28 Feb 2025 21:53:46 +0530 Subject: [PATCH 23/23] Fixed import --- .../navbar-new/sidebar-search-new/sidebar-search-new.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/ui/src/components/navbar-new/sidebar-search-new/sidebar-search-new.tsx b/packages/ui/src/components/navbar-new/sidebar-search-new/sidebar-search-new.tsx index f93011a32e..3c93400a56 100644 --- a/packages/ui/src/components/navbar-new/sidebar-search-new/sidebar-search-new.tsx +++ b/packages/ui/src/components/navbar-new/sidebar-search-new/sidebar-search-new.tsx @@ -1,10 +1,9 @@ import { FormHTMLAttributes, ReactNode } from 'react' +import { Button, Input, Label } from '@/components' import { Icon } from '@components/icon' import { Sidebar } from '@components/sidebar/sidebar' -import { Button, Input, Label } from '@harnessio/ui/components' - import { useSearch } from './search-context' interface SidebarSearchProps extends FormHTMLAttributes {