Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Radix-related fixes, improved main menu + OSM sign-in #465

Merged
merged 28 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
001b55c
Set Biome to use Spaces
opyh Dec 10, 2024
b03dd89
Remove obsolete <FeatureClusterPanel /> component
opyh Dec 10, 2024
63a4556
Fix MapboxGL buttons in dark mode
opyh Dec 10, 2024
85e4d17
Introduce more <AppStateLink /> usages
opyh Dec 10, 2024
5778a7c
Remove obsolete code from <FeatureNameHeader />
opyh Dec 10, 2024
30e6a09
Fix screenreader hint in <SearchPanel />
opyh Dec 10, 2024
a1fe412
Smaller Biome/typing fixes in <SearchPanel />
opyh Dec 10, 2024
d82a3b8
Don't open <ThemePanel /> automatically on start
opyh Dec 11, 2024
1f57980
Make useViewportSize hook SSR compatible
opyh Dec 11, 2024
09414ed
Refactor/fix main menu
opyh Dec 11, 2024
b78cac1
Use `l` hotkey again for expert / OSM mode
opyh Dec 11, 2024
fb5ce2e
Improve `useExpertMode()` readability
opyh Dec 11, 2024
9c21b4e
Use Radix theme colors for category and filter buttons
opyh Dec 11, 2024
5dc255c
Merge remote-tracking branch 'origin/feature/a11ymap' into feature/a1…
opyh Dec 16, 2024
ae48904
Allow to show links directly in the main toolbar again
opyh Dec 16, 2024
fca8c16
Radix-ify the onboarding
opyh Dec 16, 2024
beb5703
Fix a linter error in App.ts
opyh Dec 16, 2024
2e5a225
Improve main menu styling, add responsive breakpoint
opyh Dec 16, 2024
160dc6e
Fix a React hydration error & main menu keyboard focus
opyh Dec 17, 2024
38bf04b
Add biome as default VSCode formatter
opyh Dec 17, 2024
9a12c20
Code cosmetics for main menu 💅
opyh Dec 17, 2024
5d63509
Fix 'location failed' wording
opyh Dec 17, 2024
d903fa7
Fix a smol comment
opyh Dec 17, 2024
97a28e2
Fix a wrongly import()ed type
opyh Dec 17, 2024
ebc9625
Improve docs for useIsomorphicLayoutEffect.tsx
opyh Dec 17, 2024
05ef70f
Wrap <AppStateLink /> with React.forwardRef
opyh Dec 30, 2024
d9874cc
Improve session menu element when logged in with OSM
opyh Dec 30, 2024
c6e4245
Use <a> tag in <JoinedEventLink /> correctly
opyh Dec 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
"indentStyle": "space"
kriskbx marked this conversation as resolved.
Show resolved Hide resolved
},
"organizeImports": {
"enabled": true
Expand Down
14 changes: 14 additions & 0 deletions src/components/App/MainMenu/AppLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type Link from "next/link";
import type { ComponentProps } from "react";
import { AppStateLink } from "../AppStateLink";
import { Button, DropdownMenu } from "@radix-ui/themes";

export default function AppLink(props: ComponentProps<typeof Link> & { buttonProps?: ComponentProps<typeof Button>}) {
const { buttonProps, children } = props

return <DropdownMenu.Item asChild>
<AppStateLink {...props}>
{children}
</AppStateLink>
</DropdownMenu.Item>
}
146 changes: 68 additions & 78 deletions src/components/App/MainMenu/AppLinks.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { useHotkeys } from '@blueprintjs/core'
import Link from 'next/link'
import { useMemo, useState } from 'react'
import React from 'react'
import styled from 'styled-components'
import { useCurrentApp } from '../../../lib/context/AppContext'
import { useCurrentMappingEvent } from '../../../lib/context/useCurrentMappingEvent'
import { useUniqueSurveyId } from '../../../lib/context/useUniqueSurveyId'
import { translatedStringFromObject } from '../../../lib/i18n/translatedStringFromObject'
import { insertPlaceholdersToAddPlaceUrl } from '../../../lib/model/ac/insertPlaceholdersToAddPlaceUrl'
import Spinner from '../../ActivityIndicator/Spinner'
import SessionLink from '../../Session/SessionLink'
import SessionMenuItem from './SessionMenuItem'
import type { ButtonProps } from '@radix-ui/themes'
import AppLink from './AppLink'
import { useExpertMode } from './useExpertMode'
import type { IApp } from '../../../lib/model/ac/App'
import type { MappingEvent } from '../../../lib/model/ac/MappingEvent'

const Badge = styled.span`
border-radius: 0.5rlh;
Expand All @@ -18,7 +21,7 @@ const Badge = styled.span`
margin: 0.1rem;
`

function JoinedEventLink(props: { label: string | null; url: string | null }) {
function JoinedEventLink(props: { label?: string; url?: string }) {
const { data: joinedMappingEvent, isValidating } = useCurrentMappingEvent()

if (isValidating) {
Expand All @@ -32,89 +35,76 @@ function JoinedEventLink(props: { label: string | null; url: string | null }) {
const label = joinedMappingEvent ? joinedMappingEvent.name : props.label

return (
<Link href={href} role="menuitem" className="nav-link">
<AppLink href={href} role="menuitem" className="nav-link">
{label}
</Link>
</AppLink>
)
}

export default function AppLinks(props: {}) {
function expandLinkMetadata(link: IApp['related']['appLinks'][string], app: IApp, joinedMappingEvent?: MappingEvent, uniqueSurveyId: string) {
const baseUrl = `https://${app._id}/`
const localizedUrl = translatedStringFromObject(link.url);
const url = link.url
&& insertPlaceholdersToAddPlaceUrl(
baseUrl,
localizedUrl,
joinedMappingEvent,
uniqueSurveyId,
)
const label = translatedStringFromObject(link.label)
const badgeLabel = translatedStringFromObject(link.badgeLabel)
const isExternal = localizedUrl?.startsWith('http')
return {
...link,
url,
label,
badgeLabel,
isExternal,
}
}

