Skip to content

Commit fa7fc29

Browse files
committed
Adds Discovery search and refactors UI fragments
Implements HTMX-driven search functionality for the Discovery page, leveraging new services and a dedicated controller endpoint. Restructures common Thymeleaf layout fragments into a dedicated `fragments/layout` directory for improved organization and maintainability. Updates all affected controllers and templates. Centralizes model attribute management by introducing helper methods in controllers for page-specific data and a `GlobalControllerAdvice` for application-wide data, such as available scopes. Integrates the `force-graph` JavaScript library as a new dependency.
1 parent 745652c commit fa7fc29

25 files changed

+280
-87
lines changed

src/main/java/dev/ikm/server/cosmos/constellations/ConstellationsController.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,27 @@ public class ConstellationsController {
1313

1414
Logger LOG = LoggerFactory.getLogger(ConstellationsController.class);
1515

16-
@GetMapping("/constellations")
17-
public String getKnowledge(Model model) {
16+
private void addSharedModelAttributes(Model model) {
1817
model.addAttribute("activePage", "constellations");
18+
model.addAttribute("titleDisplayName", "Constellations");
1919
model.addAttribute("footerText", "Mapping the stars of knowledge");
20+
}
21+
22+
@GetMapping("/constellations")
23+
public String getKnowledge(Model model) {
24+
addSharedModelAttributes(model);
2025
return "constellations";
2126
}
2227

2328
@HxRequest
2429
@GetMapping("/constellations")
2530
public FragmentsRendering getKnowledgeWithFragments(Model model) {
26-
model.addAttribute("titleDisplayName", "Constellations");
27-
model.addAttribute("activePage", "constellations");
28-
model.addAttribute("footerText", "Mapping the stars of knowledge");
31+
addSharedModelAttributes(model);
2932
return FragmentsRendering
3033
.with("constellations :: main-content")
31-
.fragment("fragments/title :: title-content")
32-
.fragment("fragments/navigation :: navigation-content")
33-
.fragment("fragments/footer :: footer-content")
34+
.fragment("fragments/layout/title :: title-content")
35+
.fragment("fragments/layout/navigation :: navigation-content")
36+
.fragment("fragments/layout/footer :: footer-content")
3437
.build();
3538
}
3639
}

src/main/java/dev/ikm/server/cosmos/discovery/DiscoveryController.java

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,55 @@
33
import io.github.wimdeblauwe.htmx.spring.boot.mvc.HxRequest;
44
import org.slf4j.Logger;
55
import org.slf4j.LoggerFactory;
6+
import org.springframework.beans.factory.annotation.Autowired;
67
import org.springframework.stereotype.Controller;
78
import org.springframework.ui.Model;
89
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.web.bind.annotation.RequestParam;
911
import org.springframework.web.servlet.view.FragmentsRendering;
1012

1113
@Controller
1214
public class DiscoveryController {
1315

1416
Logger LOG = LoggerFactory.getLogger(DiscoveryController.class);
1517

16-
@GetMapping("/discovery")
17-
public String getData(Model model) {
18+
private final DiscoveryService discoveryService;
19+
private final SearchService searchService;
20+
21+
@Autowired
22+
public DiscoveryController(DiscoveryService discoveryService, SearchService searchService) {
23+
this.discoveryService = discoveryService;
24+
this.searchService = searchService;
25+
}
26+
27+
private void addSharedModelAttributes(Model model) {
1828
model.addAttribute("activePage", "discovery");
29+
model.addAttribute("titleDisplayName", "Discovery");
1930
model.addAttribute("footerText", "Navigate your knowledge universe");
31+
}
32+
33+
@GetMapping("/discovery")
34+
public String getData(Model model) {
35+
addSharedModelAttributes(model);
2036
return "discovery";
2137
}
2238

2339
@HxRequest
2440
@GetMapping("/discovery")
2541
public FragmentsRendering getDataWithFragments(Model model) {
26-
model.addAttribute("titleDisplayName", "Discovery");
27-
model.addAttribute("activePage", "discovery");
28-
model.addAttribute("footerText", "Navigate your knowledge universe");
42+
addSharedModelAttributes(model);
2943
return FragmentsRendering
3044
.with("discovery :: main-content")
31-
.fragment("fragments/title :: title-content")
32-
.fragment("fragments/navigation :: navigation-content")
33-
.fragment("fragments/footer :: footer-content")
45+
.fragment("fragments/layout/title :: title-content")
46+
.fragment("fragments/layout/navigation :: navigation-content")
47+
.fragment("fragments/layout/footer :: footer-content")
3448
.build();
3549
}
50+
51+
@HxRequest
52+
@GetMapping("/discovery/search")
53+
public String search(@RequestParam("query") String query, Model model) {
54+
searchService.search(query);
55+
return "discovery-search";
56+
}
3657
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package dev.ikm.server.cosmos.discovery;
2+
3+
import dev.ikm.server.cosmos.api.coordinate.CalculatorService;
4+
import org.springframework.stereotype.Service;
5+
6+
@Service
7+
public class DiscoveryService {
8+
9+
private final CalculatorService calculatorService;
10+
11+
public DiscoveryService(CalculatorService calculatorService) {
12+
this.calculatorService = calculatorService;
13+
}
14+
15+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package dev.ikm.server.cosmos.discovery;
2+
3+
import java.util.List;
4+
import java.util.UUID;
5+
6+
public record SearchResultDTO(
7+
List<UUID> id
8+
9+
) {
10+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package dev.ikm.server.cosmos.discovery;
2+
3+
import dev.ikm.server.cosmos.api.coordinate.CalculatorService;
4+
import dev.ikm.tinkar.coordinate.stamp.calculator.LatestVersionSearchResult;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.stereotype.Service;
7+
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
@Service
12+
public class SearchService {
13+
14+
private final CalculatorService calculatorService;
15+
16+
@Autowired
17+
public SearchService(CalculatorService calculatorService) {
18+
this.calculatorService = calculatorService;
19+
}
20+
21+
public List<SearchResultDTO> search(String query) {
22+
List<LatestVersionSearchResult> results = new ArrayList<>();
23+
try {
24+
results.addAll(calculatorService.getStampCalculator().search(query, 100).castToList());
25+
} catch (Exception e) {
26+
throw new RuntimeException(e);
27+
}
28+
29+
return null;
30+
}
31+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package dev.ikm.server.cosmos.global;
2+
3+
import dev.ikm.server.cosmos.scope.ScopeService;
4+
import org.springframework.ui.Model;
5+
import org.springframework.web.bind.annotation.ControllerAdvice;
6+
import org.springframework.web.bind.annotation.ModelAttribute;
7+
8+
@ControllerAdvice
9+
public class GlobalControllerAdvice {
10+
11+
private final ScopeService scopeService;
12+
13+
public GlobalControllerAdvice(ScopeService scopeService) {
14+
this.scopeService = scopeService;
15+
}
16+
17+
@ModelAttribute
18+
public void addGlobalAttributes(Model model) {
19+
// This ensures 'scopes' is available on every page for the navigation dropdown
20+
model.addAttribute("scopes", scopeService.retrieveAllScopes());
21+
22+
// You can also handle 'activeScope' here if it's stored in the session
23+
// or determine it based on the request
24+
}
25+
}

src/main/java/dev/ikm/server/cosmos/home/HomeController.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,27 @@ public class HomeController {
1313

1414
Logger LOG = LoggerFactory.getLogger(HomeController.class);
1515

16-
@GetMapping("/home")
17-
public String getHome(Model model) {
16+
private void addSharedModelAttributes(Model model) {
1817
model.addAttribute("activePage", "home");
18+
model.addAttribute("titleDisplayName", "Home");
1919
model.addAttribute("footerText", "Explore your knowledge universe");
20+
}
21+
22+
@GetMapping("/home")
23+
public String getHome(Model model) {
24+
addSharedModelAttributes(model);
2025
return "home";
2126
}
2227

2328
@HxRequest
2429
@GetMapping("/home")
2530
public FragmentsRendering getHomeWithFragments(Model model) {
26-
model.addAttribute("titleDisplayName", "Home");
27-
model.addAttribute("activePage", "home");
28-
model.addAttribute("footerText", "Explore your knowledge universe");
31+
addSharedModelAttributes(model);
2932
return FragmentsRendering
3033
.with("home :: main-content")
31-
.fragment("fragments/title :: title-content")
32-
.fragment("fragments/navigation :: navigation-content")
33-
.fragment("fragments/footer :: footer-content")
34+
.fragment("fragments/layout/title :: title-content")
35+
.fragment("fragments/layout/navigation :: navigation-content")
36+
.fragment("fragments/layout/footer :: footer-content")
3437
.build();
3538
}
3639
}

src/main/java/dev/ikm/server/cosmos/portal/PortalController.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,27 @@ public class PortalController {
1313

1414
Logger LOG = LoggerFactory.getLogger(PortalController.class);
1515

16-
@GetMapping("/portal")
17-
public String getQuality(Model model) {
16+
private void addSharedModelAttributes(Model model) {
1817
model.addAttribute("activePage", "portal");
18+
model.addAttribute("titleDisplayName", "Portal");
1919
model.addAttribute("footerText", "Gateway to the Cosmos AI");
20+
}
21+
22+
@GetMapping("/portal")
23+
public String getQuality(Model model) {
24+
addSharedModelAttributes(model);
2025
return "portal";
2126
}
2227

2328
@HxRequest
2429
@GetMapping("/portal")
2530
public FragmentsRendering getQualityWithFragments(Model model) {
26-
model.addAttribute("titleDisplayName", "Portal");
27-
model.addAttribute("activePage", "portal");
28-
model.addAttribute("footerText", "Gateway to the Cosmos AI");
31+
addSharedModelAttributes(model);
2932
return FragmentsRendering
3033
.with("portal :: main-content")
31-
.fragment("fragments/title :: title-content")
32-
.fragment("fragments/navigation :: navigation-content")
33-
.fragment("fragments/footer :: footer-content")
34+
.fragment("fragments/layout/title :: title-content")
35+
.fragment("fragments/layout/navigation :: navigation-content")
36+
.fragment("fragments/layout/footer :: footer-content")
3437
.build();
3538
}
3639
}

src/main/java/dev/ikm/server/cosmos/query/QueryController.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,27 @@ public class QueryController {
1313

1414
Logger LOG = LoggerFactory.getLogger(QueryController.class);
1515

16-
@GetMapping("/query")
17-
public String getQuery(Model model) {
16+
private void addSharedModelAttributes(Model model) {
1817
model.addAttribute("activePage", "query");
18+
model.addAttribute("titleDisplayName", "Query");
1919
model.addAttribute("footerText", "Precise knowledge retrieval");
20+
}
21+
22+
@GetMapping("/query")
23+
public String getQuery(Model model) {
24+
addSharedModelAttributes(model);
2025
return "query";
2126
}
2227

2328
@HxRequest
2429
@GetMapping("/query")
2530
public FragmentsRendering getQueryWithFragments(Model model) {
26-
model.addAttribute("titleDisplayName", "Query");
27-
model.addAttribute("activePage", "query");
28-
model.addAttribute("footerText", "Precise knowledge retrieval");
31+
addSharedModelAttributes(model);
2932
return FragmentsRendering
3033
.with("query :: main-content")
31-
.fragment("fragments/title :: title-content")
32-
.fragment("fragments/navigation :: navigation-content")
33-
.fragment("fragments/footer :: footer-content")
34+
.fragment("fragments/layout/title :: title-content")
35+
.fragment("fragments/layout/navigation :: navigation-content")
36+
.fragment("fragments/layout/footer :: footer-content")
3437
.build();
3538
}
3639
}

src/main/java/dev/ikm/server/cosmos/rules/RulesController.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,27 @@ public class RulesController {
1313

1414
Logger LOG = LoggerFactory.getLogger(RulesController.class);
1515

16-
@GetMapping("/rules")
17-
public String getQuery(Model model) {
16+
private void addSharedModelAttributes(Model model) {
1817
model.addAttribute("activePage", "rules");
18+
model.addAttribute("titleDisplayName", "Rules");
1919
model.addAttribute("footerText", "Automation and logic management");
20+
}
21+
22+
@GetMapping("/rules")
23+
public String getQuery(Model model) {
24+
addSharedModelAttributes(model);
2025
return "rules";
2126
}
2227

2328
@HxRequest
2429
@GetMapping("/rules")
2530
public FragmentsRendering getQueryWithFragments(Model model) {
26-
model.addAttribute("titleDisplayName", "Rules");
27-
model.addAttribute("activePage", "rules");
28-
model.addAttribute("footerText", "Automation and logic management");
31+
addSharedModelAttributes(model);
2932
return FragmentsRendering
3033
.with("rules :: main-content")
31-
.fragment("fragments/title :: title-content")
32-
.fragment("fragments/navigation :: navigation-content")
33-
.fragment("fragments/footer :: footer-content")
34+
.fragment("fragments/layout/title :: title-content")
35+
.fragment("fragments/layout/navigation :: navigation-content")
36+
.fragment("fragments/layout/footer :: footer-content")
3437
.build();
3538
}
3639
}

0 commit comments

Comments
 (0)