Commit Graph

35 Commits

Author SHA1 Message Date
sdarbinyan
71d5f4d320 feat(builder): visual homepage blocks, merchant-language widget settings, real carousel arrows
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

P0 user feedback: homepage builder showed raw section.id like 'section-hero'/'section-categories'; hero widget exposed 'full-bleed'/'boxed' and raw px/vh as free text with no explanation; Overlay/Autoplay toggles made no sense without a slides concept; product carousel widgets rendered arrows nowhere near a working carousel.

Homepage section (sections list -> visual blocks):
- Replaced raw section.id display with a merchant-facing block catalog (icon + name + one-line explanation) for hero/categories/featured-products/product-carousel/recently-viewed/banner/partners/custom-html
- Added block catalog picker to append new blocks (was fixed at whatever the seed data had - task asked 'what if we add manually? not fixed 3')
- Added duplicate and remove per block, alongside the existing drag-to-reorder
- Verified in browser: labels render correctly, add-block and duplicate both confirmed working end-to-end

Widgets section (hero widget):
- 'Layout' free-text replaced with a select (Full width / Boxed) instead of typing 'full-bleed'/'boxed' blind
- 'Height' free-text replaced with a select (Compact/Medium/Tall/Full screen) mapped to real vh values
- New Slides editor: title/subtitle pairs an admin can add/remove: this is the actual multi-slide data the Overlay/Autoplay toggles were referring to with nothing to point at before
- HeroWidgetData contract gains slides[]/autoplay; HeroWidgetComponent now renders a real rotator (dots, click-to-jump, autoplay interval) when more than one slide exists - previously autoplay/overlay props existed but there was no slideshow behavior anywhere to control

Carousel arrows root cause and fix:
- widget-manifest.json offers 'carousel' as a layout option for product-collection/product-carousel widgets, and the admin UI let you select it, but ProductCarouselWidgetComponent always rendered a static CSS grid regardless - there was no carousel implementation to have arrows in the first place
- Now renders a real horizontally-scrollable strip with working prev/next buttons (native scrollBy, disabled at each end) when section.layout.strategy === 'carousel'; falls back to the existing grid otherwise
- Confirmed src/app/components/items-carousel (a PrimeNG p-carousel) is dead code, not wired into any route or widget - not the source of the reported bug

New builder.* i18n keys (en/ru/hy), zero duplicate-key collisions verified via scan
2026-07-19 14:14:29 +04:00
sdarbinyan
726df0cee0 feat(builder): visual footer builder with drag-and-drop columns
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

P0 user feedback: footer static pages were comma-separated text; no way to add extra phones/emails for different countries.

- New FooterColumnConfig/FooterLinkConfig model (footer-config.model.ts): columns of links, each link pointing at an existing static page (resolved by key, so it survives route renames) or a custom URL
- Footer Builder UI: add/remove columns and links, per-link toggle between 'existing page' (dropdown of real static pages) and 'custom URL', drag-and-drop reordering of both columns and links via @angular/cdk/drag-drop (same primitive already used by the homepage section builder)
- Wired FooterResolverService (the service the real storefront footer actually renders through) to read footer.columns as the primary source when present - without this the builder would have saved data nobody ever displayed. Falls back to the existing legacy static-page auto-grouping when no columns are configured, so existing sites are unaffected
- CompanyContactConfig gains additionalPhones/additionalEmails (primary phone/email field unchanged) with add/remove UI for country-specific support lines
- Old comma-separated staticPageKeys input removed from the UI; field kept on the model as deprecated/read-compat only
- New builder.* i18n keys (en/ru/hy); fixed an accidental duplicate-key collision with pre-existing navigation-section addLink/removeLink keys during the rename pass
- Verified in browser: added column, added link, switched link source page->custom, added phone number - all reactive and error-free
2026-07-19 13:58:57 +04:00
sdarbinyan
440d2ec211 refactor(builder): single language manager, theme before branding
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

