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

Release/v1.0.1 #4914

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open

Release/v1.0.1 #4914

wants to merge 18 commits into from

Conversation

findtopher
Copy link
Member

@findtopher findtopher commented Oct 10, 2024

What changes are proposed in this pull request?

final merge for release v1.0.1

DO NOT MERGE UNTIL 7AM on 10/11

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced the VideoLookerReact component for enhanced video playback.
    • Added new hooks for improved event handling and state management.
    • Enhanced the COCO integration with new export functionalities.
  • Bug Fixes

    • Streamlined event handling in the ImaVidLooker and ModalLooker components.
  • Documentation

    • Updated user guides and release notes to reflect recent changes and improvements.
  • Tests

    • Expanded test coverage for bubble functionalities.
  • Chores

    • Cleaned up unused imports and improved code structure across various components.

brimoor and others added 16 commits October 3, 2024 18:32
Remove deprecated fiftyone-desktop refs
* add dynamic embedded document field type for rrd files

* add schema utils to work with embedded doc type fields

* add versioned renderer with url+metadata support

* remove explicit version
* organizing

* rm Tmp

* cleanup

* add example back

* cleaning

* useKeyEvents hook

* after load handling

* fix import

* enable timeline

* default to true

* refreshers
* release notes

* negative wait note

---------

Co-authored-by: Benjamin Kane <ben@voxel51.com>
Copy link
Contributor

coderabbitai bot commented Oct 10, 2024

Caution

Review failed

The head commit changed during the review from 2adc94e to b48fbce.

Walkthrough

The pull request introduces significant changes across various components in the application, primarily focusing on the ImaVidLooker, ModalLooker, and the addition of new hooks and utilities. Key modifications include restructuring imports, simplifying state management, and enhancing video playback functionality. Several new components and hooks are introduced, such as VideoLookerReact and useLooker, while existing components have been refactored for improved clarity and functionality. Additionally, the documentation has been updated to reflect these changes.

Changes

File Path Change Summary
app/packages/core/src/components/Modal/ImaVidLooker.tsx Updated imports; simplified internal logic by utilizing useKeyEvents; removed hoveredSample state management.
app/packages/core/src/components/Modal/ModalLooker.tsx Restructured imports; removed useLookerOptionsUpdate function; made sample property required in LookerProps.
app/packages/core/src/components/Modal/VideoLooker.tsx Introduced VideoLookerReact component for video playback; integrated hooks for state management.
app/packages/core/src/components/Modal/hooks.ts Added useLookerOptionsUpdate hook for managing Looker options in Recoil state.
app/packages/core/src/components/Modal/use-key-events.ts Introduced use-key-events hook for keyboard event handling based on hovered sample.
app/packages/core/src/components/Modal/use-looker.ts Added useLooker hook for managing Looker component lifecycle and interactions.
app/packages/core/src/components/Modal/utils.ts Added shortcutToHelpItems function for processing shortcut entries.
app/packages/looker/src/elements/base.ts Modified boot method to use optional chaining for event listener addition.
app/packages/looker/src/elements/common/bubbles.test.ts Expanded test cases for getBubbles to include new fields.
app/packages/looker/src/elements/common/bubbles.ts Updated getBubbles function to use unwind instead of flatMap.
app/packages/looker/src/elements/common/looker.ts Updated import statements for TypeScript's type-only imports.
app/packages/looker/src/index.ts Added export for getFrameNumber from ./elements/util.
app/packages/looker/src/lookers/imavid/index.ts Added export for BUFFERING_PAUSE_TIMEOUT from ./constants.
app/packages/looker/src/lookers/video.ts Enhanced video frame management and added timeline processing logic.
app/packages/looker/src/state.ts Updated interfaces to include new properties related to key event handling and timeline.
app/packages/plugins/src/externalize.ts Added new import for @fiftyone/plugins and modified global Window interface.
app/packages/state/src/hooks/useCreateLooker.ts Updated function signature to include optional enableTimeline parameter.
app/packages/state/src/recoil/modal.ts Changed type signature for modalLooker atom.
app/packages/state/src/utils.ts Updated getStandardizedUrls function to accept additional ModalSample type.
app/packages/utilities/src/schema.ts Added new functions for schema handling related to embedded document types.
docs/source/integrations/coco.rst Updated documentation for COCO integration with new parameters and export functionalities.
docs/source/release-notes.rst Updated release notes for versions 2.1.1 and 1.0.1.
docs/source/user_guide/app.rst Enhanced FiftyOne App documentation with new examples and parameter details.
docs/source/user_guide/dataset_creation/datasets.rst Updated documentation for COCODetectionDataset, including changes to labels.json.
docs/source/user_guide/export_datasets.rst Updated export documentation reflecting changes in the export() method and dataset types.
e2e-pw/src/oss/poms/modal/imavid-controls.ts Introduced waitUntilBufferingIsFinished method in modal controls.
fiftyone/constants.py Updated COMPATIBLE_VERSIONS constant for broader version compatibility.
fiftyone/core/session/session.py Adjusted logic in the wait method of the Session class.
fiftyone/server/metadata.py Added import for RrdFile in the _ADDITIONAL_MEDIA_FIELDS dictionary.
fiftyone/utils/coco.py Renamed classes parameter to categories in add_coco_labels function.
fiftyone/utils/quickstart.py Removed desktop parameter from various function signatures.
fiftyone/utils/rerun.py Introduced rerun.py file with utilities for working with Rerun and RrdFile class.

Possibly related PRs

Suggested labels

documentation

Suggested reviewers

  • brimoor
  • benjaminpkane

🐰 In the meadow, changes bloom bright,
New hooks and components take flight.
With videos now playing with glee,
The code's a dance, as smooth as can be!
Let's hop along, celebrate with cheer,
For every change brings us near! 🎉


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.

@findtopher findtopher requested a review from a team October 10, 2024 20:20
Copy link
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: 17

🧹 Outside diff range and nitpick comments (41)
fiftyone/utils/rerun.py (2)

14-25: LGTM: Class definition and fields are well-structured.

The RrdFile class is well-defined with appropriate inheritance and a clear docstring. The _MEDIA_FIELD attribute and field definitions are correct for the intended purpose.

Consider adding type hints to the filepath and version fields for improved code clarity:

-    filepath = fof.StringField()
-    version = fof.StringField()
+    filepath: fof.StringField = fof.StringField()
+    version: fof.StringField = fof.StringField()

1-25: Overall assessment: Well-implemented utility for Rerun integration.

This new file introduces a clean and concise implementation for working with Rerun data files. The RrdFile class is well-structured and follows good practices. The addition of this utility aligns with the PR objectives for the release version 1.0.1.

As the project continues to evolve, consider the following suggestions for future improvements:

  1. If the Rerun integration becomes more complex, consider creating a separate module for Rerun-related utilities.
  2. Implement unit tests for the RrdFile class to ensure its functionality and maintain code quality as the project grows.
app/packages/utilities/src/schema.ts (2)

55-74: Approve implementation with suggestions for improvement

The getFieldsWithEmbeddedDocType function is well-implemented and efficiently traverses the schema to find fields with the specified embeddedDocType. It adheres to TypeScript best practices with proper type annotations.

To further improve the function, consider the following suggestions:

  1. Add input validation for the schema parameter to ensure it's not null or undefined.
  2. Consider adding a type guard for the field.fields check to improve type safety.

Here's an example of how you could implement these suggestions:

