Skip to content

Conversation

@sahilmane69
Copy link

This PR improves the UX of the existing DatasetUpload component by:

  • Preventing double submissions
  • Adding loading state and disabling inputs during upload
  • Showing clear success and error feedback

No backend or API changes.
Related to Issue #59.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @sahilmane69, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the user experience for uploading training datasets by introducing a dedicated DatasetUpload component. The changes focus on improving UI responsiveness and providing clear feedback, ensuring that users are aware of the upload status, preventing accidental double submissions, and receiving explicit notifications for successful uploads or encountered errors. This is purely a frontend improvement with no backend or API modifications.

Highlights

  • New Dataset Upload Component: Introduced a brand new DatasetUpload React component to handle the process of uploading training data.
  • Improved User Experience: Enhanced the user experience by implementing loading states, disabling inputs during upload, and preventing double submissions.
  • Clear Feedback Mechanism: Added clear success and error feedback messages to inform the user about the outcome of their upload attempts.
  • Git Ignore Update: Added node_modules/ to the .gitignore file to prevent tracking generated dependencies.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new DatasetUpload component with improved user experience for file uploads, including loading states and feedback messages. The changes are well-structured. My review focuses on improving maintainability, accessibility, and robustness of the new component. I've suggested adding client-side file validation, improving error handling, making the component more accessible for screen reader users, and extracting hardcoded values into constants for better maintainability.

Comment on lines +8 to +13
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files[0]) {
setFile(e.target.files[0])
setStatus(null)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The component currently doesn't perform any client-side validation on the selected file. Based on the backend code, it seems to expect a CSV file. You should add validation to check the file type (e.g., text/csv) and potentially the file size to provide immediate feedback to the user and prevent unnecessary uploads of invalid files. This improves user experience and reduces load on the backend.

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFile = e.target.files?.[0];
    if (selectedFile) {
      if (!selectedFile.type.includes('csv')) {
        setStatus({ type: 'error', message: 'Invalid file type. Please upload a CSV file.' });
        setFile(null);
        e.target.value = ''; // Reset input to allow re-selecting the same file
        return;
      }

      setFile(selectedFile);
      setStatus(null);
    }
  }

const DatasetUpload: React.FC = () => {
const [file, setFile] = useState<File | null>(null)
const [isUploading, setIsUploading] = useState(false)
const [status, setStatus] = useState<{ type: 'success' | 'error'; message: string } | null>(null)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The component uses hardcoded strings for status messages on lines 33, 36, and 39. It's a best practice to extract these into a constants object. This improves maintainability, reduces the chance of typos, and makes future internationalization easier.

Example:

const STATUS_MESSAGES = {
  SUCCESS: 'Dataset uploaded successfully!',
  FAILURE: 'Failed to upload dataset. Please try again.',
  NETWORK_ERROR: 'Network error. Please check your connection.',
};

// Then use it like:
setStatus({ type: 'success', message: STATUS_MESSAGES.SUCCESS });

formData.append('file', file)

try {
const response = await fetch('/api/v1/training-datasets/upload', {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The API endpoint URL /api/v1/training-datasets/upload is hardcoded. It's better to store it in a central configuration file or as a constant. This makes it easier to manage and update API endpoints, especially if they are used in multiple places or need to change between environments.

For example, you could define a constant at the top of the component:
const UPLOAD_API_ENDPOINT = '/api/v1/training-datasets/upload';
...and then use it in the fetch call.

Comment on lines +35 to +37
} else {
setStatus({ type: 'error', message: 'Failed to upload dataset. Please try again.' })
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The error message for a failed upload is generic. The backend might provide a more specific error message in the response body. You should attempt to parse the response to get a more descriptive error message. This will improve the user experience by providing more context about what went wrong.

      } else {
        let errorMessage = 'Failed to upload dataset. Please try again.';
        try {
          const errorData = await response.json();
          if (errorData && errorData.message) {
            errorMessage = errorData.message;
          }
        } catch {
          // Ignore if response is not JSON
        }
        setStatus({ type: 'error', message: errorMessage });
      }

Comment on lines +50 to +61
<input
type="file"
onChange={handleFileChange}
disabled={isUploading}
className="block w-full text-sm text-gray-400
file:mr-4 file:py-2 file:px-4
file:rounded-full file:border-0
file:text-sm file:font-semibold
file:bg-indigo-600 file:text-white
hover:file:bg-indigo-700
disabled:opacity-50 disabled:cursor-not-allowed"
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This file input is missing an associated <label>. Labels are crucial for accessibility as they provide context for screen reader users. You should wrap the input with a label. You can add a visually hidden span inside the label for screen reader text (e.g., using Tailwind's sr-only class).

        <label>
          <span className="sr-only">Choose a file to upload</span>
          <input
            type="file"
            onChange={handleFileChange}
            disabled={isUploading}
            className="block w-full text-sm text-gray-400
              file:mr-4 file:py-2 file:px-4
              file:rounded-full file:border-0
              file:text-sm file:font-semibold
              file:bg-indigo-600 file:text-white
              hover:file:bg-indigo-700
              disabled:opacity-50 disabled:cursor-not-allowed"
          />
        </label>

Comment on lines +64 to +72
<div
className={`p-3 rounded text-sm ${
status.type === 'success'
? 'bg-green-900/50 text-green-300'
: 'bg-red-900/50 text-red-300'
}`}
>
{status.message}
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The status message updates dynamically, but screen readers may not announce these changes. To improve accessibility, you should add role="status" and aria-live="polite" to the status message container. This ensures that users of assistive technologies are notified of the upload status.

          <div
            role="status"
            aria-live="polite"
            className={`p-3 rounded text-sm ${
              status.type === 'success'
                ? 'bg-green-900/50 text-green-300'
                : 'bg-red-900/50 text-red-300'
            }`}
          >
            {status.message}
          </div>

@abhishek-nexgen-dev
Copy link
Member

@sahilmane69 Please Refer Figma file to make Ui Batter

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.

2 participants