fix(i18n): use singular Gmail review counts
This commit is contained in:
@@ -226,6 +226,37 @@ describe('GmailReviewPage', () => {
|
|||||||
expect(mockedApi.put).not.toHaveBeenCalled();
|
expect(mockedApi.put).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.each([
|
||||||
|
{ count: 0, candidatesEn: '0 candidate threads', candidatesNb: '0 kandidattråder', jobsEn: '', jobsNb: '', messagesEn: '', messagesNb: '' },
|
||||||
|
{ count: 1, candidatesEn: '1 candidate thread', candidatesNb: '1 kandidattråd', jobsEn: '1 suggested job', jobsNb: '1 foreslått jobb', messagesEn: '1 message', messagesNb: '1 melding' },
|
||||||
|
{ count: 2, candidatesEn: '2 candidate threads', candidatesNb: '2 kandidattråder', jobsEn: '2 suggested jobs', jobsNb: '2 foreslåtte jobber', messagesEn: '2 messages', messagesNb: '2 meldinger' },
|
||||||
|
])('uses the correct review counts for $count on a live language switch', async ({ count, candidatesEn, candidatesNb, jobsEn, jobsNb, messagesEn, messagesNb }) => {
|
||||||
|
const threads = Array.from({ length: count }, (_, index) => reviewThread({ threadId: `thread-${index}`, subject: `Synthetic review ${index}`, messageCount: count }));
|
||||||
|
const items = threads.map(thread => ({ threadId: thread.threadId, companyName: 'Synthetic laboratory', suggestedJobTitle: 'Research technician' }));
|
||||||
|
mockedApi.get.mockImplementation((url: string) => Promise.resolve({ data: url === '/gmail/review-candidates' ? reviewQueue(threads) : { count, items } } as any));
|
||||||
|
renderPage();
|
||||||
|
await screen.findByText(candidatesEn);
|
||||||
|
if (count) {
|
||||||
|
expect(screen.getByText(jobsEn)).toBeVisible();
|
||||||
|
expect(threadRow('Synthetic review 0').getByText(`${messagesEn} · ${copy('gmailReviewRouteReview')}`)).toBeVisible();
|
||||||
|
} else {
|
||||||
|
expect(screen.getByText(copy('gmailReviewNoCandidates'))).toBeVisible();
|
||||||
|
expect(screen.queryByText('0 suggested jobs')).not.toBeInTheDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
await changeLanguage('nb');
|
||||||
|
expect(screen.getByText(candidatesNb)).toBeVisible();
|
||||||
|
if (count) {
|
||||||
|
expect(screen.getByText(jobsNb)).toBeVisible();
|
||||||
|
expect(threadRow('Synthetic review 0').getByText(`${messagesNb} · ${copy('gmailReviewRouteReview')}`)).toBeVisible();
|
||||||
|
} else {
|
||||||
|
expect(screen.getByText(copy('gmailReviewNoCandidates'))).toBeVisible();
|
||||||
|
expect(screen.queryByText('0 foreslåtte jobber')).not.toBeInTheDocument();
|
||||||
|
}
|
||||||
|
expect(mockedApi.get).toHaveBeenCalledTimes(2);
|
||||||
|
expect(mockedApi.post).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
test('decision, manual sync and suggested creation each own their captured request against duplicate and competing actions', async () => {
|
test('decision, manual sync and suggested creation each own their captured request against duplicate and competing actions', async () => {
|
||||||
const second = reviewThread({ threadId: 'thread-2', subject: 'Other owned thread' });
|
const second = reviewThread({ threadId: 'thread-2', subject: 'Other owned thread' });
|
||||||
const suggestion = { threadId: 'thread-1', companyName: 'Acme', suggestedJobTitle: 'Backend Developer', subject: 'Suggestion subject', recruiterName: 'Maria', recruiterEmail: 'maria@acme.test', preview: 'Recorded preview' };
|
const suggestion = { threadId: 'thread-1', companyName: 'Acme', suggestedJobTitle: 'Backend Developer', subject: 'Suggestion subject', recruiterName: 'Maria', recruiterEmail: 'maria@acme.test', preview: 'Recorded preview' };
|
||||||
|
|||||||
@@ -2529,12 +2529,15 @@ export const translations = {
|
|||||||
gmailReviewRouteSuggested: "Suggested",
|
gmailReviewRouteSuggested: "Suggested",
|
||||||
gmailReviewRouteLinked: "Linked",
|
gmailReviewRouteLinked: "Linked",
|
||||||
gmailReviewRouteRejected: "Rejected",
|
gmailReviewRouteRejected: "Rejected",
|
||||||
|
gmailReviewCandidateThread: "{count} candidate thread",
|
||||||
gmailReviewCandidateThreads: "{count} candidate threads",
|
gmailReviewCandidateThreads: "{count} candidate threads",
|
||||||
gmailReviewAutoLinkCount: "{count} auto-link",
|
gmailReviewAutoLinkCount: "{count} auto-link",
|
||||||
gmailReviewReviewCount: "{count} review",
|
gmailReviewReviewCount: "{count} review",
|
||||||
gmailReviewUnmatchedCount: "{count} unmatched",
|
gmailReviewUnmatchedCount: "{count} unmatched",
|
||||||
|
gmailReviewSuggestedJobCount: "{count} suggested job",
|
||||||
gmailReviewSuggestedJobsCount: "{count} suggested jobs",
|
gmailReviewSuggestedJobsCount: "{count} suggested jobs",
|
||||||
gmailReviewNoCandidates: "No Gmail review candidates match the current filter.",
|
gmailReviewNoCandidates: "No Gmail review candidates match the current filter.",
|
||||||
|
gmailReviewSingleMessageSummary: "{count} message · {route}",
|
||||||
gmailReviewThreadSummary: "{count} messages · {route}",
|
gmailReviewThreadSummary: "{count} messages · {route}",
|
||||||
gmailReviewHasImported: "Has imported messages",
|
gmailReviewHasImported: "Has imported messages",
|
||||||
gmailReviewNotes: "Review notes",
|
gmailReviewNotes: "Review notes",
|
||||||
@@ -5749,12 +5752,15 @@ export const translations = {
|
|||||||
gmailReviewRouteSuggested: "Foreslått",
|
gmailReviewRouteSuggested: "Foreslått",
|
||||||
gmailReviewRouteLinked: "Tilknyttet",
|
gmailReviewRouteLinked: "Tilknyttet",
|
||||||
gmailReviewRouteRejected: "Avvist",
|
gmailReviewRouteRejected: "Avvist",
|
||||||
|
gmailReviewCandidateThread: "{count} kandidattråd",
|
||||||
gmailReviewCandidateThreads: "{count} kandidattråder",
|
gmailReviewCandidateThreads: "{count} kandidattråder",
|
||||||
gmailReviewAutoLinkCount: "{count} automatisk tilknytning",
|
gmailReviewAutoLinkCount: "{count} automatisk tilknytning",
|
||||||
gmailReviewReviewCount: "{count} til kontroll",
|
gmailReviewReviewCount: "{count} til kontroll",
|
||||||
gmailReviewUnmatchedCount: "{count} uten treff",
|
gmailReviewUnmatchedCount: "{count} uten treff",
|
||||||
|
gmailReviewSuggestedJobCount: "{count} foreslått jobb",
|
||||||
gmailReviewSuggestedJobsCount: "{count} foreslåtte jobber",
|
gmailReviewSuggestedJobsCount: "{count} foreslåtte jobber",
|
||||||
gmailReviewNoCandidates: "Ingen kandidater til Gmail-kontroll samsvarer med gjeldende filter.",
|
gmailReviewNoCandidates: "Ingen kandidater til Gmail-kontroll samsvarer med gjeldende filter.",
|
||||||
|
gmailReviewSingleMessageSummary: "{count} melding · {route}",
|
||||||
gmailReviewThreadSummary: "{count} meldinger · {route}",
|
gmailReviewThreadSummary: "{count} meldinger · {route}",
|
||||||
gmailReviewHasImported: "Har importerte meldinger",
|
gmailReviewHasImported: "Har importerte meldinger",
|
||||||
gmailReviewNotes: "Kontrollnotater",
|
gmailReviewNotes: "Kontrollnotater",
|
||||||
|
|||||||
@@ -241,11 +241,15 @@ export default function GmailReviewPage({ embedded = false, active = true }: { e
|
|||||||
|
|
||||||
{!unavailable && data ? (
|
{!unavailable && data ? (
|
||||||
<Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", mb: 2 }}>
|
<Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", mb: 2 }}>
|
||||||
<Chip label={t("gmailReviewCandidateThreads", { count: data.candidateThreadCount })} variant="outlined" sx={chipSx} />
|
<Chip label={data.candidateThreadCount === 1
|
||||||
|
? t("gmailReviewCandidateThread", { count: data.candidateThreadCount })
|
||||||
|
: t("gmailReviewCandidateThreads", { count: data.candidateThreadCount })} variant="outlined" sx={chipSx} />
|
||||||
<Chip label={t("gmailReviewAutoLinkCount", { count: data.autoLinkThreadCount })} color="success" variant="outlined" sx={chipSx} />
|
<Chip label={t("gmailReviewAutoLinkCount", { count: data.autoLinkThreadCount })} color="success" variant="outlined" sx={chipSx} />
|
||||||
<Chip label={t("gmailReviewReviewCount", { count: data.reviewThreadCount })} color="warning" variant="outlined" sx={chipSx} />
|
<Chip label={t("gmailReviewReviewCount", { count: data.reviewThreadCount })} color="warning" variant="outlined" sx={chipSx} />
|
||||||
<Chip label={t("gmailReviewUnmatchedCount", { count: data.unmatchedThreadCount })} variant="outlined" sx={chipSx} />
|
<Chip label={t("gmailReviewUnmatchedCount", { count: data.unmatchedThreadCount })} variant="outlined" sx={chipSx} />
|
||||||
{suggestions?.count ? <Chip label={t("gmailReviewSuggestedJobsCount", { count: suggestions.count })} color="secondary" variant="outlined" sx={chipSx} /> : null}
|
{suggestions?.count ? <Chip label={suggestions.count === 1
|
||||||
|
? t("gmailReviewSuggestedJobCount", { count: suggestions.count })
|
||||||
|
: t("gmailReviewSuggestedJobsCount", { count: suggestions.count })} color="secondary" variant="outlined" sx={chipSx} /> : null}
|
||||||
</Box>
|
</Box>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
@@ -261,7 +265,9 @@ export default function GmailReviewPage({ embedded = false, active = true }: { e
|
|||||||
<Box sx={{ minWidth: 0, flex: "1 1 420px" }}>
|
<Box sx={{ minWidth: 0, flex: "1 1 420px" }}>
|
||||||
<Typography id={headingId} component={embedded ? "h3" : "h2"} variant="subtitle1" sx={{ fontWeight: 700, overflowWrap: "anywhere" }}>{thread.subject}</Typography>
|
<Typography id={headingId} component={embedded ? "h3" : "h2"} variant="subtitle1" sx={{ fontWeight: 700, overflowWrap: "anywhere" }}>{thread.subject}</Typography>
|
||||||
<Typography variant="body2" sx={{ color: "text.secondary" }}>
|
<Typography variant="body2" sx={{ color: "text.secondary" }}>
|
||||||
{t("gmailReviewThreadSummary", { count: thread.messageCount, route: routeLabel(thread.routing) })}
|
{thread.messageCount === 1
|
||||||
|
? t("gmailReviewSingleMessageSummary", { count: thread.messageCount, route: routeLabel(thread.routing) })
|
||||||
|
: t("gmailReviewThreadSummary", { count: thread.messageCount, route: routeLabel(thread.routing) })}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", mt: 0.75 }}>
|
<Box sx={{ display: "flex", gap: 0.75, flexWrap: "wrap", mt: 0.75 }}>
|
||||||
{thread.matchedQueries.slice(0, 3).map((query) => (
|
{thread.matchedQueries.slice(0, 3).map((query) => (
|
||||||
|
|||||||
Reference in New Issue
Block a user