export function getFieldsWithEmbeddedDocType(
  schema: Schema,
  embeddedDocType: string
): Field[] {
  if (!schema) {
    throw new Error("Schema is required");
  }

  const result: Field[] = [];

  function recurse(schema: Schema) {
    for (const field of Object.values(schema)) {
      if (field.embeddedDocType === embeddedDocType) {
        result.push(field);
      }
      if (field.fields && typeof field.fields === "object") {
        recurse(field.fields);
      }
    }
  }

  recurse(schema);
  return result;
}

These changes will make the function more robust and type-safe.


76-93: Approve implementation with suggestions for minor improvements

The doesSchemaContainEmbeddedDocType function is well-implemented, efficiently using recursion and Array.some() to search for the specified embeddedDocType. It's concise, readable, and adheres to TypeScript best practices.

To further enhance the function, consider the following suggestions:

  1. Add input validation for the schema parameter.
  2. Use a type guard for the field.fields check to improve type safety.

Here's an example of how you could implement these suggestions:

export function doesSchemaContainEmbeddedDocType(
  schema: Schema,
  embeddedDocType: string
): boolean {
  if (!schema) {
    throw new Error("Schema is required");
  }

  function recurse(schema: Schema): boolean {
    return Object.values(schema).some((field) => {
      if (field.embeddedDocType === embeddedDocType) {
        return true;
      }
      if (field.fields && typeof field.fields === "object") {
        return recurse(field.fields);
      }
      return false;
    });
  }

  return recurse(schema);
}

These minor changes will make the function more robust and type-safe while maintaining its efficiency.

app/packages/core/src/components/Modal/hooks.ts (1)

22-41: Good implementation of the useLookerOptionsUpdate hook.

The hook is well-structured and follows React and Recoil best practices. It correctly handles asynchronous operations and provides a flexible way to update Looker options.

Consider improving type definitions.

To enhance type safety and code clarity:

  1. Replace the {} type with a more specific interface or type for the update parameter.
  2. Add a return type for the hook.

Here's a suggested improvement:

interface LookerOptions {
  // Define the structure of your options here
  showJSON?: boolean;
  showHelp?: boolean;
  // Add other properties as needed
}

export const useLookerOptionsUpdate = (): (
  update: Partial<LookerOptions>,
  updater?: (updated: LookerOptions) => void
) => Promise<void> => {
  return useRecoilCallback(
    ({ snapshot, set }) =>
      async (update: Partial<LookerOptions>, updater?: (updated: LookerOptions) => void) => {
        // ... rest of the implementation
      }
  );
};

This change will provide better type checking and autocompletion for the update object and make the hook's return type explicit.

🧰 Tools
🪛 Biome

[error] 25-25: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

app/packages/looker/src/elements/common/looker.ts (1)

29-33: Improved state structure in event handlers

The changes to state destructuring in both keydown and keyup event handlers are good improvements:

  1. Moving shouldHandleKeyEvents under options suggests a more organized state structure.
  2. The core logic remains unchanged, preserving existing functionality.

For consistency, consider applying the same destructuring pattern to the keyup handler:

keyup: ({ event, update, dispatchEvent }) => {
  // ...
  update(({ SHORTCUTS, error, options: { shouldHandleKeyEvents } }) => {
    // ... (rest of the code remains the same)
  });
},

This change would make both event handlers consistent in their state access pattern.

Also applies to: 52-52

e2e-pw/src/oss/poms/modal/imavid-controls.ts (2)

35-42: LGTM! Consider adding a timeout for robustness.

The waitUntilBufferingIsFinished method is well-implemented and uses appropriate data attributes for testing. However, to prevent potential infinite waiting, consider adding a timeout to the waitForFunction call.

You could modify the method like this:

private async waitUntilBufferingIsFinished(timeout = 30000) {
  await this.page.waitForFunction(
    () =>
      document
        .querySelector("[data-cy=imavid-playhead]")
        ?.getAttribute("data-playhead-state") !== "buffering",
    { timeout }
  );
}

This change allows for a configurable timeout with a default of 30 seconds, enhancing the robustness of the method.


44-50: Good improvement! Consider adding error handling and logging.

The addition of waitUntilBufferingIsFinished before toggling play/pause is a valuable improvement. It ensures that the video is ready before performing the action, which should lead to more reliable behavior.

To further enhance the robustness of this method, consider adding error handling and logging:

private async togglePlay() {
  try {
    await this.waitUntilBufferingIsFinished();
    console.log("Buffering finished, proceeding with toggle play");

    let currentPlayHeadStatus = await this.playPauseButton.getAttribute(
      "data-playhead-state"
    );

    const original = currentPlayHeadStatus;
    console.log(`Original playhead status: ${original}`);

    // ... rest of the method ...

  } catch (error) {
    console.error("Error in togglePlay:", error);
    throw error;
  }
}

This change adds error handling and logging, which can be valuable for debugging and maintaining the test suite.

fiftyone/utils/quickstart.py (1)

Line range hint 14-37: LGTM: Function signature and body updates are correct.

The removal of the desktop parameter from the function signature and the corresponding simplification of the function body are consistent with the intended changes.

Update the docstring to reflect the removed desktop parameter.

The function's docstring should be updated to remove the mention of the desktop parameter for consistency with the new function signature.

app/packages/state/src/recoil/modal.ts (2)

Line range hint 26-30: LGTM! Consider updating documentation.

The change in the modalLooker atom type from AbstractLooker<BaseState> | null to Lookers | null is a positive improvement. It aligns with the import changes and likely enhances type safety and code clarity.

If there's any documentation referencing the modalLooker atom, please ensure it's updated to reflect this type change.


72-75: LGTM! Consider a minor optimization.

The introduction of optional chaining in id?.endsWith("-modal") is a great improvement for null safety. It prevents potential runtime errors if id is null or undefined.

For a slight optimization and improved readability, you could consider using nullish coalescing:

return id?.endsWith("-modal") ? id.replace("-modal", "") : id ?? null;

This ensures that if id is undefined, the selector returns null instead of undefined, maintaining consistency with the selector's return type.

app/packages/utilities/src/schema.test.ts (2)

65-65: LGTM: Test suite updates improve readability and robustness

The formatting changes in the describe block names enhance readability. The update to the spread operator usage in the getFieldInfo tests improves robustness by handling potentially undefined fields.

Consider adding a type assertion to SCHEMA.embedded.fields to avoid the non-null assertion operator (!):

expect(schema.getFieldInfo("embedded.field", SCHEMA)).toEqual({
  ...(SCHEMA.embedded.fields as NonNullable<typeof SCHEMA.embedded.fields>).field,
  pathWithDbField: "",
});

This approach provides better type safety without using the non-null assertion operator.

Also applies to: 82-82, 92-92


146-176: LGTM: Solid test suite for doesSchemaContainEmbeddedDocType

The new test suite for doesSchemaContainEmbeddedDocType is well-structured and covers important scenarios, including top-level fields, nested fields, non-existent types, and empty schemas.

Consider adding a test case for a deeply nested embeddedDocType to ensure the function works correctly with more complex schema structures. For example:

it("should return true for deeply nested embeddedDocType", () => {
  const deepSchema = {
    level1: {
      fields: {
        level2: {
          fields: {
            level3: {
              embeddedDocType: "fiftyone.core.labels.DeepLabel"
            }
          }
        }
      }
    }
  };
  expect(
    schema.doesSchemaContainEmbeddedDocType(deepSchema, "fiftyone.core.labels.DeepLabel")
  ).toBe(true);
});

This addition would further strengthen the test coverage.

app/packages/state/src/hooks/useCreateLooker.ts (2)

39-40: Good addition, but documentation needed

