-
Notifications
You must be signed in to change notification settings - Fork 17
feat: add bulk import for environment variables #124
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
base: main
Are you sure you want to change the base?
Conversation
Add utility function to parse .env file content into key-value pairs. Handles comments, empty lines, quoted values, and duplicate keys.
Add modal dialog for importing environment variables from .env content. Supports both pasting content and file upload with real-time preview.
Add Bulk Import button and modal integration. Imported variables merge with existing ones (duplicates are replaced).
Apply the same bulk import functionality to the add-new-agent page.
This fixes the empty first row issue that occurred after bulk importing environment variables.
Enables bulk import modal usage in the add new agent page.
Gets current form values directly at import time instead of relying on memoized watched values.
📝 WalkthroughWalkthroughAdds a bulk-import modal and .env parser, integrates import UI into environment-variable editors (shared and page-level), and re-exports the new component and utilities from the shared-component package. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Modal as EnvBulkImportModal
participant Parser as parseEnvContent
participant Form as EnvironmentVariable
User->>Modal: Open modal
User->>Modal: Paste content / Upload file
Modal->>Modal: Read textarea or file text
Note right of Modal: Live variable count\nand invalid-key warnings
User->>Modal: Click Import
Modal->>Parser: parseEnvContent(content)
Parser-->>Modal: { valid: EnvVariable[], invalid: string[] }
Modal->>Form: onImport(valid)
Form->>Form: Merge imported vars by key\n(import overrides), drop empty rows
Form-->>User: Updated form state/display
Modal->>Modal: Clear content and close
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
console/workspaces/libs/shared-component/src/components/EnvironmentVariable.tsx (1)
19-115: Consider consolidating duplicate EnvironmentVariable components.This component is nearly identical to the one in
console/workspaces/pages/add-new-agent/src/components/EnvironmentVariable.tsx, with only minor differences in import paths and styling. Since both components share the same logic for handling environment variables and bulk imports, consolidating them into a single shared implementation would:
- Reduce code duplication
- Simplify maintenance
- Ensure consistent behavior across pages
Consider using this shared-component version in add-new-agent by importing it rather than maintaining two separate implementations.
🔎 Verification: Check if EnvironmentVariable is exported from shared-component
#!/bin/bash # Check if EnvironmentVariable is exported from shared-component index rg -n "EnvironmentVariable" console/workspaces/libs/shared-component/src/components/index.ts console/workspaces/libs/shared-component/src/index.tsconsole/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (1)
61-79: Consider adding error handling for file upload.The file upload handler lacks error handling for:
- FileReader errors (e.g., file read failures)
- Large file sizes that might cause browser issues
- Non-text file content
For production robustness, consider adding:
const handleFileUpload = useCallback( (e: ChangeEvent<HTMLInputElement>) => { const file = e.target.files?.[0]; if (!file) return; // Optional: check file size (e.g., 1MB limit) if (file.size > 1024 * 1024) { // Show error to user return; } const reader = new FileReader(); reader.onload = (event) => { const text = event.target?.result; if (typeof text === "string") { setContent(text); } }; reader.onerror = () => { // Show error to user }; reader.readAsText(file); e.target.value = ""; }, [] );
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
console/common/config/rush/pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (8)
console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsxconsole/workspaces/libs/shared-component/src/components/EnvironmentVariable.tsxconsole/workspaces/libs/shared-component/src/components/index.tsconsole/workspaces/libs/shared-component/src/index.tsconsole/workspaces/libs/shared-component/src/utils/envParser.tsconsole/workspaces/libs/shared-component/src/utils/index.tsconsole/workspaces/pages/add-new-agent/package.jsonconsole/workspaces/pages/add-new-agent/src/components/EnvironmentVariable.tsx
🧰 Additional context used
🧬 Code graph analysis (3)
console/workspaces/libs/shared-component/src/utils/envParser.ts (1)
console/workspaces/libs/shared-component/src/utils/index.ts (2)
EnvVariable(20-20)parseEnvContent(19-19)
console/workspaces/pages/add-new-agent/src/components/EnvironmentVariable.tsx (2)
console/workspaces/libs/shared-component/src/components/EnvironmentVariable.tsx (1)
EnvironmentVariable(27-115)console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (1)
EnvBulkImportModal(39-190)
console/workspaces/libs/shared-component/src/components/EnvironmentVariable.tsx (2)
console/workspaces/pages/add-new-agent/src/components/EnvironmentVariable.tsx (1)
EnvironmentVariable(26-104)console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (1)
EnvBulkImportModal(39-190)
🔇 Additional comments (17)
console/workspaces/libs/shared-component/src/components/index.ts (1)
28-28: LGTM!The export follows the established barrel pattern and correctly exposes the new EnvBulkImportModal component.
console/workspaces/libs/shared-component/src/index.ts (1)
20-20: LGTM!The export correctly expands the public API to include utilities (parseEnvContent and EnvVariable type) for use by consumers.
console/workspaces/pages/add-new-agent/package.json (1)
52-52: LGTM!The workspace dependency correctly enables the add-new-agent page to consume EnvBulkImportModal and related utilities from the shared-component library.
console/workspaces/libs/shared-component/src/utils/index.ts (1)
19-20: LGTM!The barrel exports correctly separate type and value exports, following TypeScript best practices for public API design.
console/workspaces/libs/shared-component/src/utils/envParser.ts (3)
19-22: LGTM!The EnvVariable interface appropriately models environment variables with a simple key-value structure.
25-34: LGTM!The stripQuotes helper correctly handles basic quote stripping for single and double quotes, which is appropriate for typical .env file formats.
37-70: LGTM!The parseEnvContent function implements a solid basic .env parser that handles:
- Cross-platform line endings
- Comments and empty lines
- Quoted values (single and double)
- Duplicate keys (last value wins)
- Proper key-value splitting at the first
=The implementation is appropriate for typical .env file formats and aligns with the PR objectives.
console/workspaces/pages/add-new-agent/src/components/EnvironmentVariable.tsx (5)
19-19: LGTM!The imports are correctly structured and all new dependencies (useState, useCallback, useMemo, FileText, EnvBulkImportModal, EnvVariable) are properly utilized in the component.
Also applies to: 21-21, 24-24
27-30: LGTM!The hook additions correctly support the bulk import feature:
getValuesavoids stale closures in handleImportreplaceenables swapping the entire env arrayuseWatchprovides reactive env valuesuseStatemanages modal visibility
32-36: LGTM!The memoization correctly stabilizes envValues for use in callbacks and validation logic, preventing unnecessary re-renders and ensuring consistent behavior.
Also applies to: 38-38
41-64: LGTM!The handleImport merge logic correctly:
- Uses
getValuesto avoid stale closures- Filters empty rows before merging
- Uses a Map for efficient key-based merging (imported values override existing)
- Preserves key insertion order (existing keys maintain position, new imports append)
- Replaces the entire array for clean state management
87-100: LGTM!The UI integration correctly adds:
- A "Bulk Import" button with appropriate icon and styling
- EnvBulkImportModal properly wired with open state and handlers
The implementation provides a smooth user experience for bulk importing environment variables.
console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (5)
19-31: LGTM!All imports are correctly structured and utilized throughout the component.
33-37: LGTM!The props interface correctly defines a standard modal contract with clear responsibilities for open state, close handling, and import callback.
44-50: LGTM!State management is clean and efficient:
- Content state for user input
- Ref for file input control
- Memoized parsing to avoid redundant work
87-99: LGTM!Both handlers are correctly implemented:
- handleImport validates count before proceeding and properly cleans up
- handleClose ensures clean state reset
101-189: LGTM!The UI implementation is excellent:
- Clean dialog structure with appropriate sizing
- Monospace textarea with helpful placeholder and theme-aware styling
- Standard file upload pattern with clear accept types
- Real-time visual feedback via count indicator with color coding
- Proper button states (Import disabled when no variables detected)
The user experience is intuitive and polished.
- Updated button text from 'Bulk Import' to 'Import' - Updated modal title from 'Bulk Import Environment Variables' to 'Import Environment Variables'
|
@menakaj , #106 (comment) is done. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
console/workspaces/libs/shared-component/src/components/EnvironmentVariable.tsx (2)
41-65: Merge logic is well-implemented.Good approach using
getValues()to read fresh form state and aMapfor deduplication. The imported variables correctly override existing ones with the same key.One consideration: line 47 filters out entries where
valueis falsy, which would exclude intentionally empty values (e.g.,EMPTY_VAR=). If empty values are valid in your use case, you might want to adjust the filter to only check for the key:- const nonEmptyExisting = currentEnv.filter((env) => env?.key && env?.value); + const nonEmptyExisting = currentEnv.filter((env) => env?.key);This is a design decision—current behavior matches the PR description of "empty rows ignored."
107-112: Modal integration is correct.The modal is properly controlled with state. The inline
onClosehandler creates a new function reference on each render—if you're concerned about re-render performance, you could memoize it:const handleModalClose = useCallback(() => setImportModalOpen(false), []);This is a minor optimization and likely unnecessary given the modal's usage pattern.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsxconsole/workspaces/libs/shared-component/src/components/EnvironmentVariable.tsxconsole/workspaces/pages/add-new-agent/src/components/EnvironmentVariable.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx
🧰 Additional context used
🧬 Code graph analysis (2)
console/workspaces/libs/shared-component/src/components/EnvironmentVariable.tsx (2)
console/workspaces/pages/add-new-agent/src/components/EnvironmentVariable.tsx (1)
EnvironmentVariable(26-104)console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (1)
EnvBulkImportModal(39-190)
console/workspaces/pages/add-new-agent/src/components/EnvironmentVariable.tsx (2)
console/workspaces/libs/shared-component/src/components/EnvironmentVariable.tsx (1)
EnvironmentVariable(27-115)console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (1)
EnvBulkImportModal(39-190)
🔇 Additional comments (11)
console/workspaces/libs/shared-component/src/components/EnvironmentVariable.tsx (5)
19-25: Imports are well-organized and complete.All new imports are necessary for the bulk import feature: hooks for state management, the FileText icon for the button, and the modal component with its type.
27-31: Good use of react-hook-form APIs.Using
getValues()inside the callback instead of relying on watched values avoids stale closure issues. Thereplacemethod fromuseFieldArrayis the correct choice for bulk updates.
33-39: Memoization and validation logic looks correct.The
useMemostabilizes theenvValuesreference, and the optional chaining inisOneEmptysafely handles potential null/undefined entries.
75-86: Fields rendering follows react-hook-form best practices.Using
field.idas the key (rather thanindex) ensures stable component identity when fields are reordered or removed.
88-106: Action buttons are well-structured.The Import button being always enabled (unlike Add) is a good UX choice—users can import regardless of current form state, and the merge logic handles cleanup.
console/workspaces/pages/add-new-agent/src/components/EnvironmentVariable.tsx (6)
19-24: LGTM!The imports are well-organized and all are used within the component. Good use of shared components and types from
@agent-management-platform/shared-component.
27-38: Well-structured hook setup with proper memoization.Good practices observed:
- Using
getValuesinsidehandleImportto get fresh form values avoids stale closure issues.- Memoizing
envValuesstabilizes the dependency for downstream logic.- The
isOneEmptycheck prevents users from creating multiple empty rows, which is good UX.
40-64: Import merge logic is well-implemented.The approach of using a
Mapfor deduplication and merging is clean. Key observations:
- Correctly avoids stale closures by calling
getValues('env')inside the callback.- Imported variables properly override existing ones with the same key.
- JavaScript
Mapmaintains insertion order, preserving the sequence of variables.One note: rows where only the key OR only the value is set will be discarded during import (line 46 requires both). This appears intentional for cleaner merges, but worth confirming this matches the expected UX.
75-85: LGTM!Correctly uses
field.idas the key for the mapped elements, which is the recommended approach foruseFieldArray. The props passed toEnvVariableEditorare consistent with the component's API.
87-94: Clean button layout implementation.The side-by-side Add and Import buttons provide a clear UX. The
isOneEmptycheck on the Add button appropriately prevents multiple empty rows.
96-100: LGTM!The
EnvBulkImportModalis properly wired with the necessary props. The modal handles its internal state cleanup on close (clearing content), and thehandleImportcallback is correctly passed for the merge operation.
console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx
Outdated
Show resolved
Hide resolved
- Added regex validation for env variable keys (POSIX standard) - Parser now returns both valid entries and invalid keys - Modal displays error feedback showing which keys were skipped - Added explanation of valid key format to help users
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Fix all issues with AI Agents 🤖
In
@console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx:
- Around line 125-146: The textarea in EnvBulkImportModal (the Box with
component="textarea" using value={content} and onChange={handleContentChange})
lacks an accessibility label; add an ARIA label or associate it with a visible
label by adding an aria-label (e.g., "Environment variables input" or similar)
or aria-labelledby referencing a nearby label element to describe its purpose
for screen readers, ensuring the attribute is applied directly on the Box
element.
♻️ Duplicate comments (1)
console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (1)
150-155: Add accept attribute to file input for better UX.The file input is missing an
acceptattribute, which relates to a previous review comment about verifying that .env files are shown in the file browser. Addingaccept=".env,text/plain"would help filter the file picker, though note that.envfiles may not be visible in some OS file browsers since they're hidden files by default on Unix-like systems.🔎 Suggested improvement
<input ref={fileInputRef} type="file" + accept=".env,text/plain" onChange={handleFileUpload} style={{ display: "none" }} + aria-label="Upload environment variables file" />You may want to manually test that .env files appear in the file browser on different operating systems (macOS, Windows, Linux) to confirm the user experience.
🧹 Nitpick comments (1)
console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (1)
181-181: Use theme alpha helper for color transparency.The color alpha manipulation using string concatenation (
theme.palette.error.light + '20') is non-standard. While it may work in some contexts, it's better to use MUI'salpha()helper function or CSS rgba() for proper color transparency.🔎 Recommended fix using alpha helper
Add alpha import at the top of the file:
import { Box, Button, Dialog, DialogTitle, DialogContent, DialogActions, Typography, useTheme, + alpha, } from "@wso2/oxygen-ui";Then update line 181:
sx={{ padding: 1.5, - backgroundColor: theme.palette.error.light + '20', + backgroundColor: alpha(theme.palette.error.light, 0.12), borderRadius: 1, border: `1px solid ${theme.palette.error.light}`, }}
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsxconsole/workspaces/libs/shared-component/src/utils/envParser.tsconsole/workspaces/libs/shared-component/src/utils/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- console/workspaces/libs/shared-component/src/utils/index.ts
- console/workspaces/libs/shared-component/src/utils/envParser.ts
🧰 Additional context used
🧬 Code graph analysis (1)
console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (2)
console/workspaces/libs/shared-component/src/utils/envParser.ts (2)
EnvVariable(19-22)parseEnvContent(51-92)console/workspaces/libs/shared-component/src/utils/index.ts (2)
EnvVariable(20-20)parseEnvContent(19-19)
🔇 Additional comments (10)
console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx (10)
19-31: LGTM!All imports are necessary and properly structured for the component's functionality.
33-37: LGTM!The interface is well-defined with appropriate types for a modal component.
39-51: LGTM!Proper use of
useMemoto optimize parsing performance, and state management is correctly structured.
53-59: LGTM!The textarea change handler is properly implemented with
useCallbackoptimization.
82-85: LGTM!Standard pattern for triggering the hidden file input.
87-94: LGTM!The import handler correctly validates that variables exist before importing and properly cleans up state.
96-100: LGTM!Proper cleanup of modal state before closing.
166-174: LGTM!The variables count indicator with proper singular/plural handling provides helpful real-time feedback to users.
177-196: LGTM!Excellent user feedback for invalid keys! The warning box clearly shows which keys were skipped and explains the valid key format requirements, helping users quickly identify and fix issues.
200-209: LGTM!The dialog actions correctly disable the Import button when no valid variables are detected, preventing invalid operations.
| // Handle file upload | ||
| const handleFileUpload = useCallback( | ||
| (e: ChangeEvent<HTMLInputElement>) => { | ||
| const file = e.target.files?.[0]; | ||
| if (!file) return; | ||
|
|
||
| const reader = new FileReader(); | ||
| reader.onload = (event) => { | ||
| const text = event.target?.result; | ||
| if (typeof text === "string") { | ||
| setContent(text); | ||
| } | ||
| }; | ||
| reader.readAsText(file); | ||
|
|
||
| // Reset input so same file can be selected again | ||
| e.target.value = ""; | ||
| }, | ||
| [] | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add file size validation and error handling.
The file upload handler has the following concerns:
- Missing file size validation: Large files could cause memory issues or make the browser unresponsive.
- Missing error handling: If
FileReaderfails (e.g., unreadable file, permission issues), the user receives no feedback. - No file type validation: Binary or non-text files could be selected and cause issues.
🔎 Proposed fix with validation and error handling
const handleFileUpload = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
+
+ // Validate file size (e.g., max 1MB)
+ const MAX_FILE_SIZE = 1024 * 1024; // 1MB
+ if (file.size > MAX_FILE_SIZE) {
+ alert(`File is too large. Maximum size is ${MAX_FILE_SIZE / 1024}KB.`);
+ e.target.value = "";
+ return;
+ }
const reader = new FileReader();
+ reader.onerror = () => {
+ alert("Failed to read file. Please try again.");
+ e.target.value = "";
+ };
reader.onload = (event) => {
const text = event.target?.result;
if (typeof text === "string") {
setContent(text);
}
};
reader.readAsText(file);
// Reset input so same file can be selected again
e.target.value = "";
},
[]
);Note: Consider using a proper notification/toast system instead of alert() for better UX.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Handle file upload | |
| const handleFileUpload = useCallback( | |
| (e: ChangeEvent<HTMLInputElement>) => { | |
| const file = e.target.files?.[0]; | |
| if (!file) return; | |
| const reader = new FileReader(); | |
| reader.onload = (event) => { | |
| const text = event.target?.result; | |
| if (typeof text === "string") { | |
| setContent(text); | |
| } | |
| }; | |
| reader.readAsText(file); | |
| // Reset input so same file can be selected again | |
| e.target.value = ""; | |
| }, | |
| [] | |
| ); | |
| // Handle file upload | |
| const handleFileUpload = useCallback( | |
| (e: ChangeEvent<HTMLInputElement>) => { | |
| const file = e.target.files?.[0]; | |
| if (!file) return; | |
| // Validate file size (e.g., max 1MB) | |
| const MAX_FILE_SIZE = 1024 * 1024; // 1MB | |
| if (file.size > MAX_FILE_SIZE) { | |
| alert(`File is too large. Maximum size is ${MAX_FILE_SIZE / 1024}KB.`); | |
| e.target.value = ""; | |
| return; | |
| } | |
| const reader = new FileReader(); | |
| reader.onerror = () => { | |
| alert("Failed to read file. Please try again."); | |
| e.target.value = ""; | |
| }; | |
| reader.onload = (event) => { | |
| const text = event.target?.result; | |
| if (typeof text === "string") { | |
| setContent(text); | |
| } | |
| }; | |
| reader.readAsText(file); | |
| // Reset input so same file can be selected again | |
| e.target.value = ""; | |
| }, | |
| [] | |
| ); |
| <Box | ||
| component="textarea" | ||
| value={content} | ||
| onChange={handleContentChange} | ||
| placeholder={`# Example format:\nAPI_KEY=your_api_key\nDATABASE_URL=postgres://...\nDEBUG="true"`} | ||
| sx={{ | ||
| width: "100%", | ||
| minHeight: 200, | ||
| padding: 1.5, | ||
| fontFamily: "monospace", | ||
| fontSize: 13, | ||
| border: `1px solid ${theme.palette.divider}`, | ||
| borderRadius: 1, | ||
| resize: "vertical", | ||
| backgroundColor: theme.palette.background.paper, | ||
| color: theme.palette.text.primary, | ||
| "&:focus": { | ||
| outline: "none", | ||
| borderColor: theme.palette.primary.main, | ||
| }, | ||
| }} | ||
| /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add accessibility label to textarea.
The textarea is missing an aria-label attribute, which is an accessibility blocker for screen reader users who need to understand the purpose of the input field.
🔎 Proposed fix
<Box
component="textarea"
value={content}
onChange={handleContentChange}
placeholder={`# Example format:\nAPI_KEY=your_api_key\nDATABASE_URL=postgres://...\nDEBUG="true"`}
+ aria-label="Environment variables content"
sx={{
width: "100%",
minHeight: 200,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Box | |
| component="textarea" | |
| value={content} | |
| onChange={handleContentChange} | |
| placeholder={`# Example format:\nAPI_KEY=your_api_key\nDATABASE_URL=postgres://...\nDEBUG="true"`} | |
| sx={{ | |
| width: "100%", | |
| minHeight: 200, | |
| padding: 1.5, | |
| fontFamily: "monospace", | |
| fontSize: 13, | |
| border: `1px solid ${theme.palette.divider}`, | |
| borderRadius: 1, | |
| resize: "vertical", | |
| backgroundColor: theme.palette.background.paper, | |
| color: theme.palette.text.primary, | |
| "&:focus": { | |
| outline: "none", | |
| borderColor: theme.palette.primary.main, | |
| }, | |
| }} | |
| /> | |
| <Box | |
| component="textarea" | |
| value={content} | |
| onChange={handleContentChange} | |
| placeholder={`# Example format:\nAPI_KEY=your_api_key\nDATABASE_URL=postgres://...\nDEBUG="true"`} | |
| aria-label="Environment variables content" | |
| sx={{ | |
| width: "100%", | |
| minHeight: 200, | |
| padding: 1.5, | |
| fontFamily: "monospace", | |
| fontSize: 13, | |
| border: `1px solid ${theme.palette.divider}`, | |
| borderRadius: 1, | |
| resize: "vertical", | |
| backgroundColor: theme.palette.background.paper, | |
| color: theme.palette.text.primary, | |
| "&:focus": { | |
| outline: "none", | |
| borderColor: theme.palette.primary.main, | |
| }, | |
| }} | |
| /> |
🤖 Prompt for AI Agents
In
@console/workspaces/libs/shared-component/src/components/EnvBulkImportModal.tsx
around lines 125-146, The textarea in EnvBulkImportModal (the Box with
component="textarea" using value={content} and onChange={handleContentChange})
lacks an accessibility label; add an ARIA label or associate it with a visible
label by adding an aria-label (e.g., "Environment variables input" or similar)
or aria-labelledby referencing a nearby label element to describe its purpose
for screen readers, ensuring the attribute is applied directly on the Box
element.
- Added yup regex validation for env key field in add-new-agent form - Keys must start with letter/underscore, contain only alphanumeric and underscores
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
console/workspaces/pages/add-new-agent/src/form/schema.ts (1)
111-114: The regex patterns intentionally differ; do not extract as a shared constant.The schema regex
/^$|^[A-Za-z_][A-Za-z0-9_]*$/allows empty strings to support incomplete form rows (users can add rows and fill them incrementally). Thecomplete-pairstest (line 116–119) enforces that both key and value are filled or both are empty, and theunique-keystest filters empty keys, preventing conflicts.The
ENV_KEY_REGEXinenvParser.ts(/^[A-Za-z_][A-Za-z0-9_]*$/) intentionally does not allow empty strings because it validates parsed.envfile content, not form input. These serve different validation contexts and should remain separate.To improve clarity, add a comment in schema.ts explaining why the regex allows empty strings for the incomplete-pair use case.
Purpose
Resolves #106
Goals
Approach
User stories
Release note
Documentation
Training
Certification
Marketing
Automation tests
Security checks
Samples
Related PRs
Migrations (if applicable)
Test environment
Learning
Summary by CodeRabbit
New Features
Chores
Bug Fix / Validation
✏️ Tip: You can customize this high-level summary in your review settings.