Skip to content

feature: Project Explorer update, first pass. #7656

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

Open
wants to merge 136 commits into
base: main
Choose a base branch
from

Conversation

nadr0
Copy link
Contributor

@nadr0 nadr0 commented Jul 1, 2025

#7592 got out of hand with the optimizations with little planning on my end.

Opening a fresh PR without this to see if this passes to do my optimizations within another body of work.

nadr0 added 30 commits June 12, 2025 15:57
@nadr0
Copy link
Contributor Author

nadr0 commented Jul 1, 2025

@jacebrowning Whenever this gets reviewed and approved I'll need to disable these two tests
image

I've disabled the useFileSystesmWatcher within the modeling page. These tests would be N/A until we enable the feature again in the future.

@jacebrowning
Copy link
Contributor

I've disabled the useFileSystesmWatcher within the modeling page. These tests would be N/A until we enable the feature again in the future.

@nadr0 OK, please create a GitHub issue to drop in the form to disable the tests. Or, if the "future" where we enable this is a long ways out, consider deleting the tests. They'll always be available in the Git history.

@franknoirot franknoirot changed the title Nadro/gh 6878/no virtual list Refactor file explorer to be a pure component (no virtualization yet) Jul 9, 2025
@franknoirot
Copy link
Contributor

Working through a code review in a bit, but here are a few initial UX thoughts @nadr0

  1. Seem to have lost the ability to hit Enter and start renaming the file or folder under the cursor. This is also the behavior of VS Code as well. I see now that you have it opening files, hmmm could Shift + Enter be used for either rename or open file? I just want some keyboard shortcut for rename and it used to be Enter I guess.
  2. Minor UX polish for future: Left arrow while cursor is on a file within a folder jumps the cursor up to the folder in VS Code

src/lib/paths.ts Outdated
/**
* Don't pass a folder path, only files with extensions for best results.
*/
export const alwaysEndFileWithEXT = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a slightly easier name would be enforceFileEXT.
Also if ext' is null I would expect the function to return filePathinstead ofnull`. I see that null is checked agains in ProjectExplorer so that would need to be changed as well but maybe worth it? In the odd case of the file not having an extension, it could still be renamed without having an extension.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It depends on who we want to have the burden of a check? This comes down to whether we support base cases?

              const originalExt = getEXTWithPeriod(name)
              const fileNameForcedWithOriginalExt = enforceFileEXT(
                requestedName,
                originalExt
              )
              if (!fileNameForcedWithOriginalExt) {
                // TODO: OH NO!
                return
              }

I did this because these are paired together, when you try to get the originalExtension from something you may not get that extension so if you attempt to enforce it it could fail. That is why there is a null check.

We really always want extensions in the codebase.

} catch (e) {
console.error(e)
}
await window.electron.writeFile(input.requestedAbsolutePath, '')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think writeFile can throw so maybe it's worth putting inside the try block as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already caught properly, within the systemIOMachine.ts. Anything that is explicitly not try/catched will be caught and handled with the onError workflow of the actor.

The reason why I try catch the thing above is if you window.electron.stat something and it doesn't exist it will throw an error which is what we want. We want it to say "Yeah you don't have a file" to make sure we can then do the create file.

