Skip to content

Commit bf70696

Browse files
committed
feat: new Search Bar for the Job Monitor
1 parent 2688537 commit bf70696

36 files changed

Lines changed: 2054 additions & 1070 deletions

packages/diracx-web-components/src/components/JobMonitor/JobDataService.ts

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,43 @@ import utc from "dayjs/plugin/utc";
77
dayjs.extend(utc);
88
import { fetcher } from "../../hooks/utils";
99
import { Filter, SearchBody, Job, JobHistory } from "../../types";
10+
import type { JobSummary } from "../../types";
1011

1112
function processSearchBody(searchBody: SearchBody) {
1213
searchBody.search = searchBody.search?.map((filter: Filter) => {
1314
if (filter.operator == "last") {
14-
return {
15-
parameter: filter.parameter,
16-
operator: "gt",
17-
value: dayjs()
18-
.subtract(1, filter.value as "hour" | "day" | "month" | "year")
19-
.toISOString(),
20-
values: filter.values,
21-
};
15+
const valueStr = filter.value as string;
16+
const match = valueStr.match(/^(\d+)\s*(minute|hour|day|month|year)s?$/i);
17+
18+
if (match) {
19+
const amount = parseInt(match[1], 10);
20+
const unit = match[2].toLowerCase() as
21+
| "minute"
22+
| "hour"
23+
| "day"
24+
| "month"
25+
| "year";
26+
27+
return {
28+
parameter: filter.parameter,
29+
operator: "gt",
30+
value: dayjs().subtract(amount, unit).toISOString(),
31+
values: filter.values,
32+
};
33+
} else {
34+
// Fallback pour l'ancienne logique si le format n'est pas reconnu
35+
return {
36+
parameter: filter.parameter,
37+
operator: "gt",
38+
value: dayjs()
39+
.subtract(
40+
1,
41+
filter.value as "minute" | "hour" | "day" | "month" | "year",
42+
)
43+
.toISOString(),
44+
values: filter.values,
45+
};
46+
}
2247
}
2348
return filter;
2449
});
@@ -203,3 +228,31 @@ export async function getJobHistory(
203228

204229
return { data: data[0].LoggingInfo };
205230
}
231+
232+
export async function getJobSummary(
233+
diracxUrl: string | null,
234+
grouping: string[],
235+
accessToken: string,
236+
searchBody?: SearchBody,
237+
): Promise<{ data: JobSummary[] }> {
238+
if (!diracxUrl) {
239+
throw new Error("Invalid URL generated for fetching job history.");
240+
}
241+
242+
if (searchBody) processSearchBody(searchBody);
243+
244+
const summaryUrl = `${diracxUrl}/api/jobs/summary`;
245+
const body = {
246+
grouping: grouping,
247+
search: searchBody?.search || [],
248+
};
249+
// Expect the response to be an array of objects with all the grouping fields
250+
const { data } = await fetcher<Array<JobSummary>>([
251+
summaryUrl,
252+
accessToken,
253+
"POST",
254+
body,
255+
]);
256+
257+
return { data };
258+
}

packages/diracx-web-components/src/components/JobMonitor/JobMonitor.tsx

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ import {
2323
} from "@tanstack/react-table";
2424

2525
import { useApplicationId } from "../../hooks/application";
26-
import { FilterToolbar } from "../shared/FilterToolbar";
2726
import { InternalFilter } from "../../types/Filter";
2827
import { Job, SearchBody } from "../../types";
2928
import { JobDataTable } from "./JobDataTable";
29+
import { JobSearchBar } from "./JobSearchBar";
3030

3131
/**
3232
* Build the Job Monitor application
@@ -98,7 +98,7 @@ export default function JobMonitor() {
9898
// Save the state of the app in local storage
9999
useEffect(() => {
100100
const state = {
101-
filters: [...filters.filter((filter) => filter.isApplied)],
101+
filters: [...filters],
102102
columnVisibility: { ...columnVisibility },
103103
columnPinning: {
104104
left: [...(columnPinning.left || [])],
@@ -123,15 +123,10 @@ export default function JobMonitor() {
123123

124124
// Handle the application of filters
125125
const handleApplyFilters = () => {
126-
// Switch the applied state of the filters
127-
setFilters((filters) =>
128-
filters.map((filter) => ({ ...filter, isApplied: true })),
129-
);
130-
131126
setSearchBody((prev) => ({
132127
...prev,
133128
search: filters.map(({ parameter, operator, value, values }) => ({
134-
parameter,
129+
parameter: fromHumanReadableText(parameter),
135130
operator,
136131
value,
137132
values,
@@ -143,18 +138,6 @@ export default function JobMonitor() {
143138
}));
144139
};
145140

146-
const handleRemoveAllFilters = useCallback(() => {
147-
setSearchBody((prevState) => ({
148-
...prevState,
149-
search: [],
150-
}));
151-
setPagination((prevState) => ({
152-
...prevState,
153-
pageIndex: 0,
154-
}));
155-
setFilters([]);
156-
}, [setFilters]);
157-
158141
// Status colors
159142
const statusColors: Record<string, string> = useMemo(
160143
() => ({
@@ -300,12 +283,11 @@ export default function JobMonitor() {
300283
overflow: "hidden",
301284
}}
302285
>
303-
<FilterToolbar
304-
columns={columns}
286+
<JobSearchBar
305287
filters={filters}
306288
setFilters={setFilters}
289+
searchBody={searchBody}
307290
handleApplyFilters={handleApplyFilters}
308-
handleClearFilters={handleRemoveAllFilters}
309291
/>
310292
<JobDataTable
311293
searchBody={searchBody}
@@ -370,3 +352,41 @@ export function validateAndConvertState(state: string): [string, boolean] {
370352

371353
return [JSON.stringify(newState), true];
372354
}
355+
356+
/**
357+
* Converts a human-readable job attribute name to its internal name.
358+
* @param name - The human-readable name of the job attribute
359+
* @returns The corresponding internal name of the job attribute
360+
*/
361+
export function fromHumanReadableText(name: string): string {
362+
switch (name) {
363+
case "ID":
364+
return "JobID";
365+
case "Minor Status":
366+
return "MinorStatus";
367+
case "Application Status":
368+
return "ApplicationStatus";
369+
case "Name":
370+
return "JobName";
371+
case "Job Group":
372+
return "JobGroup";
373+
case "Type":
374+
return "JobType";
375+
case "Last Update Time":
376+
return "LastUpdateTime";
377+
case "Last Sign of Life":
378+
return "HeartBeatTime";
379+
case "Submission Time":
380+
return "SubmissionTime";
381+
case "Owner Group":
382+
return "OwnerGroup";
383+
case "Start Execution Time":
384+
return "StartExecTime";
385+
case "End Execution Time":
386+
return "EndExecTime";
387+
case "User Priority":
388+
return "UserPriority";
389+
default:
390+
return name; // Return the original name if no match found
391+
}
392+
}

0 commit comments

Comments
 (0)