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

Enhanced running of annotations actions #8727

Open
wants to merge 20 commits into
base: develop
Choose a base branch
from

Conversation

bsekachev
Copy link
Member

@bsekachev bsekachev commented Nov 20, 2024

Motivation and context

How has this been tested?

Checklist

  • I submit my changes into the develop branch
  • I have created a changelog fragment
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • I have linked related issues (see GitHub docs)
  • I have increased versions of npm packages if it is necessary
    (cvat-canvas,
    cvat-core,
    cvat-data and
    cvat-ui)

License

  • I submit my code changes under the same MIT License that covers the project.
    Feel free to contact the maintainers if that's a concern.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced undo/redo functionality for annotation actions, enhancing user interaction.
    • Enhanced annotation actions to support various object types, increasing flexibility.
    • Added capability to execute annotation actions on specific objects.
    • New commit method for managing annotation changes in the Collection class.
    • Added runAnnotationAction method across various components for improved action handling.
  • Bug Fixes

    • Removed outdated tests related to job saving and automatic saving recommendations.
  • Documentation

    • Updated interfaces and method signatures to reflect new action handling capabilities.
  • Style

    • Adjusted styles for improved layout in the annotation actions modal.

Copy link
Contributor

coderabbitai bot commented Nov 20, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This update introduces significant enhancements to the annotation actions functionality within the CVAT application. Key features include the ability to undo and redo changes in annotation actions, support for various object types in annotation actions, and the capability to execute actions on specific objects. Additionally, several classes and methods related to annotation actions have been restructured or added, improving the overall flexibility and usability of the annotation tools. The changes also involve modifications to the API and UI components to accommodate these new features.

Changes

File Change Summary
changelog.d/20241120_234543_sekachev.bs_updated_annotations_actions.md Introduced undo/redo functionality for annotation actions.
changelog.d/20241120_234732_sekachev.bs_updated_annotations_actions.md Enhanced annotation actions to support various object types.
changelog.d/20241120_234852_sekachev.bs_updated_annotations_actions.md Added capability to execute annotation actions on specific objects.
cvat-core/src/annotations-actions.ts Introduced new action management functions and registered actions. Removed old single-frame action interfaces and classes.
cvat-core/src/annotations-actions/base-action.ts Added abstract class BaseAction and related types/enums for action management.
cvat-core/src/annotations-actions/base-collection-action.ts Introduced framework for handling collection actions with new interfaces and methods.
cvat-core/src/annotations-actions/base-shapes-action.ts Added abstract class for shape-related actions with new methods.
cvat-core/src/annotations-actions/propagate-shapes.ts Introduced PropagateShapes class for managing shape propagation across frames.
cvat-core/src/annotations-actions/remove-filtered-shapes.ts Added RemoveFilteredShapes class for managing shape removal actions.
cvat-core/src/annotations-collection.ts Added commit method for managing annotation additions/removals.
cvat-core/src/annotations-filter.ts Enhanced object state conversion and attribute handling methods.
cvat-core/src/annotations-objects.ts Simplified withContext method return structure in several classes.
cvat-core/src/api-implementation.ts Updated action execution methods in API implementation.
cvat-core/src/api.ts Restructured action handling in the API, added new call method.
cvat-core/src/enums.ts Added COMMIT_ANNOTATIONS value to HistoryActions enum.
cvat-core/src/index.ts Updated imports and method references in the CVATCore interface.
cvat-core/src/object-state.ts Added export method to ObjectState class for serialization.
cvat-core/src/session-implementation.ts Introduced commitAnnotationsImplementation method in Job and Task classes.
cvat-core/src/session.ts Added commit method to Session class for annotation management.
cvat-ui/src/components/annotation-page/annotations-actions/annotations-actions-modal.tsx Updated component to handle broader action types and improved state management.
cvat-ui/src/components/annotation-page/annotations-actions/styles.scss Modified styles for annotation action components.
cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx Added runAnnotationAction method to ItemTopComponent props.
cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx Introduced RunAnnotationActionItem function and updated menu items.
cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx Added runAnnotationAction method to ObjectItemComponent props.
cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/object-item.tsx Integrated runAnnotationAction method in ObjectItemContainer.
cvat-ui/src/cvat-core-wrapper.ts Updated imports and exports for new action handling types.
tests/cypress/e2e/features/annotations_actions.js Removed three test cases related to job saving and automatic saving recommendations.

Poem

In the meadow where annotations play,
A rabbit hops, brightening the day.
Undo, redo, actions galore,
With every hop, we explore more!
Shapes and colors, they dance and twirl,
In the world of CVAT, watch them swirl! 🐇✨


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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

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

Copy link
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: 16

🧹 Outside diff range and nitpick comments (32)
changelog.d/20241120_234852_sekachev.bs_updated_annotations_actions.md (1)

3-4: Expand the changelog entry with more details

While the entry follows the correct format, consider adding more details about:

  • Types of objects that can be targeted
  • Examples of supported actions
  • Any limitations or prerequisites
 ### Added

