Skip to content

Add integration with The Blue Alliance API#69

Merged
luanzeba merged 16 commits intomainfrom
luanzeba/add-blue-alliance-integration
Jan 25, 2026
Merged

Add integration with The Blue Alliance API#69
luanzeba merged 16 commits intomainfrom
luanzeba/add-blue-alliance-integration

Conversation

@luanzeba
Copy link
Collaborator

@luanzeba luanzeba commented Jan 31, 2025

What this adds

This PR brings Blue Alliance integration to QRScout, letting teams automatically populate match and team data instead of entering everything manually.

Demo

https://drive.google.com/file/d/1yngyo1dCD3IyDDvnJwL60g0vJDplahSF/view?usp=sharing

Key changes

New dialog

Added a "Prefill Match Data" button in the configuration panel. image
Once clicked, we use their team number from the JSON config to fetch all this year's events and present them to the user to choose from. Once the user chooses the event, we load all the match information into local storage. image
- In testing this, I found that the events don't show up in the blue alliance API until the day of the event for some reason.

New inputs

We added a couple of new input types for the JSON config:

TBA-match-number

This input uses the data fetched from The Blue Alliance API to populate a "select" input with all the qualifying matches from the specified event. CleanShot 2025-09-19 at 15 39 53@2x

TBA-team-and-robot

This input uses the data fetched from The Blue Alliance API to populate a "select" input with all the "team number (robot number)" options for match selected above. CleanShot 2025-09-19 at 15 25 52@2x
Both of these inputs fallback to a number input if anything goes wrong.

Added docs

README on the new input types

Note

We did not update the default config in this PR. We'll do that in a separate PR after thorough testing that these new inputs are behaving as expected.

@luanzeba luanzeba force-pushed the luanzeba/add-blue-alliance-integration branch from b61c79c to 6c7b83f Compare January 31, 2025 15:16
@github-actions
Copy link

github-actions bot commented Jan 31, 2025

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://FRC2713.github.io/QRScout/pr-preview/pr-69/

Built to branch gh-pages at 2026-01-25 12:59 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@luanzeba luanzeba marked this pull request as draft February 3, 2025 14:26
@luanzeba luanzeba force-pushed the luanzeba/add-blue-alliance-integration branch from 24c058c to 9f539b3 Compare April 2, 2025 02:07
@luanzeba luanzeba force-pushed the luanzeba/add-blue-alliance-integration branch 2 times, most recently from 26d6904 to 3430408 Compare September 19, 2025 19:43
luanzeba and others added 11 commits January 15, 2026 21:55
1. Prefill match data information for your team prior to the event.
   - Before scouting an event, click the new "Prefill Match Data"
     button.
   - This will fetch all events for the current year for your team based
     on the config file and provide you with a dialog to choose which
     event to use for match data.
   - Once the event is selected, it will fetch and store all matches for
     that event into our local storage-backed state.
   - If no internet is available, we display an error to the user but no
     state is lost.
2. DynamicMatchNumberInput Component:
   - Shows a dropdown select menu with all qualification match numbers when match data is available.
   - Falls back to a standard number input when no match data is available.
   - Maintains all other features of the original NumberInput component.
3. DynamicTeamNumberInput Component:
   - Automatically populates based on the selected match number and robot position ("R1", "B2", etc.).
   - Shows a dropdown with the correct team number when available.
   - Automatically sets the team number value when a valid option is found.
   - Falls back to a standard number input when no match data is available or no robot position is selected.
4. Updated ConfigurableInput:
   - Special case handling for "matchNumber" and "teamNumber" fields.
   - Uses the dynamic input components for these fields.
   - Maintains the original components for all other fields.

This implementation:
- Shows a dropdown select input for match number only when there's match data in the state
- Shows a dropdown select input for team number when both match data is available and a match is selected
- Automatically populates the team number based on the robot position from the dropdown
- Preserves existing functionality when no match data is available
- Fails gracefully if the form doesn't have match number or team number inputs

The code is designed to respect the existing patterns and structure of the application while adding the new functionality in a clean, maintainable way.
1. Self-contained functionality:
  - The MatchDataFetcher now includes its own button and dialog handling
  - It no longer requires a render prop or children function pattern
  - No need for external refs or state handling by the parent component
2. Clearer separation of concerns:
  - Each component is now responsible for its own domain
  - ConfigSection is responsible for layout and general section functionality
  - MatchDataFetcher is solely responsible for the TBA data fetching workflow
3. Simplified parent component:
  - Removed unnecessary state, refs, and effect hooks from ConfigSection
  - Reduced the number of imports in ConfigSection
  - Eliminated complex prop-passing and render prop patterns
- Add `TBA-match-number` input type for selecting qualification matches
- Add `TBA-team-and-robot` input type for selecting teams with robot positions
- Replace dynamic field overrides with proper configurable input types
- Teams can now control Blue Alliance integration through JSON config
- Remove old DynamicMatchNumberInput and DynamicTeamNumberInput components
- Update cmdk dependency to fix missing component issue

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit refines the Blue Alliance integration by renaming components for better clarity and adding extensive documentation to help teams understand and configure the TBA features.

