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

feat: configuration screen #153

Merged
merged 41 commits into from
Jun 21, 2023
Merged

feat: configuration screen #153

merged 41 commits into from
Jun 21, 2023

Conversation

cguedes
Copy link
Collaborator

@cguedes cguedes commented Jun 13, 2023

This PR adds a configuration and underlying settings support to the app.

Features:

  • Settings core
    • Typed settings for (general, openAI and sidecar.logging)
    • Values read from .env with fallback to default value (first initialisation)
    • Settings saved in a JSON file
  • Settings UI
    • Opened (and closed) via menu shortcut refstudio -> settings or keyboard Cmd+, shortcut
    • Sidebar icon ⚙️ to open modal
    • Modal component that display settings in panel sections
    • Editable OpenAI and Sidecar logging values
  • Sidecar integration
    • settings are sent to sidecar via environment variables
      • APP_DATA_DIR - (default to Tauri's appDataDir())
      • PROJECT_NAME - (default to project-x)
      • OPENAI_API_KEY - (default from OPENAI_API_KEY env)
      • OPENAI_CHAT_MODEL - (default from OPENAI_CHAT_MODEL or gpt-3.5-turbo)
      • OPENAI_COMPLETE_MODEL - (default from OPENAI_COMPLETE_MODEL env or davinci)
      • SIDECAR_ENABLE_LOGGING - (default from SIDECAR_ENABLE_LOGGING env or false)
      • SIDECAR_LOG_DIR - (default from SIDECAR_LOG_DIR env or /tmp)
  • Rust
    • module for application menu (skeleton for file and edit actions)
    • handler for application menu actions and send then as events to the frontend via events integration
    • read env vars using dotenv
  • Utilities
    • useAsyncEffect utility to simplify async effects
    • noop to simplify tests with mandatory handler we don't need to use/test
  • Tests & coverage
    • 100% coverage 😅

image


Tasks

  • Config settings screen window
  • Global trigger with Cmd+,
  • Little gear icon down in the lower left corner like in VS Code
  • Config settings schema + settings API
  • settings storage
  • Config panel for OpenAI settings: OPENAI_API_KEY, OPENAI_COMPLETE_MODEL, OPENAI_CHAT_MODEL
  • Default settings read from env vars
  • Flow settings (as ENV) when calling sidecar
  • Register tauri menu action for Settings
  • Unit tests

@cguedes cguedes linked an issue Jun 13, 2023 that may be closed by this pull request
@hammer
Copy link
Contributor

hammer commented Jun 14, 2023

Nice! In addition to access to this screen from the keyboard, we should probably put a little gear icon down in the lower left corner like in VS Code.

Currently I configure 3 things with OpenAI based on what I saw in @gjreda's checkin: OPENAI_API_KEY, OPENAI_COMPLETE_MODEL, OPENAI_CHAT_MODEL. We should probably grow the list of OpenAI configuration parameters to include all 3.

Also, I configure these settings now through environment variables. Should this configuration screen auto-populate with what it finds in environment variables? If so, we should probably also add some text for each configuration variable to indicate what environment variable name we use. I tend to think of the configuration hierarchy as starting with environment variables, which can be overridden by config files, which can be overridden by command-line flags. Given that we expect most users to install this application and run it from a launcher or by clicking an icon, I'm not sure if it makes sense to give every configuration variable a corresponding environment variable, but it sure is convenient to not have to set these variables each time I try out the app...

I'm thinking at least for OpenAI we do honor environment variables for now.

@cguedes
Copy link
Collaborator Author

cguedes commented Jun 14, 2023

I think that using environment variables as defaults (show in the config screen) is a nice to have (mostly for development - and maybe for some reasonable defaults if we include some sort of .env in the build).

Adding command-line arguments seems a bit to much for now.

Also, I'm going to save the settings in a permanent storage (.json file) to persist settings over app runs.

danvk
danvk previously approved these changes Jun 15, 2023
Copy link
Collaborator

@danvk danvk left a comment

Choose a reason for hiding this comment

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

I'm also curious about the relationship between .env and settings.json. Is the latter populated from the former only once when you first start the app? That may be unavoidable, but I can definitely imagine it being a source of confusion in the future.

If we anticipate having lots of settings, it might be convenient to use a library like this one to generate a basic form UI from the schema for the settings:
https://github.com/rjsf-team/react-jsonschema-form

I believe VS Code does something like this. Here's an example of how the settings are specified for an extension:
https://github.com/asciidoctor/asciidoctor-vscode/blob/50515506f5c55eb14caee419bd15bda67b501700/package.json#L267

src/components/PrimarySideBar.test.tsx Outdated Show resolved Hide resolved
src/components/PrimarySideBar.tsx Outdated Show resolved Hide resolved
await unregister(SETTINGS_SHORTCUT_TOGGLE);
await unregister(SETTINGS_SHORTCUT_CLOSE);
await register(SETTINGS_SHORTCUT_TOGGLE, () => onToggle(!open));
await register(SETTINGS_SHORTCUT_CLOSE, () => onToggle(false));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Presumably you don't want ESC to be registered globally, only when the Settings modal is open?

My suggestion would be:

  • SettingsModal is always open when it's in the virtual DOM.
  • Its visibility is owned by the parent (App) which also registers the Cmd, shortcut (and presumably never needs to unregister it).
  • SettingsModal registers the ESC shortcut and unregisters it when it unmounts. It can just have an onClose prop.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My (initial) idea was to have a drop-in component for the settings that handles the open/close behaviour. Meanwhile, with the sidebar action to open the settings I've have to move the open/close control to the App.

With the addition of the window menu entries and handles I rewrite this component to:

  • Stop using Tauri's global shortcut (that feature is for scenarios when you want a OS-wide shortcut trigger for the app)
  • Adopt Tauri's events for the communication between Rust and the front-end
  • New event for the settings menu click (tauri://menu/settings)
  • Emit settings menu event when on clicks in the Settings icon in the sidebar

src/App.tsx Outdated Show resolved Hide resolved
},
},
{
fileName: 'settings',
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this persist settings in settings.json?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, the lib appends the extension and ignores the extension if we define it.
I've also made the dir explicit to help discover where the file is.

@cguedes
Copy link
Collaborator Author

cguedes commented Jun 16, 2023

I'm also curious about the relationship between .env and settings.json. Is the latter populated from the former only once when you first start the app? That may be unavoidable, but I can definitely imagine it being a source of confusion in the future.

I see your confusion. The idea is to be able to bundle a .env file with default configurations that is read (once) to bootstrap de settings (settings.json). From that point onwards the app only read that file.

I think that for now, too keep it simple, we should have the defaults (ex: OPENAI_COMPLETE_MODEL and OPENAI_CHAT_MODEL) in the code and stop using the .env file. We can revisit this topic in the future when building config levels (i.e: user, app, project).

Also bc for the backend development (CC @gjreda) that file would be useful to store keys that would be received via sidebar when the app is running.

@codecov
Copy link

codecov bot commented Jun 19, 2023

Codecov Report

Merging #153 (470aa05) into main (46c2733) will increase coverage by 6.05%.
The diff coverage is 93.17%.

@@            Coverage Diff             @@
##             main     #153      +/-   ##
==========================================
+ Coverage   57.19%   63.25%   +6.05%     
==========================================
  Files          70       82      +12     
  Lines        3413     4022     +609     
  Branches      226      285      +59     
==========================================
+ Hits         1952     2544     +592     
- Misses       1440     1457      +17     
  Partials       21       21              
Impacted Files Coverage Δ
src/App.tsx 0.00% <0.00%> (ø)
src/filesystem.ts 18.24% <33.33%> (+0.41%) ⬆️
src/events.ts 58.82% <58.82%> (ø)
src/components/JSONDebug.tsx 80.95% <80.95%> (ø)
src/api/sidecar.ts 100.00% <100.00%> (+66.66%) ⬆️
src/atoms/test-utils.ts 100.00% <100.00%> (ø)
src/components/PrimarySideBar.tsx 100.00% <100.00%> (ø)
src/hooks/useAsyncEffect.ts 100.00% <100.00%> (ø)
src/settings/DebugSettingsPane.tsx 100.00% <100.00%> (ø)
src/settings/GeneralSettingsPane.tsx 100.00% <100.00%> (ø)
... and 8 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@cguedes cguedes marked this pull request as ready for review June 19, 2023 15:10
@cguedes cguedes requested a review from sehyod June 19, 2023 15:10
@gjreda
Copy link
Collaborator

gjreda commented Jun 19, 2023

I'm probably not the best person to review the front-end code here, but the way we are doing the new env passing works for me.

sehyod
sehyod previously approved these changes Jun 20, 2023
src/components/PrimarySideBar.test.tsx Outdated Show resolved Hide resolved
sehyod
sehyod previously approved these changes Jun 20, 2023
@cguedes cguedes mentioned this pull request Jun 21, 2023
11 tasks
@cguedes cguedes requested a review from sehyod June 21, 2023 15:42
@sergioramos sergioramos merged commit cb9c10f into main Jun 21, 2023
11 checks passed
@sergioramos sergioramos deleted the 76-configuration-screen branch June 21, 2023 15:45
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.

Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Configuration screen
6 participants