All files / src/components WhatsNewPrompt.tsx

100% Statements 30/30
100% Branches 5/5
100% Functions 3/3
100% Lines 30/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 661x   1x 1x 1x                       1x                                   1x 1x 12x   12x   11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x 11x   11x 11x 11x 11x 1x 1x 1x       11x  
import { i18n } from '@/helpers/i18n';
import type { JustUpdatedNotice } from '@/hooks/useJustUpdated';
import { useState } from 'react';
import { PromptSnackbar } from './PromptSnackbar';
import { WhatsNewModal } from './WhatsNewModal';
 
/**
 * Props for {@link WhatsNewPrompt}.
 * - `notice` - The just-installed release, or `undefined` to render nothing.
 * - `onAcknowledge` - Invoked once the user has seen or dismissed the notes.
 */
interface WhatsNewPromptProps {
  notice: JustUpdatedNotice | undefined;
  onAcknowledge: () => void;
}
 
/**
 * Announces what changed after the extension updated itself.
 *
 * Mirrors `UpdatePrompt` — same snackbar, same modal — but for a release
 * that is already installed, so there's nothing to apply: the modal ends in a
 * single acknowledging button rather than a call to action, and either control
 * settles it. The notes ship inside the build (`__CHANGELOG_CURRENT__`), so this
 * works offline and shows exactly what was published for the release.
 * @component
 * @category Components
 * @param props - The prompt props (see {@link WhatsNewPromptProps}).
 * @returns The rendered post-update prompt, or nothing when there's nothing to announce.
 * @example
 * ```tsx
 * const { notice, acknowledge } = useJustUpdated();
 * <WhatsNewPrompt notice={notice} onAcknowledge={acknowledge} />
 * ```
 * @source
 */
export function WhatsNewPrompt({ notice, onAcknowledge }: WhatsNewPromptProps) {
  const [notesOpen, setNotesOpen] = useState(false);
 
  if (!notice) return null;
 
  return (
    <>
      <PromptSnackbar
        testId="whats-new-snackbar"
        actionTestId="whats-new-snackbar-apply"
        dismissTestId="whats-new-snackbar-dismiss"
        // Steps aside for the modal, exactly as the update prompt does.
        open={!notesOpen}
        message={i18n('update_installed_message', [notice.version])}
        actionLabel={i18n('update_whats_new')}
        onAction={() => setNotesOpen(true)}
        onDismiss={onAcknowledge}
        dismissLabel={i18n('update_dismiss')}
      />
      <WhatsNewModal
        notice={notice}
        open={notesOpen}
        onClose={() => {
          setNotesOpen(false);
          onAcknowledge();
        }}
      />
    </>
  );
}