Skip to content

TF-4178 Create a new label#4182

Merged
hoangdat merged 7 commits intofeatures/labelfrom
feature/tf-4178-create-a-new-label
Dec 10, 2025
Merged

TF-4178 Create a new label#4182
hoangdat merged 7 commits intofeatures/labelfrom
feature/tf-4178-create-a-new-label

Conversation

@dab246
Copy link
Member

@dab246 dab246 commented Nov 26, 2025

Issue

#4178

Resolved

Screen.Recording.2025-11-26.at.16.59.22.mov

Summary by CodeRabbit

  • New Features

    • Create-label flow: UI for creating labels with name validation, color selection and success/failure feedback.
    • Color picker modal with HSV controls, hex input, and a reusable color palette.
  • Improvements

    • New reusable color selection widgets and selectable color swatches.
    • Button styling enhanced with optional border; modal actions support disabled state.
    • Added localization strings for label creation and feedback.
  • Dependencies

    • Added HSV color picker library.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions
Copy link

This PR has been deployed to https://linagora.github.io/tmail-flutter/4182.

@dab246 dab246 force-pushed the feature/tf-4179-display-tag-list-in-sidebar branch from 8b64b6e to 63e7d93 Compare December 8, 2025 09:12
@dab246 dab246 force-pushed the feature/tf-4178-create-a-new-label branch from efc6cde to 9669372 Compare December 9, 2025 02:23
@coderabbitai
Copy link

coderabbitai bot commented Dec 9, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a full "create label" feature and supporting UI: new color-selection widgets (ColorCircleWidget, ColorsMapWidget, ColorPickerModal) and exports; new label creation pipeline across datasource, API, repository, and interactor; presentation changes including CreateNewLabelModal, LabelController wiring and a web modal flow; shared widget import refactors to core; error-handling helper parseErrorForSetResponse and related tests; localization entries and toast handling for create-label flows; small API surface changes (ImagePaths, color constant, TMailButtonWidget factory param, ModalListActionButtonWidget flag) and a new dependency on flutter_hsvcolor_picker.

Possibly related PRs

  • linagora/tmail-flutter PR 4181 — overlaps on label feature changes including LabelController updates and label-related UI/resource additions.

Suggested reviewers

  • tddang-linagora

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'TF-4178 Create a new label' clearly and directly summarizes the main objective of the changeset, which is to implement label creation functionality.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9669372 and e451449.

