mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 11:51:10 -05:00
Add version control context processor and integrate map functionality with dedicated JavaScript
This commit is contained in:
181
static/css/version-control.css
Normal file
181
static/css/version-control.css
Normal file
@@ -0,0 +1,181 @@
|
||||
/* Version Control System Styles */
|
||||
|
||||
.version-control-ui {
|
||||
--vcs-primary: #3b82f6;
|
||||
--vcs-success: #10b981;
|
||||
--vcs-warning: #f59e0b;
|
||||
--vcs-error: #ef4444;
|
||||
--vcs-gray: #6b7280;
|
||||
}
|
||||
|
||||
/* Branch Status Indicators */
|
||||
.branch-indicator {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.branch-indicator.active {
|
||||
background-color: rgba(16, 185, 129, 0.1);
|
||||
color: var(--vcs-success);
|
||||
}
|
||||
|
||||
.branch-indicator.inactive {
|
||||
background-color: rgba(107, 114, 128, 0.1);
|
||||
color: var(--vcs-gray);
|
||||
}
|
||||
|
||||
/* Change Status Tags */
|
||||
.change-status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 0.375rem;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.change-status.applied {
|
||||
background-color: rgba(16, 185, 129, 0.1);
|
||||
color: var(--vcs-success);
|
||||
}
|
||||
|
||||
.change-status.pending {
|
||||
background-color: rgba(245, 158, 11, 0.1);
|
||||
color: var(--vcs-warning);
|
||||
}
|
||||
|
||||
.change-status.failed {
|
||||
background-color: rgba(239, 68, 68, 0.1);
|
||||
color: var(--vcs-error);
|
||||
}
|
||||
|
||||
/* Change History */
|
||||
.change-history {
|
||||
border-left: 2px solid #e5e7eb;
|
||||
margin-left: 1rem;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
.change-history-item {
|
||||
position: relative;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.change-history-item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -1.25rem;
|
||||
top: 1.5rem;
|
||||
height: 0.75rem;
|
||||
width: 0.75rem;
|
||||
border-radius: 9999px;
|
||||
background-color: white;
|
||||
border: 2px solid var(--vcs-primary);
|
||||
}
|
||||
|
||||
/* Merge Interface */
|
||||
.merge-conflict {
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 0.5rem;
|
||||
margin: 1rem 0;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.merge-conflict-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.merge-conflict-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.merge-version {
|
||||
background-color: #f9fafb;
|
||||
padding: 1rem;
|
||||
border-radius: 0.375rem;
|
||||
}
|
||||
|
||||
/* Branch Selection */
|
||||
.branch-selector {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.branch-list {
|
||||
max-height: 24rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.branch-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.375rem;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.branch-item:hover {
|
||||
background-color: #f9fafb;
|
||||
}
|
||||
|
||||
.branch-item.active {
|
||||
background-color: rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
/* Version Tags */
|
||||
.version-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
background-color: #f3f4f6;
|
||||
color: var(--vcs-gray);
|
||||
font-size: 0.875rem;
|
||||
margin: 0.25rem;
|
||||
}
|
||||
|
||||
/* Loading States */
|
||||
.vcs-loading {
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.vcs-loading::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
border: 2px solid #e5e7eb;
|
||||
border-top-color: var(--vcs-primary);
|
||||
border-radius: 50%;
|
||||
animation: vcs-spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes vcs-spin {
|
||||
to {
|
||||
transform: translate(-50%, -50%) rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 640px) {
|
||||
.merge-conflict-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.branch-selector {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
20
static/js/map-init.js
Normal file
20
static/js/map-init.js
Normal file
@@ -0,0 +1,20 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const mapContainer = document.getElementById('map');
|
||||
if (!mapContainer) return;
|
||||
|
||||
const lat = parseFloat(mapContainer.dataset.lat);
|
||||
const lng = parseFloat(mapContainer.dataset.lng);
|
||||
const name = mapContainer.dataset.name;
|
||||
|
||||
if (isNaN(lat) || isNaN(lng)) return;
|
||||
|
||||
const map = L.map('map').setView([lat, lng], 13);
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap contributors'
|
||||
}).addTo(map);
|
||||
|
||||
L.marker([lat, lng])
|
||||
.addTo(map)
|
||||
.bindPopup(name);
|
||||
});
|
||||
155
static/js/version-control.js
Normal file
155
static/js/version-control.js
Normal file
@@ -0,0 +1,155 @@
|
||||
// Version Control System Functionality
|
||||
|
||||
class VersionControl {
|
||||
constructor() {
|
||||
this.setupEventListeners();
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
// Branch switching
|
||||
document.addEventListener('htmx:afterRequest', (event) => {
|
||||
if (event.detail.target.id === 'branch-form-container') {
|
||||
this.handleBranchFormResponse(event);
|
||||
}
|
||||
});
|
||||
|
||||
// Listen for branch switches
|
||||
document.addEventListener('branch-switched', () => {
|
||||
this.refreshContent();
|
||||
});
|
||||
|
||||
// Handle merge operations
|
||||
document.addEventListener('htmx:afterRequest', (event) => {
|
||||
if (event.detail.target.id === 'merge-panel') {
|
||||
this.handleMergeResponse(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
handleBranchFormResponse(event) {
|
||||
if (event.detail.successful) {
|
||||
// Clear the branch form container
|
||||
document.getElementById('branch-form-container').innerHTML = '';
|
||||
// Trigger branch list refresh
|
||||
document.body.dispatchEvent(new CustomEvent('branch-updated'));
|
||||
}
|
||||
}
|
||||
|
||||
handleMergeResponse(event) {
|
||||
if (event.detail.successful) {
|
||||
const mergePanel = document.getElementById('merge-panel');
|
||||
if (mergePanel.innerHTML.includes('Merge Successful')) {
|
||||
// Trigger content refresh after successful merge
|
||||
setTimeout(() => {
|
||||
this.refreshContent();
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
refreshContent() {
|
||||
// Reload the page to show content from new branch
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// Branch operations
|
||||
createBranch(name, parentBranch = null) {
|
||||
const formData = new FormData();
|
||||
formData.append('name', name);
|
||||
if (parentBranch) {
|
||||
formData.append('parent', parentBranch);
|
||||
}
|
||||
|
||||
return fetch('/vcs/branches/create/', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-CSRFToken': this.getCsrfToken()
|
||||
}
|
||||
}).then(response => response.json());
|
||||
}
|
||||
|
||||
switchBranch(branchName) {
|
||||
const formData = new FormData();
|
||||
formData.append('branch', branchName);
|
||||
|
||||
return fetch('/vcs/branches/switch/', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-CSRFToken': this.getCsrfToken()
|
||||
}
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
document.body.dispatchEvent(new CustomEvent('branch-switched'));
|
||||
}
|
||||
return response.json();
|
||||
});
|
||||
}
|
||||
|
||||
// Merge operations
|
||||
initiateMerge(sourceBranch, targetBranch) {
|
||||
const formData = new FormData();
|
||||
formData.append('source', sourceBranch);
|
||||
formData.append('target', targetBranch);
|
||||
|
||||
return fetch('/vcs/merge/', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-CSRFToken': this.getCsrfToken()
|
||||
}
|
||||
}).then(response => response.json());
|
||||
}
|
||||
|
||||
resolveConflicts(resolutions) {
|
||||
return fetch('/vcs/resolve-conflicts/', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(resolutions),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': this.getCsrfToken()
|
||||
}
|
||||
}).then(response => response.json());
|
||||
}
|
||||
|
||||
// History operations
|
||||
getHistory(branch = null) {
|
||||
let url = '/vcs/history/';
|
||||
if (branch) {
|
||||
url += `?branch=${encodeURIComponent(branch)}`;
|
||||
}
|
||||
|
||||
return fetch(url)
|
||||
.then(response => response.json());
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
getCsrfToken() {
|
||||
return document.querySelector('[name=csrfmiddlewaretoken]').value;
|
||||
}
|
||||
|
||||
showError(message) {
|
||||
const errorDiv = document.createElement('div');
|
||||
errorDiv.className = 'bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4';
|
||||
errorDiv.innerHTML = `
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
<svg class="h-5 w-5 text-red-500" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<p>${message}</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
document.querySelector('.version-control-ui').prepend(errorDiv);
|
||||
setTimeout(() => errorDiv.remove(), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize version control
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
window.versionControl = new VersionControl();
|
||||
});
|
||||
Reference in New Issue
Block a user