191 lines
8.6 KiB
Twig
191 lines
8.6 KiB
Twig
|
|
{% extends '@EasyAdmin/page/content.html.twig' %}
|
||
|
|
|
||
|
|
{% block page_title %}
|
||
|
|
<i class="fa fa-cloud-download-alt me-2"></i>eBay Aspects importieren — {{ articleType.name }}
|
||
|
|
<small class="text-muted fw-normal ms-2 fs-6">Kategorie {{ categoryId }}</small>
|
||
|
|
{% endblock %}
|
||
|
|
|
||
|
|
{% block main %}
|
||
|
|
|
||
|
|
<form method="post" id="aspect-import-form">
|
||
|
|
<input type="hidden" name="_token" value="{{ csrf_token('ebay_aspect_import') }}">
|
||
|
|
|
||
|
|
{# ── Summary bar ──────────────────────────────────────────────────── #}
|
||
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
||
|
|
<div class="d-flex gap-2 align-items-center">
|
||
|
|
<span class="badge bg-danger fs-6">{{ counts.required }} Required</span>
|
||
|
|
<span class="badge bg-warning text-dark fs-6">{{ counts.recommended }} Recommended</span>
|
||
|
|
<span class="badge bg-secondary fs-6">{{ counts.optional }} Optional</span>
|
||
|
|
<span class="text-muted small ms-2">Auto-matched {{ rows|filter(r => r.action == 'match')|length }} · Create {{ rows|filter(r => r.action == 'create')|length }} · Skip {{ rows|filter(r => r.action == 'skip')|length }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="d-flex gap-2">
|
||
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" id="btn-select-all-create">All → Create</button>
|
||
|
|
<button type="button" class="btn btn-sm btn-outline-secondary" id="btn-select-all-skip">All → Skip</button>
|
||
|
|
<a href="{{ ea_url().setController('App\\Infrastructure\\Http\\Controller\\Admin\\ArticleTypeCrudController').setAction('index').generateUrl() }}"
|
||
|
|
class="btn btn-sm btn-outline-secondary">
|
||
|
|
<i class="fa fa-arrow-left me-1"></i>Abbrechen
|
||
|
|
</a>
|
||
|
|
<button type="submit" class="btn btn-primary btn-sm">
|
||
|
|
<i class="fa fa-check me-1"></i>Importieren
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{# ── Main table ───────────────────────────────────────────────────── #}
|
||
|
|
<table class="table table-hover align-middle" id="aspects-table">
|
||
|
|
<thead class="table-light">
|
||
|
|
<tr>
|
||
|
|
<th style="width:22%">eBay Aspect</th>
|
||
|
|
<th style="width:10%">Tier</th>
|
||
|
|
<th style="width:28%">eBay-Werte</th>
|
||
|
|
<th style="width:13%">Aktion</th>
|
||
|
|
<th>Attribut / Name + Typ</th>
|
||
|
|
<th style="width:8%" class="text-center">Pflicht?</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
{% for i, row in rows %}
|
||
|
|
{% set aspect = row.aspect %}
|
||
|
|
<tr class="aspect-row{% if row.alreadyAssigned %} table-success{% endif %}" data-index="{{ i }}">
|
||
|
|
|
||
|
|
{# Aspect name #}
|
||
|
|
<td>
|
||
|
|
<span class="fw-medium">{{ aspect.name }}</span>
|
||
|
|
{% if row.alreadyAssigned %}
|
||
|
|
<span class="badge bg-success ms-1" title="Bereits zugewiesen">✓</span>
|
||
|
|
{% endif %}
|
||
|
|
</td>
|
||
|
|
|
||
|
|
{# Tier badge #}
|
||
|
|
<td>
|
||
|
|
{% if aspect.required %}
|
||
|
|
<span class="badge bg-danger">Required</span>
|
||
|
|
{% elseif aspect.usage == 'RECOMMENDED' %}
|
||
|
|
<span class="badge bg-warning text-dark">Recommended</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="badge bg-secondary">Optional</span>
|
||
|
|
{% endif %}
|
||
|
|
</td>
|
||
|
|
|
||
|
|
{# eBay values preview #}
|
||
|
|
<td>
|
||
|
|
{% if aspect.values %}
|
||
|
|
<span class="text-muted small">
|
||
|
|
{{ aspect.values|slice(0, 6)|join(', ') }}{% if aspect.values|length > 6 %} <em>(+{{ aspect.values|length - 6 }} weitere)</em>{% endif %}
|
||
|
|
</span>
|
||
|
|
{% else %}
|
||
|
|
<span class="text-muted small fst-italic">Freitext</span>
|
||
|
|
{% endif %}
|
||
|
|
</td>
|
||
|
|
|
||
|
|
{# Action selector #}
|
||
|
|
<td>
|
||
|
|
<select name="aspects[{{ i }}][action]"
|
||
|
|
class="form-select form-select-sm aspect-action"
|
||
|
|
data-index="{{ i }}">
|
||
|
|
<option value="skip" {% if row.action == 'skip' %}selected{% endif %}>— Überspringen</option>
|
||
|
|
<option value="match" {% if row.action == 'match' %}selected{% endif %}>Vorhandenes verknüpfen</option>
|
||
|
|
<option value="create" {% if row.action == 'create' %}selected{% endif %}>Neu anlegen</option>
|
||
|
|
</select>
|
||
|
|
<input type="hidden" name="aspects[{{ i }}][ebayName]" value="{{ aspect.name }}">
|
||
|
|
<input type="hidden" name="aspects[{{ i }}][ebayValues]" value="{{ aspect.values|join(',') }}">
|
||
|
|
<input type="hidden" name="aspects[{{ i }}][ebayRequired]" value="{{ aspect.required ? '1' : '0' }}">
|
||
|
|
</td>
|
||
|
|
|
||
|
|
{# Attribute input (match or create) #}
|
||
|
|
<td>
|
||
|
|
{# Match: pick existing definition #}
|
||
|
|
<div class="section-match-{{ i }}" style="display:{% if row.action == 'match' %}block{% else %}none{% endif %};">
|
||
|
|
<select name="aspects[{{ i }}][definitionId]" class="form-select form-select-sm">
|
||
|
|
{% for def in allDefs %}
|
||
|
|
<option value="{{ def.id }}" {% if row.preMatchId == def.id|toString %}selected{% endif %}>
|
||
|
|
{{ def.name }} ({{ def.type.value }})
|
||
|
|
</option>
|
||
|
|
{% endfor %}
|
||
|
|
</select>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{# Create: name + type #}
|
||
|
|
<div class="section-create-{{ i }}" style="display:{% if row.action == 'create' %}block{% else %}none{% endif %};">
|
||
|
|
<div class="d-flex gap-1">
|
||
|
|
<input type="text"
|
||
|
|
name="aspects[{{ i }}][name]"
|
||
|
|
value="{{ aspect.name }}"
|
||
|
|
class="form-control form-control-sm flex-grow-1"
|
||
|
|
placeholder="Attribut-Name">
|
||
|
|
<select name="aspects[{{ i }}][type]" class="form-select form-select-sm" style="width:auto;">
|
||
|
|
<option value="string" {% if row.suggestedType == 'string' %}selected{% endif %}>Text</option>
|
||
|
|
<option value="select" {% if row.suggestedType == 'select' %}selected{% endif %}>Select ({{ aspect.values|length }} Werte)</option>
|
||
|
|
<option value="int">Int</option>
|
||
|
|
<option value="float">Float</option>
|
||
|
|
</select>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{# Skip: placeholder #}
|
||
|
|
<div class="section-skip-{{ i }}" style="display:{% if row.action == 'skip' %}block{% else %}none{% endif %};">
|
||
|
|
<span class="text-muted small">—</span>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
|
||
|
|
{# Required checkbox #}
|
||
|
|
<td class="text-center">
|
||
|
|
<div class="section-req-{{ i }}" style="display:{% if row.action != 'skip' %}block{% else %}none{% endif %};">
|
||
|
|
<input type="checkbox"
|
||
|
|
name="aspects[{{ i }}][required]"
|
||
|
|
value="1"
|
||
|
|
class="form-check-input"
|
||
|
|
{% if aspect.required %}checked{% endif %}>
|
||
|
|
</div>
|
||
|
|
</td>
|
||
|
|
|
||
|
|
</tr>
|
||
|
|
{% endfor %}
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
|
||
|
|
<div class="d-flex justify-content-end gap-2 mt-3">
|
||
|
|
<a href="{{ ea_url().setController('App\\Infrastructure\\Http\\Controller\\Admin\\ArticleTypeCrudController').setAction('index').generateUrl() }}"
|
||
|
|
class="btn btn-outline-secondary">Abbrechen</a>
|
||
|
|
<button type="submit" class="btn btn-primary">
|
||
|
|
<i class="fa fa-check me-1"></i>Importieren
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
</form>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
(function () {
|
||
|
|
function syncRow(index, action) {
|
||
|
|
['match', 'create', 'skip'].forEach(s => {
|
||
|
|
const el = document.querySelector(`.section-${s}-${index}`);
|
||
|
|
if (el) el.style.display = s === action ? 'block' : 'none';
|
||
|
|
});
|
||
|
|
const req = document.querySelector(`.section-req-${index}`);
|
||
|
|
if (req) req.style.display = action !== 'skip' ? 'block' : 'none';
|
||
|
|
}
|
||
|
|
|
||
|
|
document.querySelectorAll('.aspect-action').forEach(sel => {
|
||
|
|
sel.addEventListener('change', function () {
|
||
|
|
syncRow(this.dataset.index, this.value);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
document.getElementById('btn-select-all-create').addEventListener('click', () => {
|
||
|
|
document.querySelectorAll('.aspect-action').forEach(sel => {
|
||
|
|
sel.value = 'create';
|
||
|
|
syncRow(sel.dataset.index, 'create');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
document.getElementById('btn-select-all-skip').addEventListener('click', () => {
|
||
|
|
document.querySelectorAll('.aspect-action').forEach(sel => {
|
||
|
|
sel.value = 'skip';
|
||
|
|
syncRow(sel.dataset.index, 'skip');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
})();
|
||
|
|
</script>
|
||
|
|
|
||
|
|
{% endblock %}
|