export default function AppLinks() {
const { data: joinedMappingEvent } = useCurrentMappingEvent()
const app = useCurrentApp()
const baseUrl = `https://${app._id}/`
const uniqueSurveyId = useUniqueSurveyId()

const {
related: { appLinks },
related: { appLinks } = {},
} = app

const [toogle, setToggle] = useState(false)
const hotkeys = useMemo(() => [
{
combo: 'l',
global: true,
label: 'Toggle OSM Power User Mode',
onKeyDown: () => setToggle(!toogle),
},

], [toogle])
const { handleKeyDown } = useHotkeys(hotkeys)

const links = Object.values(appLinks)
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((link) => {
const url = link.url
&& insertPlaceholdersToAddPlaceUrl(
baseUrl,
translatedStringFromObject(link.url),
joinedMappingEvent,
uniqueSurveyId,
)
const label = translatedStringFromObject(link.label)
const badgeLabel = translatedStringFromObject(link.badgeLabel)
const classNamesFromTags = link.tags && link.tags.map((tag) => `${tag}-link`)
const className = ['nav-link'].concat(classNamesFromTags).join(' ')

const isAddPlaceLink = link.tags && link.tags.indexOf('add-place') !== -1
const isAddPlaceLinkWithoutCustomUrl = isAddPlaceLink && (!url || url == '/add-place')

if (isAddPlaceLinkWithoutCustomUrl) {
return (
<Link
key="add-place"
href="/node/create"
className={className}
role="menuitem"
>
{label}
{badgeLabel && <Badge>{badgeLabel}</Badge>}
</Link>
)
}

const isEventsLink = link.tags && link.tags.indexOf('events') !== -1
if (isEventsLink) {
return <JoinedEventLink {...{ label, url }} key="joined-event" />
}

const isSessionLink = link.tags && link.tags.indexOf('session') !== -1
if (isSessionLink) {
return (
toogle && <SessionLink {...{ label }} key="session" className={className} onKeyDown={handleKeyDown} />
)
}

if (typeof url === 'string') {
return (
<Link key={url} href={url} className={className} role="menuitem">
{label}
{badgeLabel && <Badge>{badgeLabel}</Badge>}
</Link>
)
}

return null
})
const { isExpertMode } = useExpertMode()

const links = React.useMemo(
() => Object.values(appLinks ?? {})
.sort((a, b) => (a.order || 0) - (b.order || 0))
.map((link) => expandLinkMetadata(link, app, joinedMappingEvent, uniqueSurveyId))
.map(({ tags, label, badgeLabel, url }) => {
const isEventsLink = tags?.includes('events')
if (isEventsLink) {
return <JoinedEventLink {...{ label, url }} key="joined-event" />
}

const isSessionLink = tags?.includes('session')
if (isSessionLink) {
return (
isExpertMode && <SessionMenuItem {...{ label }} key="session" />
)
}

if (typeof url === 'string') {
const buttonProps: ButtonProps = {
variant: tags?.includes('primary') ? 'solid' : 'soft',
highContrast: true,
};
return (
<AppLink key={url} href={url} role="menuitem" buttonProps={buttonProps}>
{label}
{badgeLabel && <Badge>{badgeLabel}</Badge>}
</AppLink>
)
}

return null
}), [app, appLinks, isExpertMode, joinedMappingEvent, uniqueSurveyId]);

return <>{links}</>
}
Loading