Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 55a74654db | |||
| 7473334714 |
+4
-202
@@ -3927,7 +3927,6 @@ def upload_admin():
|
||||
"""
|
||||
Upload page route for inventory items.
|
||||
Accessible to users with insert permission.
|
||||
Supports duplication by passing duplicate_from parameter.
|
||||
|
||||
Returns:
|
||||
flask.Response: Rendered template or redirect
|
||||
@@ -3940,54 +3939,9 @@ def upload_admin():
|
||||
flash('Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', 'error')
|
||||
return redirect(url_for('login'))
|
||||
|
||||
# Check if this is a duplication request
|
||||
duplicate_from = request.args.get('duplicate_from')
|
||||
duplicate_flag = request.args.get('duplicate') # Check for sessionStorage-based duplication
|
||||
duplicate_data = None
|
||||
|
||||
# Handle the old method (duplicate_from parameter with item ID)
|
||||
if duplicate_from:
|
||||
try:
|
||||
original_item = it.get_item(duplicate_from)
|
||||
if original_item:
|
||||
duplicate_data = {
|
||||
'name': original_item.get('Name', ''),
|
||||
'description': original_item.get('Beschreibung', ''),
|
||||
'location': original_item.get('Ort', ''),
|
||||
'room': original_item.get('Raum', ''),
|
||||
'category': original_item.get('Kategorie', ''),
|
||||
'year': original_item.get('Anschaffungsjahr', ''),
|
||||
'cost': original_item.get('Anschaffungskosten', ''),
|
||||
'filter1': original_item.get('Filter1', ''),
|
||||
'filter2': original_item.get('Filter2', ''),
|
||||
'filter3': original_item.get('Filter3', ''),
|
||||
'images': original_item.get('Images', []),
|
||||
'original_id': duplicate_from
|
||||
}
|
||||
# Copy all filter fields (Filter1_1 through Filter3_5)
|
||||
for i in range(1, 4): # Filter1, Filter2, Filter3
|
||||
for j in range(1, 6): # _1 through _5
|
||||
filter_key = f'Filter{i}_{j}'
|
||||
if filter_key in original_item:
|
||||
duplicate_data[f'filter{i}_{j}'] = original_item[filter_key]
|
||||
|
||||
flash('Element wird dupliziert. Bitte überprüfen Sie die Daten und passen Sie sie bei Bedarf an.', 'info')
|
||||
else:
|
||||
flash('Ursprungs-Element für Duplizierung nicht gefunden.', 'error')
|
||||
except Exception as e:
|
||||
app.logger.warning(f"Error loading item for duplication: {e}")
|
||||
flash('Fehler beim Laden der Duplizierungsdaten.', 'error')
|
||||
|
||||
# Handle the new method (sessionStorage-based duplication)
|
||||
elif duplicate_flag == 'true':
|
||||
# No server-side processing needed - JavaScript will handle sessionStorage data
|
||||
# Just indicate that duplication mode is active
|
||||
flash('Element wird dupliziert. Die Daten werden aus dem Session-Speicher geladen.', 'info')
|
||||
|
||||
return render_template(
|
||||
'upload_admin.html',
|
||||
username=session['username'],
|
||||
duplicate_data=duplicate_data,
|
||||
library_module_enabled=cfg.MODULES.is_enabled('library'),
|
||||
student_cards_module_enabled=cfg.MODULES.is_enabled('student_cards'),
|
||||
show_library_features=False,
|
||||
@@ -4014,46 +3968,9 @@ def library_admin():
|
||||
flash('Bibliotheks-Modul ist deaktiviert.', 'error')
|
||||
return redirect(url_for('home_admin'))
|
||||
|
||||
duplicate_from = request.args.get('duplicate_from')
|
||||
duplicate_flag = request.args.get('duplicate')
|
||||
duplicate_data = None
|
||||
|
||||
if duplicate_from:
|
||||
try:
|
||||
original_item = it.get_item(duplicate_from)
|
||||
if original_item:
|
||||
duplicate_data = {
|
||||
'name': original_item.get('Name', ''),
|
||||
'description': original_item.get('Beschreibung', ''),
|
||||
'location': original_item.get('Ort', ''),
|
||||
'room': original_item.get('Raum', ''),
|
||||
'category': original_item.get('Kategorie', ''),
|
||||
'year': original_item.get('Anschaffungsjahr', ''),
|
||||
'cost': original_item.get('Anschaffungskosten', ''),
|
||||
'filter1': original_item.get('Filter1', ''),
|
||||
'filter2': original_item.get('Filter2', ''),
|
||||
'filter3': original_item.get('Filter3', ''),
|
||||
'images': original_item.get('Images', []),
|
||||
'original_id': duplicate_from
|
||||
}
|
||||
for i in range(1, 4):
|
||||
for j in range(1, 6):
|
||||
filter_key = f'Filter{i}_{j}'
|
||||
if filter_key in original_item:
|
||||
duplicate_data[f'filter{i}_{j}'] = original_item[filter_key]
|
||||
flash('Buch wird dupliziert. Bitte überprüfen Sie die Daten und passen Sie sie bei Bedarf an.', 'info')
|
||||
else:
|
||||
flash('Ursprungs-Element für Duplizierung nicht gefunden.', 'error')
|
||||
except Exception as e:
|
||||
app.logger.warning(f"Error loading item for duplication: {e}")
|
||||
flash('Fehler beim Laden der Duplizierungsdaten.', 'error')
|
||||
elif duplicate_flag == 'true':
|
||||
flash('Buch wird dupliziert. Die Daten werden aus dem Session-Speicher geladen.', 'info')
|
||||
|
||||
return render_template(
|
||||
'upload_admin.html',
|
||||
username=session['username'],
|
||||
duplicate_data=duplicate_data,
|
||||
library_module_enabled=cfg.MODULES.is_enabled('library'),
|
||||
student_cards_module_enabled=cfg.MODULES.is_enabled('student_cards'),
|
||||
show_library_features=True,
|
||||
@@ -5388,18 +5305,18 @@ def upload_item():
|
||||
individual_codes = []
|
||||
if individual_codes_raw:
|
||||
individual_codes = [c.strip() for c in str(individual_codes_raw).replace(',', '\n').splitlines() if c.strip()]
|
||||
|
||||
|
||||
|
||||
# Check if this is a duplication
|
||||
is_duplicating = request.form.get('is_duplicating') == 'true'
|
||||
|
||||
|
||||
# Get duplicate_images if duplicating
|
||||
duplicate_images = request.form.getlist('duplicate_images') if is_duplicating else []
|
||||
|
||||
|
||||
# Make sure duplicate_images is always a list, even if there's only one
|
||||
if is_duplicating and duplicate_images and not isinstance(duplicate_images, list):
|
||||
duplicate_images = [duplicate_images]
|
||||
|
||||
|
||||
# Log details about each image
|
||||
if is_duplicating and duplicate_images:
|
||||
for i, img in enumerate(duplicate_images):
|
||||
@@ -5819,121 +5736,6 @@ def upload_item():
|
||||
flash(error_msg, 'error')
|
||||
return redirect(url_for(success_redirect_endpoint))
|
||||
|
||||
|
||||
@app.route('/duplicate_item', methods=['POST'])
|
||||
def duplicate_item():
|
||||
"""
|
||||
Route for duplicating an existing item.
|
||||
Returns JSON response with success status.
|
||||
Enhanced for mobile browser compatibility.
|
||||
|
||||
Returns:
|
||||
flask.Response: JSON response with success status and data
|
||||
"""
|
||||
try:
|
||||
# Check authentication
|
||||
if 'username' not in session:
|
||||
return jsonify({'success': False, 'message': 'Nicht angemeldet'}), 401
|
||||
|
||||
# Check if user is admin
|
||||
username = session['username']
|
||||
current_permissions = us.get_effective_permissions(session['username'])
|
||||
|
||||
if not current_permissions['actions'].get('can_edit', False):
|
||||
flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error')
|
||||
return redirect(url_for('home_admin'))
|
||||
|
||||
# Detect if request is from mobile device
|
||||
is_mobile = 'Mobile' in request.headers.get('User-Agent', '')
|
||||
is_ios = 'iPhone' in request.headers.get('User-Agent', '') or 'iPad' in request.headers.get('User-Agent', '')
|
||||
|
||||
# Log mobile duplication for debugging
|
||||
if is_mobile:
|
||||
app.logger.info(f"Mobile duplication from {request.headers.get('User-Agent', 'unknown')} by {encrypt_text(username)}")
|
||||
|
||||
# Get original item ID
|
||||
original_item_id = request.form.get('original_item_id')
|
||||
if not original_item_id:
|
||||
return jsonify({'success': False, 'message': 'Ursprungs-Element-ID fehlt'}), 400
|
||||
|
||||
# Fetch original item data
|
||||
original_item = it.get_item(original_item_id)
|
||||
if not original_item:
|
||||
return jsonify({'success': False, 'message': 'Ursprungs-Element nicht gefunden'}), 404
|
||||
|
||||
# Process filters as arrays (same as stored in database)
|
||||
filter1_array = original_item.get('Filter', [])
|
||||
filter2_array = original_item.get('Filter2', [])
|
||||
filter3_array = original_item.get('Filter3', [])
|
||||
|
||||
# Ensure filters are arrays
|
||||
if not isinstance(filter1_array, list):
|
||||
filter1_array = [filter1_array] if filter1_array else []
|
||||
if not isinstance(filter2_array, list):
|
||||
filter2_array = [filter2_array] if filter2_array else []
|
||||
if not isinstance(filter3_array, list):
|
||||
filter3_array = [filter3_array] if filter3_array else []
|
||||
|
||||
# Verify image paths for mobile devices to avoid issues with non-existent images
|
||||
images = original_item.get('Images', [])
|
||||
verified_images = []
|
||||
|
||||
if is_mobile:
|
||||
for img in images:
|
||||
img_path = os.path.join(app.config['UPLOAD_FOLDER'], img)
|
||||
if os.path.exists(img_path) and os.path.isfile(img_path):
|
||||
verified_images.append(img)
|
||||
else:
|
||||
app.logger.warning(f"Image not found for duplication: {img}")
|
||||
|
||||
# If we lost images in verification, log it
|
||||
if len(verified_images) < len(images):
|
||||
app.logger.warning(f"Only {len(verified_images)} of {len(images)} images verified for mobile duplication")
|
||||
else:
|
||||
verified_images = images
|
||||
|
||||
# For iOS devices, add more diagnostics and reduce data size if needed
|
||||
if is_ios:
|
||||
# Check if images exist (we now use main images as thumbnails)
|
||||
images_exist = []
|
||||
for img in verified_images[:5]: # Only check first 5 to save time
|
||||
img_path = os.path.join(app.config['UPLOAD_FOLDER'], img)
|
||||
if os.path.exists(img_path):
|
||||
images_exist.append(True)
|
||||
else:
|
||||
images_exist.append(False)
|
||||
|
||||
# Log detailed diagnostics
|
||||
app.logger.info(f"iOS duplication details: {len(verified_images)} images, "
|
||||
f"images available: {all(images_exist)}, "
|
||||
f"filter sizes: {len(filter1_array)}, {len(filter2_array)}, {len(filter3_array)}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': 'Duplizierungsdaten erfolgreich vorbereitet',
|
||||
'item_data': {
|
||||
'name': original_item.get('Name', ''),
|
||||
'description': original_item.get('Beschreibung', ''),
|
||||
'location': original_item.get('Ort', ''),
|
||||
'room': original_item.get('Raum', ''),
|
||||
'category': original_item.get('Kategorie', ''),
|
||||
'year': original_item.get('Anschaffungsjahr', ''),
|
||||
'cost': original_item.get('Anschaffungskosten', ''),
|
||||
'filter1': filter1_array,
|
||||
'filter2': filter2_array,
|
||||
'filter3': filter3_array,
|
||||
'images': verified_images, # Using verified images instead of original
|
||||
'isMobile': is_mobile,
|
||||
'isIOS': is_ios
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error in duplicate_item: {e}")
|
||||
|
||||
return jsonify({'success': False, 'message': 'Serverfehler beim Duplizieren'}), 500
|
||||
|
||||
|
||||
def _soft_delete_item_groups(db, root_item_ids, username):
|
||||
"""Soft-delete one or more item groups and their borrow records."""
|
||||
now = datetime.datetime.now()
|
||||
|
||||
@@ -939,7 +939,7 @@
|
||||
const response = await fetch(`/api/is_student_card/${encodeURIComponent(code)}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
'Content-Type': 'application/json',
|
||||
// Falls du in Flask CSRF-Protect nutzt, muss der Token mitgesendet werden:
|
||||
'X-CSRFToken': '{{ csrf_token }}',
|
||||
'X-CSRF-Token': '{{ csrf_token }}'
|
||||
|
||||
@@ -819,7 +819,7 @@
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .duplicate-button, .schedule-button, .damage-button {
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .schedule-button, .damage-button {
|
||||
padding: 10px 18px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
@@ -942,27 +942,6 @@
|
||||
box-shadow: 0 2px 4px rgba(23, 162, 184, 0.3);
|
||||
}
|
||||
|
||||
/* Duplicate Button */
|
||||
.duplicate-button {
|
||||
background-color: #6f42c1;
|
||||
color: white;
|
||||
border: 2px solid #6f42c1;
|
||||
}
|
||||
|
||||
.duplicate-button:hover {
|
||||
background-color: #5a32a3;
|
||||
border-color: #4e2a8e;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 8px rgba(111, 66, 193, 0.3);
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.duplicate-button:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 4px rgba(111, 66, 193, 0.3);
|
||||
}
|
||||
|
||||
.damage-button {
|
||||
background-color: #fd7e14;
|
||||
color: white;
|
||||
@@ -1645,7 +1624,7 @@
|
||||
gap: 10px !important;
|
||||
}
|
||||
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .duplicate-button, .schedule-button {
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .schedule-button {
|
||||
width: 100% !important;
|
||||
min-height: 44px !important;
|
||||
padding: 12px 20px !important;
|
||||
@@ -1777,7 +1756,7 @@
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .duplicate-button, .schedule-button {
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .schedule-button {
|
||||
padding: 10px 20px;
|
||||
font-size: 0.9rem;
|
||||
min-width: 110px;
|
||||
@@ -1790,7 +1769,7 @@
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .duplicate-button, .schedule-button {
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .schedule-button {
|
||||
padding: 8px 16px;
|
||||
font-size: 0.85rem;
|
||||
min-width: 95px;
|
||||
@@ -1808,7 +1787,7 @@
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .duplicate-button, .schedule-button {
|
||||
.ausleihen, .edit-button, .delete-button, .details-button, .schedule-button {
|
||||
padding: 12px 24px;
|
||||
font-size: 1rem;
|
||||
min-width: 120px;
|
||||
@@ -1980,7 +1959,7 @@
|
||||
}
|
||||
|
||||
/* Standardize form and document buttons */
|
||||
.save-button, .cancel-button, .remove-book-cover-button, .remove-duplicate-image-button,
|
||||
.save-button, .cancel-button, .remove-book-cover-button,
|
||||
.import-book-button, .fetch-isbn-button, .nav-back-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -3465,9 +3444,6 @@ document.addEventListener('DOMContentLoaded', ()=>{
|
||||
{% if current_permissions.actions.get('can_edit', False) %}
|
||||
<button class="edit-button" onclick="openEditModalForSelectedUnit('${item._id}', 'specific-item-card-${item._id}')">Bearbeiten</button>
|
||||
{% endif %}
|
||||
{% if current_permissions.actions.get('can_insert', False) %}
|
||||
<button class="duplicate-button" onclick="duplicateItem('${item._id}')">Duplizieren</button>
|
||||
{% endif %}
|
||||
{% if current_permissions.pages.get('admin_school_settings', False) %}
|
||||
${canScheduleItem ? `<button class="schedule-button" onclick="openScheduleModal('${item._id}')">Reservieren</button>` : ''}
|
||||
{% endif %}
|
||||
@@ -4244,7 +4220,6 @@ document.addEventListener('DOMContentLoaded', ()=>{
|
||||
: `<button class="ausleihen disabled-button" disabled>Ausgeliehen</button>`
|
||||
}
|
||||
<button class="edit-button" onclick="openEditModalForSelectedUnit('${item._id}', 'specific-item-modal-${item._id}')">Bearbeiten</button>
|
||||
<button class="duplicate-button" onclick="duplicateItem('${item._id}')">Duplizieren</button>
|
||||
${damageReports && damageReports.length > 0 ? `<button class="damage-button" onclick="markDamageAsRepaired('${item._id}')">Repariert</button>` : `<button class="damage-button" onclick="registerDamage('${item._id}')">Schaden melden</button>`}
|
||||
${canScheduleItem ? `<button class="schedule-button" onclick="openScheduleModal('${item._id}')">Reservieren</button>` : ''}
|
||||
<form method="POST" action="/delete_item/${item._id}" style="display:inline;" onsubmit="return confirm('Sind Sie sicher?')">
|
||||
@@ -5044,55 +5019,6 @@ document.addEventListener('DOMContentLoaded', ()=>{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Duplication function
|
||||
function duplicateItem(itemId) {
|
||||
// Show loading indicator
|
||||
const loadingDiv = document.createElement('div');
|
||||
loadingDiv.innerHTML = `
|
||||
<div style="position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
||||
background: rgba(0,0,0,0.5); z-index: 10000; display: flex;
|
||||
align-items: center; justify-content: center;">
|
||||
<div class="modal-dialog-white">
|
||||
<div>Element wird dupliziert...</div>
|
||||
<div class="modal-content-margin">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(loadingDiv);
|
||||
|
||||
// Create form data for the duplicate_item request
|
||||
const formData = new FormData();
|
||||
formData.append('original_item_id', itemId);
|
||||
|
||||
// Send duplication request to get item data
|
||||
fetch('/duplicate_item', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
document.body.removeChild(loadingDiv);
|
||||
|
||||
if (data.success) {
|
||||
// Store duplication data in sessionStorage for the upload page
|
||||
sessionStorage.setItem('duplicateItemData', JSON.stringify(data.item_data));
|
||||
|
||||
// Redirect to upload admin page
|
||||
window.location.href = '/upload_admin?duplicate=true';
|
||||
} else {
|
||||
alert('Fehler beim Duplizieren: ' + (data.message || 'Unbekannter Fehler'));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
document.body.removeChild(loadingDiv);
|
||||
console.error('Error duplicating item:', error);
|
||||
alert('Fehler beim Duplizieren des Elements. Bitte versuchen Sie es erneut.');
|
||||
});
|
||||
}
|
||||
|
||||
// Helper functions for appointment display
|
||||
function formatAppointmentDate(dateString) {
|
||||
if (!dateString) return '';
|
||||
|
||||
@@ -11,59 +11,6 @@
|
||||
{% block title %}{{ page_title|default('Artikel hochladen') }} - Inventarsystem{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if duplicate_data and duplicate_data.images %}
|
||||
<!-- Hidden server-side values for duplication, will be processed by JavaScript -->
|
||||
<div id="server-duplicate-data"
|
||||
data-name="{{ duplicate_data.name|default('') }}"
|
||||
data-description="{{ duplicate_data.description|default('') }}"
|
||||
data-location="{{ duplicate_data.location|default('') }}"
|
||||
data-room="{{ duplicate_data.room|default('') }}"
|
||||
data-year="{{ duplicate_data.year|default('') }}"
|
||||
data-cost="{{ duplicate_data.cost|default('') }}"
|
||||
data-images="{{ duplicate_data.images|tojson|safe }}"
|
||||
data-filter1="{{ duplicate_data.filter1|tojson|safe if duplicate_data.filter1 else '[]' }}"
|
||||
data-filter2="{{ duplicate_data.filter2|tojson|safe if duplicate_data.filter2 else '[]' }}"
|
||||
data-filter3="{{ duplicate_data.filter3|tojson|safe if duplicate_data.filter3 else '[]' }}"
|
||||
data-original-id="{{ duplicate_data.original_id|default('') }}"
|
||||
style="display:none;">
|
||||
</div>
|
||||
<script>
|
||||
// Pre-initialize duplicate data from server
|
||||
var serverDuplicateData = null;
|
||||
const dataElement = document.getElementById('server-duplicate-data');
|
||||
if (dataElement) {
|
||||
// Safely parse JSON arrays with error handling
|
||||
function safeJsonParse(jsonStr, defaultValue = []) {
|
||||
try {
|
||||
if (!jsonStr) return defaultValue;
|
||||
return JSON.parse(jsonStr);
|
||||
} catch (e) {
|
||||
console.error("Error parsing JSON:", e, "Value was:", jsonStr);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Get images data and log it for debugging
|
||||
const imagesData = dataElement.getAttribute('data-images') || "[]";
|
||||
console.log("Raw images data attribute:", imagesData);
|
||||
|
||||
serverDuplicateData = {
|
||||
name: dataElement.getAttribute('data-name') || "",
|
||||
description: dataElement.getAttribute('data-description') || "",
|
||||
location: dataElement.getAttribute('data-location') || "",
|
||||
room: dataElement.getAttribute('data-room') || "",
|
||||
year: dataElement.getAttribute('data-year') || "",
|
||||
cost: dataElement.getAttribute('data-cost') || "",
|
||||
images: safeJsonParse(imagesData),
|
||||
filter1: safeJsonParse(dataElement.getAttribute('data-filter1')),
|
||||
filter2: safeJsonParse(dataElement.getAttribute('data-filter2')),
|
||||
filter3: safeJsonParse(dataElement.getAttribute('data-filter3')),
|
||||
original_id: dataElement.getAttribute('data-original-id') || ""
|
||||
};
|
||||
console.log("Server-provided duplicate data:", serverDuplicateData);
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
<style>
|
||||
/* Book information display styles */
|
||||
@@ -296,38 +243,11 @@
|
||||
color: #721c24 !important;
|
||||
}
|
||||
|
||||
/* Duplicate code popup styling */
|
||||
.popup-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
z-index: 10000;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
animation: overlayFadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes overlayFadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.duplicate-code-popup {
|
||||
background-color: white;
|
||||
padding: 30px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3);
|
||||
max-width: 500px;
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
animation: popupSlideIn 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes popupSlideIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
@@ -1878,11 +1798,11 @@
|
||||
if (existingPopup) {
|
||||
existingPopup.remove();
|
||||
}
|
||||
|
||||
|
||||
// Create popup overlay
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'popup-overlay';
|
||||
|
||||
|
||||
// Create popup content
|
||||
overlay.innerHTML = `
|
||||
<div class="duplicate-code-popup">
|
||||
@@ -1895,9 +1815,9 @@
|
||||
<button class="popup-close-button" onclick="this.closest('.popup-overlay').remove()">Verstanden</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
|
||||
// Auto-remove after 10 seconds
|
||||
setTimeout(() => {
|
||||
if (overlay.parentNode) {
|
||||
@@ -2049,34 +1969,6 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Handle duplication data if available (from sessionStorage or server)
|
||||
if (typeof prefillFormWithDuplicateData === 'function') {
|
||||
setTimeout(() => {
|
||||
prefillFormWithDuplicateData();
|
||||
}, 500); // Wait for all dropdowns to load
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize duplication data - handle both server-side and sessionStorage data
|
||||
let duplicateData = null;
|
||||
|
||||
// First check if serverDuplicateData is defined by the script above
|
||||
if (typeof serverDuplicateData !== 'undefined' && serverDuplicateData) {
|
||||
console.log("Using server-provided duplicateData:", serverDuplicateData);
|
||||
duplicateData = serverDuplicateData;
|
||||
|
||||
// Ensure images is properly handled as an array
|
||||
if (duplicateData.images) {
|
||||
if (typeof duplicateData.images === 'string') {
|
||||
try {
|
||||
duplicateData.images = JSON.parse(duplicateData.images);
|
||||
} catch (e) {
|
||||
console.error("Error parsing duplicate images array:", e);
|
||||
}
|
||||
}
|
||||
console.log("Parsed duplicate images successfully.");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user