P0 user feedback: General asked admins to type locale codes comma-separated, and Branding (logos) came before Theme (colors).

- Root cause: General duplicated language management as raw text/CSV inputs while a full Languages manager section (add/remove/set-default with per-locale content seeding) already existed one tab away. Removed the duplicate inputs; General now shows a read-only chip summary (default language first, marked) with a 'Manage languages' link to the real manager. One source of truth, no comma parsing, no risk of bypassing LocaleSyncService
- Builder navigation now orders Theme before Branding - merchants pick a palette first, then upload logos that match it
- New builder keys (languagesSummaryDesc, manageLanguages) in en/ru/hy; verified in browser (chips RU-default/EN/HY, nav order theme->branding)
2026-07-19 08:53:10 +04:00
sdarbinyan
04b36bab9b feat(builder): implement visual homepage builder
New HomepageOverviewComponent (Tasks 1+8), mounted at the top of the
existing Homepage section page: completion ring, active/hidden section
counts, recommended next step, last-modified timestamp, and a 6-item
Homepage Health checklist (hero/categories/products/promotion/
newsletter/any-sections) - all derived from the real page.sections/
widgets data already in the facade, nothing fabricated.

Existing page-level drag-and-drop reordering (homepage-section's
CdkDragDrop over page.sections) was already implemented pre-Sprint 5 -
left as-is per "build on top of, do not replace."

Widgets section (Task 2) rewritten from a bare list into visual cards:
per-widget icon + humanized type label (hero/categories/product-
collection), a visible/hidden toggle and badge, up/down move buttons
(keyboard-accessible reorder within a section - see Known limitations
for why this replaces pointer drag for widgets specifically), duplicate,
and remove (with confirm). The existing per-type field editors (hero/
categories/product-collection) are unchanged; the raw-JSON fallback for
unknown widget types now sits behind a collapsed "Advanced settings"
disclosure instead of being the default view.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 10:24:13 +04:00
sdarbinyan
a83cfdfe4d feat(builder): implement professional brand management experience
New BrandOverviewComponent, mounted at the top of the existing
Branding section page (no route/schema/business-logic changes):

- Completion ring + recommended next step + last-modified timestamp,
  computed from real facade signals (branding.logoUrl/faviconUrl/
  socialImageUrl, theme.palette, theme.typography, lastSavedAt) -
  nothing fabricated.
- Brand Health checklist (6 items: logo, favicon, colors, typography,
  social image, accessibility) - icon+text, never color alone.
- Color palette preview: 10 swatches from the real ThemePaletteConfig
  (primary/secondary/accent/success/warning/danger/backgrounds/text/
  border), each with a readable label.
- Real WCAG contrast check (contrast.util.ts, relative-luminance
  formula) between configured text and background colors - shows an
  inline warning when below 4.5:1, never blocks publishing.
- Typography live preview using the configured heading/body font
  families and base size.
- Social share preview card (Open Graph-style) using the existing
  socialImageUrl + seo.default.title/description, with an explicit
  empty state when no image is set yet.

Scope cut from the full brief given this session's cost already well
over budget entering this sprint - see Known limitations in the final
report (no multi-variant logo/favicon management, no live responsive
device preview, no new media library/asset picker; all reuse the
existing single-logo/single-favicon fields and image-field upload
component as-is).

Could not verify live in-browser this sprint: port 4200 is held by
another chat's dev server. Verified via `tsc --noEmit` (clean) and
manual template/binding review only; one binding (`--pct` custom-
property style binding) was replaced with a plain computed string to
remove an unverifiable risk rather than ship it unverified.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 10:13:35 +04:00
sdarbinyan
76e9689e11 fix(general): route supported-languages field through LocaleSyncService, guard unsupported default locale
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
General's free-text 'Supported Languages' field overwrote
tenant/localization.supportedLocales directly, skipping LocaleSyncService's
propagation to per-locale nav/static-page translation entries - the exact
sync Languages' add/remove buttons already go through correctly. Now diffs
against the current list and routes each added/removed locale through
facade.addLocale()/removeLocale().