The addition of the optional enableTimeline parameter is a good way to extend the functionality while maintaining backward compatibility. However, it would be beneficial to add a JSDoc comment explaining the purpose and usage of this new parameter.

Consider adding a JSDoc comment like this:

/**
 * @param enableTimeline - Optional. When true, enables timeline-related functionality.
 */

116-116: Good integration, consider type assertion

The addition of enableTimeline to the config object correctly integrates the new parameter. For added safety, consider using a type assertion to ensure enableTimeline is always a boolean:

enableTimeline: enableTimeline as boolean,

This will help catch potential type-related issues early in development.

app/packages/looker/src/state.ts (2)

178-178: LGTM with a minor suggestion.

The addition of shouldHandleKeyEvents as an optional boolean property is a good improvement for more granular control over key event handling. It follows TypeScript best practices and naming conventions.

Consider adding a JSDoc comment to explain the purpose and default behavior of this property, which would enhance code readability and maintainability.


222-222: LGTM with a minor suggestion.

The addition of enableTimeline as a required boolean property in the VideoConfig interface is a good enhancement for controlling timeline functionality in video configurations. It follows TypeScript best practices and naming conventions.

Consider adding a JSDoc comment to explain the purpose and impact of this property on the video configuration, which would improve code documentation and assist other developers in understanding its usage.

docs/source/integrations/coco.rst (4)

Line range hint 219-230: Great update to the COCO format example!

The addition of more fields in the "images" section provides a more comprehensive and realistic representation of the COCO format. This improvement helps users better understand the structure of COCO-formatted data.

Consider adding a brief explanation of these new fields (especially "license" and "coco_url") in the text preceding or following this example to provide context for users who might be unfamiliar with the COCO format.


240-247: Excellent updates to the annotation example!

The changes to the "bbox" values and the addition of the "area" field make this example more realistic and informative. Using floating-point numbers for bounding box coordinates provides a more accurate representation of how annotations are typically stored in COCO format.

Consider adding a brief explanation of the "area" field and its significance in COCO annotations. This would help users understand why this information is included and how it might be used in object detection tasks.


270-272: Great addition showing COCO category import!

This new code snippet effectively demonstrates that COCO categories are imported along with the dataset. It's a valuable addition that helps users understand how to access and use the original COCO category information in their FiftyOne datasets.

Consider adding a brief explanation of how users might utilize this category information in their workflows. For example, you could mention that these categories can be useful for filtering samples, generating statistics, or ensuring consistency when working with multiple COCO datasets.


319-328: Excellent updates to the COCO predictions example!

The changes in this section improve the clarity and correctness of the example for adding COCO predictions to a dataset. The updated comment about category_id and the explicit definition of the categories variable provide a more accurate representation of how to work with COCO categories in FiftyOne.

To further enhance clarity, consider adding a brief explanation of why it's important to use coco_dataset.info["categories"] instead of coco_dataset.default_classes. This could help users understand the significance of maintaining consistency between the imported COCO categories and the predictions being added.

fiftyone/core/session/session.py (1)

Line range hint 1128-1139: LGTM! Consider adding a docstring update.

The changes to the wait method improve its behavior and readability. The use of the _wait_closed flag for non-negative wait times is a good approach.

Consider updating the method's docstring to reflect the new behavior for negative wait values, which now wait indefinitely instead of returning immediately.

docs/source/user_guide/app.rst (10)

Line range hint 1-27: LGTM! Consider adding a brief example.

The introduction and "App environments" section provide a good overview of the FiftyOne App and its flexibility. The mention of the plugin framework is valuable information for users looking to extend the App's functionality.

Consider adding a brief one-line code example of how to launch the App to give readers an immediate sense of its usage.


Line range hint 28-153: LGTM! Consider clarifying the session.wait() behavior.

The "Sessions" section provides excellent guidance on creating and managing App sessions, with helpful code examples for various scenarios. The notes about asynchronous behavior and platform-specific considerations are valuable.

In the note about session.wait(), consider clarifying what happens when the App is closed manually. Does the script continue execution, or does it terminate? This information could be helpful for users writing scripts that depend on App interaction.


Line range hint 154-516: LGTM! Consider adding a note about performance implications.

The "Using the sidebar" section provides comprehensive coverage of the sidebar functionality, including filtering, indexing, and customization options. The explanations and code examples are clear and informative.

Consider adding a brief note about the performance implications of creating indexes, especially for large datasets. This could help users make informed decisions about when and how to use indexing.


Line range hint 517-534: Consider expanding the "Using the view bar" section.

While this section provides a basic introduction to the view bar, it could be more informative for users.

Consider expanding this section with the following:

  1. More detailed explanation of what operations are available in the view bar.
  2. A code example showing how to access and use the Session.view property.
  3. A brief explanation of how the view bar interacts with other App features like the sidebar filters.

Line range hint 535-570: LGTM! Consider adding a code example.

The "Grouping samples" section effectively explains the dynamic grouping functionality in the App, including navigation options and special features for ordered groups. The accompanying GIFs are helpful for visualizing the process.

Consider adding a brief code example showing how to programmatically create a grouped view of a dataset. This could help users understand how the App's grouping feature relates to the underlying data structure.


Line range hint 571-686: LGTM! Consider adding a note about performance.

The "Field visibility" section provides excellent guidance on configuring field visibility in the App, covering both manual selection and filter rules. The explanations are clear and the accompanying visuals are helpful.

Consider adding a brief note about the performance implications of showing/hiding fields, especially for datasets with many fields or large numbers of samples. This could help users optimize their App experience when working with complex datasets.


Line range hint 687-968: LGTM! Consider adding a note about color accessibility.

The "Color schemes" section provides excellent guidance on configuring color schemes both in the App and programmatically. The explanations of different customization options are clear and the code examples are helpful.

Consider adding a brief note about color accessibility considerations when choosing custom color schemes. This could include tips for ensuring sufficient contrast and avoiding color combinations that might be difficult for colorblind users to distinguish.


Line range hint 969-1093: LGTM! Consider adding information about view sharing.

The "Saving views" and "Viewing a sample" sections effectively explain how to save and load views, and how to interact with individual samples in the App. The information about persisting views and customizing tooltips is particularly valuable.

Consider adding information about whether saved views can be shared between users or exported/imported between different FiftyOne installations. This could be useful for collaborative workflows or for users working across multiple environments.


Line range hint 1094-1604: LGTM! Consider adding information about custom visualizers.

The sections on image, video, and 3D visualizers, as well as selecting samples and labels, provide excellent guidance on using these features in the App. The explanations are clear and the inclusion of keyboard shortcuts is very helpful.

Consider adding information about whether users can create custom visualizers or extend the existing ones. This could be valuable for users with specialized visualization needs that aren't covered by the built-in visualizers.


Line range hint 1605-2453: LGTM! Consider adding a troubleshooting section.

The final sections covering tagging, object patches, evaluation patches, video clips, similarity sorting, multiple media fields, and App configuration provide excellent coverage of advanced features and customization options. The explanations and code examples are clear and informative.

Consider adding a brief troubleshooting section at the end of the document. This could cover common issues users might encounter when using the App and provide solutions or workarounds. This addition could be very helpful for users, especially those new to FiftyOne.

docs/source/user_guide/export_datasets.rst (2)

Line range hint 4-4: Address the TODO comment for adding tests

The TODO comment indicates that tests are missing for this function. It's important to add unit tests to ensure the function behaves correctly for various inputs.

Would you like assistance in generating unit tests for this function?


Line range hint 12-24: Revise discount and fee structure for better customer experience

