Skip to content

Commit 5908f23

Browse files
committed
837 | Added a metabase dashboard and advanced questions in it
1 parent 568a05d commit 5908f23

13 files changed

+352
-13
lines changed

avni-server-api/src/main/java/org/avni/server/dao/metabase/DatabaseRepository.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public void createAdvancedQuestion(Database database) {
155155
.withVisualization(VisualizationType.PIE);
156156
MetabaseQuery query = createAdvancedQuery("individual", "subject_type", config, database);
157157
postQuestion(
158-
"Pie Chart : Count of Non Voided Individuals - Non Voided Subject Type",
158+
QuestionName.QUESTION_1.getQuestionName(),
159159
query,
160160
config,
161161
getCollectionForDatabase(database).getIdAsInt()
@@ -174,7 +174,7 @@ public void createAdvancedQuestion2(Database database) {
174174
.withVisualization(VisualizationType.PIE);
175175
MetabaseQuery query = createAdvancedQuery("program_enrolment", "program", config, database);
176176
postQuestion(
177-
"Pie Chart : Number of Non exited and Non voided Enrollments for Non Voided Program ",
177+
QuestionName.QUESTION_2.getQuestionName(),
178178
query,
179179
config,
180180
getCollectionForDatabase(database).getIdAsInt()

avni-server-api/src/main/java/org/avni/server/dao/metabase/MetabaseConnector.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.avni.server.dao.metabase;
22

33
import org.avni.server.domain.metabase.GroupPermissionsBody;
4+
import org.avni.server.util.ObjectMapperSingleton;
45
import org.springframework.beans.factory.annotation.Value;
56
import org.springframework.boot.web.client.RestTemplateBuilder;
67
import org.springframework.http.HttpEntity;
@@ -38,9 +39,14 @@ protected <T> HttpEntity<T> createHttpEntity(T body) {
3839
return new HttpEntity<>(body, headers);
3940
}
4041

41-
protected void sendPutRequest(String url, Map<String, ?> requestBody) {
42-
HttpEntity<Map<String, ?>> entity = createHttpEntity(requestBody);
43-
restTemplate.exchange(url, HttpMethod.PUT, entity, Map.class);
42+
protected void sendPutRequest(String url, Object requestBody) {
43+
try {
44+
String jsonBody = ObjectMapperSingleton.getObjectMapper().writeValueAsString(requestBody);
45+
HttpEntity<String> entity = createHttpEntity(jsonBody);
46+
restTemplate.exchange(url, HttpMethod.PUT, entity, String.class);
47+
} catch (Exception e) {
48+
throw new RuntimeException("Error serializing request body to JSON", e);
49+
}
4450
}
4551

4652
public <T> T postForObject(String url, Object request, Class<T> responseType) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package org.avni.server.dao.metabase;
2+
3+
import org.avni.server.domain.metabase.*;
4+
import org.springframework.boot.web.client.RestTemplateBuilder;
5+
import org.springframework.stereotype.Repository;
6+
7+
import java.util.List;
8+
9+
10+
@Repository
11+
public class MetabaseDashboardRepository extends MetabaseConnector {
12+
private final DatabaseRepository databaseRepository;
13+
14+
public MetabaseDashboardRepository(RestTemplateBuilder restTemplateBuilder , DatabaseRepository databaseRepository) {
15+
super(restTemplateBuilder);
16+
this.databaseRepository = databaseRepository;
17+
}
18+
19+
public Dashboard save(CreateDashboardRequest createDashboardRequest) {
20+
String url = metabaseApiUrl + "/dashboard";
21+
return postForObject(url, createDashboardRequest, Dashboard.class);
22+
}
23+
24+
25+
public CollectionItem getDashboardByName(CollectionInfoResponse globalCollection) {
26+
List<CollectionItem> items = databaseRepository.getExistingCollectionItems(globalCollection.getIdAsInt());
27+
28+
return items.stream()
29+
.filter(item -> item.getName().equals(globalCollection.getName()))
30+
.findFirst()
31+
.orElse(null);
32+
}
33+
34+
public void updateDashboard(int dashboardId, DashboardUpdateRequest request) {
35+
String url = metabaseApiUrl + "/dashboard/" + dashboardId;
36+
sendPutRequest(url, request);
37+
}
38+
}

avni-server-api/src/main/java/org/avni/server/domain/metabase/CollectionItem.java

+9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
@JsonIgnoreProperties(ignoreUnknown = true)
66
public class CollectionItem {
77
private String name;
8+
9+
public CollectionItem() {
10+
}
11+
12+
public CollectionItem(String name, int id) {
13+
this.name = name;
14+
this.id = id;
15+
}
16+
817
private int id;
918

1019
public String getName() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.avni.server.domain.metabase;
2+
3+
public class CreateDashboardRequest {
4+
private final String name;
5+
private final String description;
6+
private final Integer collection_id;
7+
8+
public CreateDashboardRequest(String name, String description, Integer collection_id) {
9+
this.name = name;
10+
this.description = description;
11+
this.collection_id = collection_id;
12+
}
13+
14+
public String getName() {
15+
return name;
16+
}
17+
18+
public String getDescription() {
19+
return description;
20+
}
21+
22+
public Integer getCollection_id() {
23+
return collection_id;
24+
}
25+
26+
@Override
27+
public String toString() {
28+
return "{" +
29+
"name='" + name + '\'' +
30+
", description='" + description + '\'' +
31+
", collectionId=" + collection_id +
32+
'}';
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.avni.server.domain.metabase;
2+
3+
import org.springframework.stereotype.Component;
4+
5+
@Component
6+
public class Dashboard {
7+
private int id;
8+
private String name;
9+
10+
public int getId() {
11+
return id;
12+
}
13+
14+
public String getName() {
15+
return name;
16+
}
17+
18+
@Override
19+
public String toString() {
20+
return "Dashboard{" +
21+
"id=" + id +
22+
", name='" + name + '\'' +
23+
'}';
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package org.avni.server.domain.metabase;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
6+
@JsonIgnoreProperties(ignoreUnknown = true)
7+
public class DashboardResponse {
8+
9+
private String name;
10+
private String id;
11+
12+
public DashboardResponse() {
13+
}
14+
15+
public DashboardResponse(@JsonProperty("name") String name,
16+
@JsonProperty("id") Object id) {
17+
this.name = name;
18+
19+
if (id instanceof Integer) {
20+
this.id = String.valueOf(id);
21+
} else {
22+
this.id = id.toString();
23+
}
24+
}
25+
26+
public String getName() {
27+
return name;
28+
}
29+
30+
public void setName(String name) {
31+
this.name = name;
32+
}
33+
34+
public String getId() {
35+
return id;
36+
}
37+
38+
public int getIdAsInt() {
39+
try {
40+
return Integer.parseInt(id);
41+
} catch (NumberFormatException e) {
42+
throw new RuntimeException("Failed to convert id to integer: " + id, e);
43+
}
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.avni.server.domain.metabase;
2+
3+
import java.util.List;
4+
5+
public class DashboardUpdateRequest {
6+
private final List<Dashcard> dashcards;
7+
8+
public DashboardUpdateRequest(List<Dashcard> dashcards) {
9+
this.dashcards = dashcards;
10+
}
11+
12+
13+
public List<Dashcard> getDashcards() {
14+
return dashcards;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package org.avni.server.domain.metabase;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
import java.util.Collections;
6+
import java.util.List;
7+
8+
public class Dashcard {
9+
@JsonProperty("id")
10+
private int dashboardId;
11+
12+
@JsonProperty("card_id")
13+
private int cardId;
14+
15+
@JsonProperty("dashboard_tab_id")
16+
private Integer dashboardTabId;
17+
18+
private int row;
19+
private int col;
20+
21+
@JsonProperty("size_x")
22+
private int sizeX;
23+
24+
@JsonProperty("size_y")
25+
private int sizeY;
26+
27+
@JsonProperty("visualization_settings")
28+
private Object visualizationSettings;
29+
30+
@JsonProperty("parameter_mappings")
31+
private List<Object> parameterMappings;
32+
33+
public Dashcard(int dashboardId, int cardId, Integer dashboardTabId, int row, int col, int sizeX, int sizeY) {
34+
this.dashboardId = dashboardId;
35+
this.cardId = cardId;
36+
this.dashboardTabId = dashboardTabId;
37+
this.row = row;
38+
this.col = col;
39+
this.sizeX = sizeX;
40+
this.sizeY = sizeY;
41+
this.visualizationSettings = Collections.emptyMap();
42+
this.parameterMappings = Collections.emptyList();
43+
}
44+
45+
public int getDashboardId() {
46+
return dashboardId;
47+
}
48+
49+
public int getCardId() {
50+
return cardId;
51+
}
52+
53+
public Integer getDashboardTabId() {
54+
return dashboardTabId;
55+
}
56+
57+
public int getRow() {
58+
return row;
59+
}
60+
61+
public int getCol() {
62+
return col;
63+
}
64+
65+
public int getSizeX() {
66+
return sizeX;
67+
}
68+
69+
public int getSizeY() {
70+
return sizeY;
71+
}
72+
73+
@Override
74+
public String toString() {
75+
return "{" +
76+
"dashboardId=" + dashboardId +
77+
", cardId=" + cardId +
78+
", dashboardTabId=" + dashboardTabId +
79+
", row=" + row +
80+
", col=" + col +
81+
", sizeX=" + sizeX +
82+
", sizeY=" + sizeY +
83+
", visualizationSettings=" + visualizationSettings +
84+
", parameterMappings=" + parameterMappings +
85+
'}';
86+
}
87+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.avni.server.domain.metabase;
2+
3+
public enum QuestionName {
4+
QUESTION_1("Pie Chart : Count of Non Voided Individuals - Non Voided Subject Type"),
5+
QUESTION_2("Pie Chart : Number of Non exited and Non voided Enrollments for Non Voided Program");
6+
7+
private final String questionName;
8+
9+
QuestionName(String questionName) {
10+
this.questionName = questionName;
11+
}
12+
13+
public String getQuestionName() {
14+
return questionName;
15+
}
16+
}

0 commit comments

Comments
 (0)