Skip to content

Commit

Permalink
added search
Browse files Browse the repository at this point in the history
  • Loading branch information
sterlp committed Jan 6, 2025
1 parent eee23b9 commit 5ca0b8f
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 38 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## v1.4.2 - (2025-01-06)

- Fixed count by TaskId
- added search by ID to the UI
- added search by task to history

## v1.4.1 - (2025-01-06)

- Added state to the TriggerLifeCycleEvent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,6 @@ public class TriggerKey implements Serializable {
private String id;
private String taskName;

public static TriggerKey of(@Nullable String id, String taskName) {
if (StringUtils.trimToNull(id) == null
&& StringUtils.trimToNull(taskName) == null) return null;

var taskId = StringUtils.trimToNull(taskName) == null
? null
: new TaskId<Serializable>(taskName.trim());
return of(StringUtils.trimToNull(id), taskId);
}

public static TriggerKey of(@Nullable String id, TaskId<? extends Serializable> taskId) {
return new TriggerKey(id == null ? UUID.randomUUID().toString() : id, taskId.name());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public long countTriggers(TriggerKey key) {
public Page<TriggerHistoryLastStateEntity> findTriggerState(
TriggerKey key, Pageable page) {
if (key == null) return triggerHistoryDetailRepository.findAll(page);
if (key.getId() == null && key.getTaskName() == null) return triggerHistoryDetailRepository.findAll(page);
if (key.getId() == null && key.getTaskName() != null) {
return triggerHistoryDetailRepository.findAll(key.getTaskName(), page);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
Expand Down Expand Up @@ -34,11 +35,13 @@ public List<Trigger> listInstances(@PathVariable("instanceId") long instanceId)

@GetMapping("history")
public PagedModel<Trigger> list(
@RequestParam(name = "id", required = false) String taskId,
@RequestParam(name = "taskName", required = false) String name,
@RequestParam(name = "id", required = false) String id,
@RequestParam(name = "taskName", required = false) String taskName,
@PageableDefault(size = 100, direction = Direction.DESC, sort = "id") Pageable pageable) {

return FromLastTriggerStateEntity.INSTANCE.toPage( //
historyService.findTriggerState(TriggerKey.of(taskId, name), pageable));
historyService.findTriggerState(
new TriggerKey(StringUtils.trimToNull(id), StringUtils.trimToNull(taskName)),
pageable));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
public interface TriggerDataRepository<T extends HasTriggerData> extends JpaRepository<T, Long> {
@Query("""
SELECT e FROM #{#entityName} e
WHERE (e.data.key.id LIKE :id% OR :id = NULL)
OR (e.data.key.taskName = :taskName OR :taskName = NULL)
WHERE (e.data.key.id LIKE :id% OR :id IS NULL)
AND (e.data.key.taskName = :taskName OR :taskName IS NULL)
""")
Page<T> findAll(@Param("id") String id,
@Param("taskName") String taskName, Pageable page);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.time.OffsetDateTime;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
Expand All @@ -15,7 +16,6 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.sterl.spring.persistent_tasks.api.TaskId;
import org.sterl.spring.persistent_tasks.api.Trigger;
import org.sterl.spring.persistent_tasks.api.TriggerKey;
import org.sterl.spring.persistent_tasks.trigger.TriggerService;
Expand All @@ -37,12 +37,14 @@ public long count() {

@GetMapping("triggers")
public PagedModel<Trigger> list(
@RequestParam(name = "id", required = false) String taskId,
@RequestParam(name = "taskName", required = false) String name,
@RequestParam(name = "id", required = false) String id,
@RequestParam(name = "taskName", required = false) String taskName,
@PageableDefault(size = 100, direction = Direction.DESC, sort = "id")
Pageable pageable) {
return FromTriggerEntity.INSTANCE.toPage(
triggerService.findAllTriggers(TriggerKey.of(taskId, name), pageable));
triggerService.findAllTriggers(
new TriggerKey(StringUtils.trimToNull(id), StringUtils.trimToNull(taskName)),
pageable));
}

@PostMapping("triggers/{taskName}/{id}/run-at")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public List<TriggerEntity> findTriggersLastPingAfter(OffsetDateTime dateTime) {
public Page<TriggerEntity> listTriggers(TriggerKey key, Pageable page) {
if (key == null) return triggerRepository.findAll(page);
if (key.getId() == null) return listTriggers(key.toTaskId(), page);
return listTriggers(key.toTaskId(), page);
return triggerRepository.findAll(key.getId(), key.getTaskName(), page);
}

public Page<TriggerEntity> listTriggers(TaskId<? extends Serializable> task, Pageable page) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,28 @@ void testList() {
assertThat(response.getBody()).contains(triggerKey.getTaskName());
}

@Test
void testSearchById() {
// GIVEN
var key1 = triggerService.queue(TaskTriggerBuilder
.newTrigger("task1").build()).getKey();
var key2 = triggerService.queue(TaskTriggerBuilder
.newTrigger("task1").build()).getKey();

// WHEN
var response = template.exchange(
baseUrl + "?id=" + key1.getId().substring(0, 30),
HttpMethod.GET,
null,
String.class);

// THEN
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isNotNull();
assertThat(response.getBody()).contains(key1.getId());
assertThat(response.getBody()).doesNotContain(key2.getId());
}

@Test
void testCancel() {
// GIVEN
Expand Down
42 changes: 31 additions & 11 deletions ui/src/history/history.page.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,55 @@
import { useEffect, useState } from "react";
import { useServerObject } from "@src/shared/http-request";
import { PagedModel, Trigger } from "@src/server-api";
import { Col, Row, Stack } from "react-bootstrap";
import { useServerObject } from "@src/shared/http-request";
import useAutoRefresh from "@src/shared/use-auto-refresh";
import HttpErrorView from "@src/shared/view/http-error.view";
import PageView from "@src/shared/view/page.view";
import ReloadButton from "@src/shared/view/reload-button.view";
import TriggerItemView from "@src/shared/view/trigger-list-item.view";
import TaskSelect from "@src/task/view/task-select.view";
import { useState } from "react";
import { Col, Form, Row, Stack } from "react-bootstrap";

const HistoryPage = () => {
const [page, setPage] = useState(0);
const [taskName, setTaskName] = useState("");
const [id, setId] = useState("");

const triggers = useServerObject<PagedModel<Trigger>>(
"/spring-tasks-api/history"
);

const doReload = () => {
triggers.doGet("?size=10&page=" + page);
triggers.doGet(
"?size=10&page=" + page + "&taskName=" + taskName + "&id=" + id
);
};

useEffect(doReload, [page]);
useEffect(() => {
const intervalId = setInterval(doReload, 10000);
return () => clearInterval(intervalId);
}, [page]);
useAutoRefresh(10000, doReload, [page, taskName, id]);

return (
<>
<Stack gap={1}>
<HttpErrorView error={triggers.error} />
<Row className="align-items-center">
<div></div>
<Row>
<Col>
<Form.Control
type="text"
placeholder="Search..."
onKeyUp={(e) =>
e.key == "Enter"
? setId(
(e.target as HTMLInputElement).value
)
: null
}
/>
</Col>
</Row>
<Row className="align-items-center mb-2">
<Col>
<TaskSelect onTaskChange={setTaskName} />
</Col>
<Col className="align-items-center">
<PageView
onPage={(p) => setPage(p)}
data={triggers.data}
Expand Down
30 changes: 23 additions & 7 deletions ui/src/trigger/triggers.page.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
import { PagedModel, Trigger } from "@src/server-api";
import HttpErrorView from "@src/shared/view/http-error.view";
import { useServerObject } from "@src/shared/http-request";
import useAutoRefresh from "@src/shared/use-auto-refresh";
import HttpErrorView from "@src/shared/view/http-error.view";
import PageView from "@src/shared/view/page.view";
import ReloadButton from "@src/shared/view/reload-button.view";
import useAutoRefresh from "@src/shared/use-auto-refresh";
import TaskSelect from "@src/task/view/task-select.view";
import { useState } from "react";
import { Col, Row, Stack } from "react-bootstrap";
import { Col, Form, Row, Stack } from "react-bootstrap";
import TriggerItemView from "../shared/view/trigger-list-item.view";

const TriggersPage = () => {
const [page, setPage] = useState(0);
const [selectedTask, setSelectedTask] = useState("");
const [taskName, setTaskName] = useState("");
const [id, setId] = useState("");
const triggers = useServerObject<PagedModel<Trigger>>(
"/spring-tasks-api/triggers"
);

const doReload = () => {
triggers.doGet("?size=10&page=" + page + "&taskId=" + selectedTask);
triggers.doGet(
"?size=10&page=" + page + "&taskName=" + taskName + "&id=" + id
);
};

useAutoRefresh(10000, doReload, [page, selectedTask]);
useAutoRefresh(10000, doReload, [page, taskName, id]);

return (
<Stack gap={1}>
<HttpErrorView error={triggers.error} />
<Row>
<Col>
<Form.Control
type="text"
placeholder="Search..."
onKeyUp={(e) =>
e.key == "Enter"
? setId((e.target as HTMLInputElement).value)
: null
}
/>
</Col>
</Row>
<Row className="align-items-center mb-2">
<Col>
<TaskSelect onTaskChange={setSelectedTask} />
<TaskSelect onTaskChange={setTaskName} />
</Col>
<Col className="align-items-center">
<PageView onPage={(p) => setPage(p)} data={triggers.data} />
Expand Down

0 comments on commit 5ca0b8f

Please sign in to comment.