-Ability to run annotations action on a certain object
+Ability to run annotations action on a specific object, including:
+- Support for [list supported object types]
+- Capability to execute [list supported actions]
+- [Any important limitations or prerequisites]
  (<https://github.com/cvat-ai/cvat/pull/8727>)
changelog.d/20241120_234543_sekachev.bs_updated_annotations_actions.md (1)

3-3: Fix grammatical issue in the changelog entry.

The phrase "an annotations action" is grammatically incorrect. It should be either singular or plural, but not mixed.

-A user may undo or redo changes, made by an annotations action
+A user may undo or redo changes made by an annotation action
🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: The plural noun “annotations” cannot be used with the article “an”. Did you mean “an annotation” or “annotations”?
Context: ... user may undo or redo changes, made by an annotations action (<https://github.com/cvat-ai/c...

(A_NNS)

cvat-core/src/annotations-actions/remove-filtered-shapes.ts (2)

8-16: Consider adding JSDoc comments for better documentation.

While the empty init() and destroy() methods are fine, adding JSDoc comments would better document their purpose and potential future use, especially since this is part of a public API.

Consider adding documentation like this:

+/**
+ * Initializes the RemoveFilteredShapes action.
+ * Currently a no-op, but may be extended in the future.
+ */
 public async init(): Promise<void> {
     // nothing to init
 }

+/**
+ * Cleans up resources used by the RemoveFilteredShapes action.
+ * Currently a no-op, but may be extended in the future.
+ */
 public async destroy(): Promise<void> {
     // nothing to destroy
 }

29-41: LGTM! Clear implementation of helper methods.

The helper methods are well-implemented with clear intent. The comment in isApplicableForObject effectively explains why the method returns false.

However, if the class remains as-is (removing all shapes without filtering), consider updating the name getter to return a more accurate description like 'Remove all shapes'.

 public get name(): string {
-    return 'Remove filtered shapes';
+    return 'Remove all shapes';
 }
cvat-core/src/annotations-actions/annotations-actions.ts (3)

26-26: Fix the linting error

Remove the extra space before the parenthesis to comply with the style guide.

-    if (!(action instanceof BaseAction) ) {
+    if (!(action instanceof BaseAction)) {
🧰 Tools
🪛 eslint

[error] 26-26: There should be no space before this paren.

(space-in-parens)

🪛 GitHub Check: Linter

[failure] 26-26:
There should be no space before this paren


25-36: Consider making action registration thread-safe

The current implementation might face race conditions if multiple actions are registered concurrently. Consider making the registration process atomic.

Consider using a synchronization mechanism or making the registration process synchronous by removing the async keyword since there are no async operations:

-export async function registerAction(action: BaseAction): Promise<void> {
+export function registerAction(action: BaseAction): void {
🧰 Tools
🪛 eslint

[error] 26-26: There should be no space before this paren.

(space-in-parens)

🪛 GitHub Check: Linter

[failure] 26-26:
There should be no space before this paren


114-114: Remove extra blank lines at end of file

Remove the extra blank lines at the end of the file to comply with the linting rules.

 }
-
-
🧰 Tools
🪛 eslint

[error] 114-115: Too many blank lines at the end of file. Max of 0 allowed.

(no-multiple-empty-lines)

🪛 GitHub Check: Linter

[failure] 114-114:
Too many blank lines at the end of file. Max of 0 allowed

cvat-ui/src/cvat-core-wrapper.ts (1)

44-46: LGTM! Good architectural improvement with specialized action classes.

The introduction of BaseShapesAction, BaseCollectionAction, and BaseAction represents a well-structured approach to handling different types of annotation actions. This modular design improves code organization and maintainability.

This architectural change allows for better separation of concerns:

  • BaseAction: Generic action handling
  • BaseShapesAction: Shape-specific operations
  • BaseCollectionAction: Collection-wide operations
cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx (2)

50-50: Consider adding parameters to runAnnotationAction

The method signature runAnnotationAction(): void is very generic. Consider adding parameters to specify which annotation action to run, improving type safety and making the API more explicit.

Example suggestion:

-    runAnnotationAction(): void;
+    runAnnotationAction(actionType: AnnotationActionType, options?: AnnotationActionOptions): void;

171-171: Consider maintaining alphabetical ordering of props

To maintain consistency with the rest of the codebase and improve maintainability, consider keeping the props in alphabetical order.

                            resetCuboidPerspective,
+                           runAnnotationAction,
                            setColorPickerVisible,
                            edit,
                            slice,
-                           runAnnotationAction,
cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx (1)

44-44: Add JSDoc documentation for the new method.

Please add documentation explaining the purpose and behavior of runAnnotationAction. This will help other developers understand when and how to use this method.

+    /** Executes an annotation action for the current object */
     runAnnotationAction(): void;
cvat-core/src/index.ts (2)

37-44: Fix missing semicolons and verify action imports

The new imports align well with the enhanced annotation actions functionality. However, there are style issues to address.

Add missing semicolons after the import statements:

-import { BaseCollectionAction } from './annotations-actions/base-collection-action'
-import { BaseShapesAction } from './annotations-actions/base-shapes-action'
+import { BaseCollectionAction } from './annotations-actions/base-collection-action';
+import { BaseShapesAction } from './annotations-actions/base-shapes-action';
🧰 Tools
🪛 eslint

[error] 43-44: Missing semicolon.

(@typescript-eslint/semi)


37-44: Well-structured enhancement to annotation actions

The changes demonstrate good architectural decisions:

  1. Clear separation of concerns in the action handling system
  2. Modular approach with base classes for different action types
  3. Consistent interface updates

Consider adding JSDoc comments to document the new action system's usage patterns and examples for future contributors.

Also applies to: 175-176, 220-221

🧰 Tools
🪛 eslint

[error] 43-44: Missing semicolon.

(@typescript-eslint/semi)

cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx (1)

50-50: Add TypeScript type information for runAnnotationAction.

The runAnnotationAction prop should have its return type specified for better type safety and documentation.

-    runAnnotationAction(): void;
+    runAnnotationAction: () => void;
cvat-core/src/object-state.ts (1)

Line range hint 528-547: Consider enhancing error handling in export implementation

While the implementation follows the established pattern, consider adding type validation or error handling for cases where the internal export handler is missing but required.

Consider this enhancement:

 value: function exportImplementation(): ObjectState {
     if (this.__internal && this.__internal.export) {
         return this.__internal.export(this);
     }

+    // Consider adding a warning or throwing an error if export is required but not available
+    // console.warn('Export handler not available for this object state');
     return this;
 },
cvat-core/src/session.ts (1)

175-178: Fix line length to improve readability

The line exceeds the maximum length of 120 characters. Consider breaking it into multiple lines.

-                async commit(added, removed, frame) {
-                    const result = await PluginRegistry.apiWrapper.call(this, prototype.annotations.commit, added, removed, frame);
-                    return result;
-                },
+                async commit(added, removed, frame) {
+                    const result = await PluginRegistry.apiWrapper.call(
+                        this,
+                        prototype.annotations.commit,
+                        added,
+                        removed,
+                        frame,
+                    );
+                    return result;
+                },
🧰 Tools
🪛 eslint

[error] 176-176: This line has a length of 131. Maximum allowed is 120.

(max-len)

cvat-core/src/annotations-actions/propagate-shapes.ts (1)

38-39: Refactor long lines to comply with the maximum line length

Lines 38 and 39 exceed the maximum allowed line length of 120 characters, as indicated by the static analysis tools. Refactoring these lines will improve readability and adhere to the project's coding standards.

Apply this diff to split the lines appropriately:

-        const frameNumbers = this.#instance instanceof Job ? await this.#instance.frames.frameNumbers() : range(0, this.#instance.size);
+        const frameNumbers = this.#instance instanceof Job
+            ? await this.#instance.frames.frameNumbers()
+            : range(0, this.#instance.size);

-        const propagatedShapes = propagateShapes<SerializedShape>(collection.shapes, number, this.#targetFrame, frameNumbers);
+        const propagatedShapes = propagateShapes<SerializedShape>(
+            collection.shapes,
+            number,
+            this.#targetFrame,
+            frameNumbers,
+        );
🧰 Tools
🪛 eslint

[error] 38-38: This line has a length of 136. Maximum allowed is 120.

(max-len)


[error] 39-39: This line has a length of 126. Maximum allowed is 120.

(max-len)

cvat-core/src/annotations-actions/base-collection-action.ts (3)

5-5: Remove unused import 'omit'

The omit function is imported from 'lodash' but is not used in this file. Unused imports can clutter the code and may cause confusion.

Apply this diff to remove the unused import:

-import { throttle, omit } from 'lodash';
+import { throttle } from 'lodash';
🧰 Tools
🪛 GitHub Check: Linter

[failure] 5-5:
'omit' is defined but never used

🪛 eslint

[error] 5-5: 'omit' is defined but never used.

(@typescript-eslint/no-unused-vars)


139-152: Correct indentation to improve code readability

There are inconsistencies in indentation from lines 139 to 152, which can reduce code readability and maintainability.

Apply this diff to correct the indentation:

         .reduce<CollectionActionInput['collection']>((acc, value, idx) => {
-            if (states[idx].objectType === ObjectType.SHAPE) {
-                acc.shapes.push(value as SerializedShape);
-            }
-            if (states[idx].objectType === ObjectType.TAG) {
-                acc.tags.push(value as SerializedTag);
-            }
-            if (states[idx].objectType === ObjectType.TRACK) {
-                acc.tracks.push(value as SerializedTrack);
-            }
-            return acc;
-        }, { shapes: [], tags: [], tracks: [] });
+        .reduce<CollectionActionInput['collection']>((acc, value, idx) => {
+            if (states[idx].objectType === ObjectType.SHAPE) {
+                acc.shapes.push(value as SerializedShape);
+            }
+
+            if (states[idx].objectType === ObjectType.TAG) {
+                acc.tags.push(value as SerializedTag);
+            }
+
+            if (states[idx].objectType === ObjectType.TRACK) {
+                acc.tracks.push(value as SerializedTrack);
+            }
+
+            return acc;
+        }, { shapes: [], tags: [], tracks: [] });
🧰 Tools
🪛 GitHub Check: Linter

[failure] 139-139:
Expected indentation of 12 spaces but found 16


[failure] 140-140:
Expected indentation of 16 spaces but found 20


[failure] 141-141:
Expected indentation of 12 spaces but found 16


[failure] 143-143:
Expected indentation of 12 spaces but found 16


[failure] 144-144:
Expected indentation of 16 spaces but found 20

🪛 eslint

[error] 139-139: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 140-140: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 141-141: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 143-143: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 144-144: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 145-145: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 147-147: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 148-148: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 149-149: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 151-151: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 152-152: Expected indentation of 8 spaces but found 12.

(@typescript-eslint/indent)


155-155: Remove extra space before 'frameData'

Multiple spaces are found before frameData in the object passed to action.applyFilter. This may affect code readability.

Apply this diff to correct the spacing:

-    const filteredByAction = action.applyFilter({ collection: exportedCollection,  frameData });
+    const filteredByAction = action.applyFilter({ collection: exportedCollection, frameData });
🧰 Tools
🪛 eslint

[error] 155-155: Multiple spaces found before 'frameData'.

(no-multi-spaces)

cvat-core/src/annotations-actions/base-shapes-action.ts (4)

5-5: Remove unused import 'omit' to clean up code.

The import 'omit' from 'lodash' is defined but never used in the file. Removing it will eliminate unnecessary code and prevent potential confusion.

Apply this diff to remove the unused import:

-import { omit, throttle } from 'lodash';
+import { throttle } from 'lodash';
🧰 Tools
🪛 eslint

[error] 5-5: 'omit' is defined but never used.

(@typescript-eslint/no-unused-vars)


79-79: Line exceeds the maximum allowed length of 120 characters.

Line 79 has a length of 123 characters, which exceeds the maximum allowed length. Splitting the line enhances readability and complies with style guidelines.

Apply this diff to split the line:

-const filteredShapesByFrame = exportedCollection.shapes.reduce<Record<number, SerializedShape[]>>((acc, shape) => {
+const filteredShapesByFrame = exportedCollection.shapes
+    .reduce<Record<number, SerializedShape[]>>((acc, shape) => {
🧰 Tools
🪛 eslint

[error] 79-79: This line has a length of 123. Maximum allowed is 120.

(max-len)


91-92: Refactor duplicate code for obtaining frameData into a helper function.

The logic for retrieving frameData is duplicated in both the run and call functions. Extracting this code into a shared helper function adheres to the DRY (Don't Repeat Yourself) principle and improves maintainability.

Duplicated code:

// In run function
const frameData = await Object.getPrototypeOf(instance).frames
    .get.implementation.call(instance, frame);

// In call function
const frameData = await Object.getPrototypeOf(instance).frames.get.implementation.call(instance, frame);

Also applies to: 170-170


171-171: Adjust spacing to correct multiple spaces before 'frameData'.

There are multiple spaces before 'frameData'. Correcting the spacing enhances code consistency and adheres to the coding standards.

Apply this diff to fix the spacing:

-const filteredByAction = action.applyFilter({ collection: { shapes: exported },  frameData });
+const filteredByAction = action.applyFilter({ collection: { shapes: exported }, frameData });
🧰 Tools
🪛 eslint

[error] 171-171: Multiple spaces found before 'frameData'.

(no-multi-spaces)

cvat-core/src/annotations-filter.ts (1)

62-64: Simplify conditional statements by removing unnecessary 'else' blocks

After a return statement in an if block, the else is unnecessary. Removing it improves code readability.

Apply this diff to refactor the code:

     if (spec.inputType === AttributeType.NUMBER) {
         return [name, +value];
     }
-    else if (spec.inputType === AttributeType.CHECKBOX) {
+    if (spec.inputType === AttributeType.CHECKBOX) {
         return [name, value === 'true'];
     }
 
     return [name, value];
🧰 Tools
🪛 eslint

[error] 62-64: Unnecessary 'else' after 'return'.

(no-else-return)

cvat-ui/src/components/annotation-page/annotations-actions/annotations-actions-modal.tsx (4)

227-227: Destructure 'props' in the function signature

For improved readability and to adhere to React best practices, destructure props directly in the function signature of ActionParameterComponent.

Apply this diff:

- function ActionParameterComponent(props: ActionParameterProps & { onChange: (value: string) => void }): JSX.Element {
+ function ActionParameterComponent({ defaultValue, type, values, onChange }: ActionParameterProps & { onChange: (value: string) => void }): JSX.Element {

Remove the destructuring of props within the function body accordingly.


279-279: Destructure 'props' in the function signature

To comply with React guidelines and resolve the linting error, destructure props in the function signature of AnnotationsActionsModalContent.

Apply this diff:

- function AnnotationsActionsModalContent(props: Props): JSX.Element {
+ function AnnotationsActionsModalContent({ onClose, targetObjectState }: Props): JSX.Element {

Update references to props.onClose and props.targetObjectState within the function body to use onClose and targetObjectState directly.


297-297: Use destructured props instead of 'props'

You are accessing props.targetObjectState while props has been destructured. This leads to inconsistency and can cause confusion.

Ensure you are using the destructured targetObjectState directly:

-     targetObjectState: props.targetObjectState ?? null,
+     targetObjectState: targetObjectState ?? null,
🧰 Tools
🪛 eslint

[error] 297-297: Must use destructuring props assignment

(react/destructuring-assignment)


381-425: Simplify frame selection logic

The conditional rendering for frame selection could be refactored for better readability.

Consider extracting the frame selection UI into a separate component to make the code more modular and easier to maintain.

cvat-core/src/annotations-collection.ts (3)

165-181: Fix indentation to comply with coding standards

Lines 165 to 181 have indentation issues as identified by the linter. Please adjust the indentation to match the project's coding standards.

Apply this diff to fix the indentation:

         ): {
-        tags: Tag[];
-        shapes: Shape[];
-        tracks: Track[];
-    } {
+            tags: Tag[];
+            shapes: Shape[];
+            tracks: Track[];
+        } {
             const removedCollection: (Shape | Tag | Track)[] = [];
             const collectionConsistent = []
-                .concat(removed.shapes, removed.tags, removed.tracks)
-            .reduce<boolean>((acc, serializedObject) => {
-                if (acc && typeof serializedObject.clientID === 'number') {
-            const collectionObject = this.objects[serializedObject.clientID];
-            if (collectionObject) {
-                removedCollection.push(collectionObject);
-                return true;
-            }
-        }
+                .concat(removed.shapes, removed.tags, removed.tracks)
+                .reduce<boolean>((acc, serializedObject) => {
+                    if (acc && typeof serializedObject.clientID === 'number') {
+                        const collectionObject = this.objects[serializedObject.clientID];
+                        if (collectionObject) {
+                            removedCollection.push(collectionObject);
+                            return true;
+                        }
+                    }
                     return false;
-    }, true);
+                }, true);
🧰 Tools
🪛 eslint

[error] 165-165: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 166-166: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 167-167: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 168-168: Expected indentation of 8 spaces but found 4.

(@typescript-eslint/indent)


[error] 172-172: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 173-173: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 174-174: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 175-175: Expected indentation of 20 spaces but found 24.

(@typescript-eslint/indent)


[error] 176-176: Expected indentation of 20 spaces but found 24.

(@typescript-eslint/indent)


[error] 177-177: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 178-178: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 180-180: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 181-181: Expected indentation of 8 spaces but found 12.

(@typescript-eslint/indent)


221-221: Split line to adhere to maximum line length

Line 221 exceeds the maximum allowed line length of 120 characters. Please split the line to improve readability.

Apply this diff to split the line:

-                [].concat(removedCollection.map((object) => object.clientID), appendedCollection.map((object) => object.clientID)),
+                [].concat(
+                    removedCollection.map((object) => object.clientID),
+                    appendedCollection.map((object) => object.clientID),
+                ),
🧰 Tools
🪛 eslint

[error] 221-221: This line has a length of 127. Maximum allowed is 120.

(max-len)


225-225: Remove unnecessary return statement

The return; statement at the end of the commit method is unnecessary since it's the last statement in the method. Removing it can clean up the code.

Apply this diff to remove the unnecessary return statement:

-            return;
🧰 Tools
🪛 eslint

[error] 225-225: Unnecessary return statement.

(no-useless-return)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 67f511b and 4460485.

📒 Files selected for processing (28)
  • changelog.d/20241120_234543_sekachev.bs_updated_annotations_actions.md (1 hunks)
  • changelog.d/20241120_234732_sekachev.bs_updated_annotations_actions.md (1 hunks)
  • changelog.d/20241120_234852_sekachev.bs_updated_annotations_actions.md (1 hunks)
  • cvat-core/src/annotations-actions.ts (0 hunks)
  • cvat-core/src/annotations-actions/annotations-actions.ts (1 hunks)
  • cvat-core/src/annotations-actions/base-action.ts (1 hunks)
  • cvat-core/src/annotations-actions/base-collection-action.ts (1 hunks)
  • cvat-core/src/annotations-actions/base-shapes-action.ts (1 hunks)
  • cvat-core/src/annotations-actions/propagate-shapes.ts (1 hunks)
  • cvat-core/src/annotations-actions/remove-filtered-shapes.ts (1 hunks)
  • cvat-core/src/annotations-collection.ts (3 hunks)
  • cvat-core/src/annotations-filter.ts (4 hunks)
  • cvat-core/src/annotations-objects.ts (9 hunks)
  • cvat-core/src/api-implementation.ts (2 hunks)
  • cvat-core/src/api.ts (5 hunks)
  • cvat-core/src/enums.ts (1 hunks)
  • cvat-core/src/index.ts (3 hunks)
  • cvat-core/src/object-state.ts (4 hunks)
  • cvat-core/src/session-implementation.ts (2 hunks)
  • cvat-core/src/session.ts (4 hunks)
  • cvat-ui/src/components/annotation-page/annotations-actions/annotations-actions-modal.tsx (14 hunks)
  • cvat-ui/src/components/annotation-page/annotations-actions/styles.scss (0 hunks)
  • cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx (3 hunks)
  • cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx (5 hunks)
  • cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx (3 hunks)
  • cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/object-item.tsx (4 hunks)
  • cvat-ui/src/cvat-core-wrapper.ts (4 hunks)
  • tests/cypress/e2e/features/annotations_actions.js (0 hunks)
💤 Files with no reviewable changes (3)
  • cvat-core/src/annotations-actions.ts
  • cvat-ui/src/components/annotation-page/annotations-actions/styles.scss
  • tests/cypress/e2e/features/annotations_actions.js
🧰 Additional context used
🪛 LanguageTool
changelog.d/20241120_234543_sekachev.bs_updated_annotations_actions.md

[grammar] ~3-~3: The plural noun “annotations” cannot be used with the article “an”. Did you mean “an annotation” or “annotations”?
Context: ... user may undo or redo changes, made by an annotations action (<https://github.com/cvat-ai/c...

(A_NNS)

🪛 eslint
cvat-core/src/annotations-actions/annotations-actions.ts

[error] 26-26: There should be no space before this paren.

(space-in-parens)

cvat-core/src/annotations-actions/base-action.ts

[error] 36-45: Unnecessary 'else' after 'return'.

(no-else-return)

cvat-core/src/annotations-actions/base-collection-action.ts

[error] 5-5: 'omit' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 107-107: Expected property shorthand.

(object-shorthand)


[error] 139-139: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 140-140: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 141-141: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 143-143: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 144-144: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 145-145: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 147-147: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 148-148: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 149-149: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 151-151: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 152-152: Expected indentation of 8 spaces but found 12.

(@typescript-eslint/indent)


[error] 155-155: Multiple spaces found before 'frameData'.

(no-multi-spaces)

cvat-core/src/annotations-actions/base-shapes-action.ts

[error] 5-5: 'omit' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 79-79: This line has a length of 123. Maximum allowed is 120.

(max-len)


[error] 171-171: Multiple spaces found before 'frameData'.

(no-multi-spaces)

cvat-core/src/annotations-actions/propagate-shapes.ts

[error] 38-38: This line has a length of 136. Maximum allowed is 120.

(max-len)


[error] 39-39: This line has a length of 126. Maximum allowed is 120.

(max-len)

cvat-core/src/annotations-collection.ts

[error] 165-165: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 166-166: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 167-167: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 168-168: Expected indentation of 8 spaces but found 4.

(@typescript-eslint/indent)


[error] 172-172: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 173-173: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 174-174: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 175-175: Expected indentation of 20 spaces but found 24.

(@typescript-eslint/indent)


[error] 176-176: Expected indentation of 20 spaces but found 24.

(@typescript-eslint/indent)


[error] 177-177: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 178-178: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 180-180: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 181-181: Expected indentation of 8 spaces but found 12.

(@typescript-eslint/indent)


[error] 221-221: This line has a length of 127. Maximum allowed is 120.

(max-len)


[error] 225-225: Unnecessary return statement.

(no-useless-return)

cvat-core/src/annotations-filter.ts

[error] 9-9: server-response-types import should occur before import of ./object-state

(import/order)


[error] 10-10: labels import should occur before import of ./object-state

(import/order)


[error] 62-64: Unnecessary 'else' after 'return'.

(no-else-return)


[error] 103-103: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 104-104: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 105-105: Expected indentation of 16 spaces but found 20.

(@typescript-eslint/indent)


[error] 106-106: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 130-130: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 131-131: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 132-132: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 133-133: Expected indentation of 8 spaces but found 4.

(@typescript-eslint/indent)


[error] 137-138: Missing semicolon.

(@typescript-eslint/semi)


[error] 139-139: Missing space after =>.

(arrow-spacing)


[error] 141-141: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 142-142: Expected indentation of 12 spaces but found 16.

(@typescript-eslint/indent)


[error] 143-143: Expected indentation of 8 spaces but found 12.

(@typescript-eslint/indent)


[error] 146-147: Missing trailing comma.

(@typescript-eslint/comma-dangle)


[error] 156-156: 'idx' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 158-158: This line has a length of 127. Maximum allowed is 120.

(max-len)


[error] 165-165: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 174-175: Missing semicolon.

(@typescript-eslint/semi)


[error] 176-176: 'idx' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 182-182: Trailing spaces not allowed.

(no-trailing-spaces)


[error] 193-193: 'idx' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 208-209: Missing semicolon.

(@typescript-eslint/semi)


[error] 226-226: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 227-227: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 228-228: Expected indentation of 12 spaces but found 8.

(@typescript-eslint/indent)


[error] 229-229: Expected indentation of 8 spaces but found 4.

(@typescript-eslint/indent)


[error] 236-236: Unnecessary semicolon.

(@typescript-eslint/no-extra-semi)

cvat-core/src/annotations-objects.ts

[error] 153-153: '_' is defined but never used.

(@typescript-eslint/no-unused-vars)

cvat-core/src/index.ts

[error] 43-44: Missing semicolon.

(@typescript-eslint/semi)

cvat-core/src/session.ts

[error] 176-176: This line has a length of 131. Maximum allowed is 120.

(max-len)

cvat-ui/src/components/annotation-page/annotations-actions/annotations-actions-modal.tsx

[error] 99-99: 'action' is already declared in the upper scope on line 95 column 32.

(@typescript-eslint/no-shadow)


[error] 297-297: Must use destructuring props assignment

(react/destructuring-assignment)


[error] 567-568: Missing semicolon.

(@typescript-eslint/semi)

🪛 GitHub Check: Linter
cvat-core/src/annotations-actions/annotations-actions.ts

[failure] 26-26:
There should be no space before this paren


[failure] 114-114:
Too many blank lines at the end of file. Max of 0 allowed

cvat-core/src/annotations-actions/base-action.ts

[failure] 36-36:
Unnecessary 'else' after 'return'

cvat-core/src/annotations-actions/base-collection-action.ts

[failure] 5-5:
'omit' is defined but never used


[failure] 107-107:
Expected property shorthand


[failure] 139-139:
Expected indentation of 12 spaces but found 16


[failure] 140-140:
Expected indentation of 16 spaces but found 20


[failure] 141-141:
Expected indentation of 12 spaces but found 16


[failure] 143-143:
Expected indentation of 12 spaces but found 16


[failure] 144-144:
Expected indentation of 16 spaces but found 20

🔇 Additional comments (40)
changelog.d/20241120_234852_sekachev.bs_updated_annotations_actions.md (1)

1-4: Verify consistency with related changelog entries

Since this is part of a larger feature set, let's ensure consistency with related changelog entries.

✅ Verification successful

Changelog entries are consistent and complementary

The two changelog entries are related to the same pull request (#8727) and describe complementary features:

  1. The ability to run annotation actions on specific objects
  2. The ability to undo/redo changes made by annotation actions

Both entries follow the same format, are properly categorized under "Added", and reference the same PR. The messaging is clear and consistent.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for related changelog entries to ensure consistent messaging

# Look for other changelog entries related to annotation actions
echo "Related changelog entries:"
fd . changelog.d -t f -e md -x grep -l "annotation.*action" {}

Length of output: 271


Script:

#!/bin/bash
# Let's check the content of both changelog files to verify consistency
echo "Content of changelog entries:"
cat changelog.d/20241120_234852_sekachev.bs_updated_annotations_actions.md
echo "---"
cat changelog.d/20241120_234543_sekachev.bs_updated_annotations_actions.md

Length of output: 476

changelog.d/20241120_234543_sekachev.bs_updated_annotations_actions.md (1)

1-4: LGTM! The changelog entry is well-structured.

The entry correctly documents the new undo/redo feature and follows the proper changelog format with a clear reference to the PR.

🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: The plural noun “annotations” cannot be used with the article “an”. Did you mean “an annotation” or “annotations”?
Context: ... user may undo or redo changes, made by an annotations action (<https://github.com/cvat-ai/c...

(A_NNS)

cvat-core/src/annotations-actions/remove-filtered-shapes.ts (2)

1-7: LGTM! Proper license and imports.

The file header contains the correct copyright notice and license. Imports are appropriate for the required functionality.


17-28: ⚠️ Potential issue

Verify the implementation logic against requirements.

There seems to be a discrepancy between the class name "RemoveFilteredShapes" and its implementation:

  1. The run() method marks all shapes as deleted without any filtering
  2. The applyFilter() method returns the unmodified collection

This might indicate either:

  • Missing implementation of the filtering logic
  • Incorrect class naming

Let's check if there are any related filter implementations:

Please clarify:

  1. Should this action apply filtering before removal?
  2. If not, should the class be renamed to something like RemoveAllShapes?
✅ Verification successful

Let me gather more context about the filtering implementation in the base class and the annotations filter.


Let me check how the base class and other actions implement filtering to understand the expected behavior.


Based on the implementation details seen in the base class and filter implementations, I can now provide the final response:

Implementation is correct but class name could be clearer

The current implementation in RemoveFilteredShapes is actually correct because:

  1. The base class BaseShapesAction already handles the filtering logic through AnnotationsFilter before calling the action's run method
  2. The action's applyFilter method is correctly implemented as a pass-through since the filtering is already done at the base class level
  3. The run method correctly handles the filtered shapes by marking them for deletion

The class name could be more precise, but it's technically accurate as it operates on shapes that were already filtered by the base implementation.

  • Consider renaming to RemoveShapes for clarity since the filtering is handled by the base class
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for filter-related implementations in annotation actions
rg -t ts "applyFilter|filter" "cvat-core/src/annotations-actions"

Length of output: 4999


Script:

#!/bin/bash
# Check the base class implementation and annotations filter
ast-grep --pattern 'class BaseShapesAction {
  $$$
}'

# Check the AnnotationsFilter implementation
cat cvat-core/src/annotations-filter.ts

Length of output: 9058


Script:

#!/bin/bash
# Check BaseShapesAction implementation
cat cvat-core/src/annotations-actions/base-shapes-action.ts

# Check how other actions implement filtering
ast-grep --pattern 'class $_ extends BaseShapesAction {
  $$$
  applyFilter($_) {
    $$$
  }
  $$$
}'

Length of output: 7254

cvat-core/src/annotations-actions/annotations-actions.ts (2)

38-39: Verify if all required actions are registered

Currently, only RemoveFilteredShapes and PropagateShapes are registered. Based on the PR objectives mentioning "Enhanced running of annotations actions", verify if additional actions need to be registered.

✅ Verification successful

Based on the search results, I can now generate a final response:

The action registrations are complete and correct

The codebase search reveals that only two concrete action implementations exist that extend the action hierarchy:

  • RemoveFilteredShapes (extends BaseShapesAction)
  • PropagateShapes (extends BaseCollectionAction)

Both of these actions are properly registered in the code. There are no other concrete action implementations that need to be registered.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Look for other action implementations that might need registration

# Search for other action class implementations
ast-grep --pattern 'class $_ extends BaseAction {
  $$$
}'

Length of output: 60


Script:

#!/bin/bash
# Let's try a different approach to find action classes

# Search for files containing "Action" in their name
fd "Action" --type f

# Search for class definitions that might be actions
rg "class.*Action" -A 2

# Look for action registrations
rg "registerAction" -A 1

Length of output: 6124


16-17: Verify the implementation of imported actions

The imported actions should implement their respective base classes correctly.

✅ Verification successful

Imports are correctly implemented and follow the inheritance hierarchy

The verification confirms that:

  • RemoveFilteredShapes properly extends BaseShapesAction
  • PropagateShapes properly extends BaseCollectionAction
  • Both BaseShapesAction and BaseCollectionAction extend the abstract BaseAction class
  • All classes implement the required abstract methods from their parent classes
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that RemoveFilteredShapes and PropagateShapes properly extend BaseAction

# Check RemoveFilteredShapes implementation
ast-grep --pattern 'class RemoveFilteredShapes extends BaseAction {
  $$$
}'

# Check PropagateShapes implementation
ast-grep --pattern 'class PropagateShapes extends BaseAction {
  $$$
}'

Length of output: 152


Script:

#!/bin/bash
# Let's try a different approach to verify the implementations

# First, let's check if these files exist
fd "remove-filtered-shapes.ts|propagate-shapes.ts" cvat-core/src/annotations-actions/

# Then, let's examine their content
echo "=== Content of remove-filtered-shapes.ts ==="
rg -A 10 "class RemoveFilteredShapes" cvat-core/src/annotations-actions/

echo "=== Content of propagate-shapes.ts ==="
rg -A 10 "class PropagateShapes" cvat-core/src/annotations-actions/

# Let's also check for the BaseAction definition
echo "=== BaseAction definition ==="
rg -A 5 "class BaseAction" cvat-core/src/annotations-actions/

Length of output: 3275


Script:

#!/bin/bash
# Let's verify the inheritance chain by checking for BaseShapesAction and BaseCollectionAction

echo "=== BaseShapesAction definition ==="
rg -A 5 "class BaseShapesAction" cvat-core/src/annotations-actions/

echo "=== BaseCollectionAction definition ==="
rg -A 5 "class BaseCollectionAction" cvat-core/src/annotations-actions/

# Let's also check if these base classes extend BaseAction
echo "=== Inheritance chain ==="
rg "class Base(Shapes|Collection)Action extends" cvat-core/src/annotations-actions/

Length of output: 1981

cvat-ui/src/cvat-core-wrapper.ts (1)

29-30: LGTM! Consistent import/export declarations.

The new types and classes are properly imported and exported, maintaining consistency throughout the module. This ensures that the enhanced annotation functionality is properly exposed to other parts of the application.

Also applies to: 74-75, 96-98

cvat-core/src/enums.ts (2)

151-151: LGTM! The new enum value follows existing conventions.

The addition of COMMIT_ANNOTATIONS to HistoryActions follows the established naming patterns and integrates well with the existing history tracking system.


151-151: Verify the usage of the new history action.

Let's ensure this new enum value is properly utilized across the codebase.

✅ Verification successful

Let me check the actual implementation to verify proper usage of this enum.


The new COMMIT_ANNOTATIONS enum is properly integrated and used in the codebase

The verification shows that:

  • The enum is correctly used in cvat-core/src/annotations-collection.ts as part of the history actions implementation
  • It's properly integrated with the annotations commit functionality exposed through the session interface
  • The implementation follows the existing pattern for history actions
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check usage of the new COMMIT_ANNOTATIONS history action

# Search for direct string references
echo "Searching for direct string references to 'Commit annotations'..."
rg -l "Commit annotations"

# Search for enum usage
echo "Searching for COMMIT_ANNOTATIONS enum usage..."
rg -l "HistoryActions.COMMIT_ANNOTATIONS"

# Search for potential history-related files that might need updates
echo "Searching for history-related files..."
fd -e ts -e tsx -e js -e jsx history

Length of output: 546


Script:

#!/bin/bash
# Check the implementation in annotations-collection.ts
echo "Checking COMMIT_ANNOTATIONS usage in annotations-collection.ts:"
rg -A 5 "COMMIT_ANNOTATIONS" annotations-collection.ts

# Check history-related implementation
echo -e "\nChecking history implementation in annotations-history.ts:"
ast-grep --pattern 'class HistoryActions {
  $$$
}'

Length of output: 444


Script:

#!/bin/bash
# Check the implementation in the correct path
echo "Checking COMMIT_ANNOTATIONS usage in cvat-core:"
rg -A 5 "COMMIT_ANNOTATIONS" cvat-core/src/annotations-collection.ts

# Check history implementation
echo -e "\nChecking history implementation:"
rg -A 10 "class .*History" cvat-core/src/annotations-history.ts

# Check for any commit-related actions
echo -e "\nChecking for commit-related patterns:"
rg -A 5 "commit.*annotation" cvat-core/src/

Length of output: 1494

cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx (2)

87-87: LGTM!

The props destructuring follows the existing pattern and maintains good code organization.


Line range hint 182-182: Verify memoization effectiveness with the new action

With the addition of runAnnotationAction, verify that the React.memo wrapper is still effectively preventing unnecessary re-renders. Consider adding a useCallback wrapper if the action is defined in the parent component.

✅ Verification successful

Based on the search results, I can now generate a final response as we have enough context about runAnnotationAction. The function is defined in a class component (object-item.tsx) and passed down through props, not created inline in any functional component.

Memoization is correctly implemented for this component

The runAnnotationAction is defined as a class method using the class fields syntax, which means it has a stable reference and won't cause unnecessary re-renders of the memoized ObjectItemBasics component. Since it's not created inline or with hooks in a functional component, there's no need for useCallback. The current implementation maintains proper memoization effectiveness.

  • The function is defined in cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/object-item.tsx as a class method
  • It's passed down through props to ObjectItemBasics which is correctly wrapped in React.memo
  • The stable reference of the class method ensures the memoization won't break
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for parent component implementations to verify callback handling
ast-grep --pattern 'const $runAnnotationAction = useCallback($$$)'

Length of output: 68


Script:

#!/bin/bash
# Let's first find where runAnnotationAction is defined and used
rg "runAnnotationAction" -A 2 -B 2

# Also search for the ObjectItemBasics component definition and its props
ast-grep --pattern 'interface $Props {
  $$$
}'

# And check the actual component implementation
ast-grep --pattern 'const ObjectItemBasics = memo<$_>(($_) => {
  $$$
})'

Length of output: 7065

cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item.tsx (2)

77-77: LGTM!

The props destructuring is correctly updated to include the new method.


138-138: Verify ItemBasics component implementation.

Ensure that the ItemBasics component's Props interface includes the runAnnotationAction prop and handles it appropriately.

✅ Verification successful

The search results show that runAnnotationAction is properly declared in the object-item-basics.tsx interface and is being used within the component. Let me verify the complete implementation to ensure it's handled correctly.


The runAnnotationAction prop is properly implemented

The verification confirms that:

  • The runAnnotationAction prop is correctly declared in the Props interface of object-item-basics.tsx
  • It's properly passed through the component hierarchy
  • The prop is being used appropriately in the component's implementation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if ItemBasics component properly declares and handles the runAnnotationAction prop

# Look for the Props interface in object-item-basics.tsx
ast-grep --pattern 'interface Props {
  $$$
  runAnnotationAction: () => void;
  $$$
}'

# Look for usage of runAnnotationAction in object-item-basics.tsx
rg "runAnnotationAction" --type ts

Length of output: 1629


Script:

#!/bin/bash
# Check the complete implementation of ItemBasics component
rg -A 5 "interface Props" cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx

# Check how runAnnotationAction is used in the component
rg -B 2 -A 2 "runAnnotationAction" cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-basics.tsx

Length of output: 811

cvat-core/src/index.ts (2)

175-176: Verify backward compatibility of action interface changes

The interface changes from runActions to runAction and the addition of callAction might impact existing code.

Let's verify the usage of these methods in the codebase:

✅ Verification successful

Based on the search results, I can now generate the final response:

Interface changes are safe and maintain backward compatibility

The changes from runActions to runAction and addition of callAction are part of a new action handling system that has been properly implemented throughout the codebase. The search results show:

  1. No existing usage of runActions was found, indicating this wasn't a breaking change
  2. The new runAction and callAction methods are properly integrated in the action system:
    • Defined in annotations-actions/annotations-actions.ts
    • Used consistently through the action system implementation
    • Have proper type definitions and implementations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for existing usage of runActions to ensure all calls are updated
rg "runActions" --type ts

# Search for existing action method calls to understand impact
rg "\.(run|call)Action" --type ts

Length of output: 61


Script:

#!/bin/bash
# Let's try a broader search for action-related patterns
rg -i "action" --type ts -A 2 cvat-core/src/

# Also search for run and call patterns
rg "\.(run|call)\(" --type ts -A 2 cvat-core/src/

# Let's check the git history for these files to understand the changes
git diff HEAD~1 cvat-core/src/index.ts

Length of output: 92042


220-221: Verify implementation of new action base classes

The addition of BaseShapesAction and BaseCollectionAction suggests a more modular approach to action handling. Let's ensure they are properly implemented and documented.

✅ Verification successful

Let me gather more information about the base classes and their usage.


Base action classes are properly implemented and used

The verification shows that both BaseShapesAction and BaseCollectionAction are well-implemented abstract classes with:

  • Clear interfaces defining input/output types
  • Abstract methods run() and applyFilter()
  • Proper inheritance from BaseAction
  • Active usage in concrete implementations like RemoveFilteredShapes and PropagateShapes

The modular approach is correctly implemented with type safety and consistent patterns across the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check implementation of base classes
ast-grep --pattern 'class BaseShapesAction {
  $$$
}'

ast-grep --pattern 'class BaseCollectionAction {
  $$$
}'

# Check for documentation
rg -A 5 "class (BaseShapesAction|BaseCollectionAction)" --type ts

Length of output: 1467


Script:

#!/bin/bash
# Check for the parent BaseAction class implementation
ast-grep --pattern 'class BaseAction {
  $$$
}'

# Check for implementations/usage of these base classes
rg -l "extends (BaseShapesAction|BaseCollectionAction)" --type ts

# Check for types used in these classes
rg "(CollectionActionInput|ShapesActionInput|CollectionActionOutput|ShapesActionOutput)" --type ts -A 2

Length of output: 5400

cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/object-item-menu.tsx (2)

347-352: LGTM!

The menu integration is well-implemented, following the existing patterns for conditional rendering based on the readonly state.


Line range hint 237-352: Verify integration with annotation actions system.

Since this is part of a larger enhancement to the annotation actions system:

  1. Ensure proper integration with the new action handling mechanisms
  2. Add unit tests for the new RunAnnotationActionItem component
cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/object-item.tsx (3)

8-8: LGTM: Modern React root API usage

The import of createRoot follows React 18's recommended way of creating roots for rendering components.


447-447: LGTM: Proper prop passing

The runAnnotationAction method is correctly passed as a prop to the ObjectStateItemComponent.


24-24: Verify modal component implementation and usage

Let's verify the consistency of modal implementations across the codebase.

✅ Verification successful

Let me try a different approach with modified commands to search for the modal implementations and usages.


Let me check the actual implementation and usage of the modal component to make a final determination.


Based on the review of the implementation and usage, I can now provide a final response:

Modal implementation is consistent and properly managed

The AnnotationsActionsModalContent component is a well-structured React modal that:

  • Uses Ant Design's Modal component consistently
  • Properly handles mounting/unmounting through React's createRoot
  • Manages its own state and cleanup
  • Is used appropriately in the object-item.tsx file for annotation actions

The implementation follows the application's patterns for modal dialogs and there are no issues with duplicate implementations or inconsistent usage.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other modal implementations and usages

# Check for other modal implementations
echo "Checking for other modal implementations..."
rg -l "createElement.*modal" --type tsx

# Check for AnnotationsActionsModalContent usage
echo "Checking AnnotationsActionsModalContent usage..."
rg -l "AnnotationsActionsModalContent" --type tsx

# Check for similar patterns of dynamic modal creation
echo "Checking for similar modal creation patterns..."
ast-grep --pattern 'createRoot($root).render(<$_/>)'

Length of output: 511


Script:

#!/bin/bash
# Search for modal implementations and usages without file type restrictions
echo "Checking for modal implementations..."
rg -l "createElement.*[Mm]odal"

echo "Checking AnnotationsActionsModalContent usage..."
rg -l "AnnotationsActionsModalContent"

echo "Checking for modal-related components..."
rg -l "Modal.*Content"

# Check the specific file content
echo "Checking the specific file content..."
cat "cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/object-item.tsx"

Length of output: 16566


Script:

#!/bin/bash
# Check the implementation of AnnotationsActionsModalContent
echo "Checking AnnotationsActionsModalContent implementation..."
cat "cvat-ui/src/components/annotation-page/annotations-actions/annotations-actions-modal.tsx"

# Check for similar modal creation patterns with context
echo "Checking similar modal creation patterns..."
rg "createRoot.*render.*Modal" -A 5

Length of output: 25700

cvat-core/src/object-state.ts (2)

2-2: LGTM: Copyright and imports updated appropriately

The copyright has been extended to 2024, and necessary serialized types have been imported to support the new export functionality.

Also applies to: 11-11


Line range hint 550-563: LGTM: Delete implementation rename maintains functionality

The rename to deleteImplementation is consistent with other changes while preserving the existing argument validation and functionality.

cvat-core/src/api-implementation.ts (2)

42-44: Verify the impact of import changes on existing code.

The change from runActions to runAction suggests a shift from batch processing to individual action processing. This could potentially break existing code that relies on the old behavior.

Let's verify the usage of these functions in the codebase:


59-60: Ensure proper error handling in the new action implementations.

The addition of callAction and update to use runAction introduces new API methods. These should include proper error handling and maintain backward compatibility.

Let's verify the implementation details:

✅ Verification successful

Based on the gathered information, I can now provide a final response:

Error handling is properly implemented in the action system architecture

The implementation follows a robust error handling pattern through:

  1. Async/await usage in all action-related functions (runAction, callAction)
  2. Type-safe implementation with proper interfaces and abstract classes
  3. Action-specific error handling through the class inheritance system (BaseAction -> BaseShapesAction)
  4. Progress and cancellation callback support for long-running operations

The architecture ensures errors are properly propagated up the call stack where they can be handled by the UI layer's extensive try-catch blocks, as evidenced by the numerous error handlers found in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check error handling in the new action implementations
# Test: Look for try-catch blocks and error handling in the implementation
ast-grep --pattern 'try {
  $$$
} catch ($$$) {
  $$$
}' src/annotations-actions/annotations-actions.ts

# Test: Check for backward compatibility handling
rg -A 5 'runAction|callAction' src/annotations-actions/annotations-actions.ts

Length of output: 366


Script:

#!/bin/bash
# Let's first find the correct location of these action implementations
fd -t f "action" --exec rg -l "runAction|callAction"

# Then check their implementations for error handling
fd -t f "action" --exec ast-grep --pattern 'try {
  $$$
} catch ($$$) {
  $$$
}'

# Also search for the implementation details
rg -A 5 "implementationMixin.*(?:run|call)Action"

Length of output: 118011


Script:

#!/bin/bash
# Let's check the implementation of runAction and callAction
rg -A 10 "function runAction|function callAction" cvat-core/src/

# Also check for error handling patterns in these implementations
ast-grep --pattern 'try {
  $$$
  runAction($$$)
  $$$
} catch ($$$) {
  $$$
}'

ast-grep --pattern 'try {
  $$$
  callAction($$$)
  $$$
} catch ($$$) {
  $$$
}'

Length of output: 2205


Script:

#!/bin/bash
# Let's examine the implementation details of these action functions
rg -B 5 -A 20 "export async function runAction|export async function callAction" cvat-core/src/annotations-actions/annotations-actions.ts

# Also check for error handling in the implementation of BaseShapesAction
rg -A 10 "class BaseShapesAction" cvat-core/src/annotations-actions/

Length of output: 2488


Script:

#!/bin/bash
# Let's check the implementation of runShapesAction and callShapesAction which handle the actual execution
rg -B 2 -A 15 "async function runShapesAction|async function callShapesAction" cvat-core/src/annotations-actions/

# Also check for error handling in the actual action implementations
rg -A 10 "extends BaseShapesAction" cvat-core/src/annotations-actions/

Length of output: 1160

cvat-core/src/session.ts (2)

369-373: LGTM! Well-typed commit method declaration

The type declaration is well-structured, using appropriate TypeScript features like Omit utility type to handle the SerializedCollection parameters.


444-444: LGTM! Proper method binding

The commit method is correctly bound to the instance context, following the established pattern in the codebase.

cvat-core/src/annotations-objects.ts (4)

527-536: LGTM! Well-structured context extension

The implementation properly extends the parent context and adds type-safe method bindings for save and export.


846-855: LGTM! Consistent with Shape class implementation

The implementation maintains consistency with the Shape class pattern while providing track-specific context.


1424-1433: LGTM! Maintains implementation consistency

The implementation follows the established pattern, ensuring consistency across annotation types.


600-600: LGTM! Consistent internal context implementation

The __internal property is consistently implemented across all annotation types, providing uniform access to context methods.

Also applies to: 950-950, 1481-1481, 2052-2052, 3094-3094

cvat-core/src/annotations-actions/base-action.ts (3)

16-20: Type 'ActionParameters' is properly structured

The ActionParameters type is well-defined, allowing for flexible parameter definitions with appropriate types and default values.


22-31: Abstract class 'BaseAction' is well-defined

The BaseAction class correctly defines the required abstract methods and getters, ensuring that subclasses will implement the necessary functionality.


39-39: Verify compatibility of 'Object.hasOwn' with target environments

The method Object.hasOwn is used, which is supported in ES2022 and later. Ensure that your project's target environment or transpilation settings support this method, or consider using Object.prototype.hasOwnProperty.call for broader compatibility.

Run the following script to verify the project's target ECMAScript version in tsconfig.json:

Also applies to: 41-41

✅ Verification successful

Object.hasOwn usage is compatible with target environments

The codebase is configured with target: "ESNext" in all tsconfig files and has browser targets specified in package.json that include Chrome >= 63 and Firefox > 102. Object.hasOwn is fully supported in these environments (Chrome 93+ and Firefox 92+), making its usage appropriate and safe in this context.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the target ECMAScript version in tsconfig.json

# Test: Ensure the target is ES2022 or later.
# Expected result: The target version is 'ES2022' or newer.

# Search for tsconfig.json and extract the target version
fd -p -t f tsconfig.json --exec jq '.compilerOptions.target' {}

Length of output: 224


Script:

#!/bin/bash
# Let's verify the actual tsconfig.json content and browser targets in package.json
echo "=== TSConfig files ==="
fd tsconfig.json -x cat {}

echo -e "\n=== Package.json browserslist or targets ==="
fd package.json -x cat {} | grep -A 5 -B 5 "browserslist\|targets"

Length of output: 3807

cvat-core/src/api.ts (5)

24-26: New imports added for action classes

The imports for BaseAction, BaseCollectionAction, and BaseShapesAction are correctly added.


196-196: Updated actions.register method to accept BaseAction

The method signature change broadens applicability and aligns with the new action handling mechanism.


202-203: Simplified actions.run method signature

The run method now accepts a single BaseAction, simplifying its usage.


226-249: Added new actions.call method

The call method enhances functionality by allowing execution of actions with specific states and frames.


449-450: Registered new action classes in classes

BaseShapesAction and BaseCollectionAction are appropriately added to the classes section.

cvat-ui/src/components/annotation-page/annotations-actions/annotations-actions-modal.tsx (2)

544-548: Ensure proper function binding and context

When defining updateProgressWrapper, ensure that it maintains the correct context if used in asynchronous operations.

Please confirm that updateProgressWrapper operates correctly in all contexts where it's called, especially in async operations.


122-122: 🛠️ Refactor suggestion

Rename variable to prevent shadowing 'action'

In the reducer case SET_ACTIVE_ANNOTATIONS_ACTION, the action parameter is shadowed by the reducer's action argument. This can cause confusion and potential issues.

Apply this diff:

- if (action.type === ReducerActionType.SET_ACTIVE_ANNOTATIONS_ACTION) {
-     const { activeAction } = action.payload;
+ if (action.type === ReducerActionType.SET_ACTIVE_ANNOTATIONS_ACTION) {
+     const { activeAction } = action.payload;

Alternatively, consider renaming the reducer's parameter to avoid shadowing.

Likely invalid or redundant comment.

Comment on lines +79 to +113
export async function callAction(
instance: Job | Task,
action: BaseAction,
actionParameters: Record<string, string>,
frame: number,
states: ObjectState[],
onProgress: (message: string, progress: number) => void,
cancelled: () => boolean,
): Promise<void> {
if (action instanceof BaseShapesAction) {
return callShapesAction(
instance,
action,
actionParameters,
frame,
states,
onProgress,
cancelled,
);
}

if (action instanceof BaseCollectionAction) {
return callCollectionAction(
instance,
action,
actionParameters,
frame,
states,
onProgress,
cancelled,
);
}

return Promise.resolve();
}
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

Apply consistent error handling improvements

Similar to runAction, this implementation would benefit from improved error handling and type safety.

Apply similar improvements:

 export async function callAction(
     instance: Job | Task,
     action: BaseAction,
     actionParameters: Record<string, string>,
     frame: number,
     states: ObjectState[],
     onProgress: (message: string, progress: number) => void,
     cancelled: () => boolean,
 ): Promise<void> {
+    if (!action) {
+        throw new ArgumentError('Action must be provided');
+    }
+
+    if (!Array.isArray(states)) {
+        throw new ArgumentError('States must be an array');
+    }
+
     if (action instanceof BaseShapesAction) {
         return callShapesAction(
             instance,
             action,
             actionParameters,
             frame,
             states,
             onProgress,
             cancelled,
         );
     }

     if (action instanceof BaseCollectionAction) {
         return callCollectionAction(
             instance,
             action,
             actionParameters,
             frame,
             states,
             onProgress,
             cancelled,
         );
     }

-    return Promise.resolve();
+    throw new ArgumentError(`Unsupported action type: ${action.constructor.name}`);
 }
📝 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 async function callAction(
instance: Job | Task,
action: BaseAction,
actionParameters: Record<string, string>,
frame: number,
states: ObjectState[],
onProgress: (message: string, progress: number) => void,
cancelled: () => boolean,
): Promise<void> {
if (action instanceof BaseShapesAction) {
return callShapesAction(
instance,
action,
actionParameters,
frame,
states,
onProgress,
cancelled,
);
}
if (action instanceof BaseCollectionAction) {
return callCollectionAction(
instance,
action,
actionParameters,
frame,
states,
onProgress,
cancelled,
);
}
return Promise.resolve();
}
export async function callAction(
instance: Job | Task,
action: BaseAction,
actionParameters: Record<string, string>,
frame: number,
states: ObjectState[],
onProgress: (message: string, progress: number) => void,
cancelled: () => boolean,
): Promise<void> {
if (!action) {
throw new ArgumentError('Action must be provided');
}
if (!Array.isArray(states)) {
throw new ArgumentError('States must be an array');
}
if (action instanceof BaseShapesAction) {
return callShapesAction(
instance,
action,
actionParameters,
frame,
states,
onProgress,
cancelled,
);
}
if (action instanceof BaseCollectionAction) {
return callCollectionAction(
instance,
action,
actionParameters,
frame,
states,
onProgress,
cancelled,
);
}
throw new ArgumentError(`Unsupported action type: ${action.constructor.name}`);
}

Comment on lines 237 to 250
function RunAnnotationActionItem(props: ItemProps): JSX.Element {
const { toolProps } = props;
const { runAnnotationAction } = toolProps;
return (
<Button
type='link'
icon={<FunctionOutlined />}
onClick={runAnnotationAction}
className='cvat-object-item-menu-remove-object'
>
Run annotation action
</Button>
);
}
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

Fix className and add tooltip for consistency.

The component has a few inconsistencies with other menu items:

  1. Using incorrect className 'cvat-object-item-menu-remove-object'
  2. Missing tooltip unlike other action buttons
 function RunAnnotationActionItem(props: ItemProps): JSX.Element {
     const { toolProps } = props;
     const { runAnnotationAction } = toolProps;
     return (
+        <CVATTooltip title='Run an annotation action on this object'>
             <Button
                 type='link'
                 icon={<FunctionOutlined />}
                 onClick={runAnnotationAction}
-                className='cvat-object-item-menu-remove-object'
+                className='cvat-object-item-menu-run-action'
             >
                 Run annotation action
             </Button>
+        </CVATTooltip>
     );
 }
📝 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
function RunAnnotationActionItem(props: ItemProps): JSX.Element {
const { toolProps } = props;
const { runAnnotationAction } = toolProps;
return (
<Button
type='link'
icon={<FunctionOutlined />}
onClick={runAnnotationAction}
className='cvat-object-item-menu-remove-object'
>
Run annotation action
</Button>
);
}
function RunAnnotationActionItem(props: ItemProps): JSX.Element {
const { toolProps } = props;
const { runAnnotationAction } = toolProps;
return (
<CVATTooltip title='Run an annotation action on this object'>
<Button
type='link'
icon={<FunctionOutlined />}
onClick={runAnnotationAction}
className='cvat-object-item-menu-run-action'
>
Run annotation action
</Button>
</CVATTooltip>
);
}

Comment on lines 381 to 395
private runAnnotationAction = (): void => {
const { objectState } = this.props;
const div = window.document.createElement('div');
window.document.body.append(div);
const root = createRoot(div);
root.render(
<AnnotationsActionsModalContent
targetObjectState={objectState}
onClose={() => {
root.unmount();
div.remove();
}}
/>,
);
};
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

Consider component lifecycle and error handling improvements

The modal implementation has several areas for improvement:

  1. Add cleanup on component unmount to prevent memory leaks
  2. Add error handling for DOM operations
  3. Consider accessibility implications

Consider this improved implementation:

 private runAnnotationAction = (): void => {
     const { objectState } = this.props;
+    try {
         const div = window.document.createElement('div');
+        div.setAttribute('role', 'dialog');
+        div.setAttribute('aria-modal', 'true');
         window.document.body.append(div);
         const root = createRoot(div);
+        const cleanup = () => {
+            root.unmount();
+            div.remove();
+        };
+        
+        // Ensure cleanup on component unmount
+        this.modalCleanup = cleanup;
         
         root.render(
             <AnnotationsActionsModalContent
                 targetObjectState={objectState}
-                onClose={() => {
-                    root.unmount();
-                    div.remove();
-                }}
+                onClose={cleanup}
             />,
         );
+    } catch (error) {
+        console.error('Failed to create annotation action modal:', error);
     };
 };

+public componentWillUnmount(): void {
+    if (this.modalCleanup) {
+        this.modalCleanup();
+    }
+}

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 9 to 10
import { SerializedCollection } from 'server-response-types';
import { Attribute, Label } from 'labels';
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

Adjust import order to comply with conventions

The imports from 'server-response-types' and 'labels' should occur before local imports like './object-state' to maintain the import order convention.

Apply this diff to reorder the imports:

 import jsonLogic from 'json-logic-js';
+import { SerializedCollection } from 'server-response-types';
+import { Attribute, Label } from 'labels';
 import { SerializedData } from './object-state';
 import { AttributeType, ObjectType, ShapeType } from './enums';
-import { SerializedCollection } from 'server-response-types';
-import { Attribute, Label } from 'labels';
📝 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
import { SerializedCollection } from 'server-response-types';
import { Attribute, Label } from 'labels';
import jsonLogic from 'json-logic-js';
import { SerializedCollection } from 'server-response-types';
import { Attribute, Label } from 'labels';
import { SerializedData } from './object-state';
import { AttributeType, ObjectType, ShapeType } from './enums';
🧰 Tools
🪛 eslint

[error] 9-9: server-response-types import should occur before import of ./object-state

(import/order)


[error] 10-10: labels import should occur before import of ./object-state

(import/order)

Comment on lines 567 to 568
)

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 missing semicolon after function call

There's a missing semicolon after the function call, which can cause syntax errors.

Apply this diff:

-                                     )
+                                     );
📝 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
)
);
🧰 Tools
🪛 eslint

