Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/#80 Project, App View 생성 #106

Merged
merged 15 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions logbat_meta/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ dependencies {
// MySQL Connector
runtimeOnly 'com.mysql:mysql-connector-j'

// JSP 관련 종속성 추가
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.1'
implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1'

// SpringBoot Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@SpringBootApplication
public class LogbatMetaApplication {
Expand All @@ -10,4 +12,13 @@ public static void main(String[] args) {
SpringApplication.run(LogbatMetaApplication.class, args);
}

@Controller
public static class HomeController {

@GetMapping("/")
public String home() {
return "redirect:/projects";
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ public class AppService {
private final AppJpaRepository appRepository;
private final ProjectJpaRepository projectRepository;

public AppCommonResponse createApp(Long projectId, String appTypeStr) {
public AppCommonResponse createApp(Long projectId, String name, String appTypeStr) {
Project project = getProject(projectId);
AppType appType = AppType.from(appTypeStr);
return AppCommonResponse.from(appRepository.save(App.of(project, appType)));
return AppCommonResponse.from(appRepository.save(App.of(project, name, appType)));
}

@Transactional(readOnly = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public class App {
@JoinColumn(name = "project_id", nullable = false)
private Project project;

@Column(name = "name", nullable = false)
private String name;

@Enumerated(EnumType.STRING)
@Column(name = "app_type", nullable = false)
private AppType appType;
Expand All @@ -40,14 +43,15 @@ public class App {
@Column(name = "created_at", nullable = false)
private LocalDateTime createdAt;

private App(Project project, AppType appType) {
private App(Project project, String name, AppType appType) {
this.project = Objects.requireNonNull(project, "프로젝트는 필수입니다.");
this.name = Objects.requireNonNull(name, "앱 이름은 필수입니다.");
this.appType = Objects.requireNonNull(appType, "앱 타입은 필수입니다.");
this.appKey = UUID.randomUUID();
}

public static App of(Project project, AppType appType) {
return new App(project, appType);
public static App of(Project project, String name, AppType appType) {
return new App(project, name, appType);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public ApiCommonResponse<AppCommonResponse> getAppById(@PathVariable Long appId)
public ApiCommonResponse<AppCommonResponse> createApp(
@PathVariable Long projectId,
@RequestBody AppCreateRequest appCreateRequest) {
AppCommonResponse app = appService.createApp(projectId, appCreateRequest.appType());
AppCommonResponse app = appService.createApp(projectId, appCreateRequest.name(), appCreateRequest.appType());

return ApiCommonResponse.createSuccessResponse(app);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package info.logbat_meta.domain.project.presentation;

import info.logbat_meta.domain.project.application.AppService;
import info.logbat_meta.domain.project.application.ProjectService;
import info.logbat_meta.domain.project.domain.enums.AppType;
import info.logbat_meta.domain.project.presentation.payload.response.AppCommonResponse;
import info.logbat_meta.domain.project.presentation.payload.response.ProjectCommonResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@Controller
@RequestMapping("/projects")
@RequiredArgsConstructor
public class ViewController {

private final ProjectService projectService;
private final AppService appService;

@GetMapping
public String projects() {
return "projects";
}

@GetMapping("/search")
public String searchProjectByName(@RequestParam String name, Model model) {
// 프로젝트가 없으면, IllegalArgumentException 발생
ProjectCommonResponse project;

try {
project = projectService.getProjectByName(name);
} catch (IllegalArgumentException e) {
return "project_not_found";
}

model.addAttribute("project", project);

List<AppCommonResponse> apps = appService.getAppsByProjectId(project.getId());
model.addAttribute("apps", apps);

return "project_detail";
}

@GetMapping("/create")
public String createProject() {
return "create_project";
}

@PostMapping("/create")
public String createProject(@RequestParam String name) {
projectService.createProject(name);
return "redirect:/projects/search?name=" + name;
}

@PostMapping("/apps/create")
public String createApp(
@RequestParam Long projectId,
@RequestParam(defaultValue = "") String name,
@RequestParam(defaultValue = "") String appType,
Model model
) {
if (projectId == null) {
return "redirect:/";
}

model.addAttribute("appTypes", AppType.values()); // Enum 값들을 모델에 추가

ProjectCommonResponse project = projectService.getProjectById(projectId);
model.addAttribute("project", project);
if (name.isBlank() || appType.isBlank()) {
return "create_app";
}
appService.createApp(projectId, name, appType);
return "redirect:/projects/search?name=" + projectService.getProjectById(projectId).getName();
}

@GetMapping("/{projectId}/apps/{appId}/delete")
public String deleteApp(
@PathVariable Long projectId,
@PathVariable Long appId
) {
ProjectCommonResponse project = projectService.getProjectById(projectId);
appService.deleteApp(project.getId(), appId);
return "redirect:/projects/search?name=" + project.getName();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package info.logbat_meta.domain.project.presentation.payload.request;

public record AppCreateRequest(String appType) {
public record AppCreateRequest(
String name,
String appType
) {

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
package info.logbat_meta.domain.project.presentation.payload.response;

import info.logbat_meta.domain.project.domain.App;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.time.LocalDateTime;

public record AppCommonResponse(Long id, Long projectId, String appType, String token,
LocalDateTime createdAt) {
@Getter
@RequiredArgsConstructor
public class AppCommonResponse {
private final Long id;
private final Long projectId;
private final String name;
private final String appType;
private final String token;
private final LocalDateTime createdAt;

public static AppCommonResponse from(App app) {
return new AppCommonResponse(app.getId(), app.getProject().getId(), app.getAppType().name(),
app.getAppKey().toString(), app.getCreatedAt());
return new AppCommonResponse(app.getId(), app.getProject().getId(), app.getName(), app.getAppType().name(),
app.getAppKey().toString(), app.getCreatedAt());
}
}

Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package info.logbat_meta.domain.project.presentation.payload.response;

import info.logbat_meta.domain.project.domain.Project;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.time.LocalDateTime;

public record ProjectCommonResponse(Long id, String name, LocalDateTime createdAt,
LocalDateTime updatedAt) {
@Getter
@RequiredArgsConstructor
public class ProjectCommonResponse {
private final Long id;
private final String name;
private final LocalDateTime createdAt;
private final LocalDateTime updatedAt;

public static ProjectCommonResponse from(Project project) {
return new ProjectCommonResponse(project.getId(), project.getName(), project.getCreatedAt(),
project.getUpdatedAt());
project.getUpdatedAt());
}
}
4 changes: 4 additions & 0 deletions logbat_meta/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
spring:
application:
name: logbat_meta
mvc:
view:
prefix: /WEB-INF/views/
suffix: .jsp

profiles:
active: local
Expand Down
13 changes: 13 additions & 0 deletions logbat_meta/src/main/webapp/WEB-INF/views/common_head.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<title>Log Bat</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
>
</head>
35 changes: 35 additions & 0 deletions logbat_meta/src/main/webapp/WEB-INF/views/create_app.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/common_head.jsp" %>
<body>
<main class="container">
<header>
<h1>Create New App for Project: ${project.name}</h1>
</header>

<section>
<form action="${pageContext.request.contextPath}/projects/apps/create" method="post">
<input type="hidden" name="projectId" value="${project.id}">

<label for="appName">App Name:</label>
<input type="text" id="appName" name="name" required>

<label for="appType">App Type:</label>
<select id="appType" name="appType" required>
<c:forEach items="${appTypes}" var="type">
<option value="${type}">${type}</option>
</c:forEach>
</select>

<%-- <label for="appDescription">App Description:</label>--%>
<%-- <textarea id="appDescription" name="description" rows="4"></textarea>--%>

<button type="submit">Create App</button>
</form>
</section>

<nav>
<a href="${pageContext.request.contextPath}/projects/search?name=${project.name}" role="button" class="secondary">Back to Project Details</a>
</nav>
</main>
</body>
</html>
29 changes: 29 additions & 0 deletions logbat_meta/src/main/webapp/WEB-INF/views/create_project.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/common_head.jsp" %>
<body>
<main class="container">
<header>
<h1>Create New Project</h1>
</header>

<section>
<form action="${pageContext.request.contextPath}/projects/create" method="post">
<label for="projectName">Project Name:</label>
<input type="text" id="projectName" name="name" required>

<%-- <label for="projectDescription">Project Description:</label>--%>
<%-- <textarea id="projectDescription" name="description" rows="4"></textarea>--%>

<%-- <label for="projectOwner">Project Owner:</label>--%>
<%-- <input type="text" id="projectOwner" name="owner" required>--%>

<button type="submit">Create Project</button>
</form>
</section>

<nav>
<a href="projects/search" role="button" class="secondary">Back to Search</a>
</nav>
</main>
</body>
</html>
58 changes: 58 additions & 0 deletions logbat_meta/src/main/webapp/WEB-INF/views/project_detail.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/common_head.jsp" %>
<body>
<main class="container">
<header>
<h1>Project Details: ${project.name}</h1>
</header>

<nav>
<ul>
<li><a href="https://view.logbat.info" role="button">모니터링 화면 보기</a></li>
</ul>
</nav>

<section>
<h2>Apps</h2>
<table>
<thead>
<tr>
<th>App Name</th>
<th>App Key</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<c:forEach var="app" items="${apps}">
<tr>
<td>${app.name}</td>
<td>${app.token}</td>
<td>
<%-- <a href="v1/projects/apps/info/${app.id}">View</a>--%>
<%-- <a href="v1/projects/apps/update/${app.id}">Edit</a>--%>
<a href="#" onclick="confirmDelete('${app.name}', '${pageContext.request.contextPath}/projects/${project.id}/apps/${app.id}/delete'); return false;">Delete</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</section>

<footer>
<form action="${pageContext.request.contextPath}/projects/apps/create" method="post">
<input type="hidden" name="projectId" value="${project.id}">
<button type="submit" >Create New App</button>
</form>
</footer>
</main>

<script>
function confirmDelete(appName, deleteUrl) {
if (confirm("정말로 '" + appName + "' 앱을 삭제하시겠습니까?")) {
window.location.href = deleteUrl;
}
}
</script>

</body>
</html>
Loading
Loading