The current implementation has some issues that could lead to customer dissatisfaction:

  1. The flat $20 fee on discounted bills can result in a higher final price for small purchases, especially with the 10% discount.
  2. This structure might discourage customer loyalty for those making smaller, frequent purchases.

Consider revising the logic to ensure that discounted prices are always lower than non-discounted prices. Some suggestions:

  1. Apply the flat fee before the discount.
  2. Use a percentage-based fee instead of a flat fee.
  3. Only apply the fee for purchases above a certain threshold.

Would you like assistance in designing and implementing a more customer-friendly pricing structure?

app/packages/core/src/components/Modal/use-key-events.ts (1)

39-39: Remove ref from the dependency array

Including ref in the dependency array is unnecessary because changes to ref.current do not trigger re-renders, and including it may cause unintended effects.

Apply this diff to remove ref from the dependency array:

-  }, [hoveredId, id, looker, ref]);
+  }, [hoveredId, id, looker]);
app/packages/core/src/components/Modal/VideoLooker.tsx (3)

21-23: useMemo may not be necessary for frameRate

Since accessing sample.frameRate is inexpensive and unlikely to cause performance issues, you can simplify the code by directly assigning frameRate without using useMemo.

Apply this diff to simplify:

-  const frameRate = useMemo(() => {
-    return sample.frameRate;
-  }, [sample]);
+  const frameRate = sample.frameRate;

61-61: useMemo may not be necessary for timelineName

Calling getName() is likely inexpensive, and its return value doesn't change between renders. You can simplify the code by directly assigning timelineName without using React.useMemo.

Apply this diff to simplify:

-  const timelineName = React.useMemo(() => getName(), [getName]);
+  const timelineName = getName();

65-70: Simplify the config assignment since totalFrames is always defined

Because TimelineController is only rendered when totalFrames is defined, the conditional check is unnecessary. You can simplify the code by directly assigning the config object.

Apply this diff to simplify:

-  config: totalFrames
-    ? {
-        totalFrames,
-        loop: true,
-      }
-    : undefined,
+  config: {
+    totalFrames,
+    loop: true,
+  },
app/packages/core/src/components/Modal/ModalLooker.tsx (1)

86-88: Consider using else if for conditional rendering to improve clarity

To improve readability and ensure that the conditions are mutually exclusive, consider changing the second if to an else if. This ensures that once a condition is met, subsequent conditions are not unnecessarily evaluated.

Apply this diff to merge the conditions:

 if (shouldRenderImavid) {
   return <ImaVidLookerReact sample={sample} />;
 }