⛔ Files ignored due to path filters (6)
  • assets/images/ic_color_picker.svg is excluded by !**/*.svg
  • contact/pubspec.lock is excluded by !**/*.lock
  • core/pubspec.lock is excluded by !**/*.lock
  • labels/pubspec.lock is excluded by !**/*.lock
  • model/pubspec.lock is excluded by !**/*.lock
  • pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (36)
  • core/lib/core.dart (3 hunks)
  • core/lib/presentation/extensions/color_extension.dart (1 hunks)
  • core/lib/presentation/resources/image_paths.dart (1 hunks)
  • core/lib/presentation/views/button/tmail_button_widget.dart (2 hunks)
  • core/lib/presentation/views/color/color_circle_widget.dart (1 hunks)
  • core/lib/presentation/views/color/color_picker_modal.dart (1 hunks)
  • core/lib/presentation/views/color/colors_map_widget.dart (1 hunks)
  • core/lib/presentation/views/dialog/modal_list_action_button_widget.dart (2 hunks)
  • core/pubspec.yaml (1 hunks)
  • labels/lib/extensions/list_label_extension.dart (1 hunks)
  • lib/features/base/mixin/handle_error_mixin.dart (2 hunks)
  • lib/features/email_recovery/presentation/widgets/email_recovery_form/email_recovery_form_desktop_builder.dart (1 hunks)
  • lib/features/identity_creator/presentation/widgets/identity_creator_form_desktop_builder.dart (1 hunks)
  • lib/features/labels/data/datasource/label_datasource.dart (1 hunks)
  • lib/features/labels/data/datasource_impl/label_datasource_impl.dart (1 hunks)
  • lib/features/labels/data/network/label_api.dart (2 hunks)
  • lib/features/labels/data/repository/label_repository_impl.dart (1 hunks)
  • lib/features/labels/domain/repository/label_repository.dart (1 hunks)
  • lib/features/labels/domain/state/create_new_label_state.dart (1 hunks)
  • lib/features/labels/domain/usecases/create_new_label_interactor.dart (1 hunks)
  • lib/features/labels/presentation/label_controller.dart (6 hunks)
  • lib/features/labels/presentation/label_interactor_bindings.dart (3 hunks)
  • lib/features/labels/presentation/widgets/create_new_label_modal.dart (1 hunks)
  • lib/features/mailbox/data/network/mailbox_api.dart (1 hunks)
  • lib/features/mailbox/presentation/base_mailbox_view.dart (2 hunks)
  • lib/features/mailbox_creator/presentation/extensions/validator_failure_extension.dart (1 hunks)
  • lib/features/mailbox_creator/presentation/mailbox_creator_view.dart (1 hunks)
  • lib/features/mailbox_dashboard/presentation/extensions/verify_display_overlay_view_on_iframe_extension.dart (1 hunks)
  • lib/features/quotas/presentation/widget/quotas_banner_widget.dart (1 hunks)
  • lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart (0 hunks)
  • lib/l10n/intl_messages.arb (2 hunks)
  • lib/main/exceptions/logic_exception.dart (1 hunks)
  • lib/main/localizations/app_localizations.dart (1 hunks)
  • lib/main/utils/toast_manager.dart (4 hunks)
  • test/features/base/mixin/parse_error_for_set_response_test.dart (1 hunks)
  • test/features/composer/presentation/composer_controller_test.dart (4 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hoangdat
Copy link
Member

hoangdat commented Dec 9, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 9, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@hoangdat hoangdat changed the base branch from feature/tf-4179-display-tag-list-in-sidebar to features/label December 9, 2025 06:49
Copy link

@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: 5

🧹 Nitpick comments (9)
labels/lib/extensions/list_label_extension.dart (1)

13-15: displayNameNotNullList implementation is correct; optionally normalize whitespace-only names

Logic is sound and safe. If you want to also drop names that are only spaces, you can trim before checking emptiness.

-  List<String> get displayNameNotNullList => map((label) => label.safeDisplayName)
-      .where((name) => name.isNotEmpty)
-      .toList();
+  List<String> get displayNameNotNullList => map((label) => label.safeDisplayName)
+      .where((name) => name.trim().isNotEmpty)
+      .toList();
core/lib/presentation/views/color/color_circle_widget.dart (1)

6-49: Clean implementation of a reusable color circle widget.

The widget structure is well-organized with proper use of Material for ink ripple effects on a circular shape. Consider adding Semantics for accessibility to describe this as a color selection button.

   @override
   Widget build(BuildContext context) {
-    return Material(
+    return Semantics(
+      button: true,
+      selected: isSelected,
+      label: 'Color option',
+      child: Material(
       type: MaterialType.transparency,
       child: InkWell(
         onTap: onTap,
         customBorder: const CircleBorder(),
         ...
       ),
+      ),
     );
   }
lib/features/labels/presentation/label_interactor_bindings.dart (1)

11-11: Cross-feature dependency on VerifyNameInteractor.

This imports VerifyNameInteractor from mailbox_creator domain. If label name validation requirements diverge from mailbox naming in the future, consider extracting a shared validation module to core or creating a label-specific validator. For now, reusing existing validation logic is pragmatic.

lib/features/labels/presentation/widgets/create_new_label_modal.dart (1)

313-320: Consider consolidating color update methods.

_updateLabelColor and _onLabelColorChanged serve similar purposes. The distinction is that ColorsMapWidget handles its own UI state while ColorPickerModal requires external state update. Consider documenting this distinction or unifying to _onLabelColorChanged for both callbacks for consistency.

core/lib/presentation/views/color/colors_map_widget.dart (2)

26-52: Color list and selection state look correct; consider clarifying initial-selection behavior

The _setUpColorList logic and didUpdateWidget handling of customColor are consistent and safe. One behavioral nuance: whenever customColor changes (including being set to null), _selectedColor is reset to custom. If the parent ever toggles customColor independently of the user’s selection, this will override any prior user choice. If that’s not desired, you might want to only update _colorList here and leave _selectedColor unchanged, or make this behavior explicit in docs.

Also applies to: 129-143


68-125: UI wiring and callbacks are sound; only micro-optimizations possible

The Wrap layout, clear button, color circles, and color-picker trigger are all wired correctly and use OnSelectColorCallback consistently. If you ever profile this, you could:

  • Lift the ValueListenableBuilder up one level to rebuild the row once instead of one builder per color.
  • Pass a child into ValueListenableBuilder (the ColorCircleWidget with fixed props) to avoid rebuilding icons on every selection change.

These are purely optional; current code is correct and maintainable.

core/lib/presentation/views/color/color_picker_modal.dart (2)

56-62: Init state is fine; calling super.initState() first would be more idiomatic

The initialization of _hsvColorNotifier and _hexColorInputController from initialColor is correct. For consistency with Flutter’s usual pattern, you may want to move super.initState() to the beginning of the method, but this is stylistic only.


181-248: Guard against invalid/partial hex values when calling toColor

_onHexColorChanged and _onPositiveAction both call value.toColor / hexColorText.toColor on arbitrary user input. If StringExtension.toColor assumes a fully-formed hex string (e.g. 6–8 digits, optional #) and throws on partial or malformed values, typing into the field or saving an invalid value could crash the modal.

Consider:

  • Only updating _hsvColorNotifier when the input length matches the supported formats, or
  • Wrapping toColor in a try/catch and ignoring/rolling back invalid input, and
  • Optionally normalizing input (e.g. stripping #, uppercasing) before parsing.

This would harden the modal against unexpected input behavior.

void _onHexColorChanged(String value) {
  final hex = value.trim();
  if (hex.isEmpty) return;

  // Example guard; adjust to what `toColor` supports.
  if (hex.length != 6 && hex.length != 7) {
    return;
  }

  try {
    _hsvColorNotifier.value = HSVColor.fromColor(hex.toColor);
  } catch (_) {
    // Optionally keep previous value or reset field.
  }
}

Also applies to: 317-324

lib/main/localizations/app_localizations.dart (1)

5454-5525: Localization getters correctly wired; consider copy/style consistency

The new label-related getters are correctly defined and aligned with intl usage and the ARB keys (including the labelName placeholder in createLabelSuccessfullyMessage). Two minor polish points you might consider:

  • The wording "You successfully created $labelName label" mirrors folder strings but is slightly awkward; "You successfully created the $labelName label" would read more naturally if you’re open to adjusting both Dart and ARB.
  • The texts mix US and UK spelling (color vs colour) across these keys; aligning on one variant for this feature area would keep the UI more consistent.

Functionally this looks good as-is.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c50f2cc and 9669372.

⛔ Files ignored due to path filters (6)
  • assets/images/ic_color_picker.svg is excluded by !**/*.svg
  • contact/pubspec.lock is excluded by !**/*.lock
  • core/pubspec.lock is excluded by !**/*.lock
  • labels/pubspec.lock is excluded by !**/*.lock
  • model/pubspec.lock is excluded by !**/*.lock
  • pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (34)
  • core/lib/core.dart (3 hunks)
  • core/lib/presentation/extensions/color_extension.dart (1 hunks)
  • core/lib/presentation/resources/image_paths.dart (1 hunks)
  • core/lib/presentation/views/button/tmail_button_widget.dart (2 hunks)
  • core/lib/presentation/views/color/color_circle_widget.dart (1 hunks)
  • core/lib/presentation/views/color/color_picker_modal.dart (1 hunks)
  • core/lib/presentation/views/color/colors_map_widget.dart (1 hunks)
  • core/lib/presentation/views/dialog/modal_list_action_button_widget.dart (2 hunks)
  • core/pubspec.yaml (1 hunks)
  • labels/lib/extensions/list_label_extension.dart (1 hunks)
  • lib/features/base/mixin/handle_error_mixin.dart (2 hunks)
  • lib/features/email_recovery/presentation/widgets/email_recovery_form/email_recovery_form_desktop_builder.dart (1 hunks)
  • lib/features/identity_creator/presentation/widgets/identity_creator_form_desktop_builder.dart (1 hunks)
  • lib/features/labels/data/datasource/label_datasource.dart (1 hunks)
  • lib/features/labels/data/datasource_impl/label_datasource_impl.dart (1 hunks)
  • lib/features/labels/data/network/label_api.dart (2 hunks)
  • lib/features/labels/data/repository/label_repository_impl.dart (1 hunks)
  • lib/features/labels/domain/repository/label_repository.dart (1 hunks)
  • lib/features/labels/domain/state/create_new_label_state.dart (1 hunks)
  • lib/features/labels/domain/usecases/create_new_label_interactor.dart (1 hunks)
  • lib/features/labels/presentation/label_controller.dart (6 hunks)
  • lib/features/labels/presentation/label_interactor_bindings.dart (3 hunks)
  • lib/features/labels/presentation/widgets/create_new_label_modal.dart (1 hunks)
  • lib/features/mailbox/data/network/mailbox_api.dart (1 hunks)
  • lib/features/mailbox/presentation/base_mailbox_view.dart (2 hunks)
  • lib/features/mailbox_creator/presentation/extensions/validator_failure_extension.dart (1 hunks)
  • lib/features/mailbox_creator/presentation/mailbox_creator_view.dart (1 hunks)
  • lib/features/mailbox_dashboard/presentation/extensions/verify_display_overlay_view_on_iframe_extension.dart (1 hunks)
  • lib/features/quotas/presentation/widget/quotas_banner_widget.dart (1 hunks)
  • lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart (0 hunks)
  • lib/l10n/intl_messages.arb (2 hunks)
  • lib/main/localizations/app_localizations.dart (1 hunks)
  • lib/main/utils/toast_manager.dart (4 hunks)
  • test/features/composer/presentation/composer_controller_test.dart (5 hunks)