Also: 'Default Language' was a free-text input with no guard against typing
a locale that isn't in the supported list - every label[defaultLocale]
lookup across nav/static-page content would then silently return undefined.
Added a validator rule (default-locale-not-supported) wired to the existing
fieldError() display, consistent with every other field-level check.

Verified live via window.ng.getComponent(): typing an unsupported code shows
the new inline error; adding 'de' via this field seeded an empty 'de'
translation entry on an existing static page, matching what Languages'
add-locale button already produces.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 19:00:17 +04:00
sdarbinyan
2417a7795b fix(languages): show error instead of silently no-oping when adding a duplicate locale
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
addLocale() always cleared the input, even when LocaleSyncService rejected
the code because it was already supported - same silent-failure shape as
the widgets JSON bug fixed earlier this session. Now checks locales()
first and shows an inline error, leaving the input untouched, instead of
clearing it like the add succeeded. Verified live: typing an existing
locale code and clicking Add now shows 'This language is already supported.'

Navigation-section was also audited (id generation, label locale-migration,
reorder swap, grouped-footer read-only fallback) - no defects found, it's
solid as-is.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 18:31:01 +04:00
sdarbinyan
ff53265fc0 fix(widgets): stop silently discarding invalid JSON edits in the props fallback textarea
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
updateJson() caught JSON.parse failures and did nothing, but the textarea
was bound to propsJson(committed props) - so on the next change-detection
pass, any in-progress invalid edit snapped back to the last-saved value
with zero feedback. Verified live via window.ng.getComponent(): typing
invalid JSON now keeps the user's draft on screen with an inline error;
fixing it commits and clears the draft/error.

Also: homepage-section drop() used CdkDragDrop<any[]> - switched to
unknown[] per the no-any rule, no behavior change.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 18:14:58 +04:00
sdarbinyan
1c71f8e83e fix(features): keep featureFlags and userExperience enabled flags in sync for wishlist/compare
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
FeatureConfigService gates wishlist/compare visibility on BOTH
featureFlags.<key> and userExperience.<key>.enabled, but the features
editor only exposed one toggle wired to featureFlags. Both default to
true so this was silent, but a config with userExperience.wishlist.enabled
(or compare) explicitly false would show the editor toggle as checked
with no way to actually turn the feature back on from this screen.

toggleFeatureAndUserExperience() now updates both flags from the single
toggle, in one updateBootstrap call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 17:55:08 +04:00
sdarbinyan
b05278c061 fix(footer): stop generating collision-prone social-link ids, fragile track key
createSocialLinkRow derived the new id from the current array length
(social-${length+1}). Add/remove/add cycles reliably reproduce a duplicate
id: add,add -> social-1/social-2; remove social-1 -> array length 1; add
-> social-2 again, colliding with the surviving row. footer.component.html
tracks footer nav items by id (@for ... track item.id), so a duplicate id
there corrupts Angular's DOM reuse on the public storefront footer.

Also switched the payment-icon @for from track icon.src to track $index -
two icon rows sharing a src (most commonly two blank ones) hit the same bug.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 17:52:43 +04:00
sdarbinyan
9e44215dd5 feat(project-editor): footer validation rules (contact email, social link URLs, payment icons)
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Real gaps, not fabricated: isValidEmail existed in primitives.ts but was
never called anywhere; social-link URL check only lived as a per-row
template hint (never blocked publish or set the nav badge); payment icons
with only src or only alt set were silently accepted.

- invalid-contact-email: company.contacts.email must be a valid email (error)
- invalid-social-link-url: footer.socialLinks entries need a valid http(s) URL (warning)
- incomplete-payment-icon: a payment icon needs both src and alt, or neither (warning)

