2024-04-19 10:50:58 -04:00
|
|
|
import { Popover } from '@headlessui/react'
|
2024-08-02 10:25:42 -04:00
|
|
|
import { useAbsoluteFilePath } from 'hooks/useAbsoluteFilePath'
|
2025-04-01 14:20:42 -07:00
|
|
|
import { useMenuListener } from 'hooks/useMenu'
|
|
|
|
import { createAndOpenNewTutorialProject } from 'lib/desktopFS'
|
2024-08-16 07:15:42 -04:00
|
|
|
import { openExternalBrowserIfDesktop } from 'lib/openWindow'
|
2025-04-01 14:20:42 -07:00
|
|
|
import { PATHS } from 'lib/paths'
|
2024-09-09 18:17:45 -04:00
|
|
|
import { reportRejection } from 'lib/trap'
|
2025-02-21 13:47:36 -05:00
|
|
|
import { settingsActor } from 'machines/appMachine'
|
2025-04-01 14:20:42 -07:00
|
|
|
import { useLocation, useNavigate } from 'react-router-dom'
|
|
|
|
|
2025-03-26 13:03:44 -05:00
|
|
|
import type { WebContentSendPayload } from '../menu/channels'
|
2025-04-01 14:20:42 -07:00
|
|
|
import { CustomIcon } from './CustomIcon'
|
|
|
|
import { useLspContext } from './LspProvider'
|
|
|
|
import Tooltip from './Tooltip'
|
2024-04-19 10:50:58 -04:00
|
|
|
|
|
|
|
const HelpMenuDivider = () => (
|
|
|
|
<div className="h-[1px] bg-chalkboard-110 dark:bg-chalkboard-80" />
|
|
|
|
)
|
|
|
|
|
|
|
|
export function HelpMenu(props: React.PropsWithChildren) {
|
|
|
|
const location = useLocation()
|
2024-08-02 15:38:39 -04:00
|
|
|
const { onProjectOpen } = useLspContext()
|
2024-08-02 10:25:42 -04:00
|
|
|
const filePath = useAbsoluteFilePath()
|
2024-08-09 02:47:25 -04:00
|
|
|
const isInProject = location.pathname.includes(PATHS.FILE)
|
2024-04-19 10:50:58 -04:00
|
|
|
const navigate = useNavigate()
|
|
|
|
|
2025-03-26 13:03:44 -05:00
|
|
|
const resetOnboardingWorkflow = () => {
|
|
|
|
settingsActor.send({
|
|
|
|
type: 'set.app.onboardingStatus',
|
|
|
|
data: {
|
|
|
|
value: '',
|
|
|
|
level: 'user',
|
|
|
|
},
|
|
|
|
})
|
|
|
|
if (isInProject) {
|
|
|
|
navigate(filePath + PATHS.ONBOARDING.INDEX)
|
|
|
|
} else {
|
|
|
|
createAndOpenNewTutorialProject({
|
|
|
|
onProjectOpen,
|
|
|
|
navigate,
|
|
|
|
}).catch(reportRejection)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const cb = (data: WebContentSendPayload) => {
|
|
|
|
if (data.menuLabel === 'Help.Reset onboarding') {
|
|
|
|
resetOnboardingWorkflow()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
useMenuListener(cb)
|
|
|
|
|
2024-04-19 10:50:58 -04:00
|
|
|
return (
|
|
|
|
<Popover className="relative">
|
2024-08-19 20:17:23 -07:00
|
|
|
<Popover.Button
|
|
|
|
className="grid p-0 m-0 border-none rounded-full place-content-center"
|
|
|
|
data-testid="help-button"
|
|
|
|
>
|
2024-04-19 10:50:58 -04:00
|
|
|
<CustomIcon
|
|
|
|
name="questionMark"
|
2024-08-02 10:25:42 -04:00
|
|
|
className="rounded-full w-7 h-7 bg-chalkboard-110 dark:bg-chalkboard-80 text-chalkboard-10"
|
2024-04-19 10:50:58 -04:00
|
|
|
/>
|
2024-07-24 23:33:31 -04:00
|
|
|
<span className="sr-only">Help and resources</span>
|
|
|
|
<Tooltip position="top-right" wrapperClassName="ui-open:hidden">
|
2024-04-19 10:50:58 -04:00
|
|
|
Help and resources
|
|
|
|
</Tooltip>
|
|
|
|
</Popover.Button>
|
|
|
|
<Popover.Panel
|
|
|
|
as="ul"
|
2024-08-02 10:25:42 -04:00
|
|
|
className="absolute right-0 left-auto flex flex-col w-64 gap-1 p-0 py-2 m-0 mb-1 text-sm border border-solid rounded shadow-lg bottom-full align-stretch text-chalkboard-10 dark:text-inherit bg-chalkboard-110 dark:bg-chalkboard-100 border-chalkboard-110 dark:border-chalkboard-80"
|
2024-04-19 10:50:58 -04:00
|
|
|
>
|
|
|
|
<HelpMenuItem
|
|
|
|
as="a"
|
|
|
|
href="https://github.com/KittyCAD/modeling-app/issues/new/choose"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
Report a bug
|
|
|
|
</HelpMenuItem>
|
|
|
|
<HelpMenuItem
|
|
|
|
as="a"
|
|
|
|
href="https://github.com/KittyCAD/modeling-app/discussions"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
Request a feature
|
|
|
|
</HelpMenuItem>
|
|
|
|
<HelpMenuItem
|
|
|
|
as="a"
|
|
|
|
href="https://discord.gg/JQEpHR7Nt2"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
Ask the community
|
|
|
|
</HelpMenuItem>
|
|
|
|
<HelpMenuDivider />
|
|
|
|
<HelpMenuItem
|
|
|
|
as="a"
|
|
|
|
href="https://zoo.dev/docs/kcl-samples"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
KCL code samples
|
|
|
|
</HelpMenuItem>
|
|
|
|
<HelpMenuItem
|
|
|
|
as="a"
|
|
|
|
href="https://zoo.dev/docs/kcl"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
KCL docs
|
|
|
|
</HelpMenuItem>
|
|
|
|
<HelpMenuDivider />
|
|
|
|
<HelpMenuItem
|
|
|
|
as="a"
|
|
|
|
href="https://github.com/KittyCAD/modeling-app/releases"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
Release notes
|
|
|
|
</HelpMenuItem>
|
2024-06-04 13:56:20 -04:00
|
|
|
<HelpMenuItem
|
|
|
|
as="button"
|
2024-08-02 10:25:42 -04:00
|
|
|
onClick={() => {
|
2024-08-09 02:47:25 -04:00
|
|
|
const targetPath = location.pathname.includes(PATHS.FILE)
|
|
|
|
? filePath + PATHS.SETTINGS_KEYBINDINGS
|
|
|
|
: PATHS.HOME + PATHS.SETTINGS_KEYBINDINGS
|
|
|
|
navigate(targetPath)
|
2024-08-02 10:25:42 -04:00
|
|
|
}}
|
2024-08-19 20:17:23 -07:00
|
|
|
data-testid="keybindings-button"
|
2024-06-04 13:56:20 -04:00
|
|
|
>
|
|
|
|
Keyboard shortcuts
|
|
|
|
</HelpMenuItem>
|
2025-03-26 13:03:44 -05:00
|
|
|
<HelpMenuItem as="button" onClick={resetOnboardingWorkflow}>
|
2024-04-19 10:50:58 -04:00
|
|
|
Reset onboarding
|
|
|
|
</HelpMenuItem>
|
|
|
|
</Popover.Panel>
|
|
|
|
</Popover>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
type HelpMenuItemProps =
|
|
|
|
| ({
|
|
|
|
as: 'a'
|
|
|
|
} & React.ComponentProps<'a'>)
|
|
|
|
| ({
|
|
|
|
as: 'button'
|
|
|
|
} & React.ComponentProps<'button'>)
|
|
|
|
|
|
|
|
function HelpMenuItem({
|
|
|
|
as,
|
|
|
|
children,
|
|
|
|
className,
|
|
|
|
...props
|
|
|
|
}: HelpMenuItemProps) {
|
|
|
|
const baseClassName = 'block px-2 py-1 hover:bg-chalkboard-80'
|
|
|
|
return (
|
2024-08-02 10:25:42 -04:00
|
|
|
<li className="p-0 m-0">
|
2024-04-19 10:50:58 -04:00
|
|
|
{as === 'a' ? (
|
2025-01-13 09:30:14 -05:00
|
|
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
2024-04-19 10:50:58 -04:00
|
|
|
<a
|
|
|
|
{...(props as React.ComponentProps<'a'>)}
|
2024-08-16 07:15:42 -04:00
|
|
|
onClick={openExternalBrowserIfDesktop(
|
|
|
|
(props as React.ComponentProps<'a'>).href
|
|
|
|
)}
|
2024-04-19 10:50:58 -04:00
|
|
|
className={`no-underline text-inherit ${baseClassName} ${className}`}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</a>
|
|
|
|
) : (
|
|
|
|
<button
|
|
|
|
{...(props as React.ComponentProps<'button'>)}
|
|
|
|
className={`border-0 p-0 m-0 text-sm w-full rounded-none text-left ${baseClassName} ${className}`}
|
|
|
|
>
|
|
|
|
{children}
|
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
</li>
|
|
|
|
)
|
|
|
|
}
|