💤 Files with no reviewable changes (1)
  • lib/features/rules_filter_creator/presentation/rules_filter_creator_view.dart
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-12-08T08:11:08.985Z
Learnt from: dab246
Repo: linagora/tmail-flutter PR: 4189
File: lib/features/login/presentation/extensions/handle_company_server_login_info_extension.dart:50-56
Timestamp: 2025-12-08T08:11:08.985Z
Learning: In the tmail-flutter codebase, prefer descriptive variable names that include full context rather than abbreviated names. For example, `removeLoginInfoInteractor` is preferred over shorter alternatives like `removeInteractor` or `interactor`, as it clearly conveys both the action (remove) and the specific data being operated on (loginInfo).

Applied to files:

  • test/features/composer/presentation/composer_controller_test.dart
  • lib/features/labels/presentation/label_interactor_bindings.dart
🪛 RuboCop (1.81.7)
lib/l10n/intl_messages.arb

[convention] 5203-5203: Put a comma after the last item of a multiline array.

(Style/TrailingCommaInArrayLiteral)

🔇 Additional comments (33)
lib/features/email_recovery/presentation/widgets/email_recovery_form/email_recovery_form_desktop_builder.dart (1)

4-4: Core import for DefaultCloseButtonWidget looks correct

Centralizing this widget under core/presentation/views/button is consistent with the rest of the modal code and does not change behavior.

