Add feeds to dropdown menu
This commit is contained in:
@ -4,11 +4,8 @@ import { Box, HStack } from './LayoutPrimitives'
|
||||
import { StyledText } from './StyledText'
|
||||
import {
|
||||
LabelColorDropdownProps,
|
||||
LabelColorObject,
|
||||
LabelOptionProps,
|
||||
} from '../../utils/settings-page/labels/types'
|
||||
import { labelColorObjects } from '../../utils/settings-page/labels/labelColorObjects'
|
||||
import { LabelColor } from '../../lib/networking/fragments/labelFragment'
|
||||
import { TwitterPicker } from 'react-color'
|
||||
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
|
||||
|
||||
|
||||
@ -1,99 +0,0 @@
|
||||
import { ReactNode, useMemo, useState } from 'react'
|
||||
import { HStack, VStack } from './../elements/LayoutPrimitives'
|
||||
import { Dropdown, DropdownOption } from '../elements/DropdownElements'
|
||||
import { StyledText } from '../elements/StyledText'
|
||||
import { Button } from '../elements/Button'
|
||||
import { currentThemeName } from '../../lib/themeUpdater'
|
||||
import { Check } from 'phosphor-react'
|
||||
|
||||
export type HeaderDropdownAction =
|
||||
| 'apply-dark-theme'
|
||||
| 'apply-light-theme'
|
||||
| 'navigate-to-install'
|
||||
| 'navigate-to-emails'
|
||||
| 'navigate-to-labels'
|
||||
| 'navigate-to-profile'
|
||||
| 'navigate-to-subscriptions'
|
||||
| 'navigate-to-api'
|
||||
| 'navigate-to-integrations'
|
||||
| 'increaseFontSize'
|
||||
| 'decreaseFontSize'
|
||||
| 'logout'
|
||||
|
||||
type DropdownMenuProps = {
|
||||
username?: string
|
||||
triggerElement: ReactNode
|
||||
actionHandler: (action: HeaderDropdownAction) => void
|
||||
}
|
||||
|
||||
export function DropdownMenu(props: DropdownMenuProps): JSX.Element {
|
||||
const [currentTheme, setCurrentTheme] = useState(currentThemeName())
|
||||
|
||||
const isDark = useMemo(() => {
|
||||
return currentTheme === 'Dark' || currentTheme === 'Darker'
|
||||
}, [currentTheme])
|
||||
|
||||
return (
|
||||
<Dropdown triggerElement={props.triggerElement}>
|
||||
<VStack css={{ py: '12px', px: '24px' }}>
|
||||
<StyledText style="menuTitle">Theme</StyledText>
|
||||
<HStack css={{ py: '8px', width: '100%', gap: '25px' }}>
|
||||
<Button
|
||||
style="themeSwitch"
|
||||
css={{ background: '#FFFFFF' }}
|
||||
data-state={isDark ? 'unselected' : 'selected'}
|
||||
onClick={() => {
|
||||
props.actionHandler('apply-light-theme')
|
||||
setCurrentTheme(currentThemeName())
|
||||
}}
|
||||
>
|
||||
{!isDark && <Check color="#F9D354" size={32} />}
|
||||
</Button>
|
||||
<Button
|
||||
style="themeSwitch"
|
||||
css={{ background: '#3D3D3D' }}
|
||||
data-state={isDark ? 'selected' : 'unselected'}
|
||||
onClick={() => {
|
||||
props.actionHandler('apply-dark-theme')
|
||||
setCurrentTheme(currentThemeName())
|
||||
}}
|
||||
>
|
||||
{isDark && <Check color="#F9D354" size={32} />}
|
||||
</Button>
|
||||
</HStack>
|
||||
</VStack>
|
||||
<DropdownOption
|
||||
onSelect={() => props.actionHandler('navigate-to-install')}
|
||||
title="Install"
|
||||
/>
|
||||
<DropdownOption
|
||||
onSelect={() => props.actionHandler('navigate-to-emails')}
|
||||
title="Emails"
|
||||
/>
|
||||
<DropdownOption
|
||||
onSelect={() => props.actionHandler('navigate-to-labels')}
|
||||
title="Labels"
|
||||
/>
|
||||
<DropdownOption
|
||||
onSelect={() => props.actionHandler('navigate-to-api')}
|
||||
title="API Keys"
|
||||
/>
|
||||
<DropdownOption
|
||||
onSelect={() => props.actionHandler('navigate-to-integrations')}
|
||||
title="Integrations"
|
||||
/>
|
||||
<DropdownOption
|
||||
onSelect={() => window.open('https://docs.omnivore.app', '_blank')}
|
||||
title="Documentation"
|
||||
/>
|
||||
<DropdownOption
|
||||
onSelect={() => window.Intercom('show')}
|
||||
title="Feedback"
|
||||
/>
|
||||
<DropdownOption
|
||||
onSelect={() => props.actionHandler('logout')}
|
||||
title="Logout"
|
||||
/>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
@ -26,19 +26,17 @@ type PrimaryDropdownProps = {
|
||||
updateLayout?: (layout: LayoutType) => void
|
||||
|
||||
showAddLinkModal?: () => void
|
||||
startSelectMultiple?: () => void
|
||||
}
|
||||
|
||||
export type HeaderDropdownAction =
|
||||
| 'navigate-to-install'
|
||||
| 'navigate-to-feeds'
|
||||
| 'navigate-to-emails'
|
||||
| 'navigate-to-labels'
|
||||
| 'navigate-to-profile'
|
||||
| 'navigate-to-subscriptions'
|
||||
| 'navigate-to-api'
|
||||
| 'navigate-to-integrations'
|
||||
| 'increaseFontSize'
|
||||
| 'decreaseFontSize'
|
||||
| 'logout'
|
||||
|
||||
export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element {
|
||||
@ -51,6 +49,9 @@ export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element {
|
||||
case 'navigate-to-install':
|
||||
router.push('/settings/installation')
|
||||
break
|
||||
case 'navigate-to-feeds':
|
||||
router.push('/settings/feeds')
|
||||
break
|
||||
case 'navigate-to-emails':
|
||||
router.push('/settings/emails')
|
||||
break
|
||||
@ -149,6 +150,10 @@ export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element {
|
||||
onSelect={() => headerDropdownActionHandler('navigate-to-install')}
|
||||
title="Install"
|
||||
/>
|
||||
<DropdownOption
|
||||
onSelect={() => headerDropdownActionHandler('navigate-to-feeds')}
|
||||
title="Feeds"
|
||||
/>
|
||||
<DropdownOption
|
||||
onSelect={() => headerDropdownActionHandler('navigate-to-emails')}
|
||||
title="Emails"
|
||||
@ -167,17 +172,6 @@ export function PrimaryDropdown(props: PrimaryDropdownProps): JSX.Element {
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{props.startSelectMultiple && (
|
||||
<>
|
||||
<DropdownOption
|
||||
onSelect={() =>
|
||||
props.startSelectMultiple && props.startSelectMultiple()
|
||||
}
|
||||
title="Select Multiple"
|
||||
/>
|
||||
<DropdownSeparator />
|
||||
</>
|
||||
)}
|
||||
<DropdownOption
|
||||
onSelect={() => headerDropdownActionHandler('navigate-to-api')}
|
||||
title="API Keys"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react"
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives'
|
||||
import { theme } from '../../tokens/stitches.config'
|
||||
import { FormInput } from '../../elements/FormElements'
|
||||
@ -54,7 +54,11 @@ type LibraryHeaderProps = {
|
||||
|
||||
performMultiSelectAction: (action: BulkAction, labelIds?: string[]) => void
|
||||
|
||||
handleLinkSubmission: (link: string, timezone: string, locale:string) => Promise<void>,
|
||||
handleLinkSubmission: (
|
||||
link: string,
|
||||
timezone: string,
|
||||
locale: string
|
||||
) => Promise<void>
|
||||
}
|
||||
|
||||
export function LibraryHeader(props: LibraryHeaderProps): JSX.Element {
|
||||
@ -220,15 +224,20 @@ export type SearchBoxProps = {
|
||||
|
||||
compact?: boolean
|
||||
onClose?: () => void
|
||||
handleLinkSubmission: (link: string, timezone: string, locale:string) => Promise<void>,
|
||||
handleLinkSubmission: (
|
||||
link: string,
|
||||
timezone: string,
|
||||
locale: string
|
||||
) => Promise<void>
|
||||
}
|
||||
|
||||
export function SearchBox(props: SearchBoxProps): JSX.Element {
|
||||
const inputRef = useRef<HTMLInputElement | null>(null)
|
||||
const [focused, setFocused] = useState(false)
|
||||
const [searchTerm, setSearchTerm] = useState(props.searchTerm ?? '')
|
||||
const [isAddAction, setIsAddAction] = useState(false);
|
||||
const IS_URL_REGEX = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
|
||||
const [isAddAction, setIsAddAction] = useState(false)
|
||||
const IS_URL_REGEX =
|
||||
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/
|
||||
|
||||
useEffect(() => {
|
||||
setSearchTerm(props.searchTerm ?? '')
|
||||
@ -284,22 +293,23 @@ export function SearchBox(props: SearchBoxProps): JSX.Element {
|
||||
e.preventDefault()
|
||||
}}
|
||||
>
|
||||
{
|
||||
(() => {
|
||||
if (isAddAction) {
|
||||
return <Plus
|
||||
{(() => {
|
||||
if (isAddAction) {
|
||||
return (
|
||||
<Plus
|
||||
size={props.compact ? 15 : 20}
|
||||
color={theme.colors.graySolid.toString()}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return <MagnifyingGlass
|
||||
return (
|
||||
<MagnifyingGlass
|
||||
size={props.compact ? 15 : 20}
|
||||
color={theme.colors.graySolid.toString()}
|
||||
/>
|
||||
})()
|
||||
}
|
||||
|
||||
)
|
||||
})()}
|
||||
</HStack>
|
||||
<form
|
||||
onSubmit={async (event) => {
|
||||
@ -308,9 +318,9 @@ export function SearchBox(props: SearchBoxProps): JSX.Element {
|
||||
if (!isAddAction) {
|
||||
props.applySearchQuery(searchTerm || '')
|
||||
} else {
|
||||
await props.handleLinkSubmission(searchTerm, timeZone, locale)
|
||||
setSearchTerm(props.searchTerm ?? "")
|
||||
props.applySearchQuery(props.searchTerm ?? "")
|
||||
await props.handleLinkSubmission(searchTerm, timeZone, locale)
|
||||
setSearchTerm(props.searchTerm ?? '')
|
||||
props.applySearchQuery(props.searchTerm ?? '')
|
||||
}
|
||||
inputRef.current?.blur()
|
||||
if (props.onClose) {
|
||||
@ -408,7 +418,11 @@ type ControlButtonBoxProps = {
|
||||
searchTerm: string | undefined
|
||||
applySearchQuery: (searchQuery: string) => void
|
||||
|
||||
handleLinkSubmission: (link: string, timezone: string, locale:string) => Promise<void>,
|
||||
handleLinkSubmission: (
|
||||
link: string,
|
||||
timezone: string,
|
||||
locale: string
|
||||
) => Promise<void>
|
||||
}
|
||||
|
||||
function MultiSelectControls(props: ControlButtonBoxProps): JSX.Element {
|
||||
@ -517,13 +531,6 @@ function SearchControlButtonBox(
|
||||
</Button>
|
||||
<PrimaryDropdown
|
||||
showThemeSection={true}
|
||||
startSelectMultiple={
|
||||
props.allowSelectMultiple
|
||||
? () => {
|
||||
props.setMultiSelectMode('none')
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
showAddLinkModal={props.showAddLinkModal}
|
||||
/>
|
||||
</>
|
||||
@ -702,9 +709,6 @@ function ControlButtonBox(props: ControlButtonBoxProps): JSX.Element {
|
||||
layout={props.layout}
|
||||
updateLayout={props.updateLayout}
|
||||
showAddLinkModal={props.showAddLinkModal}
|
||||
startSelectMultiple={() => {
|
||||
props.setMultiSelectMode('none')
|
||||
}}
|
||||
/>
|
||||
</HStack>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user