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 @ready")).toBeInTheDocument();
|
||||||
expect(screen.getByText("Lock to @discovered")).toBeInTheDocument();
|
expect(screen.getByText("Lock to @discovered")).toBeInTheDocument();
|
||||||
expect(screen.getByText("Lock to @applied")).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 @skipped")).toBeInTheDocument();
|
||||||
expect(screen.getByText("Lock to @expired")).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", () => {
|
it("searches by company name and routes to the matched state", () => {
|
||||||
const onSelectJob = vi.fn();
|
const onSelectJob = vi.fn();
|
||||||
const jobs: Job[] = [
|
const jobs: Job[] = [
|
||||||
@ -377,11 +396,44 @@ describe("JobCommandBar", () => {
|
|||||||
fireEvent.keyDown(input, { key: "Tab" });
|
fireEvent.keyDown(input, { key: "Tab" });
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
screen.queryByText(/^@(ready|discovered|applied|skipped|expired)$/),
|
screen.queryByText(
|
||||||
|
/^@(ready|discovered|applied|in-progress|skipped|expired)$/,
|
||||||
|
),
|
||||||
).not.toBeInTheDocument();
|
).not.toBeInTheDocument();
|
||||||
expect((input as HTMLInputElement).value).toBe("@all");
|
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", () => {
|
it("excludes processing jobs from every lock scope", () => {
|
||||||
const jobs: Job[] = [
|
const jobs: Job[] = [
|
||||||
createJob({
|
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)]",
|
"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:
|
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)]",
|
"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:
|
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)]",
|
"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:
|
expired:
|
||||||
|
|||||||
@ -6,6 +6,7 @@ export type StatusLock =
|
|||||||
| "ready"
|
| "ready"
|
||||||
| "discovered"
|
| "discovered"
|
||||||
| "applied"
|
| "applied"
|
||||||
|
| "in_progress"
|
||||||
| "skipped"
|
| "skipped"
|
||||||
| "expired";
|
| "expired";
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ const lockAliases: Record<StatusLock, string[]> = {
|
|||||||
ready: ["ready", "rdy"],
|
ready: ["ready", "rdy"],
|
||||||
discovered: ["discovered", "discover", "disc"],
|
discovered: ["discovered", "discover", "disc"],
|
||||||
applied: ["applied", "apply", "app"],
|
applied: ["applied", "apply", "app"],
|
||||||
|
in_progress: ["in-progress", "inprogress", "progress", "prog"],
|
||||||
skipped: ["skipped", "skip", "skp"],
|
skipped: ["skipped", "skip", "skp"],
|
||||||
expired: ["expired", "expire", "exp"],
|
expired: ["expired", "expire", "exp"],
|
||||||
};
|
};
|
||||||
@ -29,6 +31,7 @@ export const lockLabel: Record<StatusLock, string> = {
|
|||||||
ready: "ready",
|
ready: "ready",
|
||||||
discovered: "discovered",
|
discovered: "discovered",
|
||||||
applied: "applied",
|
applied: "applied",
|
||||||
|
in_progress: "in-progress",
|
||||||
skipped: "skipped",
|
skipped: "skipped",
|
||||||
expired: "expired",
|
expired: "expired",
|
||||||
};
|
};
|
||||||
@ -124,6 +127,7 @@ export const jobMatchesLock = (job: JobListItem, lock: StatusLock) => {
|
|||||||
if (lock === "ready") return job.status === "ready";
|
if (lock === "ready") return job.status === "ready";
|
||||||
if (lock === "discovered") return job.status === "discovered";
|
if (lock === "discovered") return job.status === "discovered";
|
||||||
if (lock === "applied") return job.status === "applied";
|
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 === "skipped") return job.status === "skipped";
|
||||||
if (lock === "expired") return job.status === "expired";
|
if (lock === "expired") return job.status === "expired";
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -15,6 +15,35 @@ const baseJob = createJob({
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("useFilteredJobs", () => {
|
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", () => {
|
it("filters by sponsor status categories", () => {
|
||||||
const jobs: Job[] = [
|
const jobs: Job[] = [
|
||||||
{ ...baseJob, id: "confirmed", sponsorMatchScore: 99 },
|
{ ...baseJob, id: "confirmed", sponsorMatchScore: 99 },
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export const useFilteredJobs = (
|
|||||||
sort: JobSort,
|
sort: JobSort,
|
||||||
) =>
|
) =>
|
||||||
useMemo(() => {
|
useMemo(() => {
|
||||||
let filtered = jobs.filter((job) => job.status !== "in_progress");
|
let filtered = [...jobs];
|
||||||
|
|
||||||
if (activeTab === "ready") {
|
if (activeTab === "ready") {
|
||||||
filtered = filtered.filter((job) => job.status === "ready");
|
filtered = filtered.filter((job) => job.status === "ready");
|
||||||
@ -34,6 +34,10 @@ export const useFilteredJobs = (
|
|||||||
);
|
);
|
||||||
} else if (activeTab === "applied") {
|
} else if (activeTab === "applied") {
|
||||||
filtered = filtered.filter((job) => job.status === "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") {
|
if (activeTab !== "all") {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user