Skip to content

Commit

Permalink
feat(3000): Add sites sidebar for Toolbar launching (#16389)
Browse files Browse the repository at this point in the history
* feat(3000): Add sites sidebar for Toolbar launching

* Fix project settings button

* Update UI snapshots for `chromium` (1)

* Rework scene config `plain` to `layout`

* Clarify "Open in new tab"

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
Twixes and github-actions[bot] authored Jul 10, 2023
1 parent 8adac54 commit 72dcf73
Show file tree
Hide file tree
Showing 29 changed files with 282 additions and 26 deletions.
Binary file modified frontend/__snapshots__/posthog-3000-navigation--dark-mode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/posthog-3000-navigation--light-mode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/public/icons/android-chrome-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/public/icons/android-chrome-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/public/icons/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/public/icons/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/public/icons/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 12 additions & 3 deletions frontend/src/layout/navigation-3000/Navigation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@
}

.Navigation3000__scene {
margin: var(--scene-padding-y) var(--scene-padding-x);
// The below is for positioning of the scene-level spinner
// `relative` is for positioning of the scene-level spinner
position: relative;
margin: var(--scene-padding-y) var(--scene-padding-x);
min-height: calc(100vh - var(--breadcrumbs-height) - var(--scene-padding-y) * 2);
overflow-x: hidden;
&.Navigation3000__scene--raw {
--scene-padding-y: 0px;
--scene-padding-x: 0px;
display: flex;
}
}

// Navbar
Expand Down Expand Up @@ -299,7 +305,7 @@
border-bottom-width: 1px;
list-style: none;

&:hover,
&:hover:not([aria-disabled='true']),
&[aria-current='page'] {
opacity: 1;
--sidebar-list-item-background: var(--border-3000);
Expand Down Expand Up @@ -404,6 +410,9 @@
row-gap: 1px;
padding: 0 var(--sidebar-horizontal-padding) 0 var(--sidebar-list-item-inset);
color: inherit !important; // Disable link color
.SidebarListItem[aria-disabled='true'] & {
cursor: default;
}
}

