feat(scaffold): add native folder picker for Workspace Path selection
Some checks failed
Deploy to OCIWP / deploy (push) Failing after 39s
Some checks failed
Deploy to OCIWP / deploy (push) Failing after 39s
- Added /api/v1/scaffold/browse-folder endpoint in ScaffoldingController to open native JFileChooser. - Updated scaffold.html to use the new API for both Pod Module and Tool Function. - Fixed JS event listener bug where workspacePath changes only affected Pod Module.
This commit is contained in:
@@ -67,12 +67,37 @@ public class ScaffoldingController {
|
||||
String date = req.get("date");
|
||||
if (date == null || date.trim().isEmpty()) date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy.MM.dd"));
|
||||
|
||||
return PodScaffolder.scaffoldPod(moduleName, port, shortName, author, date);
|
||||
String defaultWorkspace = "c:\\eGovFrameDev-4.3.1-64bit\\workspace-egov\\dap-was-dapmt";
|
||||
String workspacePath = req.getOrDefault("workspacePath", defaultWorkspace);
|
||||
if (workspacePath.trim().isEmpty()) {
|
||||
workspacePath = defaultWorkspace;
|
||||
}
|
||||
System.setProperty("AXHUB_SOURCE_DIR", workspacePath);
|
||||
|
||||
return PodScaffolder.scaffoldPod(moduleName, port, shortName, author, date);
|
||||
} catch (Exception e) {
|
||||
return "오류 발생: " + e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/browse-folder")
|
||||
public String browseFolder() {
|
||||
try {
|
||||
System.setProperty("java.awt.headless", "false");
|
||||
javax.swing.JFileChooser chooser = new javax.swing.JFileChooser();
|
||||
chooser.setCurrentDirectory(new java.io.File("c:\\eGovFrameDev-4.3.1-64bit\\workspace-egov"));
|
||||
chooser.setDialogTitle("Select Workspace Folder");
|
||||
chooser.setFileSelectionMode(javax.swing.JFileChooser.DIRECTORIES_ONLY);
|
||||
chooser.setAcceptAllFileFilterUsed(false);
|
||||
if (chooser.showOpenDialog(null) == javax.swing.JFileChooser.APPROVE_OPTION) {
|
||||
return chooser.getSelectedFile().getAbsolutePath();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return "Error: " + e.getMessage();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@PostMapping("/tool")
|
||||
public String scaffoldTool(@RequestBody Map<String, String> req) {
|
||||
try {
|
||||
|
||||
@@ -797,6 +797,35 @@
|
||||
<!-- Pod Creation Form -->
|
||||
<div class="tab-pane fade show active" id="pod" role="tabpanel">
|
||||
<form id="podForm">
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-12">
|
||||
<label class="form-label">Workspace Path</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="workspacePath" id="podWorkspacePathInput" placeholder="직접 폴더 경로를 입력(붙여넣기) 하거나 선택하세요" value="c:\eGovFrameDev-4.3.1-64bit\workspace-egov\dap-was-dapmt">
|
||||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" style="border-color: #3f3f46; color: #a1a1aa;">폴더 선택</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-dark" style="background-color: #18181b; border-color: #3f3f46;">
|
||||
<li><a class="dropdown-item" href="#" onclick="const input = document.getElementById('podWorkspacePathInput'); input.value='c:\\eGovFrameDev-4.3.1-64bit\\workspace-egov\\dap-was-dapmt'; input.dispatchEvent(new Event('change')); return false;" style="color: #f4f4f5;">dap-was-dapmt (기본)</a></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="const input = document.getElementById('podWorkspacePathInput'); input.value='c:\\eGovFrameDev-4.3.1-64bit\\workspace-egov\\axhub-backend-main'; input.dispatchEvent(new Event('change')); return false;" style="color: #f4f4f5;">axhub-backend-main</a></li>
|
||||
<li><hr class="dropdown-divider" style="border-color: #3f3f46;"></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="openServerFolderPicker('podWorkspacePathInput'); return false;" style="color: #f4f4f5;">폴더 선택(+)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="file" id="podFolderPicker" webkitdirectory directory style="display: none;" onchange="
|
||||
if(this.files && this.files.length > 0) { alert("Path: " + this.files[0].path + ", webkitRel: " + this.files[0].webkitRelativePath + ", name: " + this.files[0].name); if(this.files[0].path) {
|
||||
let firstFilePath = this.files[0].path;
|
||||
let relPath = this.files[0].webkitRelativePath;
|
||||
let folderPath = firstFilePath.substring(0, firstFilePath.length - relPath.length);
|
||||
if (folderPath.endsWith('\\') || folderPath.endsWith('/')) {
|
||||
folderPath = folderPath.substring(0, folderPath.length - 1);
|
||||
}
|
||||
const input = document.getElementById('podWorkspacePathInput');
|
||||
input.value = folderPath;
|
||||
input.dispatchEvent(new Event('change'));
|
||||
}
|
||||
">
|
||||
<div class="input-hint">직접 경로를 붙여넣거나 우측 <b>[폴더 선택]</b> 버튼을 눌러 선택하세요.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label">Module Name</label>
|
||||
<input type="text" class="form-control" name="moduleName" placeholder="e.g. hr (will be prefixed with axhub-tool-)" required>
|
||||
@@ -834,8 +863,23 @@
|
||||
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-dark" style="background-color: #18181b; border-color: #3f3f46;">
|
||||
<li><a class="dropdown-item" href="#" onclick="const input = document.getElementById('workspacePathInput'); input.value='c:\\eGovFrameDev-4.3.1-64bit\\workspace-egov\\dap-was-dapmt'; input.dispatchEvent(new Event('change')); return false;" style="color: #f4f4f5;">dap-was-dapmt (기본)</a></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="const input = document.getElementById('workspacePathInput'); input.value='c:\\eGovFrameDev-4.3.1-64bit\\workspace-egov\\axhub-backend-main'; input.dispatchEvent(new Event('change')); return false;" style="color: #f4f4f5;">axhub-backend-main</a></li>
|
||||
<li><hr class="dropdown-divider" style="border-color: #3f3f46;"></li>
|
||||
<li><a class="dropdown-item" href="#" onclick="openServerFolderPicker('workspacePathInput'); return false;" style="color: #f4f4f5;">폴더 선택(+)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="file" id="toolFolderPicker" webkitdirectory directory style="display: none;" onchange="
|
||||
if(this.files && this.files.length > 0) { alert("Path: " + this.files[0].path + ", webkitRel: " + this.files[0].webkitRelativePath + ", name: " + this.files[0].name); if(this.files[0].path) {
|
||||
let firstFilePath = this.files[0].path;
|
||||
let relPath = this.files[0].webkitRelativePath;
|
||||
let folderPath = firstFilePath.substring(0, firstFilePath.length - relPath.length);
|
||||
if (folderPath.endsWith('\\') || folderPath.endsWith('/')) {
|
||||
folderPath = folderPath.substring(0, folderPath.length - 1);
|
||||
}
|
||||
const input = document.getElementById('workspacePathInput');
|
||||
input.value = folderPath;
|
||||
input.dispatchEvent(new Event('change'));
|
||||
}
|
||||
">
|
||||
<div class="input-hint">직접 경로를 붙여넣거나 우측 <b>[폴더 선택]</b> 버튼을 눌러 선택하세요.</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1536,7 +1580,7 @@
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const loadModules = () => {
|
||||
const workspacePath = document.querySelector('input[name="workspacePath"]')?.value || '';
|
||||
const workspacePath = document.querySelector('#toolForm input[name="workspacePath"]')?.value || document.querySelector('input[name="workspacePath"]')?.value || '';
|
||||
fetch(`/api/v1/scaffold/modules?workspacePath=${encodeURIComponent(workspacePath)}`)
|
||||
.then(res => res.json())
|
||||
.then(modules => {
|
||||
@@ -1551,11 +1595,11 @@
|
||||
.catch(err => console.error('Failed to load modules:', err));
|
||||
};
|
||||
loadModules();
|
||||
const wsInput = document.querySelector('input[name="workspacePath"]');
|
||||
if (wsInput) {
|
||||
wsInput.addEventListener('change', loadModules);
|
||||
wsInput.addEventListener('blur', loadModules); // Typing custom path and clicking away
|
||||
}
|
||||
const wsInputs = document.querySelectorAll('input[name="workspacePath"]');
|
||||
wsInputs.forEach(wsInput => {
|
||||
wsInput.addEventListener('change', loadModules);
|
||||
wsInput.addEventListener('blur', loadModules);
|
||||
});
|
||||
});
|
||||
|
||||
handleFormSubmit('podForm', '/api/v1/scaffold/pod');
|
||||
@@ -1626,7 +1670,7 @@
|
||||
|
||||
async function loadUseCasesForSelection() {
|
||||
const moduleName = document.getElementById('targetModuleSelect').value;
|
||||
const workspacePath = document.querySelector('input[name="workspacePath"]')?.value || '';
|
||||
const workspacePath = document.querySelector('#toolForm input[name="workspacePath"]')?.value || document.querySelector('input[name="workspacePath"]')?.value || '';
|
||||
const categoryKey = document.querySelector('#toolForm [name="categoryKey"]').value.trim();
|
||||
const select = document.getElementById('toolGroupUseCaseSelect');
|
||||
select.innerHTML = '<option value="">새 UseCase 생성</option>';
|
||||
@@ -1643,7 +1687,7 @@
|
||||
|
||||
async function loadCategoriesForSelection() {
|
||||
const moduleName = document.getElementById('targetModuleSelect').value;
|
||||
const workspacePath = document.querySelector('input[name="workspacePath"]')?.value || '';
|
||||
const workspacePath = document.querySelector('#toolForm input[name="workspacePath"]')?.value || document.querySelector('input[name="workspacePath"]')?.value || '';
|
||||
const select = document.getElementById('domainCategorySelect');
|
||||
const nameInput = document.getElementById('domainCategoryName');
|
||||
select.innerHTML = '<option value="">새 도메인 생성</option>';
|
||||
@@ -2348,5 +2392,22 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
function openServerFolderPicker(inputId) {
|
||||
fetch("/api/v1/scaffold/browse-folder")
|
||||
.then(res => res.text())
|
||||
.then(path => {
|
||||
if(path && !path.startsWith("Error:") && path !== "") {
|
||||
const input = document.getElementById(inputId);
|
||||
input.value = path;
|
||||
input.dispatchEvent(new Event("change"));
|
||||
} else if (path.startsWith("Error:")) {
|
||||
alert(path);
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user