[error] 567-568: Missing semicolon.

(@typescript-eslint/semi)

const reducer = (state: State, action: ActionUnion<typeof reducerActions>): State => {
if (action.type === ReducerActionType.SET_ANNOTATIONS_ACTIONS) {
const { actions } = action.payload;
const list = state.targetObjectState ? actions
.filter((action) => action.isApplicableForObject(state.targetObjectState as ObjectState)) : actions;
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

Rename variable to prevent shadowing 'action'

The variable action in the .filter callback shadows the action variable from the outer scope of the reducer. This can lead to confusion and potential bugs.

Apply this diff to rename the inner variable:

- .filter((action) => action.isApplicableForObject(state.targetObjectState as ObjectState)) : actions;
+ .filter((item) => item.isApplicableForObject(state.targetObjectState as ObjectState)) : actions;
📝 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
.filter((action) => action.isApplicableForObject(state.targetObjectState as ObjectState)) : actions;
.filter((item) => item.isApplicableForObject(state.targetObjectState as ObjectState)) : actions;
🧰 Tools
🪛 eslint

[error] 99-99: 'action' is already declared in the upper scope on line 95 column 32.

(@typescript-eslint/no-shadow)

@@ -100,19 +91,42 @@
),
};

let lastSelectedActions: [string, Record<string, string>][] = [];
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

