snapshot: preserve builder deletion and onboarding ux improvements
This commit is contained in:
@@ -977,6 +977,14 @@ body {
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.builder-card-head-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.builder-entity-card-head strong {
|
||||
color: #142033;
|
||||
font-size: 15px;
|
||||
@@ -1003,6 +1011,7 @@ body {
|
||||
.builder-switch-stack {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
justify-items: end;
|
||||
}
|
||||
|
||||
.builder-switch input[type='checkbox'],
|
||||
@@ -1031,61 +1040,62 @@ body {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.section-rule-grid.drag-over {
|
||||
outline: 1px dashed #9db4d2;
|
||||
outline-offset: 6px;
|
||||
}
|
||||
|
||||
.section-rule-card {
|
||||
display: grid;
|
||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 13px 14px;
|
||||
padding: 14px 16px;
|
||||
border: 1px solid #d6e0ec;
|
||||
border-radius: 14px;
|
||||
background: linear-gradient(180deg, #f9fbff, #ffffff);
|
||||
cursor: move;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(180deg, #fbfdff, #ffffff);
|
||||
transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.section-rule-card:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 10px 20px rgba(15, 23, 42, 0.06);
|
||||
border-color: #b8cae0;
|
||||
box-shadow: 0 14px 24px rgba(15, 23, 42, 0.07);
|
||||
border-color: #b2c6df;
|
||||
}
|
||||
|
||||
.section-rule-card.is-locked {
|
||||
background: linear-gradient(180deg, #f4f7fb, #fafcff);
|
||||
background: linear-gradient(180deg, #f5f8fc, #fbfdff);
|
||||
}
|
||||
|
||||
.section-rule-card.dragging {
|
||||
opacity: 0.58;
|
||||
}
|
||||
|
||||
.section-rule-card.manual-dragging {
|
||||
opacity: 0.72;
|
||||
border-color: #8fb1d8;
|
||||
box-shadow: 0 16px 30px rgba(15, 23, 42, 0.10);
|
||||
}
|
||||
|
||||
.section-rule-drag {
|
||||
color: #8aa0be;
|
||||
font-size: 18px;
|
||||
letter-spacing: -2px;
|
||||
user-select: none;
|
||||
align-self: stretch;
|
||||
.section-rule-actions {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding-right: 2px;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
body.builder-dragging,
|
||||
body.builder-dragging * {
|
||||
cursor: grabbing !important;
|
||||
user-select: none !important;
|
||||
.section-move-btn {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border: 1px solid #cdd9e8;
|
||||
border-radius: 11px;
|
||||
background: linear-gradient(180deg, #ffffff, #f5f9ff);
|
||||
color: #274264;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 6px 12px rgba(15, 23, 42, 0.04);
|
||||
transition: transform 0.16s ease, border-color 0.16s ease, background-color 0.16s ease, box-shadow 0.16s ease;
|
||||
}
|
||||
|
||||
.section-move-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
border-color: #9db4d2;
|
||||
background: linear-gradient(180deg, #ffffff, #eef5ff);
|
||||
box-shadow: 0 10px 16px rgba(15, 23, 42, 0.07);
|
||||
}
|
||||
|
||||
.section-move-btn:disabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.section-rule-copy {
|
||||
@@ -1096,7 +1106,8 @@ body.builder-dragging * {
|
||||
|
||||
.section-rule-copy strong {
|
||||
color: #0f172a;
|
||||
font-size: 14px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
|
||||
@@ -192,6 +192,10 @@ h1 {
|
||||
}
|
||||
|
||||
.section-head {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
border-bottom: 1px dashed #dde4f1;
|
||||
padding-bottom: 8px;
|
||||
@@ -210,6 +214,9 @@ h1 {
|
||||
}
|
||||
|
||||
.section-itsetup .section-head {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
margin: -14px -14px 16px;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid #d5e2f9;
|
||||
@@ -348,6 +355,11 @@ h1 {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
.section-toggle-btn {
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.itsetup-checklist-body {
|
||||
padding: 0;
|
||||
background: #ffffff;
|
||||
|
||||
@@ -148,92 +148,36 @@
|
||||
|
||||
const sectionRuleGrid = document.getElementById('section-rule-grid');
|
||||
if (sectionRuleGrid) {
|
||||
let draggingSectionCard = null;
|
||||
let manualDraggingSectionCard = null;
|
||||
|
||||
function getSectionInsertBeforeNode(mouseY) {
|
||||
const cards = Array.from(sectionRuleGrid.querySelectorAll('.section-rule-card:not(.dragging)'));
|
||||
return cards.find((card) => {
|
||||
const box = card.getBoundingClientRect();
|
||||
return mouseY < box.top + box.height / 2;
|
||||
function updateSectionMoveButtons() {
|
||||
const cards = Array.from(sectionRuleGrid.querySelectorAll('.section-rule-card'));
|
||||
cards.forEach((card, index) => {
|
||||
const upBtn = card.querySelector('[data-move-section="up"]');
|
||||
const downBtn = card.querySelector('[data-move-section="down"]');
|
||||
if (upBtn) upBtn.disabled = index === 0;
|
||||
if (downBtn) downBtn.disabled = index === cards.length - 1;
|
||||
});
|
||||
}
|
||||
|
||||
function getManualSectionInsertBeforeNode(mouseY) {
|
||||
const cards = Array.from(sectionRuleGrid.querySelectorAll('.section-rule-card:not(.manual-dragging)'));
|
||||
return cards.find((card) => {
|
||||
const box = card.getBoundingClientRect();
|
||||
return mouseY < box.top + box.height / 2;
|
||||
});
|
||||
}
|
||||
|
||||
function onManualSectionMove(event) {
|
||||
if (!manualDraggingSectionCard) return;
|
||||
event.preventDefault();
|
||||
sectionRuleGrid.classList.add('drag-over');
|
||||
const beforeNode = getManualSectionInsertBeforeNode(event.clientY);
|
||||
if (beforeNode) {
|
||||
sectionRuleGrid.insertBefore(manualDraggingSectionCard, beforeNode);
|
||||
} else {
|
||||
sectionRuleGrid.appendChild(manualDraggingSectionCard);
|
||||
}
|
||||
}
|
||||
|
||||
function endManualSectionDrag() {
|
||||
if (!manualDraggingSectionCard) return;
|
||||
manualDraggingSectionCard.classList.remove('manual-dragging');
|
||||
manualDraggingSectionCard = null;
|
||||
sectionRuleGrid.classList.remove('drag-over');
|
||||
document.body.classList.remove('builder-dragging');
|
||||
document.removeEventListener('mousemove', onManualSectionMove);
|
||||
document.removeEventListener('mouseup', endManualSectionDrag);
|
||||
}
|
||||
|
||||
sectionRuleGrid.querySelectorAll('.section-rule-card').forEach((card) => {
|
||||
card.addEventListener('dragstart', (event) => {
|
||||
draggingSectionCard = card;
|
||||
card.classList.add('dragging');
|
||||
event.dataTransfer.effectAllowed = 'move';
|
||||
event.dataTransfer.setData('text/plain', card.dataset.sectionKey || '');
|
||||
});
|
||||
card.addEventListener('dragend', () => {
|
||||
card.classList.remove('dragging');
|
||||
sectionRuleGrid.classList.remove('drag-over');
|
||||
draggingSectionCard = null;
|
||||
});
|
||||
const handle = card.querySelector('.section-rule-drag');
|
||||
if (handle) {
|
||||
handle.addEventListener('mousedown', (event) => {
|
||||
event.preventDefault();
|
||||
manualDraggingSectionCard = card;
|
||||
card.classList.add('manual-dragging');
|
||||
sectionRuleGrid.classList.add('drag-over');
|
||||
document.body.classList.add('builder-dragging');
|
||||
document.addEventListener('mousemove', onManualSectionMove);
|
||||
document.addEventListener('mouseup', endManualSectionDrag);
|
||||
});
|
||||
sectionRuleGrid.addEventListener('click', (event) => {
|
||||
const button = event.target.closest('[data-move-section]');
|
||||
if (!button) return;
|
||||
const card = button.closest('.section-rule-card');
|
||||
if (!card) return;
|
||||
const direction = button.dataset.moveSection;
|
||||
if (direction === 'up') {
|
||||
const previousCard = card.previousElementSibling;
|
||||
if (previousCard) {
|
||||
sectionRuleGrid.insertBefore(card, previousCard);
|
||||
}
|
||||
} else if (direction === 'down') {
|
||||
const nextCard = card.nextElementSibling;
|
||||
if (nextCard) {
|
||||
sectionRuleGrid.insertBefore(nextCard, card);
|
||||
}
|
||||
}
|
||||
updateSectionMoveButtons();
|
||||
});
|
||||
|
||||
sectionRuleGrid.addEventListener('dragover', (event) => {
|
||||
event.preventDefault();
|
||||
sectionRuleGrid.classList.add('drag-over');
|
||||
if (!draggingSectionCard) return;
|
||||
const beforeNode = getSectionInsertBeforeNode(event.clientY);
|
||||
if (beforeNode) {
|
||||
sectionRuleGrid.insertBefore(draggingSectionCard, beforeNode);
|
||||
} else {
|
||||
sectionRuleGrid.appendChild(draggingSectionCard);
|
||||
}
|
||||
});
|
||||
|
||||
sectionRuleGrid.addEventListener('dragleave', () => {
|
||||
sectionRuleGrid.classList.remove('drag-over');
|
||||
});
|
||||
|
||||
sectionRuleGrid.addEventListener('drop', (event) => {
|
||||
event.preventDefault();
|
||||
sectionRuleGrid.classList.remove('drag-over');
|
||||
});
|
||||
updateSectionMoveButtons();
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -222,6 +222,45 @@
|
||||
});
|
||||
}
|
||||
|
||||
function setupSectionCheckboxToggles() {
|
||||
document.querySelectorAll('[data-section-checkbox-toggle]').forEach(function (button) {
|
||||
const sectionCard = button.closest('.section-card');
|
||||
if (!sectionCard) return;
|
||||
|
||||
const getCheckboxes = function () {
|
||||
return Array.from(sectionCard.querySelectorAll('.custom-section-checkbox input[type="checkbox"]'));
|
||||
};
|
||||
|
||||
const refreshButtonLabel = function () {
|
||||
const checkboxes = getCheckboxes();
|
||||
if (!checkboxes.length) {
|
||||
button.classList.add('hidden');
|
||||
return;
|
||||
}
|
||||
button.classList.remove('hidden');
|
||||
const allChecked = checkboxes.every(function (box) { return box.checked; });
|
||||
button.textContent = allChecked ? (button.dataset.labelClear || 'Auswahl aufheben') : (button.dataset.labelSelect || 'Alle auswählen');
|
||||
};
|
||||
|
||||
button.addEventListener('click', function () {
|
||||
const checkboxes = getCheckboxes();
|
||||
if (!checkboxes.length) return;
|
||||
const shouldCheck = checkboxes.some(function (box) { return !box.checked; });
|
||||
checkboxes.forEach(function (box) {
|
||||
box.checked = shouldCheck;
|
||||
box.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
});
|
||||
refreshButtonLabel();
|
||||
});
|
||||
|
||||
getCheckboxes().forEach(function (box) {
|
||||
box.addEventListener('change', refreshButtonLabel);
|
||||
});
|
||||
|
||||
refreshButtonLabel();
|
||||
});
|
||||
}
|
||||
|
||||
function setupChecklistColumns() {
|
||||
document.querySelectorAll('.itsetup-checklist-body > [id^="id_"]').forEach(function (container) {
|
||||
const itemCount = container.querySelectorAll(':scope > div').length;
|
||||
@@ -271,6 +310,7 @@
|
||||
setupWorkEmailAutofill();
|
||||
setupBusinessCardAutofill();
|
||||
setupChecklistToggles();
|
||||
setupSectionCheckboxToggles();
|
||||
setupChecklistColumns();
|
||||
jumpToFirstErrorPage();
|
||||
updateStep();
|
||||
|
||||
Reference in New Issue
Block a user