Skip to content

fix: Edit deployment variable#164

Merged
adityachoudhari26 merged 1 commit intomainfrom
edit-deployment-variable
Oct 23, 2024
Merged

fix: Edit deployment variable#164
adityachoudhari26 merged 1 commit intomainfrom
edit-deployment-variable

Conversation

@adityachoudhari26
Copy link
Copy Markdown
Member

@adityachoudhari26 adityachoudhari26 commented Oct 23, 2024

Summary by CodeRabbit

  • New Features

    • Introduced the EditVariableDialog component for editing variable data within a dialog interface.
    • Enhanced VariableDropdown to include the EditVariableDialog, allowing users to edit variables directly from the dropdown menu.
  • Bug Fixes

    • Updated internal state management for dropdown visibility in VariableDropdown.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 23, 2024

Walkthrough

A new React component named EditVariableDialog has been added to facilitate the editing of variable data within a dialog interface. It integrates form validation using zod and manages its open/closed state internally. The VariableDropdown component has been modified to incorporate this dialog, enhancing its functionality by allowing users to edit variables directly from the dropdown menu. The changes include updates to the component's state management and the structure of the dropdown menu.

Changes

File Change Summary
apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/variables/EditVariableDialog.tsx Introduced EditVariableDialog component for editing variable data with form validation using zod.
apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/variables/VariableDropdown.tsx Updated to include EditVariableDialog, modified internal state management, and changed variable type from DeploymentVariable to VariableData.

Possibly related PRs

  • fix: Variable sets #150: The changes in this PR involve the introduction of a new React component EditVariableDialog, which is related to the modifications made in VariableDropdown.tsx where the EditVariableDialog is utilized to enhance the dropdown's functionality for editing variables.

Suggested reviewers

  • jsbroks

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (2)
apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/variables/VariableDropdown.tsx (1)

78-89: LGTM: Clean dialog integration with consistent patterns.

The EditVariableDialog integration follows the same pattern as other actions and properly manages state.

Consider extracting the common menu item styles to avoid repetition:

+const menuItemStyles = "flex items-center gap-2";

 <EditVariableDialog
   variable={variable}
   onClose={() => setOpen(false)}
 >
   <DropdownMenuItem
-    className="flex items-center gap-2"
+    className={menuItemStyles}
     onSelect={(e) => e.preventDefault()}
   >
apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/variables/EditVariableDialog.tsx (1)

58-65: Enhance accessibility support.

Consider adding the following accessibility improvements:

  1. ARIA labels for the dialog
  2. Keyboard navigation handling
 <Dialog
   open={open}
   onOpenChange={(o) => {
     setOpen(o);
     if (!o) onClose();
   }}
+  aria-label="Edit Variable"
 >
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 109f733 and 29194ae.

📒 Files selected for processing (2)
  • apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/variables/EditVariableDialog.tsx (1 hunks)
  • apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/variables/VariableDropdown.tsx (3 hunks)
🧰 Additional context used
🔇 Additional comments (4)
apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/variables/VariableDropdown.tsx (3)

72-72: LGTM: Clean state management implementation.

The dropdown's open state is properly managed and correctly passed to the DropdownMenu component.

Also applies to: 74-74


1-1: Verify the impact of type change from DeploymentVariable to VariableData.

The change in type from DeploymentVariable to VariableData needs verification to ensure compatibility across the codebase.

Also applies to: 25-25, 28-28


69-69: Verify the variable object structure matches VariableData type.

Ensure that all properties required by the VariableData type are present in the variable prop passed to this component.

✅ Verification successful

Let me try different search patterns to find the type definition and component usage.

The previous command failed due to typescript file type not being recognized. Let's try with plain text search to find the relevant information about the type structure and component usage.


Let me search for the schema.DeploymentVariable type definition since VariableData extends it.

This will help us understand the complete structure of VariableData type by finding its base type definition.


Based on the search results, I can now provide a final response since we have found the type definitions and their relationships:

Type change from DeploymentVariable to VariableData is safe and consistent

The VariableData type in variable-data.ts is defined as:

export type VariableData = schema.DeploymentVariable & {
  values: VariableValue[];
};

It extends schema.DeploymentVariable and adds a values array property, making it a superset of the original type. This means the type change is backward compatible and all properties from the original type are preserved, with additional type safety for the values array.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for VariableData type definition
ast-grep --pattern 'type VariableData = {
  $$$
}'

# Search for usage of this component to verify prop passing
rg "<VariableDropdown" -A 3 --type typescript

Length of output: 224


Script:

#!/bin/bash
# Search for VariableData type/interface definition
rg "type VariableData|interface VariableData" -A 5

# Search for VariableDropdown component usage
rg "VariableDropdown.*variable=" -A 2

# Search for imports of VariableData
rg "import.*VariableData.*from"

Length of output: 1648


Script:

#!/bin/bash
# Search for DeploymentVariable type/interface in schema
rg "DeploymentVariable" -A 10 --type ts

# Search for the schema import source
rg "import.*schema.*from" -A 1 apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/variables/variable-data.ts

Length of output: 40897

apps/webservice/src/app/[workspaceSlug]/systems/[systemSlug]/deployments/[deploymentSlug]/variables/EditVariableDialog.tsx (1)

1-26: LGTM! Well-organized imports.

The imports are logically grouped and include all necessary dependencies.