lib/features/mailbox_creator/presentation/extensions/validator_failure_extension.dart (1)

52-62: getMessageLabelError is consistent with existing failure mappers

Branching mirrors other helpers, and the chosen localization keys fit the label use case. No issues from a correctness standpoint.

core/lib/presentation/views/dialog/modal_list_action_button_widget.dart (1)

11-20: New isPositiveActionEnabled flag cleanly adds a disabled state; confirm ConfirmDialogButton supports nullable callbacks

The flag and styling logic are straightforward and backward compatible (default true). Disabling via onTapAction: null is a good pattern as long as ConfirmDialogButton’s onTapAction parameter is nullable and treated as disabled.

Please double‑check ConfirmDialogButton’s constructor signature to ensure onTapAction is declared as VoidCallback? (or otherwise safely handles null) so this disabled state compiles and behaves as intended.

Also applies to: 39-46

lib/features/mailbox_creator/presentation/mailbox_creator_view.dart (1)

6-7: Refactor to use core button/dialog widgets is sound

Switching to the core DefaultCloseButtonWidget and ModalListActionButtonWidget keeps behavior unchanged while centralizing shared UI components.

lib/features/labels/data/repository/label_repository_impl.dart (1)

16-19: Repository createNewLabel pass‑through is correct

The method cleanly delegates to the datasource and matches the repository pattern established by getAllLabels.