Avoid using module-level mutable variables for component state

The variable lastSelectedActions is declared outside of the component and mutated within the reducer. This can lead to unexpected behavior, especially if multiple instances of this component are rendered or if the component is re-mounted.

Consider using the useRef hook to store mutable data that persists across renders without causing re-renders, or integrate lastSelectedActions into the component's state using useState.

- let lastSelectedActions: [string, Record<string, string>][] = [];
+ const lastSelectedActionsRef = useRef<[string, Record<string, string>][]>([]);

Update references to lastSelectedActions in your code to use lastSelectedActionsRef.current.

Committable suggestion skipped: line range outside the PR's diff.

cvat-core/src/annotations-collection.ts Show resolved Hide resolved
@bsekachev bsekachev changed the title [WIP] Enhanced running of annotations actions Enhanced running of annotations actions Nov 20, 2024
Copy link

sonarcloud bot commented Nov 20, 2024

@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 69.20904% with 109 lines in your changes missing coverage. Please review.

Project coverage is 74.08%. Comparing base (1e7ff33) to head (d14f822).
Report is 12 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #8727      +/-   ##
===========================================
- Coverage    74.20%   74.08%   -0.12%     
===========================================
  Files          401      406       +5     
  Lines        43504    43713     +209     
  Branches      3950     3984      +34     
===========================================
+ Hits         32280    32386     +106     
- Misses       11224    11327     +103     
Components Coverage Δ
cvat-ui 78.24% <69.20%> (-0.27%) ⬇️
cvat-server 70.49% <ø> (-0.02%) ⬇️
---- 🚨 Try these New Features:

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