.SidebarListItem__rename {
Expand Down
16 changes: 14 additions & 2 deletions frontend/src/layout/navigation-3000/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,37 @@ import { Sidebar } from './components/Sidebar'
import './Navigation.scss'
import { themeLogic } from './themeLogic'
import { navigation3000Logic } from './navigationLogic'
import clsx from 'clsx'
import { sceneLogic } from 'scenes/sceneLogic'

export function Navigation({ children }: { children: ReactNode }): JSX.Element {
useMountedLogic(themeLogic)
const { sceneConfig } = useValues(sceneLogic)
const { activeNavbarItem } = useValues(navigation3000Logic)

useEffect(() => {
// FIXME: Include debug notice in a non-obstructing way
document.getElementById('bottom-notice')?.remove()
}, [])

if (sceneConfig?.layout === 'plain') {
throw new Error('Navigation should never be rendered for a plain scene')
}

return (
<div className="Navigation3000">
<Navbar />
{activeNavbarItem && <Sidebar key={activeNavbarItem.identifier} navbarItem={activeNavbarItem} />}
<NotebookSideBar>
<main>
<Breadcrumbs />
<div className="Navigation3000__scene">
<div className="Navigation3000__content">{children}</div>
<div
className={clsx(
'Navigation3000__scene',
sceneConfig?.layout === 'app-raw' && 'Navigation3000__scene--raw'
)}
>
{children}
</div>
</main>
</NotebookSideBar>
Expand Down
7 changes: 6 additions & 1 deletion frontend/src/layout/navigation-3000/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { navigation3000Logic } from '../navigationLogic'
import { NAVBAR_ITEMS } from '../navbarItems'
import { themeLogic } from '../themeLogic'
import { NavbarButton } from './NavbarButton'
import { urls } from 'scenes/urls'

export function Navbar(): JSX.Element {
const { user } = useValues(userLogic)
Expand Down Expand Up @@ -91,7 +92,11 @@ export function Navbar(): JSX.Element {
}
placement="right-end"
/>
<NavbarButton icon={<IconSettings />} identifier={Scene.ProjectSettings} />
<NavbarButton
icon={<IconSettings />}
identifier={Scene.ProjectSettings}
to={urls.projectSettings()}
/>
<Popover
overlay={<SitePopoverOverlay />}
visible={isSitePopoverOpen}
Expand Down
13 changes: 12 additions & 1 deletion frontend/src/layout/navigation-3000/components/SidebarList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { IconCheckmark, IconClose, IconEllipsis } from 'lib/lemon-ui/icons'
import { BasicListItem, ExtendedListItem, ExtraListItemContext, SidebarCategory } from '../types'
import React, { useEffect, useMemo, useRef, useState } from 'react'
import { LemonMenu } from 'lib/lemon-ui/LemonMenu'
import { LemonButton, lemonToast } from '@posthog/lemon-ui'
import { LemonButton, LemonTag, lemonToast } from '@posthog/lemon-ui'
import { navigation3000Logic } from '../navigationLogic'
import { captureException } from '@sentry/react'
import { KeyboardShortcut } from './KeyboardShortcut'
Expand Down Expand Up @@ -104,6 +104,16 @@ function SidebarListItem({
if (!item.url || item.isNamePlaceholder) {
formattedName = <i>{formattedName}</i>
}
if (item.tag) {
formattedName = (
<>
{formattedName}
<LemonTag type={item.tag.status} size="small" className="ml-2">
{item.tag.text}
</LemonTag>
</>
)
}

const { onRename } = item
const menuItems = useMemo(() => {
Expand Down Expand Up @@ -264,6 +274,7 @@ function SidebarListItem({
!!item.marker?.status && `SidebarListItem--marker-status-${item.marker.status}`,
'summary' in item && 'SidebarListItem--extended'
)}
aria-disabled={!item.url}
aria-current={active ? 'page' : undefined}
style={style} // eslint-disable-line react/forbid-dom-props
>
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/layout/navigation-3000/navbarItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
IconLive,
IconPerson,
IconRecording,
IconTools,
IconUnverifiedEvent,
} from 'lib/lemon-ui/icons'
import { Scene } from 'scenes/sceneTypes'
Expand All @@ -23,6 +24,7 @@ import { insightsSidebarLogic } from './sidebars/insights'
import { dataManagementSidebarLogic } from './sidebars/dataManagement'
import { annotationsSidebarLogic } from './sidebars/annotations'
import { experimentsSidebarLogic } from './sidebars/experiments'
import { toolbarSidebarLogic } from './sidebars/toolbar'

/** A list of navbar sections with items. */
export const NAVBAR_ITEMS: NavbarItem[][] = [
Expand Down Expand Up @@ -93,6 +95,12 @@ export const NAVBAR_ITEMS: NavbarItem[][] = [
icon: <IconExperiment />,
logic: experimentsSidebarLogic,
},
{
identifier: Scene.ToolbarLaunch,
label: 'Toolbar',
icon: <IconTools />,
logic: toolbarSidebarLogic,
},
],
[
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const dataManagementSidebarLogic = kea<dataManagementSidebarLogicType>([
{
loadEventDefinitions: async ({ startIndex, stopIndex }) => {
if (!startIndex) {
cache.requestedEventDefinitions.length = 0 // Clear cache
cache.requestedEventDefinitions = []
}
for (let i = startIndex; i < stopIndex; i++) {
cache.requestedEventDefinitions[i] = true
Expand All @@ -59,7 +59,7 @@ export const dataManagementSidebarLogic = kea<dataManagementSidebarLogicType>([
{
loadPropertyDefinitions: async ({ startIndex, stopIndex }) => {
if (!startIndex) {
cache.requestedPropertyDefinitions.length = 0 // Clear cache
cache.requestedPropertyDefinitions = []
}
for (let i = startIndex; i < stopIndex; i++) {
cache.requestedPropertyDefinitions[i] = true
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/layout/navigation-3000/sidebars/insights.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export const insightsSidebarLogic = kea<insightsSidebarLogicType>([
listeners(({ values, cache }) => ({
loadInsights: () => {
if (!values.paramsFromFilters.offset) {
cache.requestedInsights.length = 0
cache.requestedInsights = []
}
},
})),
Expand Down
118 changes: 118 additions & 0 deletions frontend/src/layout/navigation-3000/sidebars/toolbar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { connect, kea, path, selectors } from 'kea'
import { sceneLogic } from 'scenes/sceneLogic'
import { Scene } from 'scenes/sceneTypes'
import { urls } from 'scenes/urls'
import { SidebarCategory, BasicListItem } from '../types'
import Fuse from 'fuse.js'
import { subscriptions } from 'kea-subscriptions'
import { navigation3000Logic } from '~/layout/navigation-3000/navigationLogic'
import { FuseSearchMatch } from './utils'
import {
AuthorizedUrlListType,
KeyedAppUrl,
authorizedUrlListLogic,
} from 'lib/components/AuthorizedUrlList/authorizedUrlListLogic'

import type { toolbarSidebarLogicType } from './toolbarType'

const fuse = new Fuse<KeyedAppUrl>([], {
keys: ['url'],
threshold: 0.3,
ignoreLocation: true,
includeMatches: true,
})

export const toolbarSidebarLogic = kea<toolbarSidebarLogicType>([
path(['layout', 'navigation-3000', 'sidebars', 'toolbarSidebarLogic']),
connect(() => ({
values: [
authorizedUrlListLogic({ actionId: null, type: AuthorizedUrlListType.TOOLBAR_URLS }),
['urlsKeyed', 'suggestionsLoading'],
sceneLogic,
['activeScene', 'sceneParams'],
],
actions: [
authorizedUrlListLogic({ actionId: null, type: AuthorizedUrlListType.TOOLBAR_URLS }),
['addUrl', 'removeUrl', 'updateUrl'],
],
})),
selectors(({ actions }) => ({
contents: [
(s) => [s.relevantUrls, s.suggestionsLoading],
(relevantUrls, suggestionsLoading) => [
{
key: 'sites',
title: 'Sites',
loading: suggestionsLoading,
items: relevantUrls.map(
([url, matches]) =>
({
key: url.url,
name: url.url,
url: url.type !== 'suggestion' ? urls.site(url.url) : null,
tag: url.type === 'suggestion' ? { status: 'warning', text: 'SUGGESTION' } : undefined,
searchMatch: matches
? {
matchingFields: matches.map((match) => match.key),
nameHighlightRanges: matches.find((match) => match.key === 'url')?.indices,
}
: null,
onRename:
url.type !== 'suggestion'
? (newUrl) => actions.updateUrl(url.originalIndex, newUrl)
: undefined,
menuItems:
url.type !== 'suggestion'
? (initiateRename) => [
{
items: [
{
to: urls.site(url.url),
targetBlank: true,
label: 'Open with Toolbar in new tab',
},
],
},
{
items: [
{
onClick: initiateRename,
label: 'Edit',
keyboardShortcut: ['enter'],
},
{
onClick: () => actions.removeUrl(url.originalIndex),
status: 'danger',
label: 'Delete site',
},
],
},
]
: [{ onClick: () => actions.addUrl(url.url), label: 'Apply suggestion' }],
} as BasicListItem)
),
} as SidebarCategory,
],
],
activeListItemKey: [
(s) => [s.activeScene, s.sceneParams],
(activeScene, sceneParams) => {
return activeScene === Scene.Site ? decodeURIComponent(sceneParams.params.url) : null
},
],
relevantUrls: [
(s) => [s.urlsKeyed, navigation3000Logic.selectors.searchTerm],
(urlsKeyed, searchTerm): [KeyedAppUrl, FuseSearchMatch[] | null][] => {
if (searchTerm) {
return fuse.search(searchTerm).map((result) => [result.item, result.matches as FuseSearchMatch[]])
}
return urlsKeyed.map((url) => [url, null])
},
],
})),
subscriptions({
urlsKeyed: (urlsKeyed) => {
fuse.setCollection(urlsKeyed)
},
}),
])
9 changes: 7 additions & 2 deletions frontend/src/layout/navigation-3000/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { LemonTagType } from '@posthog/lemon-ui'
import { Logic, LogicWrapper } from 'kea'
import { Dayjs } from 'lib/dayjs'
import { LemonMenuItems } from 'lib/lemon-ui/LemonMenu'
Expand Down Expand Up @@ -76,8 +77,7 @@ export interface BasicListItem {
/** Whether the name is a placeholder (e.g. an insight derived name), in which case it'll be italicized. */
isNamePlaceholder?: boolean
/**
* URL within the app.
* In rare cases this can be explicitly null (e.g. the "Load more" item). Such items are italicized.
* URL within the app. In specific cases this can be null - such items are italicized.
*/
url: string | null
/** An optional marker to highlight item state. */
Expand All @@ -90,6 +90,11 @@ export interface BasicListItem {
*/
status?: 'muted' | 'success' | 'warning' | 'danger' | 'completion'
}
/** An optional tag shown as a suffix of the name. */
tag?: {
status: LemonTagType
text: string
}
/** If search is on, this should be present to convey why this item is included in results. */
searchMatch?: SearchMatch | null
menuItems?: LemonMenuItems | ((initiateRename?: () => void) => LemonMenuItems)
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/layout/navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export function Navigation({ children }: { children: any }): JSX.Element {
<div className="h-screen flex flex-col">
{activeScene !== Scene.Ingestion && <TopBar />}
<SideBar>
<div className={clsx('main-app-content', sceneConfig?.plain && 'main-app-content--plain')}>
{!sceneConfig?.plain && (
<div className={clsx('main-app-content', sceneConfig?.layout === 'plain' && 'main-app-content--plain')}>
{sceneConfig?.layout !== 'plain' && (
<>
<BillingAlertsV2 />
{!sceneConfig?.hideProjectNotice && <ProjectNotice />}
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/layout/navigation/navigationLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@ export const navigationLogic = kea<navigationLogicType>({
}),
selectors: {
/** `bareNav` whether the current scene should display a sidebar at all */
bareNav: [(s) => [s.fullscreen, s.sceneConfig], (fullscreen, sceneConfig) => fullscreen || sceneConfig?.plain],
bareNav: [
(s) => [s.fullscreen, s.sceneConfig],
(fullscreen, sceneConfig) => fullscreen || sceneConfig?.layout === 'plain',
],
isSideBarShown: [
(s) => [s.mobileLayout, s.isSideBarShownBase, s.isSideBarShownMobile, s.bareNav],
(mobileLayout, isSideBarShownBase, isSideBarShownMobile, bareNav) =>
Expand Down
9 changes: 5 additions & 4 deletions frontend/src/lib/lemon-ui/LemonTag/LemonTag.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
background: none;
}

&.LemonTag--size-small {
font-size: 0.625rem;
padding: 0.0625rem 0.1875rem;
}

.LemonTag__icon {
font-size: 0.875rem;
margin-right: 0.125rem;
Expand All @@ -60,8 +65,4 @@
min-height: 1.5rem;
padding: 0.125rem 0.125rem;
}

&.clickable {
cursor: pointer;
}
}
Loading

0 comments on commit 72dcf73

Please sign in to comment.