feat(command-bar): hide low relevance matches by default (#186)
This commit is contained in:
parent
625264c3a2
commit
4f8664cb9c
@ -24,6 +24,8 @@ Search matches job fields with fuzzy ranking:
|
|||||||
- company/employer
|
- company/employer
|
||||||
- location
|
- location
|
||||||
|
|
||||||
|
By default, very low-relevance matches are hidden so results stay focused on likely intent.
|
||||||
|
|
||||||
Results are grouped by status sections:
|
Results are grouped by status sections:
|
||||||
|
|
||||||
- Ready
|
- Ready
|
||||||
|
|||||||
@ -19,7 +19,7 @@ describe("JobCommandBar score helpers", () => {
|
|||||||
expect(score).toBe(0);
|
expect(score).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("ranks exact and fuzzy matches above non-matches for a query", () => {
|
it("keeps only relevant matches when a query is provided", () => {
|
||||||
const grouped = groupJobsForCommandBar(
|
const grouped = groupJobsForCommandBar(
|
||||||
[
|
[
|
||||||
createJob({
|
createJob({
|
||||||
@ -44,10 +44,22 @@ describe("JobCommandBar score helpers", () => {
|
|||||||
"backend",
|
"backend",
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(grouped.ready.map((job) => job.id)).toEqual([
|
expect(grouped.ready.map((job) => job.id)).toEqual(["exact", "fuzzy"]);
|
||||||
"exact",
|
});
|
||||||
"fuzzy",
|
|
||||||
"no-match",
|
it("filters out weak fuzzy matches below the relevance floor", () => {
|
||||||
]);
|
const grouped = groupJobsForCommandBar(
|
||||||
|
[
|
||||||
|
createJob({
|
||||||
|
id: "weak-fuzzy",
|
||||||
|
title: "Backend Engineer",
|
||||||
|
employer: "Platform Co",
|
||||||
|
discoveredAt: "2025-01-02T00:00:00Z",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
"bde",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(grouped.ready).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -34,6 +34,7 @@ export const lockLabel: Record<StatusLock, string> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const tokenRegex = /^\s*@([a-z-]*)/i;
|
const tokenRegex = /^\s*@([a-z-]*)/i;
|
||||||
|
const MINIMUM_MATCH_SCORE = 600;
|
||||||
|
|
||||||
const parseTime = (value: string | null) => {
|
const parseTime = (value: string | null) => {
|
||||||
if (!value) return Number.NaN;
|
if (!value) return Number.NaN;
|
||||||
@ -158,24 +159,29 @@ export const groupJobsForCommandBar = (
|
|||||||
other: [],
|
other: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
const sorted = [...scopedJobs].sort((a, b) => {
|
const scoredJobs = normalizedQuery
|
||||||
if (normalizedQuery) {
|
? scopedJobs
|
||||||
const firstScore = computeJobMatchScore(a, normalizedQuery);
|
.map((job) => ({
|
||||||
const secondScore = computeJobMatchScore(b, normalizedQuery);
|
job,
|
||||||
if (firstScore !== secondScore) return secondScore - firstScore;
|
score: computeJobMatchScore(job, normalizedQuery),
|
||||||
}
|
}))
|
||||||
|
.filter(({ score }) => score >= MINIMUM_MATCH_SCORE)
|
||||||
|
: scopedJobs.map((job) => ({ job, score: 0 }));
|
||||||
|
|
||||||
const first = parseTime(a.discoveredAt);
|
const sorted = scoredJobs.sort((a, b) => {
|
||||||
const second = parseTime(b.discoveredAt);
|
if (normalizedQuery && a.score !== b.score) return b.score - a.score;
|
||||||
|
|
||||||
|
const first = parseTime(a.job.discoveredAt);
|
||||||
|
const second = parseTime(b.job.discoveredAt);
|
||||||
if (!Number.isNaN(first) && !Number.isNaN(second)) {
|
if (!Number.isNaN(first) && !Number.isNaN(second)) {
|
||||||
return second - first;
|
return second - first;
|
||||||
}
|
}
|
||||||
if (!Number.isNaN(first)) return -1;
|
if (!Number.isNaN(first)) return -1;
|
||||||
if (!Number.isNaN(second)) return 1;
|
if (!Number.isNaN(second)) return 1;
|
||||||
return b.id.localeCompare(a.id);
|
return b.job.id.localeCompare(a.job.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const job of sorted) {
|
for (const { job } of sorted) {
|
||||||
groups[getCommandGroup(job.status)].push(job);
|
groups[getCommandGroup(job.status)].push(job);
|
||||||
}
|
}
|
||||||
return groups;
|
return groups;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user