lib/main/utils/toast_manager.dart (1)

18-18: Label creation failure/success toasts are wired correctly

Defaulting CreateNewLabelFailure to createNewLabelFailure ensures a user‑visible error, and using newLabel.safeDisplayName in the success toast is a good defensive choice around label naming.

Also applies to: 31-31, 201-204, 267-270

core/lib/presentation/extensions/color_extension.dart (1)

279-279: LGTM!

The new color constant follows the established naming convention and is placed appropriately among other gray color definitions.

lib/features/identity_creator/presentation/widgets/identity_creator_form_desktop_builder.dart (1)

4-4: LGTM!

The import path change aligns with the centralization of shared widgets in the core package, improving code organization and reusability.

lib/features/labels/data/datasource/label_datasource.dart (1)

6-7: LGTM!

The interface extension follows the established pattern and provides a clear contract for label creation.

lib/features/labels/data/datasource_impl/label_datasource_impl.dart (1)

22-31: LGTM!

The implementation correctly follows the established pattern used by getAllLabels, maintaining consistency in error handling and API delegation.

lib/features/labels/domain/repository/label_repository.dart (1)

6-7: LGTM!

The repository interface extension mirrors the datasource contract, maintaining clean layer separation.

core/lib/presentation/resources/image_paths.dart (1)

265-265: LGTM!

The new image path accessor follows the established pattern, and the SVG asset file exists at assets/images/ic_color_picker.svg.

lib/features/mailbox_dashboard/presentation/extensions/verify_display_overlay_view_on_iframe_extension.dart (1)

12-13: LGTM!

The logic correctly extends overlay visibility to include the new label creation modal. Both labelController and isCreateNewLabelModalVisible are properly defined in LabelController and accessible through MailboxDashBoardController.

lib/features/mailbox/data/network/mailbox_api.dart (1)

199-199: LGTM!

The refactoring to use parseErrorForSetResponse from HandleSetErrorMixin properly centralizes error handling logic and reduces code duplication. The mixin method robustly handles all error scenarios: invalidArguments, invalidResultReference, and unknown errors, ensuring no error cases fall through unhandled.

lib/features/quotas/presentation/widget/quotas_banner_widget.dart (1)

1-1: LGTM!

The import path change aligns with the centralization of shared widgets in the core package, as reflected by the new export in core/lib/core.dart.

test/features/composer/presentation/composer_controller_test.dart (2)

102-111: LGTM!

The MockLabelController correctly implements the LabelController interface with appropriate Rx types for the label feature integration.


160-162: LGTM!

The labelController getter properly exposes the MockLabelController for test scaffolding.

core/lib/presentation/views/button/tmail_button_widget.dart (1)

113-141: LGTM!

The border parameter addition to fromIcon factory brings consistency with the main constructor and fromText factory, enabling border customization for icon-only button use cases like the color picker widgets.

core/lib/core.dart (3)

78-78: LGTM!

Export addition for default_close_button_widget.dart is appropriately placed with other button widgets.


91-91: LGTM!

Export for modal_list_action_button_widget.dart is logically grouped with dialog-related widgets.


119-121: LGTM!

