2025-04-01 23:54:26 -07:00
|
|
|
import type { IconDefinition } from '@fortawesome/free-solid-svg-icons'
|
2024-04-15 12:04:17 -04:00
|
|
|
import { Resizable } from 're-resizable'
|
2025-04-01 23:54:26 -07:00
|
|
|
import type { MouseEventHandler } from 'react'
|
|
|
|
import { useCallback, useContext, useEffect, useMemo } from 'react'
|
2024-04-15 12:04:17 -04:00
|
|
|
import { useHotkeys } from 'react-hotkeys-hook'
|
2025-04-01 23:54:26 -07:00
|
|
|
|
2025-04-10 20:08:39 -04:00
|
|
|
import { useAppState } from '@src/AppState'
|
2025-04-01 23:54:26 -07:00
|
|
|
import { ActionIcon } from '@src/components/ActionIcon'
|
|
|
|
import type { CustomIconName } from '@src/components/CustomIcon'
|
|
|
|
import { MachineManagerContext } from '@src/components/MachineManagerProvider'
|
|
|
|
import { ModelingPane } from '@src/components/ModelingSidebar/ModelingPane'
|
|
|
|
import type {
|
|
|
|
SidebarAction,
|
|
|
|
SidebarType,
|
|
|
|
} from '@src/components/ModelingSidebar/ModelingPanes'
|
|
|
|
import { sidebarPanes } from '@src/components/ModelingSidebar/ModelingPanes'
|
|
|
|
import Tooltip from '@src/components/Tooltip'
|
|
|
|
import { useModelingContext } from '@src/hooks/useModelingContext'
|
2025-04-10 20:08:39 -04:00
|
|
|
import { useNetworkContext } from '@src/hooks/useNetworkContext'
|
|
|
|
import { NetworkHealthState } from '@src/hooks/useNetworkStatus'
|
2025-04-01 23:54:26 -07:00
|
|
|
import { useKclContext } from '@src/lang/KclProvider'
|
2025-04-10 20:08:39 -04:00
|
|
|
import { EngineConnectionStateType } from '@src/lang/std/engineConnection'
|
2025-04-01 23:54:26 -07:00
|
|
|
import { SIDEBAR_BUTTON_SUFFIX } from '@src/lib/constants'
|
|
|
|
import { isDesktop } from '@src/lib/isDesktop'
|
2025-04-24 13:32:49 -05:00
|
|
|
import { useSettings } from '@src/lib/singletons'
|
|
|
|
import { commandBarActor } from '@src/lib/singletons'
|
2025-04-23 15:20:45 -04:00
|
|
|
import { reportRejection } from '@src/lib/trap'
|
|
|
|
import { refreshPage } from '@src/lib/utils'
|
|
|
|
import { hotkeyDisplay } from '@src/lib/hotkeyWrapper'
|
|
|
|
import usePlatform from '@src/hooks/usePlatform'
|
[Feature]: Load external model becomes Add file to project, global application add file to project with home page update. (#6506)
* chore: saving off skeleton
* fix: saving skeleton
* chore: skeleton for loading projects from project directory path
* chore: cleaning up useless state transition to be an on event direct to action state
* fix: new structure for web vs desktop vs react machine provider code
* chore: saving off skeleton
* fix: skeleton logic for react? going to move it from a string to obj.string
* fix: trying to prevent error element unmount on global react components. This is bricking JS state
* fix: we are so back
* chore: implemented navigating to specfic KCL file
* chore: implementing renaming project
* chore: deleting project
* fix: auto fixes
* fix: old debug/testing file oops
* chore: generic create new file
* chore: skeleton for web create file provide
* chore: basic machine vitest... need to figure out how to get window.electron implemented in vitest?
* chore: save off progress before deleting other project implementation, a few missing features still
* chore: trying a different init skeleton? most likely will migrate
* chore: first attempt of purging projects context provider
* chore: enabling toast for some machine state
* chore: enabling more toast success and error
* chore: writing read write state to the system io based on the project path
* fix: tsc fixes
* fix: use file system watcher, navigate to project after creation via the requestProjectName
* chore: open project command, hooks vs snapshot context helpers
* chore: implemented open and create project for e2e testing. They are hard coded in poor spot for now.
* fix: codespell fixes
* chore: implementing more project commands
* chore: PR improvements for root.tsx
* chore: leaving comment about new Router.tsx layout
* fix: removing debugging code
* fix: rewriting component for readability
* fix: improving web initialization
* chore: implementing import file from url which is not actually that?
* fix: clearing search params on import file from url
* fix: fixed two e2e tests, forgot needsReview when making new command
* fix: fixing some import from url business logic to pass e2e tests
* chore: script for diffing circular deps +/-
* fix: formatting
* fix: massive fix for circular depsga!
* fix: trying to fix some errors and auto fmt
* fix: updating deps
* fix: removing debugging code
* fix: big clean up
* fix: more deletion
* fix: tsc cleanup
* fix: TSC TSC TSC TSC!
* fix: typo fix
* fix: clear query params on web only, desktop not required
* fix: removing unused code
* fmt
* Bring back `trap` removed in merge
* Use explicit types instead of `any`s on arg configs
* Add project commands directly to command palette
* fix: deleting debugging code, from PR review
* fix: this got added back(?)
* fix: using referred type
* fix: more PR clean up
* fix: big block comment for xstate architecture decision
* fix: more pr comment fixes
* fix: saving off logic, need a big cleanup because I hacked it together to get a POC
* fix: extra business?
* fix: merge conflict just added them back why dude
* fix: more PR comments
* fix: big ciruclar deps fix, commandBarActor in appActor
* chore: writing e2e test, still need to fix 3 bugs
* chore: adding more scenarios
* fix: formatting
* fix: fixing tsc errors
* chore: deleting the old text to cad and using the new application level one, almost there
* fix: prompt to edit works
* fix: large push to get 1 text to cad command... the usage is a little buggy with delete and navigate within /file
* fix: settings for highlight edges now works
* chore: adding another e2e test
* fix: cleaning up e2e tests and writing more of them
* fix: tsc type
* chore: more e2e improvements, unique project name in text to cad
* chore: e2e tests should be good to go
* fix: gotcha comment
* fix: enabled web t2c, codespell fixes
* fix: fixing merge conflcits??
* feat: implemented load external for kcl samples
* feat: load external model from disk
* fix: trying to delete old stuff
* fix: all command trigger locations now have defaults for current project
* fix: gotcha comment for the future
* chore: hiding import file from url command, two separate commands for 3d and kcl file adding
* chore: commands are now add file to project, 3rd iteration
* fix: t2c in file menu fixed
* chore: updating file menu for new global actions
* fix: auto fixes
* fix: the command bar arg flow for web add kcl file seems backwards?
* chore: updated home layout, added create from kcl sample button
* chore: remapping some menu actions
* fix: fixing open dialog copy
* fix: an e2e test
* fix: fixed e2e tests
* fix: fixed e2e tests
* fix: auto fixes
* fix: pr clean up
* fix: removing console log
* fix: PR updates
* fix: the reviewed stage boolean required the expected state to change. Also I progressed the command bar too soon
* fix: no idea how this passed locally yesterday? I removed the {dir} unused but I need the function's logic but not the return value...
* fix: should be good to go?
---------
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-04-29 13:04:45 -05:00
|
|
|
import { settingsActor } from '@src/lib/singletons'
|
2024-04-15 12:04:17 -04:00
|
|
|
|
2024-08-04 15:59:04 -07:00
|
|
|
interface BadgeInfoComputed {
|
2025-02-25 13:18:59 -06:00
|
|
|
value: number | boolean | string
|
2024-08-04 15:59:04 -07:00
|
|
|
onClick?: MouseEventHandler<any>
|
2025-02-25 13:18:59 -06:00
|
|
|
className?: string
|
|
|
|
title?: string
|
2024-08-04 15:59:04 -07:00
|
|
|
}
|
|
|
|
|
2024-09-13 14:49:33 -04:00
|
|
|
function getPlatformString(): 'web' | 'desktop' {
|
|
|
|
return isDesktop() ? 'desktop' : 'web'
|
|
|
|
}
|
|
|
|
|
2025-05-08 20:37:21 -04:00
|
|
|
export function ModelingSidebar() {
|
2024-10-25 19:28:10 -04:00
|
|
|
const machineManager = useContext(MachineManagerContext)
|
2024-07-31 23:29:24 -04:00
|
|
|
const kclContext = useKclContext()
|
2025-02-21 13:47:36 -05:00
|
|
|
const settings = useSettings()
|
2024-07-24 22:02:16 -04:00
|
|
|
const { send, context } = useModelingContext()
|
2024-04-15 12:04:17 -04:00
|
|
|
const pointerEventsCssClass =
|
2024-07-02 17:16:27 +10:00
|
|
|
context.store?.openPanes.length === 0
|
2024-04-15 12:04:17 -04:00
|
|
|
? 'pointer-events-none '
|
2024-04-15 21:40:45 -04:00
|
|
|
: 'pointer-events-auto '
|
2025-02-28 16:15:57 -08:00
|
|
|
const showDebugPanel = settings.app.showDebugPanel
|
2024-07-24 22:02:16 -04:00
|
|
|
|
2025-04-10 20:08:39 -04:00
|
|
|
const { overallState, immediateState } = useNetworkContext()
|
|
|
|
const { isExecuting } = useKclContext()
|
|
|
|
const { isStreamReady } = useAppState()
|
|
|
|
const reliesOnEngine =
|
|
|
|
(overallState !== NetworkHealthState.Ok &&
|
|
|
|
overallState !== NetworkHealthState.Weak) ||
|
|
|
|
isExecuting ||
|
|
|
|
immediateState.type !== EngineConnectionStateType.ConnectionEstablished ||
|
|
|
|
!isStreamReady
|
|
|
|
|
2024-09-13 14:49:33 -04:00
|
|
|
const paneCallbackProps = useMemo(
|
|
|
|
() => ({
|
|
|
|
kclContext,
|
2025-02-21 13:47:36 -05:00
|
|
|
settings,
|
2024-09-13 14:49:33 -04:00
|
|
|
platform: getPlatformString(),
|
|
|
|
}),
|
2025-02-21 13:47:36 -05:00
|
|
|
[kclContext.diagnostics, settings]
|
2024-09-13 14:49:33 -04:00
|
|
|
)
|
|
|
|
|
2024-07-24 22:02:16 -04:00
|
|
|
const sidebarActions: SidebarAction[] = [
|
2025-04-07 16:28:11 -04:00
|
|
|
{
|
[Feature]: Load external model becomes Add file to project, global application add file to project with home page update. (#6506)
* chore: saving off skeleton
* fix: saving skeleton
* chore: skeleton for loading projects from project directory path
* chore: cleaning up useless state transition to be an on event direct to action state
* fix: new structure for web vs desktop vs react machine provider code
* chore: saving off skeleton
* fix: skeleton logic for react? going to move it from a string to obj.string
* fix: trying to prevent error element unmount on global react components. This is bricking JS state
* fix: we are so back
* chore: implemented navigating to specfic KCL file
* chore: implementing renaming project
* chore: deleting project
* fix: auto fixes
* fix: old debug/testing file oops
* chore: generic create new file
* chore: skeleton for web create file provide
* chore: basic machine vitest... need to figure out how to get window.electron implemented in vitest?
* chore: save off progress before deleting other project implementation, a few missing features still
* chore: trying a different init skeleton? most likely will migrate
* chore: first attempt of purging projects context provider
* chore: enabling toast for some machine state
* chore: enabling more toast success and error
* chore: writing read write state to the system io based on the project path
* fix: tsc fixes
* fix: use file system watcher, navigate to project after creation via the requestProjectName
* chore: open project command, hooks vs snapshot context helpers
* chore: implemented open and create project for e2e testing. They are hard coded in poor spot for now.
* fix: codespell fixes
* chore: implementing more project commands
* chore: PR improvements for root.tsx
* chore: leaving comment about new Router.tsx layout
* fix: removing debugging code
* fix: rewriting component for readability
* fix: improving web initialization
* chore: implementing import file from url which is not actually that?
* fix: clearing search params on import file from url
* fix: fixed two e2e tests, forgot needsReview when making new command
* fix: fixing some import from url business logic to pass e2e tests
* chore: script for diffing circular deps +/-
* fix: formatting
* fix: massive fix for circular depsga!
* fix: trying to fix some errors and auto fmt
* fix: updating deps
* fix: removing debugging code
* fix: big clean up
* fix: more deletion
* fix: tsc cleanup
* fix: TSC TSC TSC TSC!
* fix: typo fix
* fix: clear query params on web only, desktop not required
* fix: removing unused code
* fmt
* Bring back `trap` removed in merge
* Use explicit types instead of `any`s on arg configs
* Add project commands directly to command palette
* fix: deleting debugging code, from PR review
* fix: this got added back(?)
* fix: using referred type
* fix: more PR clean up
* fix: big block comment for xstate architecture decision
* fix: more pr comment fixes
* fix: saving off logic, need a big cleanup because I hacked it together to get a POC
* fix: extra business?
* fix: merge conflict just added them back why dude
* fix: more PR comments
* fix: big ciruclar deps fix, commandBarActor in appActor
* chore: writing e2e test, still need to fix 3 bugs
* chore: adding more scenarios
* fix: formatting
* fix: fixing tsc errors
* chore: deleting the old text to cad and using the new application level one, almost there
* fix: prompt to edit works
* fix: large push to get 1 text to cad command... the usage is a little buggy with delete and navigate within /file
* fix: settings for highlight edges now works
* chore: adding another e2e test
* fix: cleaning up e2e tests and writing more of them
* fix: tsc type
* chore: more e2e improvements, unique project name in text to cad
* chore: e2e tests should be good to go
* fix: gotcha comment
* fix: enabled web t2c, codespell fixes
* fix: fixing merge conflcits??
* feat: implemented load external for kcl samples
* feat: load external model from disk
* fix: trying to delete old stuff
* fix: all command trigger locations now have defaults for current project
* fix: gotcha comment for the future
* chore: hiding import file from url command, two separate commands for 3d and kcl file adding
* chore: commands are now add file to project, 3rd iteration
* fix: t2c in file menu fixed
* chore: updating file menu for new global actions
* fix: auto fixes
* fix: the command bar arg flow for web add kcl file seems backwards?
* chore: updated home layout, added create from kcl sample button
* chore: remapping some menu actions
* fix: fixing open dialog copy
* fix: an e2e test
* fix: fixed e2e tests
* fix: fixed e2e tests
* fix: auto fixes
* fix: pr clean up
* fix: removing console log
* fix: PR updates
* fix: the reviewed stage boolean required the expected state to change. Also I progressed the command bar too soon
* fix: no idea how this passed locally yesterday? I removed the {dir} unused but I need the function's logic but not the return value...
* fix: should be good to go?
---------
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-04-29 13:04:45 -05:00
|
|
|
id: 'add-file-to-project',
|
|
|
|
title: 'Add file to project',
|
|
|
|
sidebarName: 'Add file to project',
|
2025-04-14 14:53:01 -04:00
|
|
|
icon: 'importFile',
|
2025-04-21 15:08:51 -04:00
|
|
|
keybinding: 'Mod + Alt + L',
|
[Feature]: Load external model becomes Add file to project, global application add file to project with home page update. (#6506)
* chore: saving off skeleton
* fix: saving skeleton
* chore: skeleton for loading projects from project directory path
* chore: cleaning up useless state transition to be an on event direct to action state
* fix: new structure for web vs desktop vs react machine provider code
* chore: saving off skeleton
* fix: skeleton logic for react? going to move it from a string to obj.string
* fix: trying to prevent error element unmount on global react components. This is bricking JS state
* fix: we are so back
* chore: implemented navigating to specfic KCL file
* chore: implementing renaming project
* chore: deleting project
* fix: auto fixes
* fix: old debug/testing file oops
* chore: generic create new file
* chore: skeleton for web create file provide
* chore: basic machine vitest... need to figure out how to get window.electron implemented in vitest?
* chore: save off progress before deleting other project implementation, a few missing features still
* chore: trying a different init skeleton? most likely will migrate
* chore: first attempt of purging projects context provider
* chore: enabling toast for some machine state
* chore: enabling more toast success and error
* chore: writing read write state to the system io based on the project path
* fix: tsc fixes
* fix: use file system watcher, navigate to project after creation via the requestProjectName
* chore: open project command, hooks vs snapshot context helpers
* chore: implemented open and create project for e2e testing. They are hard coded in poor spot for now.
* fix: codespell fixes
* chore: implementing more project commands
* chore: PR improvements for root.tsx
* chore: leaving comment about new Router.tsx layout
* fix: removing debugging code
* fix: rewriting component for readability
* fix: improving web initialization
* chore: implementing import file from url which is not actually that?
* fix: clearing search params on import file from url
* fix: fixed two e2e tests, forgot needsReview when making new command
* fix: fixing some import from url business logic to pass e2e tests
* chore: script for diffing circular deps +/-
* fix: formatting
* fix: massive fix for circular depsga!
* fix: trying to fix some errors and auto fmt
* fix: updating deps
* fix: removing debugging code
* fix: big clean up
* fix: more deletion
* fix: tsc cleanup
* fix: TSC TSC TSC TSC!
* fix: typo fix
* fix: clear query params on web only, desktop not required
* fix: removing unused code
* fmt
* Bring back `trap` removed in merge
* Use explicit types instead of `any`s on arg configs
* Add project commands directly to command palette
* fix: deleting debugging code, from PR review
* fix: this got added back(?)
* fix: using referred type
* fix: more PR clean up
* fix: big block comment for xstate architecture decision
* fix: more pr comment fixes
* fix: saving off logic, need a big cleanup because I hacked it together to get a POC
* fix: extra business?
* fix: merge conflict just added them back why dude
* fix: more PR comments
* fix: big ciruclar deps fix, commandBarActor in appActor
* chore: writing e2e test, still need to fix 3 bugs
* chore: adding more scenarios
* fix: formatting
* fix: fixing tsc errors
* chore: deleting the old text to cad and using the new application level one, almost there
* fix: prompt to edit works
* fix: large push to get 1 text to cad command... the usage is a little buggy with delete and navigate within /file
* fix: settings for highlight edges now works
* chore: adding another e2e test
* fix: cleaning up e2e tests and writing more of them
* fix: tsc type
* chore: more e2e improvements, unique project name in text to cad
* chore: e2e tests should be good to go
* fix: gotcha comment
* fix: enabled web t2c, codespell fixes
* fix: fixing merge conflcits??
* feat: implemented load external for kcl samples
* feat: load external model from disk
* fix: trying to delete old stuff
* fix: all command trigger locations now have defaults for current project
* fix: gotcha comment for the future
* chore: hiding import file from url command, two separate commands for 3d and kcl file adding
* chore: commands are now add file to project, 3rd iteration
* fix: t2c in file menu fixed
* chore: updating file menu for new global actions
* fix: auto fixes
* fix: the command bar arg flow for web add kcl file seems backwards?
* chore: updated home layout, added create from kcl sample button
* chore: remapping some menu actions
* fix: fixing open dialog copy
* fix: an e2e test
* fix: fixed e2e tests
* fix: fixed e2e tests
* fix: auto fixes
* fix: pr clean up
* fix: removing console log
* fix: PR updates
* fix: the reviewed stage boolean required the expected state to change. Also I progressed the command bar too soon
* fix: no idea how this passed locally yesterday? I removed the {dir} unused but I need the function's logic but not the return value...
* fix: should be good to go?
---------
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-04-29 13:04:45 -05:00
|
|
|
action: () => {
|
|
|
|
const currentProject =
|
|
|
|
settingsActor.getSnapshot().context.currentProject
|
2025-04-07 16:28:11 -04:00
|
|
|
commandBarActor.send({
|
|
|
|
type: 'Find and select command',
|
[Feature]: Load external model becomes Add file to project, global application add file to project with home page update. (#6506)
* chore: saving off skeleton
* fix: saving skeleton
* chore: skeleton for loading projects from project directory path
* chore: cleaning up useless state transition to be an on event direct to action state
* fix: new structure for web vs desktop vs react machine provider code
* chore: saving off skeleton
* fix: skeleton logic for react? going to move it from a string to obj.string
* fix: trying to prevent error element unmount on global react components. This is bricking JS state
* fix: we are so back
* chore: implemented navigating to specfic KCL file
* chore: implementing renaming project
* chore: deleting project
* fix: auto fixes
* fix: old debug/testing file oops
* chore: generic create new file
* chore: skeleton for web create file provide
* chore: basic machine vitest... need to figure out how to get window.electron implemented in vitest?
* chore: save off progress before deleting other project implementation, a few missing features still
* chore: trying a different init skeleton? most likely will migrate
* chore: first attempt of purging projects context provider
* chore: enabling toast for some machine state
* chore: enabling more toast success and error
* chore: writing read write state to the system io based on the project path
* fix: tsc fixes
* fix: use file system watcher, navigate to project after creation via the requestProjectName
* chore: open project command, hooks vs snapshot context helpers
* chore: implemented open and create project for e2e testing. They are hard coded in poor spot for now.
* fix: codespell fixes
* chore: implementing more project commands
* chore: PR improvements for root.tsx
* chore: leaving comment about new Router.tsx layout
* fix: removing debugging code
* fix: rewriting component for readability
* fix: improving web initialization
* chore: implementing import file from url which is not actually that?
* fix: clearing search params on import file from url
* fix: fixed two e2e tests, forgot needsReview when making new command
* fix: fixing some import from url business logic to pass e2e tests
* chore: script for diffing circular deps +/-
* fix: formatting
* fix: massive fix for circular depsga!
* fix: trying to fix some errors and auto fmt
* fix: updating deps
* fix: removing debugging code
* fix: big clean up
* fix: more deletion
* fix: tsc cleanup
* fix: TSC TSC TSC TSC!
* fix: typo fix
* fix: clear query params on web only, desktop not required
* fix: removing unused code
* fmt
* Bring back `trap` removed in merge
* Use explicit types instead of `any`s on arg configs
* Add project commands directly to command palette
* fix: deleting debugging code, from PR review
* fix: this got added back(?)
* fix: using referred type
* fix: more PR clean up
* fix: big block comment for xstate architecture decision
* fix: more pr comment fixes
* fix: saving off logic, need a big cleanup because I hacked it together to get a POC
* fix: extra business?
* fix: merge conflict just added them back why dude
* fix: more PR comments
* fix: big ciruclar deps fix, commandBarActor in appActor
* chore: writing e2e test, still need to fix 3 bugs
* chore: adding more scenarios
* fix: formatting
* fix: fixing tsc errors
* chore: deleting the old text to cad and using the new application level one, almost there
* fix: prompt to edit works
* fix: large push to get 1 text to cad command... the usage is a little buggy with delete and navigate within /file
* fix: settings for highlight edges now works
* chore: adding another e2e test
* fix: cleaning up e2e tests and writing more of them
* fix: tsc type
* chore: more e2e improvements, unique project name in text to cad
* chore: e2e tests should be good to go
* fix: gotcha comment
* fix: enabled web t2c, codespell fixes
* fix: fixing merge conflcits??
* feat: implemented load external for kcl samples
* feat: load external model from disk
* fix: trying to delete old stuff
* fix: all command trigger locations now have defaults for current project
* fix: gotcha comment for the future
* chore: hiding import file from url command, two separate commands for 3d and kcl file adding
* chore: commands are now add file to project, 3rd iteration
* fix: t2c in file menu fixed
* chore: updating file menu for new global actions
* fix: auto fixes
* fix: the command bar arg flow for web add kcl file seems backwards?
* chore: updated home layout, added create from kcl sample button
* chore: remapping some menu actions
* fix: fixing open dialog copy
* fix: an e2e test
* fix: fixed e2e tests
* fix: fixed e2e tests
* fix: auto fixes
* fix: pr clean up
* fix: removing console log
* fix: PR updates
* fix: the reviewed stage boolean required the expected state to change. Also I progressed the command bar too soon
* fix: no idea how this passed locally yesterday? I removed the {dir} unused but I need the function's logic but not the return value...
* fix: should be good to go?
---------
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
2025-04-29 13:04:45 -05:00
|
|
|
data: {
|
|
|
|
name: 'add-kcl-file-to-project',
|
|
|
|
groupId: 'application',
|
|
|
|
argDefaultValues: {
|
|
|
|
method: 'existingProject',
|
|
|
|
projectName: currentProject?.name,
|
|
|
|
...(!isDesktop() ? { source: 'kcl-samples' } : {}),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
},
|
2025-04-07 16:28:11 -04:00
|
|
|
},
|
2024-07-24 22:02:16 -04:00
|
|
|
{
|
|
|
|
id: 'export',
|
|
|
|
title: 'Export part',
|
2024-11-06 14:32:06 -05:00
|
|
|
sidebarName: 'Export part',
|
2024-07-24 22:02:16 -04:00
|
|
|
icon: 'floppyDiskArrow',
|
|
|
|
keybinding: 'Ctrl + Shift + E',
|
2025-04-10 20:08:39 -04:00
|
|
|
disable: () =>
|
|
|
|
reliesOnEngine ? 'Need engine connection to export' : undefined,
|
2024-07-24 22:02:16 -04:00
|
|
|
action: () =>
|
2025-01-23 10:25:21 -05:00
|
|
|
commandBarActor.send({
|
2024-07-24 22:02:16 -04:00
|
|
|
type: 'Find and select command',
|
|
|
|
data: { name: 'Export', groupId: 'modeling' },
|
|
|
|
}),
|
|
|
|
},
|
2024-08-04 00:51:30 -04:00
|
|
|
{
|
|
|
|
id: 'make',
|
|
|
|
title: 'Make part',
|
2024-11-06 14:32:06 -05:00
|
|
|
sidebarName: 'Make part',
|
2024-08-04 00:51:30 -04:00
|
|
|
icon: 'printer3d',
|
|
|
|
keybinding: 'Ctrl + Shift + M',
|
2024-09-09 18:17:45 -04:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
2024-08-04 00:51:30 -04:00
|
|
|
action: async () => {
|
2025-01-23 10:25:21 -05:00
|
|
|
commandBarActor.send({
|
2024-08-04 00:51:30 -04:00
|
|
|
type: 'Find and select command',
|
|
|
|
data: { name: 'Make', groupId: 'modeling' },
|
|
|
|
})
|
|
|
|
},
|
2024-08-19 15:57:31 -07:00
|
|
|
hide: () => !isDesktop(),
|
|
|
|
disable: () => {
|
|
|
|
return machineManager.noMachinesReason()
|
|
|
|
},
|
2024-08-04 00:51:30 -04:00
|
|
|
},
|
2025-04-23 15:20:45 -04:00
|
|
|
{
|
|
|
|
id: 'refresh',
|
|
|
|
title: 'Refresh app',
|
|
|
|
sidebarName: 'Refresh app',
|
|
|
|
icon: 'arrowRotateRight',
|
|
|
|
keybinding: 'Mod + R',
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
|
|
action: async () => {
|
|
|
|
refreshPage('Sidebar button').catch(reportRejection)
|
|
|
|
},
|
|
|
|
},
|
2024-07-24 22:02:16 -04:00
|
|
|
]
|
2024-08-04 00:51:30 -04:00
|
|
|
const filteredActions: SidebarAction[] = sidebarActions.filter(
|
|
|
|
(action) =>
|
2024-09-13 14:49:33 -04:00
|
|
|
!action.hide ||
|
|
|
|
(action.hide instanceof Function && !action.hide(paneCallbackProps))
|
2024-08-04 00:51:30 -04:00
|
|
|
)
|
2024-07-24 22:02:16 -04:00
|
|
|
|
|
|
|
// // Filter out the debug panel if it's not supposed to be shown
|
|
|
|
// // TODO: abstract out for allowing user to configure which panes to show
|
|
|
|
const filteredPanes = useMemo(
|
|
|
|
() =>
|
|
|
|
(showDebugPanel.current
|
|
|
|
? sidebarPanes
|
|
|
|
: sidebarPanes.filter((pane) => pane.id !== 'debug')
|
|
|
|
).filter(
|
|
|
|
(pane) =>
|
2024-09-13 14:49:33 -04:00
|
|
|
!pane.hide ||
|
|
|
|
(pane.hide instanceof Function && !pane.hide(paneCallbackProps))
|
2024-07-24 22:02:16 -04:00
|
|
|
),
|
2024-09-13 14:49:33 -04:00
|
|
|
[sidebarPanes, paneCallbackProps]
|
2024-07-24 22:02:16 -04:00
|
|
|
)
|
|
|
|
|
2024-08-04 15:59:04 -07:00
|
|
|
const paneBadgeMap: Record<SidebarType, BadgeInfoComputed> = useMemo(() => {
|
2025-04-01 23:54:26 -07:00
|
|
|
return filteredPanes.reduce(
|
|
|
|
(acc, pane) => {
|
|
|
|
if (pane.showBadge) {
|
|
|
|
acc[pane.id] = {
|
|
|
|
value: pane.showBadge.value(paneCallbackProps),
|
|
|
|
onClick: pane.showBadge.onClick,
|
|
|
|
className: pane.showBadge.className,
|
|
|
|
title: pane.showBadge.title,
|
|
|
|
}
|
2024-08-04 15:59:04 -07:00
|
|
|
}
|
2025-04-01 23:54:26 -07:00
|
|
|
return acc
|
|
|
|
},
|
|
|
|
{} as Record<SidebarType, BadgeInfoComputed>
|
|
|
|
)
|
2024-09-13 14:49:33 -04:00
|
|
|
}, [paneCallbackProps])
|
|
|
|
|
|
|
|
// Clear any hidden panes from the `openPanes` array
|
|
|
|
useEffect(() => {
|
|
|
|
const panesToReset: SidebarType[] = []
|
2025-02-25 13:18:59 -06:00
|
|
|
|
2024-09-13 14:49:33 -04:00
|
|
|
sidebarPanes.forEach((pane) => {
|
|
|
|
if (
|
|
|
|
pane.hide === true ||
|
|
|
|
(pane.hide instanceof Function && pane.hide(paneCallbackProps))
|
|
|
|
) {
|
|
|
|
panesToReset.push(pane.id)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
if (panesToReset.length > 0) {
|
|
|
|
send({
|
|
|
|
type: 'Set context',
|
|
|
|
data: {
|
|
|
|
openPanes: context.store?.openPanes.filter(
|
|
|
|
(pane) => !panesToReset.includes(pane)
|
|
|
|
),
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
2025-02-28 16:15:57 -08:00
|
|
|
}, [settings.app.showDebugPanel])
|
2024-07-31 23:29:24 -04:00
|
|
|
|
2024-07-24 22:02:16 -04:00
|
|
|
const togglePane = useCallback(
|
|
|
|
(newPane: SidebarType) => {
|
|
|
|
send({
|
|
|
|
type: 'Set context',
|
|
|
|
data: {
|
|
|
|
openPanes: context.store?.openPanes.includes(newPane)
|
|
|
|
? context.store?.openPanes.filter((pane) => pane !== newPane)
|
|
|
|
: [...context.store?.openPanes, newPane],
|
|
|
|
},
|
|
|
|
})
|
|
|
|
},
|
|
|
|
[context.store?.openPanes, send]
|
|
|
|
)
|
2024-04-15 12:04:17 -04:00
|
|
|
|
|
|
|
return (
|
|
|
|
<Resizable
|
2025-05-08 20:37:21 -04:00
|
|
|
className={`group flex-1 flex flex-col z-10 my-2 pr-1 ${pointerEventsCssClass}`}
|
2024-04-15 12:04:17 -04:00
|
|
|
defaultSize={{
|
|
|
|
width: '550px',
|
|
|
|
height: 'auto',
|
|
|
|
}}
|
|
|
|
minWidth={200}
|
2025-02-07 21:19:09 +11:00
|
|
|
maxWidth={window.innerWidth - 10}
|
2024-09-13 14:49:33 -04:00
|
|
|
handleWrapperClass="sidebar-resize-handles"
|
2024-04-15 12:04:17 -04:00
|
|
|
handleClasses={{
|
|
|
|
right:
|
2024-07-02 17:16:27 +10:00
|
|
|
(context.store?.openPanes.length === 0 ? 'hidden ' : 'block ') +
|
2024-04-15 21:40:45 -04:00
|
|
|
'translate-x-1/2 hover:bg-chalkboard-10 hover:dark:bg-chalkboard-110 bg-transparent transition-colors duration-75 transition-ease-out delay-100 ',
|
2024-05-16 22:30:47 -04:00
|
|
|
left: 'hidden',
|
|
|
|
top: 'hidden',
|
|
|
|
topLeft: 'hidden',
|
|
|
|
topRight: 'hidden',
|
|
|
|
bottom: 'hidden',
|
|
|
|
bottomLeft: 'hidden',
|
|
|
|
bottomRight: 'hidden',
|
2024-04-15 12:04:17 -04:00
|
|
|
}}
|
|
|
|
>
|
2024-11-06 14:32:06 -05:00
|
|
|
<div id="app-sidebar" className="flex flex-row h-full">
|
2024-07-24 22:02:16 -04:00
|
|
|
<ul
|
2024-06-18 12:42:47 -04:00
|
|
|
className={
|
2024-07-24 22:02:16 -04:00
|
|
|
(context.store?.openPanes.length === 0 ? 'rounded-r ' : '') +
|
|
|
|
'relative z-[2] pointer-events-auto p-0 col-start-1 col-span-1 h-fit w-fit flex flex-col ' +
|
2024-09-16 17:12:54 -04:00
|
|
|
'bg-chalkboard-10 border border-solid border-chalkboard-30 dark:bg-chalkboard-90 dark:border-chalkboard-80 group-focus-within:border-primary dark:group-focus-within:border-chalkboard-50 shadow-sm '
|
2024-06-18 12:42:47 -04:00
|
|
|
}
|
|
|
|
>
|
2024-07-24 22:02:16 -04:00
|
|
|
<ul
|
|
|
|
id="pane-buttons-section"
|
|
|
|
className={
|
|
|
|
'w-fit p-2 flex flex-col gap-2 ' +
|
|
|
|
(context.store?.openPanes.length >= 1 ? 'pr-0.5' : '')
|
|
|
|
}
|
|
|
|
>
|
|
|
|
{filteredPanes.map((pane) => (
|
|
|
|
<ModelingPaneButton
|
|
|
|
key={pane.id}
|
|
|
|
paneConfig={pane}
|
|
|
|
paneIsOpen={context.store?.openPanes.includes(pane.id)}
|
|
|
|
onClick={() => togglePane(pane.id)}
|
|
|
|
aria-pressed={context.store?.openPanes.includes(pane.id)}
|
2024-07-31 23:29:24 -04:00
|
|
|
showBadge={paneBadgeMap[pane.id]}
|
2024-07-24 22:02:16 -04:00
|
|
|
/>
|
|
|
|
))}
|
|
|
|
</ul>
|
2024-08-04 00:51:30 -04:00
|
|
|
{filteredActions.length > 0 && (
|
|
|
|
<>
|
2024-09-16 17:12:54 -04:00
|
|
|
<hr className="w-full border-chalkboard-30 dark:border-chalkboard-80" />
|
2024-08-04 00:51:30 -04:00
|
|
|
<ul
|
|
|
|
id="sidebar-actions"
|
|
|
|
className="w-fit p-2 flex flex-col gap-2"
|
|
|
|
>
|
|
|
|
{filteredActions.map((action) => (
|
|
|
|
<ModelingPaneButton
|
|
|
|
key={action.id}
|
|
|
|
paneConfig={{
|
|
|
|
id: action.id,
|
2024-11-06 14:32:06 -05:00
|
|
|
sidebarName: action.sidebarName,
|
2024-08-04 00:51:30 -04:00
|
|
|
icon: action.icon,
|
|
|
|
keybinding: action.keybinding,
|
|
|
|
iconClassName: action.iconClassName,
|
|
|
|
iconSize: 'md',
|
|
|
|
}}
|
|
|
|
onClick={action.action}
|
2024-08-19 15:57:31 -07:00
|
|
|
disabledText={action.disable?.()}
|
2024-08-04 00:51:30 -04:00
|
|
|
/>
|
|
|
|
))}
|
|
|
|
</ul>
|
|
|
|
</>
|
|
|
|
)}
|
2024-07-24 22:02:16 -04:00
|
|
|
</ul>
|
|
|
|
<ul
|
|
|
|
id="pane-section"
|
2024-06-18 12:42:47 -04:00
|
|
|
className={
|
2024-11-06 14:32:06 -05:00
|
|
|
'ml-[-1px] col-start-2 col-span-1 flex flex-col items-stretch gap-2 ' +
|
|
|
|
(context.store?.openPanes.length >= 1 ? `w-full` : `hidden`)
|
2024-06-18 12:42:47 -04:00
|
|
|
}
|
|
|
|
>
|
2024-07-24 22:02:16 -04:00
|
|
|
{filteredPanes
|
|
|
|
.filter((pane) => context?.store.openPanes.includes(pane.id))
|
|
|
|
.map((pane) => (
|
2024-06-18 12:42:47 -04:00
|
|
|
<ModelingPane
|
2024-07-24 22:02:16 -04:00
|
|
|
key={pane.id}
|
|
|
|
icon={pane.icon}
|
2024-11-06 14:32:06 -05:00
|
|
|
title={pane.sidebarName}
|
|
|
|
onClose={() => {}}
|
2024-06-18 12:42:47 -04:00
|
|
|
id={`${pane.id}-pane`}
|
|
|
|
>
|
|
|
|
{pane.Content instanceof Function ? (
|
2024-11-06 14:32:06 -05:00
|
|
|
<pane.Content
|
|
|
|
id={pane.id}
|
|
|
|
onClose={() => togglePane(pane.id)}
|
|
|
|
/>
|
2024-06-18 12:42:47 -04:00
|
|
|
) : (
|
|
|
|
pane.Content
|
|
|
|
)}
|
|
|
|
</ModelingPane>
|
2024-07-24 22:02:16 -04:00
|
|
|
))}
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</Resizable>
|
2024-04-15 12:04:17 -04:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2024-07-24 22:02:16 -04:00
|
|
|
interface ModelingPaneButtonProps
|
|
|
|
extends React.HTMLAttributes<HTMLButtonElement> {
|
|
|
|
paneConfig: {
|
|
|
|
id: string
|
2024-11-06 14:32:06 -05:00
|
|
|
sidebarName: string
|
2024-07-24 22:02:16 -04:00
|
|
|
icon: CustomIconName | IconDefinition
|
|
|
|
keybinding: string
|
|
|
|
iconClassName?: string
|
|
|
|
iconSize?: 'sm' | 'md' | 'lg'
|
|
|
|
}
|
|
|
|
onClick: () => void
|
2024-07-28 21:59:06 -04:00
|
|
|
paneIsOpen?: boolean
|
2024-08-04 15:59:04 -07:00
|
|
|
showBadge?: BadgeInfoComputed
|
2024-08-19 15:57:31 -07:00
|
|
|
disabledText?: string
|
2024-04-15 12:04:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
function ModelingPaneButton({
|
|
|
|
paneConfig,
|
2024-07-24 22:02:16 -04:00
|
|
|
onClick,
|
|
|
|
paneIsOpen,
|
2024-07-31 23:29:24 -04:00
|
|
|
showBadge,
|
2024-08-19 15:57:31 -07:00
|
|
|
disabledText,
|
2024-07-24 22:02:16 -04:00
|
|
|
...props
|
2024-04-15 12:04:17 -04:00
|
|
|
}: ModelingPaneButtonProps) {
|
2025-04-23 15:20:45 -04:00
|
|
|
const platform = usePlatform()
|
2024-07-24 22:02:16 -04:00
|
|
|
useHotkeys(paneConfig.keybinding, onClick, {
|
2024-04-15 12:04:17 -04:00
|
|
|
scopes: ['modeling'],
|
|
|
|
})
|
|
|
|
|
|
|
|
return (
|
2025-05-08 20:37:21 -04:00
|
|
|
<div
|
|
|
|
id={paneConfig.id + '-button-holder'}
|
|
|
|
className="relative"
|
|
|
|
data-onboarding-id={`${paneConfig.id}-pane-button`}
|
|
|
|
>
|
2024-08-04 15:59:04 -07:00
|
|
|
<button
|
2024-09-16 17:12:54 -04:00
|
|
|
className="group pointer-events-auto flex items-center justify-center border-transparent dark:border-transparent disabled:!border-transparent p-0 m-0 rounded-sm !outline-0 focus-visible:border-primary"
|
2024-08-04 15:59:04 -07:00
|
|
|
onClick={onClick}
|
2024-11-06 14:32:06 -05:00
|
|
|
name={paneConfig.sidebarName}
|
2024-12-20 16:19:59 -05:00
|
|
|
data-testid={paneConfig.id + SIDEBAR_BUTTON_SUFFIX}
|
2024-08-19 15:57:31 -07:00
|
|
|
disabled={disabledText !== undefined}
|
|
|
|
aria-disabled={disabledText !== undefined}
|
2024-08-04 15:59:04 -07:00
|
|
|
{...props}
|
|
|
|
>
|
|
|
|
<ActionIcon
|
|
|
|
icon={paneConfig.icon}
|
2024-09-16 17:12:54 -04:00
|
|
|
className={paneConfig.iconClassName || ''}
|
|
|
|
size={paneConfig.iconSize || 'md'}
|
|
|
|
iconClassName={paneIsOpen ? ' !text-chalkboard-10' : ''}
|
2024-08-04 15:59:04 -07:00
|
|
|
bgClassName={
|
|
|
|
'rounded-sm ' + (paneIsOpen ? '!bg-primary' : '!bg-transparent')
|
|
|
|
}
|
|
|
|
/>
|
|
|
|
<span className="sr-only">
|
2024-11-06 14:32:06 -05:00
|
|
|
{paneConfig.sidebarName}
|
2024-08-04 15:59:04 -07:00
|
|
|
{paneIsOpen !== undefined ? ` pane` : ''}
|
|
|
|
</span>
|
|
|
|
<Tooltip
|
|
|
|
position="right"
|
|
|
|
contentClassName="max-w-none flex items-center gap-4"
|
|
|
|
hoverOnly
|
|
|
|
>
|
|
|
|
<span className="flex-1">
|
2024-11-06 14:32:06 -05:00
|
|
|
{paneConfig.sidebarName}
|
2024-08-19 15:57:31 -07:00
|
|
|
{disabledText !== undefined ? ` (${disabledText})` : ''}
|
2024-08-04 15:59:04 -07:00
|
|
|
{paneIsOpen !== undefined ? ` pane` : ''}
|
|
|
|
</span>
|
|
|
|
<kbd className="hotkey text-xs capitalize">
|
2025-04-23 15:20:45 -04:00
|
|
|
{hotkeyDisplay(paneConfig.keybinding, platform)}
|
2024-08-04 15:59:04 -07:00
|
|
|
</kbd>
|
|
|
|
</Tooltip>
|
|
|
|
</button>
|
|
|
|
{!!showBadge?.value && (
|
2024-07-31 23:29:24 -04:00
|
|
|
<p
|
2024-08-04 15:59:04 -07:00
|
|
|
id={`${paneConfig.id}-badge`}
|
2024-07-31 23:29:24 -04:00
|
|
|
className={
|
2025-02-25 13:18:59 -06:00
|
|
|
showBadge.className
|
|
|
|
? showBadge.className
|
|
|
|
: 'absolute m-0 p-0 bottom-4 left-4 w-3 h-3 flex items-center justify-center text-[10px] font-semibold text-white bg-primary hue-rotate-90 rounded-full border border-chalkboard-10 dark:border-chalkboard-80 z-50 hover:cursor-pointer hover:scale-[2] transition-transform duration-200'
|
2024-07-31 23:29:24 -04:00
|
|
|
}
|
2024-08-04 15:59:04 -07:00
|
|
|
onClick={showBadge.onClick}
|
2025-02-25 13:18:59 -06:00
|
|
|
title={
|
|
|
|
showBadge.title
|
|
|
|
? showBadge.title
|
|
|
|
: `Click to view ${showBadge.value} notification${
|
|
|
|
Number(showBadge.value) > 1 ? 's' : ''
|
|
|
|
}`
|
|
|
|
}
|
2024-07-31 23:29:24 -04:00
|
|
|
>
|
|
|
|
<span className="sr-only"> has </span>
|
2025-02-25 13:18:59 -06:00
|
|
|
{typeof showBadge.value === 'number' ||
|
|
|
|
typeof showBadge.value === 'string' ? (
|
2024-08-04 15:59:04 -07:00
|
|
|
<span>{showBadge.value}</span>
|
2024-07-31 23:29:24 -04:00
|
|
|
) : (
|
|
|
|
<span className="sr-only">a</span>
|
|
|
|
)}
|
2025-02-25 13:18:59 -06:00
|
|
|
{typeof showBadge.value === 'number' && (
|
|
|
|
<span className="sr-only">
|
|
|
|
notification{Number(showBadge.value) > 1 ? 's' : ''}
|
|
|
|
</span>
|
|
|
|
)}
|
2024-07-31 23:29:24 -04:00
|
|
|
</p>
|
|
|
|
)}
|
2024-08-04 15:59:04 -07:00
|
|
|
</div>
|
2024-04-15 12:04:17 -04:00
|
|
|
)
|
|
|
|
}
|