This commit is contained in:
mindol1004
2024-10-18 18:01:26 +09:00
parent 62e15760bf
commit ac844f4ca3
12 changed files with 71 additions and 36 deletions

View File

@@ -3,7 +3,7 @@
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layouts/signin-layout}" lang="ko" xml:lang="ko">
<head>
<title>로그인 페이지</title>
<title>Sign In</title>
</head>
<body>
<section layout:fragment="content">

View File

@@ -77,7 +77,7 @@ public class QuartzConfig {
factory.setDataSource(dataSource);
factory.setTransactionManager(transactionManager);
factory.setJobFactory(jobFactory);
factory.setAutoStartup(false);
factory.setAutoStartup(true);
factory.setWaitForJobsToCompleteOnShutdown(true);
return factory;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 355 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -13,18 +13,18 @@ const scheduleService = {
},
pauseJob: async (groupName, jobName) => {
const response = await apiClient.get(`/api/schedule/pause/${groupName}/${jobName}`);
return response.data.data;
await apiClient.get(`/api/schedule/pause/${groupName}/${jobName}`);
return true;
},
resumeJob: async (groupName, jobName) => {
const response = await apiClient.get(`/api/schedule/resume/${groupName}/${jobName}`);
return response.data.data;
await apiClient.get(`/api/schedule/resume/${groupName}/${jobName}`);
return true;
},
triggerJob: async (groupName, jobName) => {
const response = await apiClient.get(`/api/schedule/trigger/${groupName}/${jobName}`);
return response.data.data;
await apiClient.get(`/api/schedule/trigger/${groupName}/${jobName}`);
return true;
},
rescheduleJob: async (jobGroup, jobName, cronExpression) => {

View File

@@ -6,6 +6,7 @@ let selectedMonth;
document.addEventListener('DOMContentLoaded', () => {
initMonthPicker();
fetchDataAndRender();
setupEventListeners();
});
const initMonthPicker = () => {
@@ -38,6 +39,12 @@ const fetchDataAndRender = async () => {
renderRecentJobsTable(recentJobs);
};
const setupEventListeners = () => {
document.getElementById('refreshBtn').addEventListener('click', async (e) => {
fetchDataAndRender();
});
};
const chartOptions = {
responsive: true,
maintainAspectRatio: false,

View File

@@ -1,16 +1,17 @@
import signService from '../../apis/sign-api.js';
document.addEventListener('DOMContentLoaded', () => {
const signOutButton = document.getElementById('signOut');
const toggleSidebar = document.getElementById('toggleSidebar');
setupEventListeners();
});
signOutButton.addEventListener('click', (e) => {
const setupEventListeners = () => {
document.getElementById('signOut').addEventListener('click', (e) => {
e.preventDefault();
signService.signOut();
});
toggleSidebar.addEventListener('click', (e) => {
document.getElementById('toggleSidebar').addEventListener('click', () => {
const body = document.body;
body.classList.toggle("toggle-sidebar");
});
});
};

View File

@@ -12,7 +12,12 @@ const setupEventListeners = () => {
e.preventDefault();
fetchDataAndRender();
});
document.getElementById('refreshJobBtn').addEventListener('click', refreshJobs);
document.getElementById('refreshJobBtn').addEventListener('click', () => {
const confirmUpdate = confirm('스케줄 재적용 하시겠습니까?');
if (confirmUpdate) {
refreshJobs();
}
});
};
const fetchDataAndRender = async () => {
@@ -99,16 +104,21 @@ const getStatusBadgeClass = (status) => {
const setupDetailModalEventListeners = (group, name) => {
document.getElementById('pauseJobBtn').onclick = () => updateJobStatus(group, name, 'PAUSED', scheduleService.pauseJob);
document.getElementById('resumeJobBtn').onclick = () => updateJobStatus(group, name, 'NORMAL', scheduleService.resumeJob);
document.getElementById('updateCronBtn').onclick = () => updateCronExpression(group, name);
document.getElementById('updateCronBtn').onclick = () => {
const confirmUpdate = confirm('스케줄을 수정하시겠습니까?');
if (confirmUpdate) {
updateCronExpression(group, name);
}
}
};
const updateCronExpression = async (group, name) => {
const newCronExpression = document.getElementById('cronExpression').value;
if (await scheduleService.rescheduleJob(group, name, newCronExpression)) {
alert('스케이 수정 되었습니다.');
alert('스케이 수정 되었습니다.');
fetchDataAndRender();
} else {
alert('스케 수정이 실패했습니다.');
alert('스케 수정이 실패했습니다.');
}
};
@@ -128,7 +138,8 @@ const updateJobControlButtons = (status) => {
};
const updateJobStatus = async (group, name, newStatus, action) => {
if (await action(group, name)) {
const result = await action(group, name);
if (result) {
const statusElement = document.querySelector('#scheduleDetailContent .badge');
statusElement.className = `badge ${getStatusBadgeClass(newStatus)}`;
statusElement.textContent = newStatus;

View File

@@ -6,6 +6,7 @@ let users = [];
document.addEventListener('DOMContentLoaded', () => {
fetchDataAndRender();
setupEventListeners();
manageTooltips.init();
});
const setupEventListeners = () => {
@@ -77,6 +78,7 @@ const updateUser = async () => {
await userService.changeRoleApprove(getModifiedRows(users, updatedUsers, "id"));
alert('회원정보가 수정 되었습니다.');
manageTooltips.hideAll();
fetchDataAndRender();
};
@@ -84,4 +86,15 @@ const deleteUser = async (id) => {
await userService.deleteUser(id);
alert('사용자가 삭제되었습니다.');
fetchDataAndRender();
};
const manageTooltips = {
init: () => {
document.querySelectorAll('[data-bs-toggle="tooltip"]')
.forEach(el => new bootstrap.Tooltip(el));
},
hideAll: () => {
const tooltip = bootstrap.Tooltip.getInstance('#updateUserBtn');
setTimeout(() => tooltip.hide(), 100);
}
};

View File

@@ -25,11 +25,14 @@
</div>
<section class="section">
<div class="row mb-4">
<div class="col-md-4">
<div class="input-group">
<div class="col-md-4 d-flex align-items-center">
<div class="input-group me-2">
<span class="input-group-text"><i class="bi bi-calendar-month"></i></span>
<input type="month" id="monthPicker" class="form-control">
</div>
<button id="refreshBtn" class="btn btn-sm btn-outline-primary" title="재조회">
<i class="bi bi-arrow-clockwise"></i>
</button>
</div>
</div>
<div class="row">
@@ -86,10 +89,10 @@
<table class="table table-hover">
<thead>
<tr>
<th class="col-1 text-nowrap sticky-top bg-light"><i class="bi bi-people"></i> 그룹명</th>
<th class="col-1 text-nowrap sticky-top bg-light"><i class="bi bi-briefcase"></i> 잡 이름</th>
<th class="col-1 text-nowrap sticky-top bg-light"><i class="bi bi-calendar-event me-2"></i> 실행 시간</th>
<th class="col-1 text-nowrap sticky-top bg-light"><i class="bi bi-activity"></i> 상태</th>
<th class="col-1 text-nowrap bg-light"><i class="bi bi-people"></i> 그룹명</th>
<th class="col-1 text-nowrap bg-light"><i class="bi bi-briefcase"></i> 잡 이름</th>
<th class="col-1 text-nowrap bg-light"><i class="bi bi-calendar-event me-2"></i> 실행 시간</th>
<th class="col-1 text-nowrap bg-light"><i class="bi bi-activity"></i> 상태</th>
</tr>
</thead>
<tbody id="recentJobsTable">

View File

@@ -64,11 +64,11 @@
<table class="table table-hover">
<thead>
<tr>
<th class="col-1 text-nowrap sticky-top bg-light"><i class="bi bi-people"></i> 그룹</th>
<th class="col-1 text-nowrap sticky-top bg-light"><i class="bi bi-briefcase"></i> 잡 이름</th>
<th class="col-1 text-nowrap sticky-top bg-light"><i class="bi bi-calendar-event"></i> 스케줄</th>
<th class="col-1 text-nowrap sticky-top bg-light"><i class="bi bi-activity"></i> 상태</th>
<th class="col-1 text-nowrap sticky-top bg-light"><i class="bi bi-gear"></i> 액션</th>
<th class="col-1 text-nowrap bg-light"><i class="bi bi-people"></i> 그룹</th>
<th class="col-1 text-nowrap bg-light"><i class="bi bi-briefcase"></i> 잡 이름</th>
<th class="col-1 text-nowrap bg-light"><i class="bi bi-calendar-event"></i> 스케줄</th>
<th class="col-1 text-nowrap bg-light"><i class="bi bi-activity"></i> 상태</th>
<th class="col-1 text-nowrap bg-light"><i class="bi bi-gear"></i> 액션</th>
</tr>
</thead>
<tbody>
@@ -81,7 +81,7 @@
</div>
</section>
<div class="modal fade" id="scheduleDetailModal" tabindex="-1" aria-labelledby="scheduleDetailModalLabel" aria-hidden="true">
<div class="modal fade" id="scheduleDetailModal" tabindex="-1" aria-labelledby="scheduleDetailModalLabel" aria-hidden="true" data-bs-backdrop="static">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-dark text-white">

View File

@@ -3,7 +3,7 @@
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layouts/signin-layout}" lang="ko" xml:lang="ko">
<head>
<title>로그인 페이지</title>
<title>Sign In</title>
</head>
<body>
<section layout:fragment="content">
@@ -13,8 +13,8 @@
<div class="card shadow-sm">
<div class="card-body p-5">
<div class="text-center mb-4">
<i class="bi bi-person-circle text-primary" style="font-size: 3rem;"></i>
<h2 class="card-title mt-3">Sign in to NXCUS-Agent</h2>
<i class="bi bi-person-bounding-box text-primary" style="font-size: 4rem;"></i>
<h2 class="card-title mt-3" style="font-weight: bold;">Sign in to NXCUS-Agent</h2>
</div>
<div class="mb-3">
<div class="input-group">
@@ -52,7 +52,7 @@
</div>
<!-- 회원가입 모달 -->
<div class="modal fade" id="signupModal" tabindex="-1" aria-labelledby="signupModalLabel" aria-hidden="true">
<div class="modal fade" id="signupModal" tabindex="-1" aria-labelledby="signupModalLabel" aria-hidden="true" data-bs-backdrop="static">
<div class="modal-dialog modal-dialog-scrollable modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-dark text-white">
@@ -108,7 +108,7 @@
</div>
<!-- 비밀번호 변경 모달 -->
<div class="modal fade" id="changePasswordModal" tabindex="-1" aria-labelledby="changePasswordModalLabel" aria-hidden="true">
<div class="modal fade" id="changePasswordModal" tabindex="-1" aria-labelledby="changePasswordModalLabel" aria-hidden="true" data-bs-backdrop="static">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-info text-white">

View File

@@ -4,7 +4,7 @@
layout:decorate="~{layouts/layout}"
layout:fragment="content" lang="ko" xml:lang="ko">
<head>
<title>사용자 관리</title>
<title>User Management</title>
</head>
<body>
<main id="main" class="main">