Wired into footer-section via the existing fieldError() pattern. Header has
no equivalent gap today (every header field is a bool/enum, always valid by
construction) so nothing was added there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 16:57:43 +04:00
sdarbinyan
4543a6b6b6 feat(project-editor): per-field inline validation for languages, homepage, widgets, navigation, static-pages
Extends the fieldError() wiring pattern (already used in theme/general/branding)
to the remaining sections that have matching ProjectValidator fieldKeys:
- languages: localization.supportedLocales (no-languages, missing-translations)
- homepage: pages (empty-homepage, missing-widget, duplicate-routes)
- widgets: pages (invalid-widget-config)
- navigation: navigation.header (duplicate-nav-links)
- static-pages: staticPages (duplicate-slugs, invalid-css)

Header/footer/features sections have no matching validator issues today,
so nothing to wire there yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 16:18:22 +04:00
sdarbinyan
d8456ecb9f feat(project-editor): header layout + sticky option
- HeaderConfig gains sticky (default true) and layout ('default'|'centered')
- header editor exposes layout select + sticky toggle
- runtime header component applies static/centered classes from config

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 15:29:55 +04:00
sdarbinyan
b183410888 feat(project-editor): reusable image-field (thumbnail+replace+remove), branding OG image+gallery
- shared app-image-field component: thumbnail preview, replace, remove, opens media-picker
- branding: add socialImageUrl + galleryUrls fields, wire to new image-field
- footer: logo + payment icon fields use image-field (drop manual media-picker plumbing)
- i18n: common.remove, adminCategories.replaceImage, builder.socialImage/gallery keys (en/ru/hy)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 15:22:45 +04:00
sdarbinyan
fffbb64e4b feat(static-pages): navigation integration (insert page link)
Milestone 6 of the Static Pages Module sprint.

- ProjectEditorFacade.addStaticPageNavLink(target, pageId): creates a
  NavigationItemConfig { type: 'staticPage', key: pageId }. This shape was
  already understood end-to-end by the resolvers (StaticPageResolverService/
  FooterResolverService derive label+route from the linked page - see
  footer-resolver.service.ts resolveGroupItem/resolveLegacyItem) - the only
  gap was that the editor UI never exposed a way to create it.