The new color-related widget exports (color_circle_widget.dart, colors_map_widget.dart, color_picker_modal.dart) are well-organized together, supporting the label color picker feature.

lib/features/labels/domain/usecases/create_new_label_interactor.dart (1)

9-28: LGTM!

The CreateNewLabelInteractor follows the established pattern for interactors in this codebase:

  • Emits loading state (CreatingNewLabel) before the async operation
  • Properly wraps success/failure in Either types
  • Uses async* generator for stream-based state emission
  • Preserves exception details in the failure state
lib/features/mailbox/presentation/base_mailbox_view.dart (1)

350-366: The null safety concern is already addressed. The openCreateNewLabelModal method accepts AccountId? and the downstream _createNewLabel method explicitly checks for null (line 76 of label_controller.dart), returning a CreateNewLabelFailure(NotFoundAccountIdException()) that displays an error to the user. No changes are required.

lib/features/labels/presentation/label_interactor_bindings.dart (1)

33-37: LGTM!

The new interactor bindings follow the established pattern in this file. The VerifyNameInteractor is stateless, so instantiating it without a repository dependency is correct.

lib/features/labels/domain/state/create_new_label_state.dart (1)

1-18: LGTM!

The state classes follow the established pattern in the codebase. The props override ensures proper equality comparison for the success state.

lib/features/labels/data/network/label_api.dart (1)

48-58: Verify server response completeness.

The copyWith to restore displayName and color from input suggests the server may not return these fields in the created object. This is a reasonable defensive pattern, but verify this behavior matches the JMAP server implementation to ensure no data is lost.

lib/features/labels/presentation/label_controller.dart (1)

54-71: LGTM!

The modal visibility pattern with whenComplete ensures proper cleanup regardless of how the modal is dismissed. The web-specific visibility flag is a good approach for platform-aware UI state.

lib/features/labels/presentation/widgets/create_new_label_modal.dart (3)

294-306: Modal closes before confirming label creation success.

The modal calls popBack() immediately after invoking the callback without waiting for the creation result. Users won't see feedback within the modal if creation fails. Consider either:

  1. Showing a loading indicator and waiting for the result before closing
  2. Documenting that toast feedback will appear after modal dismissal (current behavior)

If the current UX is intentional (toast shows after modal closes), this is acceptable.


336-345: LGTM!

All disposable resources (FocusNode, TextEditingController, ValueNotifiers) are properly cleaned up. The assignment _labelDisplayNameList = [] on line 343 is unnecessary since the state object is being disposed, but it's harmless.


42-44: DI lookups assume bindings are registered.

Get.find<ImagePaths>() and Get.find<VerifyNameInteractor>() are called during state initialization. This works because LabelController.openCreateNewLabelModal calls injectLabelsBindings() before showing this modal. Just ensure this dependency ordering is maintained.

core/lib/presentation/views/color/color_picker_modal.dart (2)

150-179: HSV picker + notifier wiring is correct

Using ValueListenableBuilder<HSVColor> around PaletteHuePicker and updating via _onHsvColorChanged is a clean pattern; there are no obvious re-entrancy or lifecycle issues here.


276-287: Mobile scaffold + backdrop tap behavior is reasonable

The nested GestureDetector pattern on mobile (outer close-tap, inner focus-clear) matches the common modal/backdrop UX and should behave correctly with Flutter’s gesture arena. No changes needed here.

lib/l10n/intl_messages.arb (1)

2-2: New label-related ARB entries are consistent with the Dart localizations

The added keys and their @ metadata (including placeholders_order and placeholders for createLabelSuccessfullyMessage) correctly match the new getters in AppLocalizations. From an i18n tooling perspective, this block is well-formed and should integrate cleanly with the existing translations.

Also applies to: 5144-5214

@dab246 dab246 force-pushed the feature/tf-4178-create-a-new-label branch from 9669372 to 0d58d28 Compare December 9, 2025 07:34
@hoangdat
Copy link
Member

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 10, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@hoangdat hoangdat merged commit 706f446 into features/label Dec 10, 2025
20 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Dec 19, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jan 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants