Update 2025-12-19 16:23:03
This commit is contained in:
@@ -1,26 +1,170 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Edit XML File - Dell Server Info{% endblock %}
|
||||
{% block title %}XML 편집: {{ filename }} - Dell Server Info{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/edit_xml.css') }}">
|
||||
<style>
|
||||
/* 전체 레이아웃 */
|
||||
.editor-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - 160px);
|
||||
/* 헤더/푸터 제외 높이 (조정 가능) */
|
||||
min-height: 600px;
|
||||
background: #fff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 툴바 (헤더) */
|
||||
.editor-toolbar {
|
||||
background-color: #f8fafc;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
padding: 0.75rem 1.5rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.editor-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.editor-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* 에디터 본문 */
|
||||
#monaco-editor-root {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 로딩 인디케이터 */
|
||||
.editor-loading {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
color: #64748b;
|
||||
font-size: 1.2rem;
|
||||
background: #f1f5f9;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="card shadow-lg">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h3>Edit XML File: <strong>{{ filename }}</strong></h3>
|
||||
<div class="container-fluid py-4 h-100">
|
||||
<!-- Breadcrumb / Navigation -->
|
||||
<div class="mb-3 d-flex align-items-center">
|
||||
<a href="{{ url_for('xml.xml_management') }}" class="text-decoration-none text-muted small fw-bold">
|
||||
<i class="bi bi-arrow-left me-1"></i>목록으로 돌아가기
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<div class="form-group">
|
||||
<label for="xmlContent">XML Content</label>
|
||||
<textarea id="xmlContent" name="content" class="form-control" rows="20">{{ content }}</textarea>
|
||||
|
||||
<form id="editorForm" method="post" style="height: 100%;">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
<!-- Monaco Editor의 내용은 submit 시 이 textarea에 동기화됨 -->
|
||||
<textarea name="content" id="hiddenContent" style="display:none;">{{ content }}</textarea>
|
||||
|
||||
<div class="editor-container">
|
||||
<!-- Toolbar -->
|
||||
<div class="editor-toolbar">
|
||||
<div class="editor-title">
|
||||
<i class="bi bi-filetype-xml text-primary fs-4"></i>
|
||||
<span>{{ filename }}</span>
|
||||
<span class="badge bg-light text-secondary border ms-2">XML</span>
|
||||
</div>
|
||||
<div class="editor-actions">
|
||||
<!-- 포맷팅 버튼 (Monaco 기능 호출) -->
|
||||
<button type="button" class="btn btn-white border text-dark btn-sm fw-bold" id="btnFormat">
|
||||
<i class="bi bi-magic me-1 text-info"></i> 자동 정렬
|
||||
</button>
|
||||
<!-- 저장 버튼 -->
|
||||
<button type="submit" class="btn btn-primary btn-sm fw-bold px-4">
|
||||
<i class="bi bi-save me-1"></i> 저장하기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success mt-3">Save Changes</button>
|
||||
<a href="{{ url_for('xml.xml_management') }}" class="btn btn-secondary mt-3">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Editor Area -->
|
||||
<div id="monaco-editor-root">
|
||||
<div class="editor-loading">
|
||||
<div class="spinner-border text-primary me-3" role="status"></div>
|
||||
<div>에디터를 불러오는 중...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<!-- Monaco Editor Loader -->
|
||||
<script src="https://unpkg.com/monaco-editor@0.45.0/min/vs/loader.js"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
if (typeof require === 'undefined') {
|
||||
document.querySelector('.editor-loading').innerHTML =
|
||||
'<div class="text-danger"><i class="bi bi-exclamation-triangle me-2"></i>Monaco Editor를 로드할 수 없습니다. 인터넷 연결을 확인하거나 CDN 차단을 확인하세요.</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
require.config({ paths: { 'vs': 'https://unpkg.com/monaco-editor@0.45.0/min/vs' } });
|
||||
|
||||
require(['vs/editor/editor.main'], function () {
|
||||
// 초기 컨텐츠 가져오기
|
||||
var initialContent = document.getElementById('hiddenContent').value;
|
||||
var container = document.getElementById('monaco-editor-root');
|
||||
|
||||
// 기존 로딩 메시지 제거
|
||||
container.innerHTML = '';
|
||||
|
||||
// 에디터 생성
|
||||
var editor = monaco.editor.create(container, {
|
||||
value: initialContent,
|
||||
language: 'xml',
|
||||
theme: 'vs', // or 'vs-dark'
|
||||
automaticLayout: true,
|
||||
minimap: { enabled: true },
|
||||
fontSize: 14,
|
||||
scrollBeyondLastLine: false,
|
||||
lineNumbers: 'on',
|
||||
formatOnPaste: true,
|
||||
formatOnType: true,
|
||||
wordWrap: 'on'
|
||||
});
|
||||
|
||||
// 1. 폼 제출 시 에디터 내용을 textarea에 동기화
|
||||
document.getElementById('editorForm').addEventListener('submit', function () {
|
||||
document.getElementById('hiddenContent').value = editor.getValue();
|
||||
});
|
||||
|
||||
// 2. 자동 정렬(Format) 버튼 기능 연결
|
||||
document.getElementById('btnFormat').addEventListener('click', function () {
|
||||
editor.getAction('editor.action.formatDocument').run();
|
||||
});
|
||||
|
||||
// 3. Ctrl+S 저장 단축키 지원
|
||||
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, function () {
|
||||
document.getElementById('editorForm').requestSubmit();
|
||||
});
|
||||
|
||||
}, function (err) {
|
||||
// 로드 실패 시 에러 표시
|
||||
document.querySelector('.editor-loading').innerHTML =
|
||||
'<div class="text-danger"><i class="bi bi-exclamation-triangle me-2"></i>에디터 리소스 로드 실패: ' + err.message + '</div>';
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user