Files
marketplaces/src/app/features/project-editor/sections/section.shared.scss
sdarbinyan 96b12a1fbe feat(project-editor): pre-publish change + validation preview
Milestone 5 of the Configuration Engine sprint.

- Facade: changeSummary computed - per modified field, before/after values
  (schema label + stringified diff vs originalBootstrap), reusing
  modifiedFields from M4.
- preview-section: new "changes since last publish" card ahead of the
  existing export/import/live-preview card - validation issue list
  (warning/error styled) plus a before/after change table. Reuses the
  existing, non-destructive ProjectEditorPreviewService.preview() call.
- i18n: previewChangesTitle/NoIssues/NoChanges/ChangeField/Before/After in
  interface + en/ru/hy.

Gate: tsc --noEmit, npm test (33/33), arch:check, build all green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 09:00:47 +04:00

231 lines
3.6 KiB
SCSS

:host {
display: block;
}
.media-field-row {
display: flex;
gap: 8px;
align-items: center;
}
.media-field-row app-input { flex: 1; }
.editor-grid {
display: grid;
gap: 12px;
}
.editor-grid.two {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.editor-grid.three {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.editor-grid.four {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.editor-grid.compact {
align-items: end;
}
label {
display: grid;
gap: 6px;
color: var(--text-primary, #1e3c38);
font-weight: 600;
}
label.full,
app-form-field.full {
grid-column: 1 / -1;
}
.field-desc {
display: block;
font-weight: 400;
font-size: 12px;
line-height: 1.4;
color: var(--text-secondary, #5f6e6a);
margin: -2px 0 2px;
}
input,
textarea,
select {
width: 100%;
padding: 10px 12px;
border: 1px solid var(--border-color, #d3dad9);
border-radius: 10px;
font: inherit;
background: #fff;
}
input[type='checkbox'] {
width: auto;
padding: 0;
}
input[type='color'] {
min-height: 44px;
padding: 4px;
}
.toggle-row {
display: flex;
align-items: center;
gap: 8px;
}
.toggles {
align-items: start;
}
.sortable-list,
.stack-list {
display: grid;
gap: 10px;
}
.sortable-item,
.sub-card {
border: 1px solid var(--border-color, #d3dad9);
border-radius: 12px;
padding: 12px;
background: #fbfcfc;
}
.editor-actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
button {
min-height: 42px;
border-radius: 10px;
border: 1px solid #497671;
background: #497671;
color: #fff;
padding: 0 14px;
font-weight: 700;
cursor: pointer;
transition: background-color var(--transition-fast, 120ms ease),
border-color var(--transition-fast, 120ms ease),
transform var(--transition-fast, 120ms ease),
box-shadow var(--transition-fast, 120ms ease);
&:hover {
background: var(--primary-hover, #3d635f);
border-color: var(--primary-hover, #3d635f);
transform: translateY(-1px);
box-shadow: var(--shadow-sm, 0 2px 8px rgba(0, 0, 0, 0.1));
}
&:active {
transform: translateY(0);
}
&:focus-visible {
outline: 2px solid #497671;
outline-offset: 2px;
}
&:disabled {
cursor: not-allowed;
opacity: 0.6;
transform: none;
box-shadow: none;
}
}
button.secondary {
background: #fff;
color: #1e3c38;
border-color: var(--border-color, #d3dad9);
&:hover {
background: var(--bg-secondary, #f5f5f5);
border-color: #497671;
}
&:focus-visible {
outline-color: #497671;
}
}
@media (prefers-reduced-motion: reduce) {
button {
transition: none;
&:hover {
transform: none;
}
}
}
.editor-error {
margin: 0;
color: #991b1b;
}
.preview-validation {
margin: 0 0 12px;
padding-left: 1.25rem;
color: var(--warning-color, #b45309);
&.has-errors {
color: var(--error-color, #991b1b);
}
li.is-warning {
color: var(--warning-color, #b45309);
}
li.is-error {
color: var(--error-color, #991b1b);
}
}
.preview-validation-ok {
margin: 0 0 12px;
color: var(--text-secondary, #5f6e6a);
}
.preview-changes {
width: 100%;
border-collapse: collapse;
font-size: 0.9rem;
th,
td {
text-align: left;
padding: 8px 10px;
border-bottom: 1px solid var(--border-color, #d3dad9);
}
th {
color: var(--text-secondary, #5f6e6a);
font-weight: 600;
}
.preview-before {
color: var(--text-secondary, #5f6e6a);
text-decoration: line-through;
}
.preview-after {
color: var(--text-primary, #1e3c38);
font-weight: 600;
}
}
@media (max-width: 900px) {
.editor-grid.two,
.editor-grid.three,
.editor-grid.four {
grid-template-columns: 1fr;
}
}