Comment on lines +28 to +32
const schema = z.object({
key: z.string().min(1),
description: z.string().min(1).max(1000),
defaultValueId: z.string().uuid().nullable(),
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider strengthening key validation rules.

While the current schema validates basic requirements, consider adding more specific validation rules for the key field:

  • Pattern validation for allowed characters
  • Format requirements (e.g., no spaces, valid variable name format)
  • Maximum length constraint
 const schema = z.object({
-  key: z.string().min(1),
+  key: z.string()
+    .min(1)
+    .max(255)
+    .regex(/^[a-zA-Z][a-zA-Z0-9_]*$/, 'Key must start with a letter and contain only letters, numbers, and underscores'),
   description: z.string().min(1).max(1000),
   defaultValueId: z.string().uuid().nullable(),
 });
📝 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.

Suggested change
const schema = z.object({
key: z.string().min(1),
description: z.string().min(1).max(1000),
defaultValueId: z.string().uuid().nullable(),
});
const schema = z.object({
key: z.string()
.min(1)
.max(255)
.regex(/^[a-zA-Z][a-zA-Z0-9_]*$/, 'Key must start with a letter and contain only letters, numbers, and underscores'),
description: z.string().min(1).max(1000),
defaultValueId: z.string().uuid().nullable(),
});

Comment on lines +69 to +121
<form onSubmit={onSubmit} className="space-y-6">
<FormField
control={form.control}
name="key"
render={({ field }) => (
<FormItem>
<FormLabel>Key</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="description"
render={({ field }) => (
<FormItem>
<FormLabel>Description</FormLabel>
<FormControl>
<Textarea {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="defaultValueId"
render={({ field: { value, onChange } }) => (
<FormItem>
<FormLabel>Default value</FormLabel>
<FormControl>
<Select value={value ?? undefined} onValueChange={onChange}>
<SelectTrigger>
<SelectValue placeholder="Default value..." />
</SelectTrigger>
<SelectContent>
{variable.values.map((v) => (
<SelectItem key={v.id} value={v.id}>
{v.value}
</SelectItem>
))}
</SelectContent>
</Select>
</FormControl>
</FormItem>
)}
/>
</form>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add form actions and handle unsaved changes.

The form lacks action buttons and unsaved changes handling. Consider:

  1. Adding Submit and Cancel buttons
  2. Confirming with user before discarding unsaved changes
 <form onSubmit={onSubmit} className="space-y-6">
   {/* existing form fields */}
+  <div className="flex justify-end space-x-2 mt-6">
+    <Button
+      type="button"
+      variant="outline"
+      onClick={() => {
+        if (form.formState.isDirty) {
+          // Add confirmation dialog here
+          if (!confirm('Discard unsaved changes?')) return;
+        }
+        setOpen(false);
+      }}
+    >
+      Cancel
+    </Button>
+    <Button type="submit" disabled={isSubmitting}>
+      {isSubmitting ? 'Saving...' : 'Save Changes'}
+    </Button>
+  </div>
 </form>

Committable suggestion was skipped due to low confidence.

Comment on lines +45 to +56
const [open, setOpen] = useState(false);
const update = api.deployment.variable.update.useMutation();
const router = useRouter();
const form = useForm({ schema, defaultValues: { ...variable } });

const onSubmit = form.handleSubmit(async (data) =>
update
.mutateAsync({ id: variable.id, data })
.then(() => form.reset(data))
.then(() => router.refresh())
.then(() => setOpen(false)),
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling and loading state management.

The form submission lacks error handling and user feedback mechanisms. Consider:

  1. Error handling for failed mutations
  2. Loading state during submission
  3. User feedback for success/failure
 export const EditVariableDialog: React.FC<EditVariableDialogProps> = ({
   variable,
   onClose,
   children,
 }) => {
   const [open, setOpen] = useState(false);
+  const [isSubmitting, setIsSubmitting] = useState(false);
   const update = api.deployment.variable.update.useMutation();
   const router = useRouter();
   const form = useForm({ schema, defaultValues: { ...variable } });

   const onSubmit = form.handleSubmit(async (data) => {
+    setIsSubmitting(true);
     update
       .mutateAsync({ id: variable.id, data })
       .then(() => form.reset(data))
       .then(() => router.refresh())
-      .then(() => setOpen(false)),
+      .then(() => setOpen(false))
+      .catch((error) => {
+        console.error('Failed to update variable:', error);
+        // Add toast or other user feedback mechanism here
+      })
+      .finally(() => setIsSubmitting(false));
   });
📝 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.

Suggested change
const [open, setOpen] = useState(false);
const update = api.deployment.variable.update.useMutation();
const router = useRouter();
const form = useForm({ schema, defaultValues: { ...variable } });
const onSubmit = form.handleSubmit(async (data) =>
update
.mutateAsync({ id: variable.id, data })
.then(() => form.reset(data))
.then(() => router.refresh())
.then(() => setOpen(false)),
);
const [open, setOpen] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const update = api.deployment.variable.update.useMutation();
const router = useRouter();
const form = useForm({ schema, defaultValues: { ...variable } });
const onSubmit = form.handleSubmit(async (data) => {
setIsSubmitting(true);
update
.mutateAsync({ id: variable.id, data })
.then(() => form.reset(data))
.then(() => router.refresh())
.then(() => setOpen(false))
.catch((error) => {
console.error('Failed to update variable:', error);
// Add toast or other user feedback mechanism here
})
.finally(() => setIsSubmitting(false));
});

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.

1 participant