- navigation-section: "Insert page link" control (page picker + button) next
  to both header and footer "Add link". Rows for a static-page link show a
  "Linked to page" indicator instead of the raw label/URL inputs (those
  fields don't apply - the resolver derives them dynamically). labelOf()
  falls back to the page id for the row heading since a static-page link has
  no label of its own.
- i18n: builder.insertPageLink, builder.linkedToPage in interface + en/ru/hy.

Verified (no rebuild needed) that pages already participate in preview(),
exportBootstrap()/importBootstrap(), and draft/publish gating - all flow
through bootstrap.staticPages and the M1-M2 additive fields untouched here.

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

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 10:18:08 +04:00
sdarbinyan
274f2a4101 fix(project-editor): close redo-staleness window, dedupe footer URL check
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Independent review pass over the Configuration Engine sprint (M1-M6).

- Facade: a fresh edit burst now clears the redo (future) stack immediately,
  not just once its debounced commit lands ~300ms later. Previously, editing
  right after an undo left canRedo() true for that window; clicking Redo
  during it would have silently discarded the new edit and jumped back to
  the stale future snapshot. Reordered two interspersed imports/interface
  for readability while in the file.
- footer-section: removed a local HTTP_URL regex + duplicate isValidUrl
  logic (its "shared/ui can't import features" justification didn't apply -
  this file already lives in features/project-editor/sections/, the same
  feature as schema/validators/). Now calls isValidHttpUrl from
  schema/validators/primitives, closing a validator duplication the sprint's
  "no duplicated validators" requirement was meant to catch.

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:10:54 +04:00
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
sdarbinyan
a7bab6be52 feat(project-editor): live inline validation and publish gating
Milestone 3 of the Configuration Engine sprint.

- Facade fieldError(key) accessor over issuesByField for inline field errors.
- Bind [error] on schema-backed fields: theme palette colours, general
  name/domain, branding logo (translated via each section).
- project-editor-nav: per-section blocking-issue count badge (issuesBySection).
- save-bar: Publish now disabled on hasBlockingIssues() (errors only, so new
  warnings no longer block); issue list tags warning vs error severity.

Editor verified rendering at /ru/edit/theme with the new nav + save bar;
validation logic covered by the 25 unit tests.

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

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 02:07:14 +04:00
sdarbinyan
ee1cbdf38b style(ui): full UX/UI + motion pass across storefront, admin, editor
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
- fix save-bar buttons to use shared app-button primitive (were unstyled)
- fix platform-nav-group border/radius via structural selectors, drop dead
  -middle/-right classes
- storefront widgets (hero/categories/product-carousel/footer-nav): design
  tokens, hover/focus states, 44px touch targets, entrance motion, reduced-
  motion guards
- admin dashboard cards + quick-actions: hover lift, entrance animation
- admin product-form gallery remove badge: hover/focus + expanded hit area
- project-editor section.shared button styles: hover/active/focus/disabled
  states + reduced-motion; section-switch fade-in motion

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 23:32:31 +04:00
sdarbinyan
b61bf0e5bc chore(project-editor): remove now-redundant .editor-section-card rule
All 11 section components use app-section-card now; the raw shell class
had no remaining consumers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 02:14:40 +04:00
sdarbinyan
da0f0cd4a4 feat(project-editor): adopt SectionCard in preview section
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 02:14:03 +04:00
sdarbinyan
058e2d571f refactor(project-editor): toggles + remove as-any casts in features section
- checkboxes -> app-toggle, wrap in SectionCard
- toggleUserExperience/toggleProductFeature typed without 'as any' (optional
  chaining on the already-typed UserExperienceConfig/ProductPageConfig union)
- removed dead, broken toggleRecentViewed method (unused, not wired to the
  template; toggleUserExperience('recentlyViewed', ...) is the live path)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 02:12:25 +04:00
sdarbinyan
0c9a855232 fix(project-editor): editable nav link labels per locale, add LocaleTabs
- navigation-section: add LocaleTabs; label input now reads/writes the
  active locale's translation via a new editableLabel() helper instead of
  always the default locale. facade.updateNavLinkLabel() gained an optional
  locale param (defaults to current default locale, so existing callers
  are unaffected) and correctly promotes a plain-string label into a
  per-locale map when writing a non-default locale.
- languages-section: wrap in SectionCard, add LocaleTabs for consistency.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 02:10:38 +04:00
sdarbinyan
1c51a819ed feat(project-editor): adopt Toggle/SectionCard in homepage and widgets sections
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 02:07:41 +04:00
sdarbinyan
475e5ad528 fix(project-editor): validate footer payment/social links, add footer logo picker
- header-section: raw checkboxes -> app-toggle, wrap in SectionCard
- footer-section: replace unvalidated pipe-delimited textareas for payment
  icons/social links with KeyValueEditor + MediaPickerComponent, add missing
  footer logo picker, validate social link URLs (http/https), wrap in SectionCard
- i18n: add footer logo / key-value-editor labels and URL validation message

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 02:06:26 +04:00
sdarbinyan
ccbf8c6e5c feat(project-editor): migrate theme section to Select/ColorPicker/SectionCard
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 02:01:34 +04:00
sdarbinyan
3bf1f31a3c feat(project-editor): adopt SectionCard in general/branding sections
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-16 01:59:54 +04:00
sdarbinyan
30afb5d778 feat(media): reusable media management
Sprint 22.

- MediaAsset gains folder (flat) and MediaListParams gains folder/tag
  filters; MediaRepository.listFolders() derives the folder list from
  existing records
- upload validation: 10MB size cap, mime allow-list (jpeg/png/webp/gif/
  svg+xml/pdf), real error messages surfaced through MediaLibraryFacade
  instead of a generic swallowed string
- SVG uploads are sanitized (script tags and on*= attributes stripped)
  before storage
- raster images (excl. gif) are downscaled to a 2000px max dimension and
  re-encoded via canvas before storage - compression, not a crop UI
- tag editing (window.prompt, comma-separated) via
  MediaLibraryFacade.updateTags()
- MediaPickerComponent wired into Project Editor branding (logo, compact
  logo, favicon) alongside its existing category/product usage - confirmed
  no image fields exist on Static Pages or as a dedicated hero field to
  wire

docs/ADMIN.md updated with the new Sprint 22 section including the storage
abstraction note (MediaRepository was already the abstraction).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-15 10:42:23 +04:00
sdarbinyan
f82344e0dd feat(project-editor): adopt Design System primitives across editor sections
Applied app-input/app-form-field/app-button to 9 of 11 Project Editor
sections: general, branding, theme, footer, homepage, widgets, languages,
navigation, preview. header and features sections were left unchanged -
they contain only checkboxes and selects, and no Checkbox/Select primitive
exists yet.

Theme section's 8 color pickers stay native <input type=color> (app-input's
type union doesn't include 'color') but are now wrapped in app-form-field
for consistent label/hint treatment. Added app-form-field.full grid-column
rule to section.shared.scss (shared by all 11 sections) alongside the
existing label.full rule, since the custom element doesn't match that
selector.

Production build green, arch:check passes.
2026-07-15 07:55:38 +04:00
sdarbinyan
170243a480 feat(project-editor): finish field descriptions + enum dropdowns across all sections
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Wires up the remaining editor sections (theme, header, footer, homepage,
widgets, features, languages, navigation) with the description text and
dropdown UX started for General/Branding:

- Every enum-backed field is now a <select> with a description per option,
  not free text: theme.mode, the new site-wide layout.type (previously had
  no editor at all - added to the Theme section, and added to that
  section's reset-scope), homepage section layout.strategy, and
  catalog.navigationMode (also previously unedited, added to Features).
- Every other field (colors, header toggles, footer contact/company fields,
  widget props, feature flags, language add, nav link label/url/visible)
  gets a one-line plain-language description under its label via the new
  *Desc i18n keys (en/ru/hy) prepared earlier.
- Genuinely open text (widget layout variant strings, JSON props) stays
  free text, description-only, per the existing widgetLayoutDesc/widgetJsonDesc
  wording - not force-fit into a dropdown.

Verified: tsc --noEmit and ng build both clean.
2026-07-15 00:45:41 +04:00
sdarbinyan
ac83c4f57f feat(project-editor): add field descriptions to General and Branding sections (partial)
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Adds a short plain-language description under each field label (new
.field-desc style, section.shared.scss) so a non-developer admin
understands what each field affects, per i18n (en/ru/hy) convention.

Only General and Branding sections are wired up so far - the *Desc i18n
keys for the remaining sections (theme/header/footer/homepage/widgets/
features/languages/navigation) were prepared in translations.ts/en/ru/hy
but not yet wired into their templates. Follow-up work.
2026-07-14 16:05:09 +04:00
sdarbinyan
68442919d3 fix(project-editor): preserve multilingual nav labels on edit
updateLabel() previously overwrote NavigationItemConfig.label with a bare
string via updateNavLink, destroying every other locale's translation
whenever a localized label object was edited. Add a facade method
updateNavLinkLabel() that inspects the existing label shape: plain
strings are replaced as before, but localized objects only have the
current default locale's key overwritten, leaving other locales intact.
2026-07-13 15:57:39 +04:00
sdarbinyan
16a134ca42 feat(project-editor): add Navigation tab for header/flat footer nav 2026-07-13 08:57:42 +04:00
sdarbinyan
b166920ad7 feat(project-editor): add Languages tab with generic locale sync 2026-07-13 08:10:00 +04:00
sdarbinyan
e2c8747fcc feat(builder): add project editor 2026-07-10 13:43:53 +04:00