We don't always need to try/catch handle every statement since the parent workflow in the machine will handle the onError.

      invoke: {
        id: SystemIOMachineActors.createBlankFile,
        src: SystemIOMachineActors.createBlankFile,
        input: ({ context, event, self }) => {
          assertEvent(event, SystemIOMachineEvents.createBlankFile)
          return {
            context,
            requestedAbsolutePath: event.data.requestedAbsolutePath,
            rootContext: self.system.get('root').getSnapshot().context,
          }
        },
        onDone: {
          target: SystemIOMachineStates.readingFolders,
          actions: [SystemIOMachineActions.toastSuccess],
        },
        onError: { <--- Handled!!
          target: SystemIOMachineStates.idle,
          actions: [SystemIOMachineActions.toastError], <-- will toast error!
        },

console.error(e)
}
}
await window.electron.mkdir(input.requestedAbsolutePath, {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar here, or maybe there is a reason it is outside the try-catch ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same reason as above, the try catch is handled on the systemIOMachine.ts onError definition of the actor being invoked.

@@ -43,6 +45,9 @@ export function ContextMenu({
})
const handleContextMenu = useCallback(
(e: globalThis.MouseEvent) => {
if (callback) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

short one liner I usually use is callback?.(e) instead of the if but just mentioning it, it may be less readable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have settled this debate internally of shorthands.

if (something)
  doSomething()

yup && yup()

^-- stuff like this

I think it is less readable seeing callback?.(e). Curious if anyone has strong opinions on this?

list.push(content)

// if a FileEntry has no children stop
if (f.children === null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably doesn't matter but in cases like this I just usually check for falsiness, that handles if for any reasons children becomes undefined

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type is of children: Array<FileEntry> | null. I kinda want stuff to shit the bed if the value is actually undefined?

If we are worried about this we may need some runtime verification on the types to ensure that object is generated without any undefined.

@andrewvarga
Copy link
Contributor

Things seem to be working still, I just noticed a few small differences compared to main:

When having a file selected and pressing Enter I get an orange outline around the Filetree pane, not sure if that's on purpose?
Also when having a file selected and then pressing Delete / Backspace I'm getting the same plus a message that the selection cannot be deleted. On main nothing happens (but no error message either).
Screenshot 2025-07-09 at 18 11 39

But it's good that the misleading hotkeys for Enter and ctrl + Del are deleted from the context menu since those didn't work on main anyway.

@andrewvarga
Copy link
Contributor

Working through a code review in a bit, but here are a few initial UX thoughts @nadr0

  1. Seem to have lost the ability to hit Enter and start renaming the file or folder under the cursor. This is also the behavior of VS Code as well. I see now that you have it opening files, hmmm could Shift + Enter be used for either rename or open file? I just want some keyboard shortcut for rename and it used to be Enter I guess.
  2. Minor UX polish for future: Left arrow while cursor is on a file within a folder jumps the cursor up to the folder in VS Code

I was going to mention that but it seems even on main it's not possible anymore to rename the files with enter?

@nadr0 nadr0 changed the title Refactor file explorer to be a pure component (no virtualization yet) feature: Project Explorer update, first pass. Jul 23, 2025
@nadr0
Copy link
Contributor Author

nadr0 commented Jul 23, 2025

Working through a code review in a bit, but here are a few initial UX thoughts @nadr0

  1. Seem to have lost the ability to hit Enter and start renaming the file or folder under the cursor. This is also the behavior of VS Code as well. I see now that you have it opening files, hmmm could Shift + Enter be used for either rename or open file? I just want some keyboard shortcut for rename and it used to be Enter I guess.
  2. Minor UX polish for future: Left arrow while cursor is on a file within a folder jumps the cursor up to the folder in VS Code
  1. In VS Code when pressing enter opens it opens the file. I've opted for this as well because when pressing enter on folders it opens the folders. I didn't want enter on filenames to be rename but enter on folders to open.

  2. I see, when you are in the first file of the folder it can jump up, gotcha.

Going through comments, i'll come up with a TODO list for this pass of review.

@nadr0
Copy link
Contributor Author

nadr0 commented Jul 23, 2025

Things seem to be working still, I just noticed a few small differences compared to main:

When having a file selected and pressing Enter I get an orange outline around the Filetree pane, not sure if that's on purpose? Also when having a file selected and then pressing Delete / Backspace I'm getting the same plus a message that the selection cannot be deleted. On main nothing happens (but no error message either). Screenshot 2025-07-09 at 18 11 39

But it's good that the misleading hotkeys for Enter and ctrl + Del are deleted from the context menu since those didn't work on main anyway.

The orange color itself is not intentional but the feature is required. I need to focus that area to use the keyboard inputs. I need an active focus on that element.

I won't if that error message is a bug with another part of the system not clearing your selection and having deletion there. I do not have any deletion callback triggered when pressing the delete key on the board.

@@ -97,48 +97,3 @@ jobs:
git commit -am "Look at this (photo)Graph *in the voice of Nickelback*" || true
git push
git push origin ${{ github.head_ref }}

npm-test-unit-components:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All jest unit test component stuff is merged into vitest since it is compatible and supports more of our repository level configurations.

@@ -134,8 +134,7 @@
"test": "vitest --mode=development",
"test:rust": "(cd rust && just test && just lint)",
"test:snapshots": "cross-env TARGET=web NODE_ENV=development playwright test --config=playwright.config.ts --grep=@snapshot --trace=on",
"test:unit": "vitest run --mode=development --exclude **/jest-component-unit-tests/*",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, deleted the jest runtime stuff since vitest automatically supports the component testing as is.

@@ -0,0 +1,175 @@
import React, { useEffect, useMemo } from 'react'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file could be migrated into another files in the future.

It is useful at the moment since it is the largest component when loading the modeling page. It allows us to initialize a few things.

I'd say okay for the time being.

@@ -0,0 +1,347 @@
// @ts-nocheck
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since jest had a different configuration setup this file is failing several static checkers. The configurations that were used in jest are different from our repository level configurations.

I've added some no checks to make the static checker happy. Any new .test.tsx will be good though.

@nadr0
Copy link
Contributor Author

nadr0 commented Jul 23, 2025

I've implemented the functionality that will close your current folder if you are in a folder and in the first position of the folder. It moves up and then closes the folder like VSCode.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants