edit.html 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>ArduPilot Overlay Manager - Edit</title>
  6. <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
  7. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
  8. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.css">
  9. <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/theme/monokai.min.css">
  10. <style>
  11. html, body { height: 100%; }
  12. body {
  13. display: flex;
  14. flex-direction: column;
  15. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  16. background-color: #f4f6f9;
  17. }
  18. .content-wrapper { flex: 1 0 auto; }
  19. .navbar-brand { font-size: 25px; }
  20. .card { border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.05); border: none;}
  21. footer { flex-shrink: 0; }
  22. .CodeMirror {
  23. height: 600px;
  24. font-size: 14px;
  25. font-family: 'Courier New', Courier, monospace;
  26. border-radius: 0;
  27. }
  28. .profile-list-item.active {
  29. background-color: #0d6efd;
  30. border-color: #0d6efd;
  31. color: white;
  32. }
  33. .profile-list-item.active .text-muted {
  34. color: rgba(255,255,255,0.9) !important;
  35. }
  36. </style>
  37. </head>
  38. <body>
  39. <div class="content-wrapper">
  40. <nav class="navbar navbar-dark bg-dark shadow-sm py-2">
  41. <div class="container-fluid px-4">
  42. <div class="d-flex align-items-center">
  43. <a class="navbar-brand d-flex align-items-center" href="/">
  44. <img src="/static/images/ardupilot_logo.png" alt="ArduPilot" height="24" class="d-inline-block align-text-top me-2">
  45. <span class="text-white">Overlay Manager</span>
  46. </a>
  47. </div>
  48. <div class="ms-auto d-flex align-items-center">
  49. <a href="javascript:void(0);" onclick="window.location.href = window.location.protocol + '//' + window.location.hostname;" class="btn btn-outline-light">
  50. <i class="bi bi-arrow-left me-2"></i>Back to Main App
  51. </a>
  52. </div>
  53. </div>
  54. </nav>
  55. <div class="container-fluid px-4 mt-4">
  56. {% if error_msg %}
  57. <div class="alert alert-danger alert-dismissible fade show shadow-sm" role="alert">
  58. <i class="bi bi-exclamation-triangle-fill me-2"></i>{{ error_msg }}
  59. <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
  60. </div>
  61. {% endif %}
  62. <div class="row g-4">
  63. <div class="col-md-3">
  64. <div class="card mb-4">
  65. <div class="card-header bg-white py-3 d-flex justify-content-between align-items-center">
  66. <h6 class="mb-0 fw-bold text-dark"><i class="bi bi-diagram-3-fill me-2 text-primary"></i>Profiles / Loadouts</h6>
  67. </div>
  68. <div class="list-group list-group-flush">
  69. {% for p in profiles %}
  70. <div class="list-group-item d-flex justify-content-between align-items-center profile-list-item {% if p.id == active_profile.id %}active{% endif %}">
  71. <div class="w-100 fw-bold text-muted {% if p.id == active_profile.id %}text-white{% endif %}">
  72. {{ p.name }}
  73. {% if p.is_readonly %}
  74. <i class="bi bi-shield-lock-fill ms-1" title="Read-Only System Profile"></i>
  75. {% elif p.is_locked %}
  76. <i class="bi bi-lock-fill ms-1" title="User Locked"></i>
  77. {% endif %}
  78. {% if p.id == active_profile.id %}<i class="bi bi-check-circle-fill ms-2"></i>{% endif %}
  79. </div>
  80. </div>
  81. {% endfor %}
  82. </div>
  83. <div class="card-footer bg-light p-3 text-center">
  84. <small class="text-muted"><i class="bi bi-info-circle me-1"></i> Return to the dashboard to switch profiles.</small>
  85. </div>
  86. </div>
  87. </div>
  88. <div class="col-md-9">
  89. <div class="card h-100 mb-5 border-0 shadow-sm">
  90. <div class="card-header bg-white py-3 d-flex justify-content-between align-items-center border-bottom-0">
  91. <h5 class="card-title mb-0 fw-bold text-dark">
  92. <i class="bi bi-pencil-square me-2 text-primary"></i>Editing: <span class="text-primary font-monospace">{{ filepath }}</span>
  93. </h5>
  94. <a href="./" class="btn btn-sm btn-outline-secondary"><i class="bi bi-arrow-left me-1"></i> Back to Loadout</a>
  95. </div>
  96. <div class="card-body p-0">
  97. {% if active_profile.is_readonly or active_profile.is_locked %}
  98. <div class="alert alert-warning m-3 shadow-sm border-0">
  99. <i class="bi bi-lock-fill me-2"></i> This profile is locked or read-only. You can view the file but cannot save changes.
  100. </div>
  101. {% endif %}
  102. <form action="edit" method="post" id="editForm">
  103. <input type="hidden" name="file_id" value="{{ file_id }}">
  104. <textarea id="code-editor" name="content">{{ content }}</textarea>
  105. {% if not active_profile.is_readonly and not active_profile.is_locked %}
  106. <div class="p-3 bg-light text-end rounded-bottom border-top">
  107. <a href="./" class="btn btn-secondary me-2">Cancel</a>
  108. <button type="submit" class="btn btn-success fw-bold"><i class="bi bi-save2-fill me-2"></i> Save Changes to DB</button>
  109. </div>
  110. {% endif %}
  111. </form>
  112. </div>
  113. </div>
  114. </div>
  115. </div>
  116. </div>
  117. </div>
  118. <footer class="py-3 bg-dark text-white-50 mt-auto">
  119. <div class="container-fluid px-4 d-flex justify-content-between">
  120. <div>
  121. <span class="mx-2">Credits: <a href="https://github.com/ArduPilot/CustomBuild/graphs/contributors" style="text-decoration: underline; color: white;">See Contributors</a></span>|
  122. <span class="mx-2">Source: <a href="https://git.equalmass.com/Equalmass/ArdupilotCustomFirmwareBuilder" style="text-decoration: underline; color: white;">Ardupilot/CustomBuild</a></span>
  123. </div>
  124. <span>ArduPilot Overlay Manager</span>
  125. </div>
  126. </footer>
  127. <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
  128. <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.js"></script>
  129. <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/mode/clike/clike.min.js"></script>
  130. <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/mode/python/python.min.js"></script>
  131. <script>
  132. var isLocked = {{ 'true' if active_profile.is_readonly or active_profile.is_locked else 'false' }};
  133. var editor = CodeMirror.fromTextArea(document.getElementById("code-editor"), {
  134. lineNumbers: true,
  135. mode: "text/x-c++src",
  136. theme: "monokai",
  137. matchBrackets: true,
  138. indentUnit: 4,
  139. indentWithTabs: false,
  140. readOnly: isLocked ? "nocursor" : false
  141. });
  142. document.getElementById('editForm').addEventListener('submit', function(e) {
  143. if (isLocked) {
  144. e.preventDefault();
  145. alert('Cannot save. The profile is currently locked.');
  146. } else {
  147. editor.save();
  148. }
  149. });
  150. </script>
  151. </body>
  152. </html>