Skip to content

Conversation

@YueyingLu
Copy link
Member

@YueyingLu YueyingLu commented Nov 13, 2025

Description

Add code to support Persistence feature in Flashbar and Alert [qIQZAtdAL9Xj].
The home of core function of Persistence is CR-199098474.

Related links, issue #, if available: n/a

How has this been tested?

Review checklist

The following items are to be evaluated by the author(s) and the reviewer(s).

Correctness

  • Changes include appropriate documentation updates.
  • Changes are backward-compatible if not indicated, see CONTRIBUTING.md.
  • Changes do not include unsupported browser features, see CONTRIBUTING.md.
  • Changes were manually tested for accessibility, see accessibility guidelines.

Security

Testing

  • Changes are covered with new/existing unit tests?
  • Changes are covered with new/existing integration tests?

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@YueyingLu YueyingLu changed the title Implement Flashbar and Alert persistence feat: Flashbar and Alert dismiss persistence Nov 13, 2025
@YueyingLu YueyingLu force-pushed the persistence-flashbar-alert branch from 1dec203 to f0eff84 Compare November 14, 2025 08:38
@codecov
Copy link

codecov bot commented Nov 14, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.99%. Comparing base (f98fa63) to head (ba0873c).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4035   +/-   ##
=======================================
  Coverage   96.99%   96.99%           
=======================================
  Files         861      861           
  Lines       25214    25257   +43     
  Branches     9094     9103    +9     
=======================================
+ Hits        24456    24499   +43     
  Misses        711      711           
  Partials       47       47           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@just-boris just-boris left a comment

Choose a reason for hiding this comment

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

Legend

⛳ – blocking comments, possible bugs
Other comments are optional code style suggestions

@YueyingLu YueyingLu force-pushed the persistence-flashbar-alert branch from 842c792 to 0730c73 Compare November 14, 2025 15:42
Copy link
Member

@just-boris just-boris left a comment

Choose a reason for hiding this comment

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

All blocking comments resolved, thanks


// Resolve second call first (race condition scenario)
resolveSecond!(false); // Item 2 should be visible
await waitFor(() => {});
Copy link
Member

Choose a reason for hiding this comment

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

Is this needed for anything?

const [checkedPersistenceKeys, setCheckedPersistenceKeys] = useState<Set<string>>(new Set());
const [persistentItemsVisibility, setPersistentItemsVisibility] = useState<Map<string, boolean>>(new Map());

const visibleItems = useMemo(() => {
Copy link
Member

Choose a reason for hiding this comment

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

This benefit is not measurable in any way. This is why typically I recommend to keep the code simple without extra things

@YueyingLu YueyingLu changed the title feat: Flashbar and Alert dismiss persistence chore: Add Flashbar and Alert dismiss persistence Nov 14, 2025
setIsPersistentlyDismissed(!!dismissed);
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
Copy link
Member

Choose a reason for hiding this comment

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

why? what if persistenceConfig.crossServicePersistence changes?


const dismiss = () => {
fireNonCancelableEvent(onDismiss);
if (persistenceConfig && persistenceConfig.uniqueKey) {
Copy link
Member

Choose a reason for hiding this comment

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

[minor] for consistency

Suggested change
if (persistenceConfig && persistenceConfig.uniqueKey) {
if (persistenceConfig?.uniqueKey) {

const headerRef = useMergeRefs(headerRefAction, headerRefContent);
const contentRef = useMergeRefs(contentRefAction, contentRefContent);
const [isPersistentlyDismissed, setIsPersistentlyDismissed] = useState(
!!(persistenceConfig && persistenceConfig.uniqueKey)
Copy link
Member

Choose a reason for hiding this comment

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

default-to-dismissed seems dangerous here, especially combined with promise without error handling in the useEffect below: if something within retrieveAlertDismiss fails then user will never see the alert.

At the very minimum the promise should have error handling, but I would strongly prefer an approach of default-to-visible

}

const checkNewPersistentItems = async () => {
const results = await Promise.all(
Copy link
Member

Choose a reason for hiding this comment

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

needs some error handling around awaits

);
}, [items, persistentItemsVisibility]);

useEffect(() => {
Copy link
Member

Choose a reason for hiding this comment

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

useEffect with async code needs cleanup function

i18nStrings?.dismissAriaLabel ?? i18n('dismissAriaLabel', deprecatedDismissAriaLabel)
);

useEffect(() => {
Copy link
Member

Choose a reason for hiding this comment

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

useEffect with async code needs cleanup function

}
}

// eslint-disable-next-line require-await
Copy link
Member

Choose a reason for hiding this comment

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

[minor] you could probably avoid these with return await Promise.resolve();?

retrieveAlertDismiss?: (persistenceConfig: AlertProps.PersistenceConfig) => Promise<boolean>;
}

export function setPersistenceFunctionsForTesting(functions: PersistenceFunction) {
Copy link
Member

Choose a reason for hiding this comment

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

why not just use mocking?

}

// Hook for managing flashbar items visibility with persistence
export function useFlashbarVisibility(items: ReadonlyArray<FlashbarProps.MessageDefinition>) {
Copy link
Member

Choose a reason for hiding this comment

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

could we move the complexity of this into the plugin rather than in the component itself? so just have a single call to retrieveFlashbarDismiss(items) which then internally handles which ones need to be fetched and which not?

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.

3 participants