The original TeamAndRobotInput has been renamed to TBATeamAndRobotInput to make its purpose immediately clear - it's specifically designed for The Blue Alliance integration, not just any team selection. We also updated all the schema names to use the "tba" prefix consistently throughout the codebase.

We encountered an interesting challenge when trying to reuse the existing NumberInput component for fallback scenarios. The NumberInput expects a full ConfigurableInputProps interface including a type field, but our TBA components need to manage their own state and behavior differently. Rather than forcing an awkward integration, we opted to implement clean, focused fallback inputs that maintain the same validation logic but don't try to share code where it doesn't naturally fit.

The documentation has been significantly expanded to match the quality and depth of the existing input type documentation. The new TBA section in the README explains both input types, provides complete configuration examples, covers the data formats teams can expect in their QR codes, and includes practical FRC scouting scenarios. We also made sure to link to the detailed API setup guide we created earlier, giving teams a complete picture of how to get started with TBA integration.

This approach follows QRScout's philosophy of giving users control - the TBA inputs enhance the experience when match data is available, but gracefully fall back to manual entry when needed. Teams can start using these inputs immediately and add the API integration later when they're ready.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add CONTRIBUTING.md with setup instructions for new developers
- Add .env.example template for environment variables
- Update .gitignore to track .env.example while ignoring actual .env files
Remove the user-provided API key flow in favor of a shipped API key:

- Get API key from VITE_TBA_API_KEY environment variable
- Inject API key via GitHub secrets in deploy workflow
- Remove TBAApiKeyDialog component and tbaApiKeyStorage utility
- Simplify MatchDataFetcher to fetch events directly
- Remove validateTBAApiKey function (no longer needed)
- Update README to remove API key setup instructions
- Delete the-blue-alliance-api-configuration.md guide

Users no longer need to configure their own TBA API key.
Add optional chaining to monaco.json.jsonDefaults to handle
lazy-loaded JSON language features.
The loading state wasn't working because onEventSelected (an async
function) wasn't being awaited, causing setIsLoading(false) to run
immediately.
Shows a spinner and 'Loading...' text while fetching events from TBA,
and disables the button to prevent duplicate requests.
@luanzeba luanzeba force-pushed the luanzeba/add-blue-alliance-integration branch from 3430408 to 3723dfa Compare January 18, 2026 01:47
The old function unnecessarily stringified and re-parsed the config JSON,
validated it (even though it came from state and was already valid), and
called setFormData which reset form values.

The new setMatchData simply stores match data in state, which is all that
was actually needed.
Pass fetchEvents directly to onClick instead of wrapping it in another
useCallback that just calls it.
@tytremblay tytremblay marked this pull request as ready for review January 19, 2026 03:15
@tytremblay
Copy link
Collaborator

This looks really good @luanzeba! I accidentally approved. How do i unapprove? A few questions:

  1. Can you share a video of using the new fields to set things up?

  2. In testing this, I found that the events don't show up in the blue alliance API until the day of the event for some reason.

    a. The events are there on the TBA site which is fed from the API. Is this still true?

  3. Are the retrieved matches and events stored in the config at all? Teams will want to use one device to pull this data, then share it with other devices without internet.

Previously, errors like 'No match data available for this event yet' were
passed to the parent component's onError callback, which displayed them
behind the open dialog. Users couldn't see the error and thought the app
was unresponsive.

Now handleEventSelected throws errors instead of calling onError, and
the dialog catches them and displays them inline with the actual error
message.
@luanzeba
Copy link
Collaborator Author

Thanks @tytremblay!

How do i unapprove?

You have to review it again with a different status.

Can you share a video of using the new fields to set things up?

Let me know if you can see this https://drive.google.com/file/d/1yngyo1dCD3IyDDvnJwL60g0vJDplahSF/view?usp=sharing

The events are there on the TBA site which is fed from the API. Is this still true?

Yep, that was my mistake. I meant the match data is not available until the first day of competition usually. The events are up way in advance. This is what it looks like if I try to pull match data from a 2026 event.
CleanShot 2026-01-22 at 17 47 57@2x

Are the retrieved matches and events stored in the config at all? Teams will want to use one device to pull this data, then share it with other devices without internet.

They're stored in local storage after the initial pull so they only need to pull it once, but I think they'd have to pull it individually in each device. I guess we could store it in the config but I think that'd add a lot of noise there. I showed what it looks like in the demo above too.

@tytremblay
Copy link
Collaborator

@luanzeba yeah, the match data makes sense. They don't generate the matches until all the teams have checked in at the event.

@luanzeba luanzeba merged commit de5d8d3 into main Jan 25, 2026
1 check passed
@luanzeba luanzeba deleted the luanzeba/add-blue-alliance-integration branch January 25, 2026 23:11
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