Fix in-progress jobs in command bar (#275)
This commit is contained in:
parent
a0220df17f
commit
ec89a02e4f
@ -148,10 +148,29 @@ describe("JobCommandBar", () => {
|
||||
expect(screen.getByText("Lock to @ready")).toBeInTheDocument();
|
||||
expect(screen.getByText("Lock to @discovered")).toBeInTheDocument();
|
||||
expect(screen.getByText("Lock to @applied")).toBeInTheDocument();
|
||||
expect(screen.getByText("Lock to @in-progress")).toBeInTheDocument();
|
||||
expect(screen.getByText("Lock to @skipped")).toBeInTheDocument();
|
||||
expect(screen.getByText("Lock to @expired")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("creates in-progress lock from @prog + Tab", () => {
|
||||
render(
|
||||
<JobCommandBar
|
||||
jobs={[createJob({ id: "job-1", status: "in_progress" })]}
|
||||
onSelectJob={vi.fn()}
|
||||
/>,
|
||||
);
|
||||
|
||||
openWithKeyboard();
|
||||
const input = screen.getByPlaceholderText(
|
||||
"Search jobs by job title or company name...",
|
||||
);
|
||||
fireEvent.change(input, { target: { value: "@prog" } });
|
||||
fireEvent.keyDown(input, { key: "Tab" });
|
||||
|
||||
expect(screen.getByText("@in-progress")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("searches by company name and routes to the matched state", () => {
|
||||
const onSelectJob = vi.fn();
|
||||
const jobs: Job[] = [
|
||||
@ -377,11 +396,44 @@ describe("JobCommandBar", () => {
|
||||
fireEvent.keyDown(input, { key: "Tab" });
|
||||
|
||||
expect(
|
||||
screen.queryByText(/^@(ready|discovered|applied|skipped|expired)$/),
|
||||
screen.queryByText(
|
||||
/^@(ready|discovered|applied|in-progress|skipped|expired)$/,
|
||||
),
|
||||
).not.toBeInTheDocument();
|
||||
expect((input as HTMLInputElement).value).toBe("@all");
|
||||
});
|
||||
|
||||
it("routes in-progress jobs to the all jobs view", () => {
|
||||
const onSelectJob = vi.fn();
|
||||
|
||||
render(
|
||||
<JobCommandBar
|
||||
jobs={[
|
||||
createJob({
|
||||
id: "in-progress-job",
|
||||
title: "Staff Engineer",
|
||||
employer: "Globex",
|
||||
status: "in_progress",
|
||||
}),
|
||||
]}
|
||||
onSelectJob={onSelectJob}
|
||||
/>,
|
||||
);
|
||||
|
||||
openWithKeyboard();
|
||||
fireEvent.change(
|
||||
screen.getByPlaceholderText(
|
||||
"Search jobs by job title or company name...",
|
||||
),
|
||||
{
|
||||
target: { value: "Globex" },
|
||||
},
|
||||
);
|
||||
fireEvent.click(screen.getByText("Staff Engineer"));
|
||||
|
||||
expect(onSelectJob).toHaveBeenCalledWith("all", "in-progress-job");
|
||||
});
|
||||
|
||||
it("excludes processing jobs from every lock scope", () => {
|
||||
const jobs: Job[] = [
|
||||
createJob({
|
||||
|
||||
@ -51,6 +51,8 @@ export const JobCommandBar: React.FC<JobCommandBarProps> = ({
|
||||
"border-sky-500/50 shadow-[0_0_0_1px_rgba(14,165,233,0.2),0_0_36px_-12px_rgba(14,165,233,0.55)]",
|
||||
applied:
|
||||
"border-emerald-500/50 shadow-[0_0_0_1px_rgba(16,185,129,0.2),0_0_36px_-12px_rgba(16,185,129,0.55)]",
|
||||
in_progress:
|
||||
"border-cyan-500/50 shadow-[0_0_0_1px_rgba(6,182,212,0.2),0_0_36px_-12px_rgba(6,182,212,0.55)]",
|
||||
skipped:
|
||||
"border-rose-500/50 shadow-[0_0_0_1px_rgba(244,63,94,0.2),0_0_36px_-12px_rgba(244,63,94,0.55)]",
|
||||
expired:
|
||||
|
||||
@ -6,6 +6,7 @@ export type StatusLock =
|
||||
| "ready"
|
||||
| "discovered"
|
||||
| "applied"
|
||||
| "in_progress"
|
||||
| "skipped"
|
||||
| "expired";
|
||||
|
||||
@ -21,6 +22,7 @@ const lockAliases: Record<StatusLock, string[]> = {
|
||||
ready: ["ready", "rdy"],
|
||||
discovered: ["discovered", "discover", "disc"],
|
||||
applied: ["applied", "apply", "app"],
|
||||
in_progress: ["in-progress", "inprogress", "progress", "prog"],
|
||||
skipped: ["skipped", "skip", "skp"],
|
||||
expired: ["expired", "expire", "exp"],
|
||||
};
|
||||
@ -29,6 +31,7 @@ export const lockLabel: Record<StatusLock, string> = {
|
||||
ready: "ready",
|
||||
discovered: "discovered",
|
||||
applied: "applied",
|
||||
in_progress: "in-progress",
|
||||
skipped: "skipped",
|
||||
expired: "expired",
|
||||
};
|
||||
@ -124,6 +127,7 @@ export const jobMatchesLock = (job: JobListItem, lock: StatusLock) => {
|
||||
if (lock === "ready") return job.status === "ready";
|
||||
if (lock === "discovered") return job.status === "discovered";
|
||||
if (lock === "applied") return job.status === "applied";
|
||||
if (lock === "in_progress") return job.status === "in_progress";
|
||||
if (lock === "skipped") return job.status === "skipped";
|
||||
if (lock === "expired") return job.status === "expired";
|
||||
return false;
|
||||
|
||||
@ -15,6 +15,35 @@ const baseJob = createJob({
|
||||
});
|
||||
|
||||
describe("useFilteredJobs", () => {
|
||||
it("keeps in-progress jobs in the all jobs tab", () => {
|
||||
const jobs: Job[] = [
|
||||
{ ...baseJob, id: "in-progress", status: "in_progress" },
|
||||
{ ...baseJob, id: "processing", status: "processing" },
|
||||
{
|
||||
...baseJob,
|
||||
id: "closed",
|
||||
status: "in_progress",
|
||||
closedAt: 1741996800,
|
||||
},
|
||||
];
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useFilteredJobs(
|
||||
jobs,
|
||||
"all",
|
||||
"all",
|
||||
"all",
|
||||
{ mode: "at_least", min: null, max: null },
|
||||
{
|
||||
key: "score",
|
||||
direction: "desc",
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
expect(result.current.map((job) => job.id)).toEqual(["in-progress"]);
|
||||
});
|
||||
|
||||
it("filters by sponsor status categories", () => {
|
||||
const jobs: Job[] = [
|
||||
{ ...baseJob, id: "confirmed", sponsorMatchScore: 99 },
|
||||
|
||||
@ -24,7 +24,7 @@ export const useFilteredJobs = (
|
||||
sort: JobSort,
|
||||
) =>
|
||||
useMemo(() => {
|
||||
let filtered = jobs.filter((job) => job.status !== "in_progress");
|
||||
let filtered = [...jobs];
|
||||
|
||||
if (activeTab === "ready") {
|
||||
filtered = filtered.filter((job) => job.status === "ready");
|
||||
@ -34,6 +34,10 @@ export const useFilteredJobs = (
|
||||
);
|
||||
} else if (activeTab === "applied") {
|
||||
filtered = filtered.filter((job) => job.status === "applied");
|
||||
} else if (activeTab === "all") {
|
||||
filtered = filtered.filter(
|
||||
(job) => job.status !== "processing" && job.closedAt == null,
|
||||
);
|
||||
}
|
||||
|
||||
if (activeTab !== "all") {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user