- if (video) {
+ else if (video) {
   return <VideoLookerReact sample={sample} />;
 }
 return <ModalLookerNoTimeline sample={sample} />;
app/packages/looker/src/elements/common/bubbles.ts (1)

Line range hint 98-102: Fix incorrect parameter passing in unwind function

The unwind function incorrectly passes the depth parameter to recursive calls due to a misuse of the Array.map method. The second argument of Array.map is thisArg, not an argument for the callback function. This can lead to unintended behavior in recursion depth.

Apply this diff to correctly pass the next depth parameter to recursive calls:

 export const unwind = (name: string, value: Data | Data[], depth = 0) => {
   if (Array.isArray(value)) {
     const next = depth + 1;
-    return depth < 2 ? value.map((val) => unwind(name, val), next).flat(3) : [];
+    return depth < 2 ? value.map((val) => unwind(name, val, next)).flat(3) : [];
   }

   const v = value[name];
fiftyone/utils/coco.py (1)

132-139: Documentation Update: Ensure Proper Linking and Formatting

The updated documentation for the categories parameter is helpful. Please verify that the reference to :meth:\parse_coco_categories`` correctly links to the intended method and is properly formatted in the generated documentation.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 739d6b1 and 233689b.

⛔ Files ignored due to path filters (2)
  • app/packages/looker/package.json is excluded by !**/*.json
  • app/yarn.lock is excluded by !**/yarn.lock, !**/*.lock, !**/*.lock
📒 Files selected for processing (35)
  • app/packages/core/src/components/Modal/ImaVidLooker.tsx (2 hunks)
  • app/packages/core/src/components/Modal/ModalLooker.tsx (3 hunks)
  • app/packages/core/src/components/Modal/VideoLooker.tsx (1 hunks)
  • app/packages/core/src/components/Modal/hooks.ts (1 hunks)
  • app/packages/core/src/components/Modal/use-key-events.ts (1 hunks)
  • app/packages/core/src/components/Modal/use-looker.ts (1 hunks)
  • app/packages/core/src/components/Modal/utils.ts (1 hunks)
  • app/packages/looker/src/elements/base.ts (1 hunks)
  • app/packages/looker/src/elements/common/bubbles.test.ts (2 hunks)
  • app/packages/looker/src/elements/common/bubbles.ts (1 hunks)
  • app/packages/looker/src/elements/common/looker.ts (3 hunks)
  • app/packages/looker/src/index.ts (1 hunks)
  • app/packages/looker/src/lookers/imavid/index.ts (1 hunks)
  • app/packages/looker/src/lookers/video.ts (3 hunks)
  • app/packages/looker/src/state.ts (3 hunks)
  • app/packages/plugins/src/externalize.ts (3 hunks)
  • app/packages/state/src/hooks/useCreateLooker.ts (4 hunks)
  • app/packages/state/src/recoil/modal.ts (3 hunks)
  • app/packages/state/src/utils.ts (2 hunks)
  • app/packages/utilities/src/schema.test.ts (7 hunks)
  • app/packages/utilities/src/schema.ts (1 hunks)
  • docs/source/integrations/coco.rst (6 hunks)
  • docs/source/release-notes.rst (1 hunks)
  • docs/source/user_guide/app.rst (1 hunks)
  • docs/source/user_guide/dataset_creation/datasets.rst (2 hunks)
  • docs/source/user_guide/export_datasets.rst (2 hunks)
  • e2e-pw/src/oss/poms/modal/imavid-controls.ts (1 hunks)
  • fiftyone/constants.py (1 hunks)
  • fiftyone/core/session/session.py (1 hunks)
  • fiftyone/server/metadata.py (2 hunks)
  • fiftyone/utils/coco.py (15 hunks)
  • fiftyone/utils/quickstart.py (2 hunks)
  • fiftyone/utils/rerun.py (1 hunks)
  • setup.py (1 hunks)
  • tests/unittests/import_export_tests.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (22)
app/packages/core/src/components/Modal/ImaVidLooker.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/components/Modal/ModalLooker.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/components/Modal/VideoLooker.tsx (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/components/Modal/hooks.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/components/Modal/use-key-events.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/components/Modal/use-looker.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/core/src/components/Modal/utils.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/elements/base.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/elements/common/bubbles.test.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/elements/common/bubbles.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/elements/common/looker.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/index.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/lookers/imavid/index.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/lookers/video.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/looker/src/state.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/plugins/src/externalize.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/state/src/hooks/useCreateLooker.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/state/src/recoil/modal.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/state/src/utils.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/utilities/src/schema.test.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

app/packages/utilities/src/schema.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

e2e-pw/src/oss/poms/modal/imavid-controls.ts (1)

Pattern **/*.{ts,tsx}: Review the Typescript and React code for conformity with best practices in React, Recoil, Graphql, and Typescript. Highlight any deviations.

🪛 Biome
app/packages/core/src/components/Modal/hooks.ts

[error] 25-25: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

🪛 Ruff
tests/unittests/import_export_tests.py

1822-1822: Ambiguous variable name: l

(E741)

🔇 Additional comments (43)
app/packages/core/src/components/Modal/utils.ts (1)

1-7: ⚠️ Potential issue

Improve type safety and clarity of the shortcutToHelpItems function

The current implementation has several areas for improvement:

  1. Add type annotations to enhance type safety and code clarity.
  2. Clarify the expected structure of the SHORTCUTS parameter.
  3. Add error handling for potential edge cases.
  4. Use modern JavaScript/TypeScript features to make the code more concise and robust.

Here's a suggested refactored version with improvements:

interface ShortcutItem {
  shortcut: string;
  [key: string]: any;
}

export function shortcutToHelpItems(shortcuts: Record<string, ShortcutItem>): ShortcutItem[] {
  if (!shortcuts || typeof shortcuts !== 'object') {
    throw new Error('SHORTCUTS must be a non-null object');
  }

  const uniqueShortcuts = new Map<string, ShortcutItem>();

  Object.values(shortcuts).forEach(item => {
    if (typeof item.shortcut !== 'string') {
      throw new Error('Each shortcut item must have a string "shortcut" property');
    }
    uniqueShortcuts.set(item.shortcut, item);
  });

  return Array.from(uniqueShortcuts.values());
}

This refactored version:

  • Adds type annotations for better type safety.
  • Uses a Map to ensure uniqueness based on the shortcut property.
  • Adds error handling for invalid input.
  • Uses modern JavaScript features like Object.values() and Array.from().

Please consider implementing these changes to improve the function's robustness and maintainability.

To ensure that this function is used correctly throughout the codebase, we can run the following verification:

This will help us understand how the function is being used and ensure that SHORTCUTS is properly defined.

app/packages/looker/src/index.ts (1)

6-6: New export added: Verify its necessity and usage

The addition of getFrameNumber to the exports is a minor change that expands the public API of this module. This change appears to be in line with the module's purpose of providing utility functions for video processing.

However, to ensure this change aligns with best practices:

  1. Confirm that getFrameNumber is indeed intended to be part of the public API.
  2. Verify that this new export is used in other parts of the codebase or is required for external usage.
  3. Ensure that getFrameNumber is properly documented in its source file.

To verify the usage and necessity of this new export, you can run the following script:

This will help ensure that the new export is necessary and properly integrated into the codebase.

fiftyone/utils/rerun.py (1)

1-11: LGTM: File structure and imports are well-organized.

The file structure follows best practices with a clear module docstring, including a copyright notice. The imports are relevant to the functionality being implemented.

app/packages/plugins/src/externalize.ts (4)

6-6: LGTM: New import statement is consistent with existing patterns.

The new import for @fiftyone/plugins follows the established naming convention and import style used throughout the file.


23-23: LGTM: New Window interface property is consistent with existing patterns.

The addition of __fop__: typeof fop; to the global Window interface maintains consistency with the existing structure and naming conventions.


41-41: LGTM: New global variable assignment is consistent with existing patterns.

The assignment of window.__fop__ = fop; maintains consistency with the existing structure and is correctly placed within the window existence check.


6-6: Summary: Successful externalization of @fiftyone/plugins module

The changes in this file effectively externalize the @fiftyone/plugins module, making it globally accessible as window.__fop__. This modification:

  1. Imports the module (line 6)
  2. Declares it in the global Window interface (line 23)
  3. Assigns it to the window object (line 41)

These changes are consistent with the existing patterns in the file and should allow plugins to access the @fiftyone/plugins module in the same way as other externalized modules.

Also applies to: 23-23, 41-41

fiftyone/constants.py (1)

45-45: LGTM: Version compatibility range updated appropriately

The update to COMPATIBLE_VERSIONS from ">=0.19,<0.25" to ">=0.19,<1.1" is appropriate for the 1.0.1 release. It maintains backward compatibility while allowing for future 1.0.x releases. This change aligns well with semantic versioning practices.

To ensure this change doesn't introduce any unexpected issues, please run the following verification script:

This script will help identify any places where the old version string might still be used or where COMPATIBLE_VERSIONS is referenced, ensuring consistency across the codebase.

✅ Verification successful

Verified: COMPATIBLE_VERSIONS updated consistently across the codebase

The COMPATIBLE_VERSIONS constant has been updated to ">=0.19,<1.1" consistently across all relevant files. No hardcoded instances of the old version string ">=0.19,<0.25" were found, ensuring compatibility updates are correctly applied.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the COMPATIBLE_VERSIONS constant is used consistently across the codebase

# Test: Search for uses of COMPATIBLE_VERSIONS
echo "Searching for uses of COMPATIBLE_VERSIONS:"
rg --type python -A 5 "COMPATIBLE_VERSIONS"

# Test: Check if there are any hardcoded version strings that might need updating
echo "Checking for hardcoded version strings:"
rg --type python '">=0\.19,<0\.25"'

Length of output: 327


Script:

#!/bin/bash
# Description: Verify that the COMPATIBLE_VERSIONS constant is used consistently across the codebase

# Test: Search for uses of COMPATIBLE_VERSIONS
echo "Searching for uses of COMPATIBLE_VERSIONS:"
rg --type py -A 5 "COMPATIBLE_VERSIONS"

# Test: Check if there are any hardcoded version strings that might need updating
echo "Checking for hardcoded version strings:"
rg --type py '">=0\.19,<0\.25"'

Length of output: 2201

app/packages/looker/src/elements/base.ts (1)

67-67: Excellent use of optional chaining operator

The change from this.element && this.element.addEventListener(eventType, this.events[eventType]); to this.element?.addEventListener(eventType, this.events[eventType]); is a great improvement. It simplifies the code while maintaining the same functionality of safely calling addEventListener only if this.element exists.

This use of the optional chaining operator (?.) is a modern TypeScript feature that aligns with best practices. It makes the code more concise and easier to read without changing its behavior.

app/packages/looker/src/elements/common/looker.ts (1)

6-9: Improved import statements for better type handling

The changes to the import statements are beneficial:

  1. Using import type for BaseState, Control, and Events helps with type checking without importing the actual values, which can lead to better tree-shaking in the final bundle.
  2. Separating the import of ControlEventKeyType indicates it's used as a value in the code, not just for type information.

These modifications align well with TypeScript best practices and can potentially improve build optimization.

fiftyone/utils/quickstart.py (4)

42-45: LGTM: Function signature and body updates are correct.

The removal of the desktop parameter from the function signature and the corresponding update in the function call are consistent with the intended changes.


48-51: LGTM: Function signature and body updates are correct.

The removal of the desktop parameter from the function signature and the corresponding update in the function call are consistent with the intended changes.


Line range hint 1-162: Summary: Consistent removal of desktop parameter improves code simplicity.

The changes in this file consistently remove the desktop parameter from all relevant function signatures and calls. This simplification aligns with the PR objectives and improves the overall clarity of the codebase. The functionality related to launching the app remains intact, with the desktop-specific option removed.

Key points:

  1. All functions (quickstart, _quickstart, _video_quickstart, and _launch_app) have been updated consistently.
  2. The changes simplify the API by removing the desktop-specific option.
  3. The docstring for the quickstart function should be updated to reflect the parameter removal.

These changes contribute positively to the codebase by streamlining the quickstart functionality.


54-62: LGTM: Function signature and body updates are correct.

The removal of the desktop parameter from the function signature and the corresponding update in the fos.launch_app call are consistent with the intended changes.

Verify that the fos.launch_app function has been updated to remove the desktop parameter in its definition:

✅ Verification successful

Verified: fos.launch_app no longer accepts the 'desktop' parameter.

The removal of the desktop parameter from the fos.launch_app function signature has been confirmed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that fos.launch_app function no longer accepts a 'desktop' parameter

# Test: Search for the fos.launch_app function definition
rg --type python -A 10 'def launch_app\('

Length of output: 74


Script:

#!/bin/bash
# Description: Verify that fos.launch_app function no longer accepts a 'desktop' parameter

# Test: Search for the fos.launch_app function definition using the correct file type
rg --type py -A 10 'def launch_app\('

Length of output: 715

app/packages/state/src/utils.ts (3)

21-21: LGTM: Import of ModalSample is correct and consistent.

The addition of ModalSample to the import statement is appropriate and aligns with the changes made to the getStandardizedUrls function. This import follows TypeScript best practices.


Line range hint 1-24: Summary: Minor changes to support ModalSample integration

The changes in this file are minimal and focused on integrating ModalSample:

  1. Import of ModalSample from "./recoil"
  2. Extension of the urls parameter type in getStandardizedUrls function

These modifications suggest a broader refactoring or feature addition involving ModalSample. The changes appear to be correct and consistent, but it's important to ensure that the new type is compatible with the existing function logic to maintain type safety.

To confirm the extent of ModalSample usage, run the following command:

#!/bin/bash
# Description: Check for other usages of ModalSample in the codebase
# Expected result: List of files and contexts where ModalSample is used

rg --type typescript 'ModalSample'

This will help verify that the integration is consistent across the codebase.

Also applies to: 105-111


108-108: LGTM: Type extension for urls parameter is appropriate.

The addition of ModalSample["urls"] as a valid type for the urls parameter enhances the function's flexibility. This change is consistent with the new import of ModalSample.

To ensure type safety, please verify that ModalSample["urls"] is compatible with the existing function logic. Run the following command to check the ModalSample type definition:

app/packages/looker/src/lookers/imavid/index.ts (1)

18-18: LGTM. Verify usage of the newly exported constant.

The addition of this export is good for code organization. It allows other parts of the application to import BUFFERING_PAUSE_TIMEOUT directly.

To ensure this change doesn't introduce any issues, please run the following script to check for any existing imports that might need updating:

If the script returns any results, please review those files to ensure they're updated to use the new export path if necessary.

✅ Verification successful

Please re-run the verification with the updated script below to accurately search for BUFFERING_PAUSE_TIMEOUT usages in TypeScript files:


Verified: The export of BUFFERING_PAUSE_TIMEOUT does not affect other parts of the codebase, as no existing imports or usages were found outside of constants.ts and index.ts. This change is safe to proceed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for existing imports of BUFFERING_PAUSE_TIMEOUT that might need updating

# Search for imports of BUFFERING_PAUSE_TIMEOUT
rg --type typescript "import.*BUFFERING_PAUSE_TIMEOUT.*from" -g '!**/constants.ts'

# Search for uses of BUFFERING_PAUSE_TIMEOUT without an import
rg --type typescript "BUFFERING_PAUSE_TIMEOUT" -g '!**/constants.ts' -g '!**/index.ts'

Length of output: 241


Script:

#!/bin/bash
# Description: Check for existing imports of BUFFERING_PAUSE_TIMEOUT that might need updating

# Search for imports of BUFFERING_PAUSE_TIMEOUT
rg "import.*BUFFERING_PAUSE_TIMEOUT.*from" -g "*.ts" -g "*.tsx"

# Search for uses of BUFFERING_PAUSE_TIMEOUT without an import
rg "BUFFERING_PAUSE_TIMEOUT" -g "*.ts" -g "*.tsx" -g '!**/constants.ts' -g '!**/index.ts'

Length of output: 155

app/packages/state/src/recoil/modal.ts (1)

1-6: LGTM! Consider verifying import usage.

The changes in imports align well with the updates in the modalLooker atom type. The removal of AbstractLooker and BaseState imports and the addition of Lookers import suggest a positive shift towards more specific typing.

To ensure these changes don't introduce any issues, please run the following script to verify the usage of imports:

✅ Verification successful

Verification Successful!
The app/packages/state/src/recoil/modal.ts file no longer uses AbstractLooker or BaseState, and the new Lookers import is correctly utilized in the modalLooker atom.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of imports in the file

# Test 1: Check for any remaining usage of AbstractLooker or BaseState
echo "Checking for any remaining usage of AbstractLooker or BaseState:"
rg --type typescript "AbstractLooker|BaseState" app/packages/state/src/recoil/modal.ts

# Test 2: Verify the usage of the new Lookers import
echo "Verifying the usage of the new Lookers import:"
rg --type typescript "Lookers" app/packages/state/src/recoil/modal.ts

Length of output: 470


Script:

#!/bin/bash
# Description: List all supported file types in ripgrep

echo "Listing all supported file types in ripgrep:"
rg --type-list

Length of output: 4920


Script:

#!/bin/bash
# Description: Verify the usage of imports without specifying file type

# Test 1: Check for any remaining usage of AbstractLooker or BaseState
echo "Checking for any remaining usage of AbstractLooker or BaseState without specifying type:"
rg "AbstractLooker|BaseState" app/packages/state/src/recoil/modal.ts

# Test 2: Verify the usage of the new Lookers import without specifying type
echo "Verifying the usage of the new Lookers import without specifying type:"
rg "Lookers" app/packages/state/src/recoil/modal.ts

Length of output: 551

app/packages/utilities/src/schema.test.ts (3)

22-23: LGTM: Schema definition updates improve consistency

The changes to the name and path properties in the schema definition enhance the clarity and consistency of the embedded fields. This improvement aligns well with best practices in schema design.

Also applies to: 33-33, 45-46, 57-57


113-144: LGTM: Comprehensive test suite for getFieldsWithEmbeddedDocType

The new test suite for getFieldsWithEmbeddedDocType is well-structured and provides excellent coverage. It tests various scenarios including top-level fields, nested fields, non-existent types, and empty schemas, which helps ensure the robustness of the function.


Line range hint 1-176: LGTM: Excellent improvements to schema definitions and test coverage

The changes in this file significantly enhance the quality and coverage of the tests for schema-related utilities. Key improvements include:

  1. Updated schema definitions for better consistency and clarity.
  2. Refactored existing test suites for improved readability and robustness.
  3. New comprehensive test suites for getFieldsWithEmbeddedDocType and doesSchemaContainEmbeddedDocType.

These changes contribute to a more maintainable and reliable codebase. Great work on expanding the test coverage!

app/packages/looker/src/elements/common/bubbles.test.ts (1)

Line range hint 1-231: LGTM: Overall structure and consistency maintained.

The new test cases for classifications and temporalDetections are well-integrated into the existing test suite. The file structure remains consistent, and the necessary imports have been added. Good job on maintaining the test file's organization.

app/packages/state/src/hooks/useCreateLooker.ts (1)

12-12: Excellent use of type-only import!

The change to a type-only import for BaseState and ImaVidConfig is a good practice in TypeScript. It clearly separates type imports from value imports, which can potentially improve build performance and reduce bundle size.

app/packages/core/src/components/Modal/ImaVidLooker.tsx (2)

20-26: Improved import organization

The changes in the import statements enhance the code organization by moving hook-related imports to a separate 'hooks' file. This follows the best practice of separating concerns and improving modularity.


136-136: Verify the functionality of useKeyEvents hook

The addition of the useKeyEvents hook simplifies the event handling logic. However, please ensure that this hook fully replaces the functionality of the removed useEffect for handling hovered samples. Verify that all necessary key events are still being handled correctly.

To verify the functionality, please run the following script:

app/packages/looker/src/state.ts (1)

462-462: LGTM! Good default configuration.

The addition of shouldHandleKeyEvents: true to DEFAULT_BASE_OPTIONS is appropriate. It sets a sensible default that maintains backwards compatibility with existing behavior.

fiftyone/server/metadata.py (3)

27-27: Import statement for RrdFile looks good.

The new import for RrdFile from fiftyone.utils.rerun is correctly placed and necessary for the subsequent changes in the file.


37-37: Addition of RrdFile to _ADDITIONAL_MEDIA_FIELDS is appropriate.

The new entry for RrdFile in the _ADDITIONAL_MEDIA_FIELDS dictionary is consistent with the existing structure and correctly associates it with the "filepath" field. This addition enables proper metadata handling for RrdFile objects.


Line range hint 1-1: Summary of changes and recommendation for further investigation.

The visible changes in this file correctly implement support for RrdFile by adding the necessary import and updating the _ADDITIONAL_MEDIA_FIELDS dictionary. However, the AI-generated summary mentions changes to the _create_media_urls function that are not visible in the provided code snippet. It is recommended to:

  1. Verify that all necessary changes to support RrdFile have been implemented, particularly in the _create_media_urls function.
  2. Update the AI-generated summary if it's inaccurate, or provide the missing code changes if they exist in a different part of the file.

These steps will ensure that the implementation is complete and consistent with the intended changes for the new media type.

To get a comprehensive view of all changes in this file, please run the following script:

docs/source/integrations/coco.rst (1)

199-200: Excellent addition of the seed parameter!

The inclusion of the seed parameter in the take() method enhances reproducibility. This change allows users to consistently select the same subset of samples across different runs, which is crucial for creating reproducible examples and tests.

docs/source/user_guide/app.rst (1)

Line range hint 1-2453: Excellent documentation with room for minor enhancements.

This comprehensive guide to the FiftyOne App is well-structured, informative, and provides clear explanations for a wide range of features and functionalities. The inclusion of code examples, visual aids, and keyboard shortcuts enhances its usefulness for users at various levels of expertise.

To further improve this already excellent document, consider the following suggestions:

  1. Add brief code examples in some sections to illustrate programmatic interaction with the App.
  2. Include notes on performance implications for certain operations, especially for large datasets.
  3. Provide information on creating custom visualizers or extending existing ones.
  4. Add a troubleshooting section to address common issues users might encounter.
  5. Consider adding information about color accessibility when discussing color schemes.

These additions would make the document even more comprehensive and user-friendly.

docs/source/user_guide/dataset_creation/datasets.rst (3)

1503-1503: LGTM: Minor update to COCO dataset example

The change from "id": 2 to "id": 1 in the COCO dataset example is correct and consistent with the rest of the documentation. This update likely reflects a more common or standardized way of representing category IDs in COCO format.


1526-1526: LGTM: Consistent update to COCO dataset example

The change from "category_id": 2 to "category_id": 1 in the COCO dataset example is consistent with the previous change to the category ID. This ensures that the example remains internally consistent and accurately represents a typical COCO format annotation.


Line range hint 1-2000: Overall: Documentation updates are accurate and consistent

The changes made to the COCO dataset import example in this documentation file are minor but important for maintaining consistency. The category ID has been updated from 2 to 1 in both the categories and annotations sections of the JSON example. These modifications improve the clarity of the example and ensure that it accurately represents a typical COCO format dataset.

No other changes were observed in the rest of the document. The existing content, including other dataset format descriptions, import instructions, and templates for custom importers, remains accurate and comprehensive.

docs/source/release-notes.rst (2)

6-13: Release notes look good!

The release notes for FiftyOne Teams 2.1.1 are clear and informative. They properly indicate the release date, include references to the previous version's updates, and highlight two specific improvements.


15-39: Comprehensive release notes for FiftyOne 1.0.1

The release notes for FiftyOne 1.0.1 are well-structured and informative. They clearly separate App and Core updates, providing specific details about improvements and bug fixes. The information is relevant and useful for users updating to this version.

app/packages/core/src/components/Modal/use-looker.ts (4)

59-60: Verify the use of sample.sample.

Ensure that accessing sample.sample is correct. If sample already contains the necessary data, double-check whether sample.sample is the intended reference.


104-104: Check the parameters passed to useKeyEvents.

Verify that passing initialRef to useKeyEvents is appropriate. Confirm that useKeyEvents expects a useRef object. If not, consider passing initialRef.current or adjusting the parameter as needed.


83-102: Validate event handler for "panels" event.

Ensure that all properties used within the event handler (e.g., showJSON, showHelp, SHORTCUTS) are correctly defined and that the logic aligns with expected behavior. Also, verify that updateLookerOptions and looker.updateOptions are used appropriately.


50-52: 🛠️ Refactor suggestion

Ensure looker.updateOptions is called on initial render if necessary.

The condition !initialRef.current prevents looker.updateOptions(lookerOptions) from running on the initial render. If the looker requires options to be set during the initial render, consider adjusting this logic.

fiftyone/utils/coco.py (1)

48-48: ⚠️ Potential issue

Parameter Rename May Affect Backward Compatibility

The add_coco_labels function has renamed the classes parameter to categories. This change might break backward compatibility for users who rely on the old parameter name. Consider adding support for the old parameter name or updating the documentation to inform users of this change.

To ensure there are no unintended references to the old classes parameter, you can run the following script:

✅ Verification successful

Parameter Rename Verified: No References to classes Found

The add_coco_labels function has been successfully renamed from classes to categories. No usages of the old classes parameter were found in the codebase, ensuring backward compatibility is maintained.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find usages of `add_coco_labels` with the `classes` parameter.

# Test: Search for occurrences of `add_coco_labels` using `classes`.
rg --type python 'add_coco_labels\([^\)]*classes='

Length of output: 83


Script:

#!/bin/bash
# Description: Find usages of `add_coco_labels` with the `classes` parameter using ast-grep.

ast-grep --lang python --pattern 'add_coco_labels($_, classes=_)'

Length of output: 67


Script:

#!/bin/bash
# Description: Find usages of `add_coco_labels` with the `classes` parameter in Python files.

# Search for occurrences of `add_coco_labels` using `classes` in Python files.
rg 'add_coco_labels\s*\([^)]*classes\s*=' -g "*.py"

Length of output: 53

tests/unittests/import_export_tests.py (1)

1320-1378: Tests for COCO Detection Dataset are correctly validating category handling

The added test cases properly verify the default behavior of alphabetized 1-based categories and the functionality of loading only matching classes using the classes and only_matching parameters.

@@ -13,7 +13,7 @@
from setuptools import setup, find_packages


VERSION = "1.0.0"
VERSION = "1.0.1"
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Version update incomplete: "1.0.0" still present in multiple files.

The search revealed that the version "1.0.0" still exists in several files across the codebase. To ensure consistency and prevent potential issues in future releases, please update all remaining instances of "1.0.0" to "1.0.1". Key areas that require attention include:

  • package.json
  • yarn.lock
  • Test files (e.g., tests/unittests/utils/openlabel.py)
  • Documentation files (e.g., docs/source/user_guide/dataset_creation/datasets.rst)
  • Migration scripts (e.g., fiftyone/migrations/revisions/v1_0_0.py)

After making these updates, consider rerunning the version search to confirm that all instances have been addressed.

🔗 Analysis chain

Version update looks good and aligns with PR objectives.

The VERSION variable has been correctly updated from "1.0.0" to "1.0.1", which is consistent with the pull request's objective of finalizing the merge for release version 1.0.1. This change is properly reflected in the get_version() function, ensuring that the correct version is used throughout the setup process.

To ensure this is the only required change for the version update, let's verify that no other occurrences of the old version exist:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining occurrences of version 1.0.0

# Test: Search for "1.0.0" in all files. Expect: No results.
rg --type-not binary "1\.0\.0"

Length of output: 63


Script:

#!/bin/bash
# Description: Check for any remaining occurrences of version 1.0.0

# Test: Search for "1.0.0" in all files. Expect: No results.
rg "1\.0\.0"

Length of output: 32135

Comment on lines +209 to +215
expect(
getBubbles(
"classes",
{ classes: { classifications: [{ label: "label" }] } },
{ classes: classifications }
)
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Complete the test case with an expectation.

The test case for classifications is incomplete. Add an expectation to verify the output of getBubbles. For example:

expect(
  getBubbles(
    "classes",
    { classes: { classifications: [{ label: "label" }] } },
    { classes: classifications }
  )
).toEqual([classifications, [{ classifications: [{ label: "label" }] }]]);

This ensures that the getBubbles function correctly handles the classifications field.

Comment on lines +225 to +231
expect(
getBubbles(
"temporal",
{ temporal: { detections: [{ label: "label" }] } },
{ temporal: temporalDetections }
)
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Complete the test case with an expectation.

The test case for temporalDetections is incomplete. Add an expectation to verify the output of getBubbles. For example:

expect(
  getBubbles(
    "temporal",
    { temporal: { detections: [{ label: "label" }] } },
    { temporal: temporalDetections }
  )
).toEqual([temporalDetections, [{ detections: [{ label: "label" }] }]]);

This ensures that the getBubbles function correctly handles the temporalDetections field.

Comment on lines +14 to +18
export default function (
ref: MutableRefObject<boolean>,
id: string,
looker: Lookers
) {
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Name the custom hook for better identification

Since this is a custom React hook, it's a best practice to name it starting with use to follow React conventions and improve debugging and readability.

Apply this diff to name the function:

-export default function (
+export default function useKeyEvents(
  ref: MutableRefObject<boolean>,
  id: string,
  looker: Lookers
) {
📝 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
export default function (
ref: MutableRefObject<boolean>,
id: string,
looker: Lookers
) {
export default function useKeyEvents(
ref: MutableRefObject<boolean>,
id: string,
looker: Lookers
) {

Comment on lines +22 to +34
useEffect(() => {
if (ref.current) {
// initial call should wait for load event
const update = () => {
looker.updateOptions({
shouldHandleKeyEvents: id === hoveredId,
});
ready.current = true;

looker.removeEventListener("load", update);
};
looker.addEventListener("load", update);
} else if (ready.current) {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add a cleanup function to useEffect to prevent potential memory leaks

To ensure that the event listener is properly removed if the component unmounts before the 'load' event fires, add a cleanup function to useEffect.

Modify the useEffect hook to return a cleanup function:

 useEffect(() => {
   if (ref.current) {
     // initial call should wait for load event
     const update = () => {
       looker.updateOptions({
         shouldHandleKeyEvents: id === hoveredId,
       });
       ready.current = true;

       looker.removeEventListener("load", update);
     };
     looker.addEventListener("load", update);
+    return () => {
+      looker.removeEventListener("load", update);
+    };
   } else if (ready.current) {
     looker.updateOptions({
       shouldHandleKeyEvents: id === hoveredId,
     });
   }
 }, [hoveredId, id, looker, ref]);
📝 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
useEffect(() => {
if (ref.current) {
// initial call should wait for load event
const update = () => {
looker.updateOptions({
shouldHandleKeyEvents: id === hoveredId,
});
ready.current = true;
looker.removeEventListener("load", update);
};
looker.addEventListener("load", update);
} else if (ready.current) {
useEffect(() => {
if (ref.current) {
// initial call should wait for load event
const update = () => {
looker.updateOptions({
shouldHandleKeyEvents: id === hoveredId,
});
ready.current = true;
looker.removeEventListener("load", update);
};
looker.addEventListener("load", update);
return () => {
looker.removeEventListener("load", update);
};
} else if (ready.current) {
looker.updateOptions({
shouldHandleKeyEvents: id === hoveredId,
});
}
}, [hoveredId, id, looker, ref]);

Comment on lines +23 to +25
import { setFrameNumberAtom } from "@fiftyone/playback";
import { Schema } from "@fiftyone/utilities";
import { getDefaultStore } from "jotai";
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Consider avoiding direct use of getDefaultStore() for state management

Directly manipulating atoms with getDefaultStore().set bypasses React's state management and can lead to unexpected side effects or difficult-to-debug issues. It's recommended to use Jotai's useAtom or useSetAtom hooks within React components to update atom values. If you need to update state from outside a React component, consider refactoring the code to pass the store explicitly or use a context provider.

Comment on lines +530 to +535
if (this.state.config.enableTimeline) {
getDefaultStore().set(setFrameNumberAtom, {
name: `timeline-${this.state.config.sampleId}`,
newFrameNumber: this.state.frameNumber,
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

Avoid directly setting atom state outside of React components

Setting atom values using getDefaultStore().set outside of React components can result in unpredictable behavior and undermine the benefits of React's controlled state updates. It's preferable to handle state changes within React components using hooks like useAtom or useSetAtom. If altering state from non-React code is necessary, consider redesigning the architecture to align with React's state management patterns.

Comment on lines 558 to 560
getVideo() {
return this.lookerElement.children[0].element as HTMLVideoElement;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Ensure getVideo() method does not expose internal implementation details

The getVideo() method returns a reference to an internal DOM element via this.lookerElement.children[0].element. Exposing internal structure can make the codebase fragile and harder to maintain if the DOM hierarchy changes. Consider abstracting this interaction or providing a more stable interface to interact with the video element.

Comment on lines +208 to +211
elif isinstance(categories[0], dict):
classes_map = {c["id"]: c["name"] for c in categories}
else:
classes_map = {i: label for i, label in enumerate(classes)}
classes_map = {i: label for i, label in enumerate(categories, 1)}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential IndexError When Accessing categories[0]

At line 208, the code checks elif isinstance(categories[0], dict): without verifying that categories is not an empty list. If categories is empty, accessing categories[0] will raise an IndexError. Please add a check to ensure that categories is not empty before accessing its first element.

Apply this diff to prevent the possible IndexError:

 elif isinstance(categories, dict):
     classes_map = categories
 elif not categories:
     classes_map = {}
-elif isinstance(categories[0], dict):
+elif categories and isinstance(categories[0], dict):
     classes_map = {c["id"]: c["name"] for c in categories}
 else:
     classes_map = {i: label for i, label in enumerate(categories, 1)}

Committable suggestion was skipped due to low confidence.

classes = dataset.distinct("predictions.detections.label")
categories = [{"id": i, "name": l} for i, l in enumerate(classes, 1)]
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Replace ambiguous variable name l

Using the variable name l can lead to confusion with the digit 1 or the uppercase I. It is recommended to use a more descriptive variable name for clarity.

Apply this diff to improve code readability:

-categories = [{"id": i, "name": l} for i, l in enumerate(classes, 1)]
+categories = [{"id": i, "name": label} for i, label in enumerate(classes, 1)]
📝 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
categories = [{"id": i, "name": l} for i, l in enumerate(classes, 1)]
categories = [{"id": i, "name": label} for i, label in enumerate(classes, 1)]
🧰 Tools
🪛 Ruff

1822-1822: Ambiguous variable name: l

(E741)

benjaminpkane and others added 2 commits October 11, 2024 10:23
* move modal looker state to use-looker

* fix video update sample

* linting
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.

4 participants