snapshot: preserve dynamic builder and section ordering work
This commit is contained in:
@@ -109,14 +109,31 @@ body {
|
||||
color: #166534;
|
||||
}
|
||||
|
||||
.builder-overview {
|
||||
.builder-summary-strip {
|
||||
margin-top: 12px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.builder-summary-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
min-height: 34px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid #d5dfec;
|
||||
border-radius: 999px;
|
||||
background: #f8fbff;
|
||||
color: #304159;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.builder-summary-pill strong {
|
||||
color: #101c30;
|
||||
}
|
||||
|
||||
.builder-stat-card,
|
||||
.builder-panel,
|
||||
.options-panel {
|
||||
border: 1px solid rgba(201, 212, 226, 0.95);
|
||||
@@ -125,34 +142,6 @@ body {
|
||||
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.05);
|
||||
}
|
||||
|
||||
.builder-stat-card {
|
||||
padding: 14px 16px;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.builder-stat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
border-color: rgba(146, 170, 199, 0.95);
|
||||
box-shadow: 0 16px 28px rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.builder-stat-label {
|
||||
display: block;
|
||||
color: #65758f;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.03em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.builder-stat-card strong {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
font-size: 28px;
|
||||
line-height: 1;
|
||||
color: #101c30;
|
||||
}
|
||||
|
||||
.builder-panel-head h2,
|
||||
.options-head h2 {
|
||||
margin: 0;
|
||||
@@ -371,6 +360,18 @@ body {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.preview-shell-compact .preview-section {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.preview-shell-compact .preview-section-head {
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.preview-shell-compact .preview-chip-list {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.preview-section {
|
||||
border: 1px solid #d7e0ec;
|
||||
border-radius: 14px;
|
||||
@@ -500,6 +501,169 @@ body {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.conditional-rule-grid {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.conditional-rule-card {
|
||||
border: 1px solid #d7e0ec;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(180deg, #fbfdff 0%, #ffffff 100%);
|
||||
padding: 14px;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.conditional-rule-card:hover {
|
||||
transform: translateY(-1px);
|
||||
border-color: #bfd0e4;
|
||||
box-shadow: 0 14px 26px rgba(15, 23, 42, 0.06);
|
||||
}
|
||||
|
||||
.conditional-rule-head {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #e6edf6;
|
||||
}
|
||||
|
||||
.conditional-rule-head-main {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.conditional-rule-head h3 {
|
||||
margin: 2px 0 4px;
|
||||
font-size: 16px;
|
||||
color: #142033;
|
||||
}
|
||||
|
||||
.conditional-rule-eyebrow {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
padding: 0 9px;
|
||||
border-radius: 999px;
|
||||
background: #eef4ff;
|
||||
color: #214d99;
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.conditional-toggle {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #5f7089;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.conditional-toggle input[type='checkbox'] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.conditional-targets {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.conditional-target-label {
|
||||
color: #5f7089;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.conditional-target-chips {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.conditional-clause-list {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.conditional-clause-row {
|
||||
display: grid;
|
||||
grid-template-columns: 56px minmax(220px, 1.35fr) minmax(180px, 0.8fr) minmax(180px, 0.85fr);
|
||||
gap: 10px;
|
||||
align-items: end;
|
||||
padding: 12px;
|
||||
border: 1px solid #e5ebf3;
|
||||
border-radius: 14px;
|
||||
background: #f8fbff;
|
||||
}
|
||||
|
||||
.conditional-clause-index {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
min-height: 38px;
|
||||
color: #33506f;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.conditional-clause-control {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.conditional-clause-control span {
|
||||
color: #5f7089;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.conditional-clause-control select,
|
||||
.conditional-clause-control input[type='text'] {
|
||||
width: 100%;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.conditional-extra-clause {
|
||||
border: 1px dashed #d7e0ec;
|
||||
border-radius: 14px;
|
||||
background: #fbfdff;
|
||||
}
|
||||
|
||||
.conditional-extra-clause summary {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
padding: 10px 12px;
|
||||
color: #35506f;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
letter-spacing: 0.03em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.conditional-extra-clause summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.conditional-extra-clause[open] summary {
|
||||
border-bottom: 1px solid #e6edf6;
|
||||
}
|
||||
|
||||
.conditional-extra-clause .conditional-clause-row {
|
||||
border: 0;
|
||||
border-radius: 0 0 14px 14px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.columns {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(220px, 1fr));
|
||||
@@ -728,35 +892,212 @@ body {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.section-rule-grid {
|
||||
.builder-entity-form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 10px;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
padding: 14px;
|
||||
border: 1px solid #d7e0ec;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(180deg, #fbfdff 0%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.section-rule-card {
|
||||
.builder-entity-head h3,
|
||||
.builder-group-head h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
color: #142033;
|
||||
}
|
||||
|
||||
.builder-entity-head .mini {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.builder-entity-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.builder-entity-control {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.builder-entity-control span {
|
||||
color: #5f7089;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.builder-entity-control-narrow {
|
||||
max-width: 180px;
|
||||
}
|
||||
|
||||
.builder-entity-control-full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.builder-card-list,
|
||||
.builder-group-stack {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.builder-group-card {
|
||||
border: 1px solid #d7e0ec;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(180deg, #f8fbff 0%, #ffffff 100%);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.builder-group-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
padding: 12px 14px;
|
||||
border-bottom: 1px solid #dfe7f1;
|
||||
background: #f2f7ff;
|
||||
}
|
||||
|
||||
.builder-entity-card {
|
||||
padding: 14px;
|
||||
border: 1px solid #e5ebf3;
|
||||
border-radius: 16px;
|
||||
background: #ffffff;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.builder-entity-card-head {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.builder-entity-card-head strong {
|
||||
color: #142033;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.entity-meta {
|
||||
margin-top: 4px;
|
||||
color: #64748b;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
font-size: 12px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.builder-switch,
|
||||
.builder-switch-inline {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #5f7089;
|
||||
font-size: 12px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.builder-switch-stack {
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.builder-switch input[type='checkbox'],
|
||||
.builder-switch-inline input[type='checkbox'] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.builder-entity-card-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.builder-empty-state {
|
||||
padding: 14px;
|
||||
border: 1px dashed #d7e0ec;
|
||||
border-radius: 14px;
|
||||
background: #fbfdff;
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.section-rule-grid {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
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;
|
||||
border: 1px solid #d6e0ec;
|
||||
border-radius: 14px;
|
||||
background: linear-gradient(180deg, #f9fbff, #ffffff);
|
||||
cursor: move;
|
||||
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;
|
||||
}
|
||||
|
||||
.section-rule-card.is-locked {
|
||||
background: linear-gradient(180deg, #f4f7fb, #fafcff);
|
||||
}
|
||||
|
||||
.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;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding-right: 2px;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
body.builder-dragging,
|
||||
body.builder-dragging * {
|
||||
cursor: grabbing !important;
|
||||
user-select: none !important;
|
||||
}
|
||||
|
||||
.section-rule-copy {
|
||||
display: grid;
|
||||
gap: 4px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.section-rule-copy strong {
|
||||
color: #0f172a;
|
||||
font-size: 14px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.section-rule-copy span,
|
||||
@@ -772,6 +1113,11 @@ body {
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.section-rule-checkbox {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@keyframes builderFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
@@ -821,10 +1167,6 @@ body {
|
||||
}
|
||||
|
||||
@media (max-width: 1220px) {
|
||||
.builder-overview {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.builder-rule-layout,
|
||||
.columns {
|
||||
grid-template-columns: repeat(2, minmax(220px, 1fr));
|
||||
@@ -834,7 +1176,8 @@ body {
|
||||
@media (max-width: 900px) {
|
||||
.builder-hero,
|
||||
.builder-panel-head,
|
||||
.options-head {
|
||||
.options-head,
|
||||
.conditional-rule-head {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
@@ -846,15 +1189,20 @@ body {
|
||||
.builder-rule-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.builder-entity-card-head {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.builder-overview,
|
||||
.columns {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.field-rule-row {
|
||||
.field-rule-row,
|
||||
.conditional-clause-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@@ -862,7 +1210,26 @@ body {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.conditional-clause-index {
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.add-option-form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.builder-entity-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.builder-entity-control-narrow,
|
||||
.builder-entity-control-full {
|
||||
max-width: none;
|
||||
grid-column: auto;
|
||||
}
|
||||
|
||||
.builder-group-head {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,4 +145,95 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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 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('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');
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user