2026-02-26 23:09:20 +04:00
|
|
|
export interface Translations {
|
|
|
|
|
header: {
|
|
|
|
|
home: string;
|
|
|
|
|
search: string;
|
|
|
|
|
about: string;
|
|
|
|
|
contacts: string;
|
|
|
|
|
searchPlaceholder: string;
|
|
|
|
|
catalog: string;
|
2026-07-09 01:13:54 +04:00
|
|
|
wishlist: string;
|
|
|
|
|
compare: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
openMenu: string;
|
|
|
|
|
closeMenu: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
};
|
|
|
|
|
footer: {
|
|
|
|
|
description: string;
|
|
|
|
|
company: string;
|
|
|
|
|
aboutUs: string;
|
|
|
|
|
contacts: string;
|
|
|
|
|
requisites: string;
|
|
|
|
|
support: string;
|
|
|
|
|
faq: string;
|
|
|
|
|
delivery: string;
|
|
|
|
|
guarantee: string;
|
|
|
|
|
legal: string;
|
|
|
|
|
offer: string;
|
|
|
|
|
privacy: string;
|
|
|
|
|
returns: string;
|
|
|
|
|
info: string;
|
|
|
|
|
aboutCompany: string;
|
|
|
|
|
documents: string;
|
|
|
|
|
paymentRules: string;
|
|
|
|
|
returnPolicy: string;
|
|
|
|
|
publicOffer: string;
|
|
|
|
|
help: string;
|
|
|
|
|
payment: string;
|
|
|
|
|
allRightsReserved: string;
|
|
|
|
|
};
|
|
|
|
|
home: {
|
|
|
|
|
welcomeTo: string;
|
|
|
|
|
subtitle: string;
|
|
|
|
|
startSearch: string;
|
|
|
|
|
loading: string;
|
|
|
|
|
errorTitle: string;
|
|
|
|
|
retry: string;
|
|
|
|
|
categoriesTitle: string;
|
|
|
|
|
categoriesSubtitle: string;
|
|
|
|
|
categoriesEmpty: string;
|
|
|
|
|
categoriesEmptyDesc: string;
|
|
|
|
|
dexarHeroTitle: string;
|
|
|
|
|
dexarHeroSubtitle: string;
|
|
|
|
|
dexarHeroTagline: string;
|
|
|
|
|
goToCatalog: string;
|
|
|
|
|
findProduct: string;
|
|
|
|
|
loadingDexar: string;
|
|
|
|
|
catalogTitle: string;
|
|
|
|
|
emptyCategoriesDexar: string;
|
|
|
|
|
categoriesSoonDexar: string;
|
|
|
|
|
itemsCount: string;
|
|
|
|
|
};
|
|
|
|
|
cart: {
|
|
|
|
|
title: string;
|
|
|
|
|
clear: string;
|
|
|
|
|
empty: string;
|
|
|
|
|
emptyDesc: string;
|
|
|
|
|
goShopping: string;
|
|
|
|
|
total: string;
|
|
|
|
|
items: string;
|
|
|
|
|
deliveryLabel: string;
|
2026-06-21 23:13:01 +04:00
|
|
|
deliveryMethod: string;
|
|
|
|
|
selectDelivery: string;
|
|
|
|
|
deliveryPlace: string;
|
|
|
|
|
deliveryTime: string;
|
|
|
|
|
digitalDelivery: string;
|
|
|
|
|
deliveryRequired: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
toPay: string;
|
|
|
|
|
agreeWith: string;
|
|
|
|
|
publicOffer: string;
|
|
|
|
|
returnPolicy: string;
|
|
|
|
|
guaranteeTerms: string;
|
|
|
|
|
privacyPolicy: string;
|
|
|
|
|
and: string;
|
|
|
|
|
checkout: string;
|
2026-06-29 00:06:18 +04:00
|
|
|
payViaQr: string;
|
|
|
|
|
payViaCard: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
close: string;
|
|
|
|
|
creatingPayment: string;
|
|
|
|
|
waitFewSeconds: string;
|
|
|
|
|
scanQr: string;
|
|
|
|
|
amountToPay: string;
|
|
|
|
|
waitingPayment: string;
|
|
|
|
|
copied: string;
|
|
|
|
|
copyLink: string;
|
|
|
|
|
openNewTab: string;
|
|
|
|
|
paymentSuccess: string;
|
|
|
|
|
paymentSuccessDesc: string;
|
|
|
|
|
sending: string;
|
|
|
|
|
send: string;
|
2026-06-02 00:57:36 +04:00
|
|
|
paymentError: string;
|
|
|
|
|
paymentErrorDesc: string;
|
|
|
|
|
retryPayment: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
paymentTimeout: string;
|
|
|
|
|
paymentTimeoutDesc: string;
|
|
|
|
|
autoClose: string;
|
|
|
|
|
confirmClear: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
removeItem: string;
|
|
|
|
|
paymentQrAlt: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
acceptTerms: string;
|
|
|
|
|
copyError: string;
|
|
|
|
|
emailSuccess: string;
|
|
|
|
|
emailError: string;
|
|
|
|
|
phoneRequired: string;
|
|
|
|
|
phoneMoreDigits: string;
|
|
|
|
|
phoneTooMany: string;
|
|
|
|
|
emailRequired: string;
|
|
|
|
|
emailTooShort: string;
|
|
|
|
|
emailTooLong: string;
|
|
|
|
|
emailNeedsAt: string;
|
|
|
|
|
emailNeedsDomain: string;
|
|
|
|
|
emailInvalid: string;
|
2026-03-24 00:09:11 +04:00
|
|
|
loginRequired: string;
|
|
|
|
|
loginRequiredDesc: string;
|
|
|
|
|
loginWithTelegram: string;
|
|
|
|
|
orScanQr: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
};
|
|
|
|
|
search: {
|
|
|
|
|
title: string;
|
|
|
|
|
placeholder: string;
|
2026-07-10 13:25:31 +04:00
|
|
|
searchBarAria: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
resultsCount: string;
|
|
|
|
|
searching: string;
|
|
|
|
|
retry: string;
|
|
|
|
|
noResults: string;
|
|
|
|
|
noResultsFor: string;
|
|
|
|
|
noResultsHint: string;
|
2026-07-10 13:25:31 +04:00
|
|
|
emptyResultsAria: string;
|
|
|
|
|
popularCategories: string;
|
|
|
|
|
recommendedProducts: string;
|
|
|
|
|
aiSuggestionHint: string;
|
|
|
|
|
suggestionType: {
|
|
|
|
|
product: string;
|
|
|
|
|
category: string;
|
|
|
|
|
brand: string;
|
|
|
|
|
collection: string;
|
|
|
|
|
seller: string;
|
|
|
|
|
'static-page': string;
|
|
|
|
|
ai: string;
|
|
|
|
|
};
|
2026-02-26 23:09:20 +04:00
|
|
|
addToCart: string;
|
|
|
|
|
loadingMore: string;
|
|
|
|
|
allLoaded: string;
|
|
|
|
|
emptyState: string;
|
2026-07-05 01:10:56 +04:00
|
|
|
minLength: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
of: string;
|
|
|
|
|
};
|
|
|
|
|
category: {
|
|
|
|
|
retry: string;
|
|
|
|
|
addToCart: string;
|
|
|
|
|
loadingMore: string;
|
|
|
|
|
allLoaded: string;
|
|
|
|
|
emptyTitle: string;
|
|
|
|
|
emptyDesc: string;
|
|
|
|
|
goHome: string;
|
|
|
|
|
loading: string;
|
|
|
|
|
};
|
2026-07-05 01:36:21 +04:00
|
|
|
catalog: {
|
|
|
|
|
title: string;
|
|
|
|
|
breadcrumb: string;
|
|
|
|
|
allCategories: string;
|
|
|
|
|
products: string;
|
|
|
|
|
loading: string;
|
|
|
|
|
loadingProducts: string;
|
|
|
|
|
errorTitle: string;
|
|
|
|
|
error: string;
|
|
|
|
|
retry: string;
|
|
|
|
|
categoryHint: string;
|
|
|
|
|
productHint: string;
|
|
|
|
|
emptyTitle: string;
|
|
|
|
|
emptyCategories: string;
|
|
|
|
|
emptyProducts: string;
|
|
|
|
|
addToCart: string;
|
|
|
|
|
categoriesCount: string;
|
|
|
|
|
productsCount: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
entriesCount: string;
|
|
|
|
|
categoryBannerPlaceholder: string;
|
|
|
|
|
navigationPlaceholder: string;
|
|
|
|
|
removeSavedSearch: string;
|
|
|
|
|
resetFilters: string;
|
|
|
|
|
filtersTitle: string;
|
2026-07-09 02:57:48 +04:00
|
|
|
from: string;
|
|
|
|
|
to: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
minValue: string;
|
|
|
|
|
maxValue: string;
|
|
|
|
|
enabled: string;
|
|
|
|
|
searchPlaceholder: string;
|
|
|
|
|
searchSubmit: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
clearSearch: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
suggestionsTitle: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
popularSearchesTitle: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
recentSearchesTitle: string;
|
|
|
|
|
searchHistoryTitle: string;
|
|
|
|
|
clearHistory: string;
|
|
|
|
|
searchNoResultsHint: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
searchProductsFound: string;
|
|
|
|
|
searchResultsSummary: string;
|
2026-07-10 15:55:38 +04:00
|
|
|
loadMore: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
sortBy: string;
|
|
|
|
|
sortRelevance: string;
|
|
|
|
|
sortLatest: string;
|
|
|
|
|
sortPriceAsc: string;
|
|
|
|
|
sortPriceDesc: string;
|
|
|
|
|
sortRating: string;
|
|
|
|
|
sortPopular: string;
|
|
|
|
|
sortDiscount: string;
|
|
|
|
|
layoutGrid: string;
|
|
|
|
|
layoutLargeGrid: string;
|
|
|
|
|
layoutCompactGrid: string;
|
2026-07-10 15:55:38 +04:00
|
|
|
layoutGrid2: string;
|
|
|
|
|
layoutGrid3: string;
|
|
|
|
|
layoutGrid4: string;
|
|
|
|
|
layoutCompact: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
layoutList: string;
|
|
|
|
|
noResults: string;
|
|
|
|
|
itemsCount: string;
|
|
|
|
|
emptyResultsTitle: string;
|
|
|
|
|
emptyResultsDescription: string;
|
|
|
|
|
previousPage: string;
|
|
|
|
|
nextPage: string;
|
|
|
|
|
pageOf: string;
|
2026-07-09 01:46:32 +04:00
|
|
|
emptyCategoryTitle: string;
|
|
|
|
|
emptyCategoryMessage: string;
|
2026-07-10 15:55:38 +04:00
|
|
|
goToParentCategory: string;
|
2026-07-09 01:46:32 +04:00
|
|
|
browseCategories: string;
|
2026-07-10 15:55:38 +04:00
|
|
|
offlineTitle: string;
|
|
|
|
|
offlineMessage: string;
|
2026-07-09 01:46:32 +04:00
|
|
|
noFilterMatchTitle: string;
|
|
|
|
|
noFilterMatchMessage: string;
|
|
|
|
|
clearFilters: string;
|
|
|
|
|
openFilters: string;
|
|
|
|
|
applyFilters: string;
|
|
|
|
|
close: string;
|
|
|
|
|
filtersDrawerAria: string;
|
|
|
|
|
sortSheetAria: string;
|
|
|
|
|
mobileToolbarAria: string;
|
|
|
|
|
gridCycle: string;
|
|
|
|
|
filtersPanelAria: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
filterPrice: string;
|
|
|
|
|
filterAvailability: string;
|
|
|
|
|
filterInStock: string;
|
|
|
|
|
filterLowStock: string;
|
|
|
|
|
filterOutOfStock: string;
|
|
|
|
|
filterRating: string;
|
|
|
|
|
filterStars: string;
|
|
|
|
|
filterBrand: string;
|
|
|
|
|
filterCategory: string;
|
|
|
|
|
filterCategoryValue: string;
|
|
|
|
|
filterSubcategory: string;
|
|
|
|
|
filterDiscount: string;
|
|
|
|
|
filterNew: string;
|
|
|
|
|
filterColor: string;
|
|
|
|
|
filterSize: string;
|
|
|
|
|
filterAttributes: string;
|
|
|
|
|
};
|
|
|
|
|
productDetails: {
|
|
|
|
|
loading: string;
|
|
|
|
|
errorTitle: string;
|
|
|
|
|
retry: string;
|
|
|
|
|
missingTitle: string;
|
|
|
|
|
missingDescription: string;
|
|
|
|
|
backToCatalog: string;
|
|
|
|
|
tabsAria: string;
|
|
|
|
|
mediaAria: string;
|
|
|
|
|
ratingStarsAria: string;
|
|
|
|
|
selectRatingAria: string;
|
|
|
|
|
reviewsEmpty: string;
|
|
|
|
|
questionsEmpty: string;
|
|
|
|
|
askQuestion: string;
|
|
|
|
|
hideQuestionForm: string;
|
|
|
|
|
questionFormTitle: string;
|
|
|
|
|
questionFormPlaceholder: string;
|
|
|
|
|
questionFormAnonymous: string;
|
|
|
|
|
submitQuestion: string;
|
|
|
|
|
reviewFormTitle: string;
|
|
|
|
|
reviewRatingLabel: string;
|
|
|
|
|
reviewTitleLabel: string;
|
|
|
|
|
reviewTitlePlaceholder: string;
|
|
|
|
|
reviewTextLabel: string;
|
|
|
|
|
reviewTextPlaceholder: string;
|
|
|
|
|
reviewAnonymous: string;
|
|
|
|
|
reviewUploadPlaceholder: string;
|
2026-07-10 13:10:35 +04:00
|
|
|
reviewRatingRequired: string;
|
|
|
|
|
reviewTextRequired: string;
|
|
|
|
|
reviewSuccess: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
submitReview: string;
|
|
|
|
|
submitting: string;
|
2026-07-10 13:10:35 +04:00
|
|
|
loadMore: string;
|
|
|
|
|
showingOf: string;
|
|
|
|
|
questionsSubmissionFuture: string;
|
|
|
|
|
specificationsGeneral: string;
|
|
|
|
|
actionsAria: string;
|
|
|
|
|
buyNow: string;
|
|
|
|
|
wishlist: string;
|
|
|
|
|
compare: string;
|
|
|
|
|
share: string;
|
|
|
|
|
notifyMe: string;
|
|
|
|
|
zoom: string;
|
|
|
|
|
fullscreen: string;
|
|
|
|
|
pdfDocument: string;
|
|
|
|
|
manualDocument: string;
|
|
|
|
|
warrantyDocument: string;
|
|
|
|
|
openDocument: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
specificationsEmpty: string;
|
|
|
|
|
warrantyTitle: string;
|
|
|
|
|
warrantyItem1: string;
|
|
|
|
|
warrantyItem2: string;
|
|
|
|
|
warrantyItem3: string;
|
|
|
|
|
verifiedPurchase: string;
|
|
|
|
|
officialSeller: string;
|
|
|
|
|
acceptedAnswer: string;
|
|
|
|
|
like: string;
|
|
|
|
|
dislike: string;
|
|
|
|
|
reviewsCountLabel: string;
|
|
|
|
|
previous: string;
|
|
|
|
|
next: string;
|
|
|
|
|
pageOf: string;
|
2026-07-05 01:36:21 +04:00
|
|
|
};
|
2026-02-26 23:09:20 +04:00
|
|
|
subcategories: {
|
|
|
|
|
loading: string;
|
|
|
|
|
retry: string;
|
|
|
|
|
emptyTitle: string;
|
|
|
|
|
emptyDesc: string;
|
|
|
|
|
goHome: string;
|
2026-03-24 00:09:11 +04:00
|
|
|
itemsInCategory: string;
|
2026-07-05 01:09:55 +04:00
|
|
|
childrenCount: string;
|
|
|
|
|
productsCount: string;
|
|
|
|
|
includesProducts: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
};
|
|
|
|
|
itemDetail: {
|
|
|
|
|
loading: string;
|
|
|
|
|
loadingDexar: string;
|
|
|
|
|
back: string;
|
|
|
|
|
backHome: string;
|
|
|
|
|
noImage: string;
|
|
|
|
|
stock: string;
|
|
|
|
|
inStock: string;
|
|
|
|
|
lowStock: string;
|
|
|
|
|
lastItems: string;
|
|
|
|
|
mediumStock: string;
|
|
|
|
|
addToCart: string;
|
|
|
|
|
description: string;
|
2026-02-28 16:13:14 +04:00
|
|
|
specifications: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
reviews: string;
|
|
|
|
|
yourReview: string;
|
|
|
|
|
leaveReview: string;
|
|
|
|
|
rating: string;
|
|
|
|
|
reviewPlaceholder: string;
|
|
|
|
|
reviewPlaceholderDexar: string;
|
|
|
|
|
anonymous: string;
|
|
|
|
|
submitting: string;
|
|
|
|
|
submit: string;
|
|
|
|
|
reviewSuccess: string;
|
|
|
|
|
reviewError: string;
|
|
|
|
|
defaultUser: string;
|
|
|
|
|
defaultUserDexar: string;
|
|
|
|
|
noReviews: string;
|
|
|
|
|
qna: string;
|
|
|
|
|
photo: string;
|
|
|
|
|
reviewsCount: string;
|
|
|
|
|
today: string;
|
|
|
|
|
yesterday: string;
|
|
|
|
|
daysAgo: string;
|
|
|
|
|
weeksAgo: string;
|
2026-03-24 00:09:11 +04:00
|
|
|
colour: string;
|
|
|
|
|
size: string;
|
2026-07-05 01:07:53 +04:00
|
|
|
relatedProducts: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
};
|
|
|
|
|
app: {
|
|
|
|
|
connecting: string;
|
|
|
|
|
serverUnavailable: string;
|
|
|
|
|
serverError: string;
|
|
|
|
|
retryConnection: string;
|
|
|
|
|
pageTitle: string;
|
|
|
|
|
};
|
2026-07-09 02:29:12 +04:00
|
|
|
platform: {
|
|
|
|
|
loadingPage: string;
|
|
|
|
|
emptyConfig: string;
|
|
|
|
|
};
|
|
|
|
|
backoffice: {
|
|
|
|
|
title: string;
|
|
|
|
|
subtitle: string;
|
|
|
|
|
loading: string;
|
|
|
|
|
products: string;
|
|
|
|
|
categories: string;
|
|
|
|
|
otherDomains: string;
|
|
|
|
|
sku: string;
|
|
|
|
|
titleColumn: string;
|
|
|
|
|
price: string;
|
|
|
|
|
status: string;
|
|
|
|
|
itemsCount: string;
|
|
|
|
|
orders: string;
|
|
|
|
|
customers: string;
|
|
|
|
|
inventory: string;
|
|
|
|
|
media: string;
|
|
|
|
|
settings: string;
|
|
|
|
|
notAvailable: string;
|
|
|
|
|
};
|
|
|
|
|
builder: {
|
|
|
|
|
title: string;
|
|
|
|
|
subtitle: string;
|
2026-07-10 13:43:53 +04:00
|
|
|
general: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
branding: string;
|
2026-07-10 13:43:53 +04:00
|
|
|
theme: string;
|
|
|
|
|
header: string;
|
|
|
|
|
footer: string;
|
|
|
|
|
homepage: string;
|
|
|
|
|
widgets: string;
|
2026-07-10 13:52:01 +04:00
|
|
|
staticPages: string;
|
2026-07-10 13:43:53 +04:00
|
|
|
marketplaceFeatures: string;
|
|
|
|
|
preview: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
brandName: string;
|
2026-07-10 13:43:53 +04:00
|
|
|
marketplaceName: string;
|
|
|
|
|
domain: string;
|
|
|
|
|
descriptionLabel: string;
|
|
|
|
|
defaultLanguage: string;
|
|
|
|
|
supportedLanguages: string;
|
|
|
|
|
logo: string;
|
|
|
|
|
smallLogo: string;
|
|
|
|
|
favicon: string;
|
2026-07-17 15:22:45 +04:00
|
|
|
socialImage: string;
|
|
|
|
|
gallery: string;
|
|
|
|
|
addGalleryImage: string;
|
2026-07-17 15:29:55 +04:00
|
|
|
headerLayout: string;
|
|
|
|
|
headerLayoutDefault: string;
|
|
|
|
|
headerLayoutCentered: string;
|
|
|
|
|
headerSticky: string;
|
2026-07-10 13:43:53 +04:00
|
|
|
marketplaceTitle: string;
|
|
|
|
|
primaryColor: string;
|
|
|
|
|
secondaryColor: string;
|
|
|
|
|
backgroundColor: string;
|
|
|
|
|
surfaceColor: string;
|
|
|
|
|
textColor: string;
|
|
|
|
|
successColor: string;
|
|
|
|
|
warningColor: string;
|
|
|
|
|
dangerColor: string;
|
|
|
|
|
showLogo: string;
|
|
|
|
|
showSearch: string;
|
|
|
|
|
showCategories: string;
|
|
|
|
|
showLanguages: string;
|
|
|
|
|
showCart: string;
|
|
|
|
|
showProfile: string;
|
|
|
|
|
showWishlist: string;
|
|
|
|
|
showCompare: string;
|
|
|
|
|
showRegion: string;
|
|
|
|
|
companyName: string;
|
|
|
|
|
address: string;
|
|
|
|
|
phone: string;
|
|
|
|
|
email: string;
|
|
|
|
|
copyright: string;
|
|
|
|
|
paymentIcons: string;
|
|
|
|
|
socialLinks: string;
|
2026-07-16 02:06:26 +04:00
|
|
|
footerLogo: string;
|
|
|
|
|
addPaymentIcon: string;
|
|
|
|
|
removePaymentIcon: string;
|
|
|
|
|
iconAltLabel: string;
|
|
|
|
|
addSocialLink: string;
|
|
|
|
|
removeSocialLink: string;
|
|
|
|
|
socialLinkLabel: string;
|
|
|
|
|
socialLinkUrl: string;
|
|
|
|
|
invalidUrl: string;
|
2026-07-10 13:52:01 +04:00
|
|
|
createPage: string;
|
|
|
|
|
deletePage: string;
|
|
|
|
|
pageId: string;
|
|
|
|
|
slug: string;
|
|
|
|
|
iconLabel: string;
|
|
|
|
|
showInFooter: string;
|
|
|
|
|
showInHeader: string;
|
|
|
|
|
showInSitemap: string;
|
|
|
|
|
requiresAuthentication: string;
|
|
|
|
|
footerGroup: string;
|
|
|
|
|
orderLabel: string;
|
|
|
|
|
translationTitle: string;
|
|
|
|
|
htmlPreview: string;
|
2026-07-15 04:11:18 +04:00
|
|
|
seoSection: string;
|
|
|
|
|
seoTitle: string;
|
|
|
|
|
seoDescription: string;
|
|
|
|
|
seoKeywords: string;
|
|
|
|
|
seoCanonical: string;
|
|
|
|
|
seoOgTitle: string;
|
|
|
|
|
seoOgDescription: string;
|
|
|
|
|
seoOgImage: string;
|
2026-07-10 13:43:53 +04:00
|
|
|
visible: string;
|
|
|
|
|
layoutLabel: string;
|
|
|
|
|
columns: string;
|
|
|
|
|
height: string;
|
|
|
|
|
overlay: string;
|
|
|
|
|
autoplay: string;
|
|
|
|
|
cardsPerRow: string;
|
|
|
|
|
filtersLabel: string;
|
|
|
|
|
showBadges: string;
|
|
|
|
|
showRating: string;
|
|
|
|
|
showPrice: string;
|
|
|
|
|
widgetJson: string;
|
|
|
|
|
reviews: string;
|
|
|
|
|
questions: string;
|
|
|
|
|
comments: string;
|
|
|
|
|
recommendations: string;
|
|
|
|
|
recentlyViewed: string;
|
|
|
|
|
searchSuggestions: string;
|
|
|
|
|
searchHistory: string;
|
|
|
|
|
livePreview: string;
|
2026-07-17 09:00:47 +04:00
|
|
|
previewChangesTitle: string;
|
|
|
|
|
previewNoIssues: string;
|
|
|
|
|
previewNoChanges: string;
|
|
|
|
|
previewChangeField: string;
|
|
|
|
|
previewChangeBefore: string;
|
|
|
|
|
previewChangeAfter: string;
|
2026-07-13 08:10:00 +04:00
|
|
|
languagesTab: string;
|
|
|
|
|
addLanguage: string;
|
|
|
|
|
removeLanguage: string;
|
|
|
|
|
setDefaultLanguage: string;
|
|
|
|
|
defaultLanguageLabel: string;
|
2026-07-13 08:57:42 +04:00
|
|
|
navigationTab: string;
|
|
|
|
|
navigationHeader: string;
|
|
|
|
|
navigationFooter: string;
|
|
|
|
|
navigationFooterGrouped: string;
|
|
|
|
|
addLink: string;
|
2026-07-17 10:18:08 +04:00
|
|
|
insertPageLink: string;
|
|
|
|
|
linkedToPage: string;
|
2026-07-13 08:57:42 +04:00
|
|
|
removeLink: string;
|
|
|
|
|
linkLabel: string;
|
|
|
|
|
linkUrl: string;
|
2026-07-10 13:43:53 +04:00
|
|
|
exportBootstrap: string;
|
|
|
|
|
importBootstrap: string;
|
|
|
|
|
exportedBootstrap: string;
|
|
|
|
|
importSource: string;
|
|
|
|
|
importError: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
featureFlags: string;
|
2026-07-13 10:51:05 +04:00
|
|
|
validationMissingLogo: string;
|
|
|
|
|
validationNoLanguages: string;
|
2026-07-17 19:00:17 +04:00
|
|
|
validationDefaultLocaleNotSupported: string;
|
2026-07-13 10:51:05 +04:00
|
|
|
validationInvalidUrl: string;
|
|
|
|
|
validationDuplicateSlugs: string;
|
|
|
|
|
validationEmptyHomepage: string;
|
|
|
|
|
validationMissingWidget: string;
|
|
|
|
|
validationDuplicateNavLinks: string;
|
|
|
|
|
validationInvalidColors: string;
|
2026-07-14 12:21:33 +04:00
|
|
|
validationMissingTranslations: string;
|
|
|
|
|
validationInvalidLayouts: string;
|
feat(project-editor): centralize schema-driven validation
Milestone 2 of the Configuration Engine sprint.
- Add schema/validators/primitives: pure isValidHexColor/HttpUrl/Email,
validateJson, validateCss, extractStyleBlocks, normalizeRoute. One function
per concern, no duplicated validator logic.
- Refactor ProjectValidator to compose the primitives and tag every issue with
section + fieldKey + severity ('error' blocks publish, 'warning' advisory).
Preserves all existing codes/messages; adds duplicate-routes, invalid-css,
invalid-widget-config checks.
- Facade: issuesByField, issuesBySection, blockingIssues, hasBlockingIssues;
publish() now gates on severity==='error' instead of any issue.
- i18n: add validationInvalidJson/Css/DuplicateRoutes/InvalidWidgetConfig to
the Translations interface + en/ru/hy.
- Specs: primitives + ProjectValidator (25 passing total).
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 01:58:36 +04:00
|
|
|
validationInvalidJson: string;
|
|
|
|
|
validationInvalidCss: string;
|
|
|
|
|
validationDuplicateRoutes: string;
|
|
|
|
|
validationInvalidWidgetConfig: string;
|
2026-07-17 16:57:43 +04:00
|
|
|
validationInvalidContactEmail: string;
|
|
|
|
|
validationInvalidSocialLinkUrl: string;
|
|
|
|
|
validationIncompletePaymentIcon: string;
|
2026-07-17 02:13:34 +04:00
|
|
|
undo: string;
|
|
|
|
|
redo: string;
|
2026-07-13 15:00:03 +04:00
|
|
|
statusDraft: string;
|
|
|
|
|
statusPublished: string;
|
|
|
|
|
unsavedChanges: string;
|
|
|
|
|
save: string;
|
|
|
|
|
publish: string;
|
2026-07-13 15:57:54 +04:00
|
|
|
confirmLeaveUnsaved: string;
|
|
|
|
|
promptLinkUrl: string;
|
|
|
|
|
promptImageUrl: string;
|
2026-07-17 10:00:33 +04:00
|
|
|
promptEmbedUrl: string;
|
|
|
|
|
htmlEditorInvalidHtml: string;
|
2026-07-13 15:57:54 +04:00
|
|
|
htmlEditorCode: string;
|
|
|
|
|
htmlEditorPreview: string;
|
2026-07-14 09:50:03 +04:00
|
|
|
lastSaved: string;
|
|
|
|
|
draftRestored: string;
|
|
|
|
|
dismiss: string;
|
|
|
|
|
resetDraft: string;
|
|
|
|
|
resetSection: string;
|
|
|
|
|
confirmResetDraft: string;
|
|
|
|
|
confirmResetSection: string;
|
2026-07-14 16:05:09 +04:00
|
|
|
marketplaceNameDesc: string;
|
|
|
|
|
domainDesc: string;
|
|
|
|
|
descriptionFieldDesc: string;
|
|
|
|
|
defaultLanguageDesc: string;
|
|
|
|
|
supportedLanguagesDesc: string;
|
|
|
|
|
logoDesc: string;
|
|
|
|
|
smallLogoDesc: string;
|
|
|
|
|
faviconDesc: string;
|
2026-07-17 15:22:45 +04:00
|
|
|
socialImageDesc: string;
|
|
|
|
|
galleryDesc: string;
|
2026-07-17 15:29:55 +04:00
|
|
|
headerLayoutDesc: string;
|
|
|
|
|
headerStickyDesc: string;
|
2026-07-14 16:05:09 +04:00
|
|
|
marketplaceTitleDesc: string;
|
|
|
|
|
primaryColorDesc: string;
|
|
|
|
|
secondaryColorDesc: string;
|
|
|
|
|
backgroundColorDesc: string;
|
|
|
|
|
surfaceColorDesc: string;
|
|
|
|
|
textColorDesc: string;
|
|
|
|
|
successColorDesc: string;
|
|
|
|
|
warningColorDesc: string;
|
|
|
|
|
dangerColorDesc: string;
|
|
|
|
|
themeModeLabel: string;
|
|
|
|
|
themeModeDesc: string;
|
|
|
|
|
themeModeLight: string;
|
|
|
|
|
themeModeLightDesc: string;
|
|
|
|
|
themeModeDark: string;
|
|
|
|
|
themeModeDarkDesc: string;
|
|
|
|
|
themeModeSystem: string;
|
|
|
|
|
themeModeSystemDesc: string;
|
|
|
|
|
siteLayoutLabel: string;
|
|
|
|
|
siteLayoutDesc: string;
|
|
|
|
|
siteLayoutDefault: string;
|
|
|
|
|
siteLayoutDefaultDesc: string;
|
|
|
|
|
siteLayoutSidebarLeft: string;
|
|
|
|
|
siteLayoutSidebarLeftDesc: string;
|
|
|
|
|
siteLayoutCarouselHome: string;
|
|
|
|
|
siteLayoutCarouselHomeDesc: string;
|
|
|
|
|
siteLayoutMinimal: string;
|
|
|
|
|
siteLayoutMinimalDesc: string;
|
|
|
|
|
showLogoDesc: string;
|
|
|
|
|
showSearchDesc: string;
|
|
|
|
|
showCategoriesDesc: string;
|
|
|
|
|
showLanguagesDesc: string;
|
|
|
|
|
showCartDesc: string;
|
|
|
|
|
showProfileDesc: string;
|
|
|
|
|
showWishlistDesc: string;
|
|
|
|
|
showCompareDesc: string;
|
|
|
|
|
showRegionDesc: string;
|
|
|
|
|
companyNameDesc: string;
|
|
|
|
|
addressDesc: string;
|
|
|
|
|
phoneDesc: string;
|
|
|
|
|
emailDesc: string;
|
|
|
|
|
copyrightDesc: string;
|
|
|
|
|
paymentIconsDesc: string;
|
|
|
|
|
socialLinksDesc: string;
|
2026-07-16 02:06:26 +04:00
|
|
|
footerLogoDesc: string;
|
|
|
|
|
iconAltLabelDesc: string;
|
|
|
|
|
socialLinkUrlDesc: string;
|
2026-07-14 16:05:09 +04:00
|
|
|
staticPagesFieldDesc: string;
|
|
|
|
|
sectionVisibleDesc: string;
|
|
|
|
|
layoutStrategyLabel: string;
|
|
|
|
|
layoutStrategyDesc: string;
|
|
|
|
|
layoutStrategyStack: string;
|
|
|
|
|
layoutStrategyStackDesc: string;
|
|
|
|
|
layoutStrategyGrid: string;
|
|
|
|
|
layoutStrategyGridDesc: string;
|
|
|
|
|
layoutStrategyHero: string;
|
|
|
|
|
layoutStrategyHeroDesc: string;
|
|
|
|
|
layoutStrategyCarousel: string;
|
|
|
|
|
layoutStrategyCarouselDesc: string;
|
|
|
|
|
layoutStrategySplit: string;
|
|
|
|
|
layoutStrategySplitDesc: string;
|
|
|
|
|
sectionColumnsDesc: string;
|
|
|
|
|
widgetLayoutDesc: string;
|
|
|
|
|
widgetHeightDesc: string;
|
|
|
|
|
widgetOverlayDesc: string;
|
|
|
|
|
widgetAutoplayDesc: string;
|
|
|
|
|
widgetColumnsDesc: string;
|
|
|
|
|
widgetCardsPerRowDesc: string;
|
|
|
|
|
widgetFiltersDesc: string;
|
|
|
|
|
widgetShowBadgesDesc: string;
|
|
|
|
|
widgetShowRatingDesc: string;
|
|
|
|
|
widgetShowPriceDesc: string;
|
|
|
|
|
widgetJsonDesc: string;
|
2026-07-17 18:14:58 +04:00
|
|
|
widgetJsonInvalid: string;
|
2026-07-14 16:05:09 +04:00
|
|
|
wishlistFeatureDesc: string;
|
|
|
|
|
compareFeatureDesc: string;
|
|
|
|
|
reviewsFeatureDesc: string;
|
|
|
|
|
questionsFeatureDesc: string;
|
|
|
|
|
commentsFeatureDesc: string;
|
|
|
|
|
recommendationsFeatureDesc: string;
|
|
|
|
|
recentlyViewedFeatureDesc: string;
|
|
|
|
|
searchSuggestionsDesc: string;
|
|
|
|
|
searchHistoryDesc: string;
|
|
|
|
|
catalogNavigationModeLabel: string;
|
|
|
|
|
catalogNavigationModeDesc: string;
|
|
|
|
|
catalogNavDefault: string;
|
|
|
|
|
catalogNavDefaultDesc: string;
|
|
|
|
|
catalogNavLeftCategory: string;
|
|
|
|
|
catalogNavLeftCategoryDesc: string;
|
|
|
|
|
catalogNavMegaCategory: string;
|
|
|
|
|
catalogNavMegaCategoryDesc: string;
|
|
|
|
|
catalogNavTopCarousel: string;
|
|
|
|
|
catalogNavTopCarouselDesc: string;
|
|
|
|
|
newLanguageDesc: string;
|
2026-07-17 18:31:01 +04:00
|
|
|
languageAlreadyAdded: string;
|
2026-07-14 16:05:09 +04:00
|
|
|
languagesTabDesc: string;
|
|
|
|
|
linkLabelDesc: string;
|
|
|
|
|
linkUrlDesc: string;
|
|
|
|
|
linkVisibleDesc: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
};
|
2026-07-14 12:21:33 +04:00
|
|
|
dashboard: {
|
|
|
|
|
title: string;
|
|
|
|
|
subtitle: string;
|
|
|
|
|
cardMarketplaceStatus: string;
|
|
|
|
|
cardProjectName: string;
|
|
|
|
|
cardCurrentTheme: string;
|
|
|
|
|
cardLanguages: string;
|
|
|
|
|
cardCategoriesCount: string;
|
|
|
|
|
cardProductsCount: string;
|
|
|
|
|
cardOrders: string;
|
|
|
|
|
cardRevenue: string;
|
|
|
|
|
cardLastPublish: string;
|
|
|
|
|
cardLastDraftSave: string;
|
|
|
|
|
cardBootstrapVersion: string;
|
|
|
|
|
cardActiveLayout: string;
|
|
|
|
|
cardEnabledWidgets: string;
|
|
|
|
|
stateLoading: string;
|
|
|
|
|
stateEmpty: string;
|
|
|
|
|
stateError: string;
|
|
|
|
|
statePendingBackend: string;
|
|
|
|
|
never: string;
|
|
|
|
|
quickActionsTitle: string;
|
|
|
|
|
actionEditProject: string;
|
|
|
|
|
actionCategories: string;
|
|
|
|
|
actionProducts: string;
|
|
|
|
|
actionStaticPages: string;
|
|
|
|
|
actionTransactions: string;
|
|
|
|
|
actionOrders: string;
|
|
|
|
|
actionMediaLibrary: string;
|
2026-07-15 20:25:12 +04:00
|
|
|
actionUsers: string;
|
|
|
|
|
actionMonitoring: string;
|
|
|
|
|
actionAnalytics: string;
|
2026-07-14 12:21:33 +04:00
|
|
|
actionPreviewMarketplace: string;
|
|
|
|
|
activityTitle: string;
|
|
|
|
|
activityEmpty: string;
|
|
|
|
|
activityDraftSaved: string;
|
|
|
|
|
activityPublished: string;
|
|
|
|
|
healthTitle: string;
|
|
|
|
|
healthAllClear: string;
|
|
|
|
|
healthBootstrapValid: string;
|
|
|
|
|
healthConfigurationValid: string;
|
|
|
|
|
healthMissingTranslations: string;
|
|
|
|
|
healthInvalidColors: string;
|
|
|
|
|
healthInvalidWidgetReferences: string;
|
|
|
|
|
healthInvalidLayouts: string;
|
|
|
|
|
comingSoonTitle: string;
|
|
|
|
|
comingSoonDescription: string;
|
|
|
|
|
backToDashboard: string;
|
|
|
|
|
};
|
2026-07-10 13:52:01 +04:00
|
|
|
staticPages: {
|
|
|
|
|
notFound: string;
|
|
|
|
|
backHome: string;
|
|
|
|
|
duplicateSlug: string;
|
|
|
|
|
emptyTitle: string;
|
feat(static-pages): CRUD completion + search/filter/bulk actions
Milestone 2 of the Static Pages Module sprint.
- StaticPagesEditorComponent: duplicate page, confirm-before-delete/bulk-
delete (matches the resetDraft confirm pattern), route/enabled/customTemplate/
media(hero/thumbnail/gallery) fields wired into the card, per-page publish/
unpublish action, status + duplicate-route/invalid-html/invalid-seo badges.
- Search (id/slug/route/title across all locales), filter by status
(draft/published) and by locale (hides pages missing a translation for the
selected locale) - all local computed() filters, no new service.
- Bulk selection (per-row + select-all-visible checkboxes) with bulk delete/
enable/disable/publish/unpublish, one updateBootstrap() call each.
- Correctness note: introduced `allPages` (unfiltered) vs `pages` (filtered
view) computeds. Every mutation (create/duplicate/delete/move/bulk) reads
from allPages(), never the filtered pages() - reading from the filtered
view would have silently deleted whatever an active search/filter hid on
the next persist(). Documented inline on persist() as a guardrail for
future edits.
- Fixed a template compile error found by the build gate: Angular templates
don't support inline arrow functions in binding expressions
((ngModelChange)="...map(v => v.trim())..." failed to parse) - moved the
gallery CSV-parsing into a component method (updateGallery).
- SEO robots field added to the page card (validated against a known-token
set from M1).
- i18n: staticPages.* extended (search/filter/bulk/route/enabled/status/
media/robots/disabled labels) across the interface + en/ru/hy.
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 09:55:21 +04:00
|
|
|
duplicateRoute: string;
|
|
|
|
|
invalidHtml: string;
|
|
|
|
|
invalidSeo: string;
|
|
|
|
|
searchPlaceholder: string;
|
|
|
|
|
filterAll: string;
|
|
|
|
|
filterAllLocales: string;
|
|
|
|
|
confirmDeletePage: string;
|
|
|
|
|
confirmBulkDelete: string;
|
|
|
|
|
duplicatePage: string;
|
|
|
|
|
selectAll: string;
|
|
|
|
|
selectedCount: string;
|
|
|
|
|
bulkDelete: string;
|
|
|
|
|
bulkEnable: string;
|
|
|
|
|
bulkDisable: string;
|
|
|
|
|
bulkPublishAction: string;
|
|
|
|
|
bulkUnpublish: string;
|
|
|
|
|
routeLabel: string;
|
|
|
|
|
enabledLabel: string;
|
|
|
|
|
statusLabel: string;
|
|
|
|
|
publishPageAction: string;
|
|
|
|
|
unpublishPageAction: string;
|
|
|
|
|
heroImageLabel: string;
|
|
|
|
|
thumbnailLabel: string;
|
|
|
|
|
galleryLabel: string;
|
|
|
|
|
customTemplateLabel: string;
|
|
|
|
|
seoRobotsLabel: string;
|
|
|
|
|
disabledBadge: string;
|
2026-07-17 10:11:31 +04:00
|
|
|
previewDesktop: string;
|
|
|
|
|
previewTablet: string;
|
|
|
|
|
previewMobile: string;
|
|
|
|
|
previewToggle: string;
|
2026-07-10 13:52:01 +04:00
|
|
|
};
|
2026-07-09 02:29:12 +04:00
|
|
|
widgets: {
|
|
|
|
|
unavailable: string;
|
|
|
|
|
};
|
2026-02-26 23:09:20 +04:00
|
|
|
carousel: {
|
|
|
|
|
loading: string;
|
|
|
|
|
addToCart: string;
|
|
|
|
|
};
|
|
|
|
|
common: {
|
|
|
|
|
retry: string;
|
|
|
|
|
loading: string;
|
2026-07-17 15:22:45 +04:00
|
|
|
remove: string;
|
2026-02-26 23:09:20 +04:00
|
|
|
};
|
2026-02-28 17:18:24 +04:00
|
|
|
location: {
|
|
|
|
|
allRegions: string;
|
|
|
|
|
chooseRegion: string;
|
|
|
|
|
detectAuto: string;
|
|
|
|
|
};
|
|
|
|
|
auth: {
|
|
|
|
|
loginRequired: string;
|
|
|
|
|
loginDescription: string;
|
|
|
|
|
checking: string;
|
|
|
|
|
loginWithTelegram: string;
|
|
|
|
|
orScanQr: string;
|
|
|
|
|
loginNote: string;
|
2026-03-25 15:32:50 +04:00
|
|
|
qrExpired: string;
|
2026-06-01 00:47:26 +04:00
|
|
|
qrError: string;
|
2026-02-28 17:18:24 +04:00
|
|
|
};
|
2026-07-09 01:13:54 +04:00
|
|
|
ux: {
|
|
|
|
|
items: string;
|
|
|
|
|
wishlistTitle: string;
|
|
|
|
|
wishlistEmptyTitle: string;
|
|
|
|
|
wishlistEmptyDescription: string;
|
|
|
|
|
clearWishlist: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
wishlistCleared: string;
|
2026-07-09 01:13:54 +04:00
|
|
|
compareTitle: string;
|
|
|
|
|
compareEmptyTitle: string;
|
|
|
|
|
compareEmptyDescription: string;
|
|
|
|
|
clearCompare: string;
|
|
|
|
|
hideIdentical: string;
|
|
|
|
|
highlightDifferences: string;
|
|
|
|
|
clearRecentlyViewed: string;
|
|
|
|
|
recentlyViewedEmpty: string;
|
|
|
|
|
saveSearch: string;
|
|
|
|
|
goToCatalog: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
wishlistAdded: string;
|
|
|
|
|
wishlistRemoved: string;
|
|
|
|
|
compareAdded: string;
|
|
|
|
|
compareRemoved: string;
|
|
|
|
|
compareLimitReached: string;
|
|
|
|
|
productShared: string;
|
|
|
|
|
productLinkCopied: string;
|
|
|
|
|
sharingUnsupported: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
addedToCart: string;
|
2026-07-09 01:40:22 +04:00
|
|
|
enterQueryBeforeSave: string;
|
|
|
|
|
savedSearchNamed: string;
|
2026-07-09 02:29:12 +04:00
|
|
|
recentlyViewedTitle: string;
|
|
|
|
|
compareAttribute: string;
|
|
|
|
|
comparePrice: string;
|
|
|
|
|
compareRating: string;
|
|
|
|
|
compareStock: string;
|
|
|
|
|
compareDiscount: string;
|
|
|
|
|
compareColor: string;
|
|
|
|
|
compareSize: string;
|
|
|
|
|
compareUnknown: string;
|
2026-07-09 01:13:54 +04:00
|
|
|
};
|
2026-07-10 13:34:25 +04:00
|
|
|
diagnostics: {
|
|
|
|
|
title: string;
|
|
|
|
|
disabledTitle: string;
|
|
|
|
|
disabledDescription: string;
|
|
|
|
|
generatedAt: string;
|
|
|
|
|
healthScore: string;
|
|
|
|
|
summary: string;
|
|
|
|
|
passedChecks: string;
|
|
|
|
|
warnings: string;
|
|
|
|
|
errors: string;
|
|
|
|
|
critical: string;
|
|
|
|
|
healthChecks: string;
|
|
|
|
|
results: string;
|
|
|
|
|
noIssues: string;
|
|
|
|
|
ok: string;
|
|
|
|
|
failed: string;
|
|
|
|
|
affectedComponent: string;
|
|
|
|
|
suggestedResolution: string;
|
|
|
|
|
severity: {
|
|
|
|
|
info: string;
|
|
|
|
|
warning: string;
|
|
|
|
|
error: string;
|
|
|
|
|
critical: string;
|
|
|
|
|
};
|
|
|
|
|
checks: {
|
|
|
|
|
bootstrapLoaded: string;
|
|
|
|
|
tenantResolved: string;
|
|
|
|
|
runtimeInitialized: string;
|
|
|
|
|
themeLoaded: string;
|
|
|
|
|
widgetManifestLoaded: string;
|
|
|
|
|
sectionEngineInitialized: string;
|
|
|
|
|
configurationEngineInitialized: string;
|
|
|
|
|
translationResourcesAvailable: string;
|
|
|
|
|
requiredAssetsAvailable: string;
|
|
|
|
|
};
|
|
|
|
|
bootstrapMissingTitle: string;
|
|
|
|
|
bootstrapMissingDescription: string;
|
|
|
|
|
bootstrapMissingResolution: string;
|
|
|
|
|
requiredPropertyMissingTitle: string;
|
|
|
|
|
requiredPropertyMissingDescription: string;
|
|
|
|
|
requiredPropertyMissingResolution: string;
|
|
|
|
|
unknownWidgetTypeTitle: string;
|
|
|
|
|
unknownWidgetTypeDescription: string;
|
|
|
|
|
unknownWidgetTypeResolution: string;
|
|
|
|
|
duplicateIdTitle: string;
|
|
|
|
|
duplicatePageIdDescription: string;
|
|
|
|
|
duplicateSectionIdDescription: string;
|
|
|
|
|
duplicateWidgetIdDescription: string;
|
|
|
|
|
duplicateIdResolution: string;
|
|
|
|
|
unknownLayoutTitle: string;
|
|
|
|
|
unknownLayoutDescription: string;
|
|
|
|
|
unknownLayoutResolution: string;
|
|
|
|
|
invalidFeatureFlagTitle: string;
|
|
|
|
|
invalidFeatureFlagDescription: string;
|
|
|
|
|
invalidFeatureFlagResolution: string;
|
|
|
|
|
brokenPageDefinitionTitle: string;
|
|
|
|
|
brokenPageDefinitionDescription: string;
|
|
|
|
|
brokenPageDefinitionResolution: string;
|
|
|
|
|
invalidNavigationTargetTitle: string;
|
|
|
|
|
invalidNavigationTargetDescription: string;
|
|
|
|
|
invalidNavigationTargetResolution: string;
|
|
|
|
|
missingTranslationTitle: string;
|
|
|
|
|
missingTranslationDescription: string;
|
|
|
|
|
missingTranslationResolution: string;
|
|
|
|
|
missingMediaTitle: string;
|
|
|
|
|
missingMediaDescription: string;
|
|
|
|
|
missingMediaResolution: string;
|
|
|
|
|
runtimeNotInitializedTitle: string;
|
|
|
|
|
runtimeNotInitializedDescription: string;
|
|
|
|
|
runtimeNotInitializedResolution: string;
|
|
|
|
|
configFallbackUsageTitle: string;
|
|
|
|
|
configFallbackUsageDescription: string;
|
|
|
|
|
configFallbackUsageResolution: string;
|
|
|
|
|
missingDatasourceTitle: string;
|
|
|
|
|
missingDatasourceDescription: string;
|
|
|
|
|
missingDatasourceResolution: string;
|
|
|
|
|
widgetRenderFailureTitle: string;
|
|
|
|
|
widgetRenderFailureDescription: string;
|
|
|
|
|
widgetRenderFailureResolution: string;
|
|
|
|
|
brokenRouteTitle: string;
|
|
|
|
|
brokenRouteDescription: string;
|
|
|
|
|
brokenRouteResolution: string;
|
|
|
|
|
imageLoadFailedTitle: string;
|
|
|
|
|
imageLoadFailedDescription: string;
|
|
|
|
|
imageLoadFailedResolution: string;
|
|
|
|
|
optionalDataMissingTitle: string;
|
|
|
|
|
optionalDataMissingDescription: string;
|
|
|
|
|
optionalDataMissingResolution: string;
|
|
|
|
|
};
|
feat(media): add Media Manager UI (grid, upload, delete)
MediaLibraryPageComponent replaces the coming-soon placeholder at
/backoffice/media. Built entirely on Sprint 6 Design System primitives
(app-card, app-button, app-input, app-empty-state, app-dialog, app-pagination,
app-skeleton) and Sprint 4 Task 2's MediaRepository/MockMediaRepository.
- Grid view with per-tile filename/size and delete action
- Hidden native file input triggered by an app-button, uploads via
MediaLibraryFacade -> MediaRepository.upload()
- Delete requires confirmation through app-dialog (destructive action)
- Search + pagination wired to MockMediaRepository's list() params
- Loading state shows app-skeleton tiles; empty state shows app-empty-state
- New mediaLibrary.* translation namespace across en/ru/hy
Verified in browser (via a temporary unguarded route, reverted before
commit - /backoffice/media itself requires Telegram QR admin auth not
available in this session): empty state renders correctly with translated
copy, search input and upload button present, no console errors.
2026-07-15 07:14:16 +04:00
|
|
|
mediaLibrary: {
|
|
|
|
|
title: string;
|
|
|
|
|
upload: string;
|
|
|
|
|
uploading: string;
|
|
|
|
|
searchPlaceholder: string;
|
|
|
|
|
delete: string;
|
|
|
|
|
deleteConfirmTitle: string;
|
|
|
|
|
deleteConfirmBody: string;
|
|
|
|
|
cancel: string;
|
|
|
|
|
confirm: string;
|
|
|
|
|
emptyTitle: string;
|
|
|
|
|
emptyDescription: string;
|
|
|
|
|
};
|
2026-07-16 00:19:41 +04:00
|
|
|
// Sprint 28: only the new empty-state copy this sprint's skeleton/empty-
|
|
|
|
|
// state consistency fix introduces - NOT the full adminProducts/
|
|
|
|
|
// adminUsers/adminMonitoring/adminAnalytics translation surface, which is
|
|
|
|
|
// still missing entirely (see docs/KNOWN-ISSUES.md, deferred to Sprint 29).
|
fix(static-pages): backfill enabled/status in export, fix missing i18n key
Independent review pass over the Static Pages Module sprint (M1-M7),
including live browser E2E per the task's own verification checklist.
- ProjectEditorFacade.normalize() now backfills enabled/status on
record-format static pages (defaulting missing values to enabled+published,
same rule ContentPageService.normalizePage applies for display - mirrored
rather than imported, to avoid a project-editor <-> content-management
circular dependency since ContentManagementFacade already depends on this
facade). Found live: exporting a page that predates this sprint and was
never touched/re-saved in the current session produced JSON missing
enabled/status entirely - the editor UI and storefront resolver both
normalize-on-read so nothing was actually broken live, but Export/Import
fidelity should match what the editor shows. Verified fixed live (export
now includes "enabled":true,"status":"published" for an untouched legacy
page) and via the full gate.
- Added the missing adminCategories.chooseImage i18n key (interface +
en/ru/hy). Found live: the media-picker "choose image" button rendered as
the literal string "adminCategories.chooseImage" - a pre-existing,
repo-wide bug (5 templates reference this key; none of the locale files
ever defined it) that I propagated into a 3rd/4th/5th... well, 2 new
occurrences by copying the existing branding-section/footer-section
pattern into static-pages-editor. Fixed the actual defect (missing
translation) rather than renaming the key, which would have required
touching 2 unrelated admin components outside this sprint's scope.
Live-verified this pass: Static Pages editor renders with all new fields;
create page works (page count 4->confirmed); device preview toggles
desktop/tablet/mobile widths correctly; navigation "Insert page link"
creates a real type:'staticPage' nav item end-to-end (confirmed in the
exported JSON); export includes all Sprint X+2 fields after the fix; no
console errors throughout.
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 11:27:29 +04:00
|
|
|
// Shared across branding/footer/static-pages/admin-product/admin-category media
|
|
|
|
|
// pickers - despite the namespace name, this is a generic "choose image" label,
|
|
|
|
|
// not category-specific. Renaming is a separate cleanup outside this sprint's
|
|
|
|
|
// scope; the key was previously referenced by 5 templates but never defined
|
|
|
|
|
// anywhere, so it rendered as the literal string "adminCategories.chooseImage".
|
|
|
|
|
adminCategories: {
|
|
|
|
|
chooseImage: string;
|
2026-07-17 15:22:45 +04:00
|
|
|
replaceImage: string;
|
fix(static-pages): backfill enabled/status in export, fix missing i18n key
Independent review pass over the Static Pages Module sprint (M1-M7),
including live browser E2E per the task's own verification checklist.
- ProjectEditorFacade.normalize() now backfills enabled/status on
record-format static pages (defaulting missing values to enabled+published,
same rule ContentPageService.normalizePage applies for display - mirrored
rather than imported, to avoid a project-editor <-> content-management
circular dependency since ContentManagementFacade already depends on this
facade). Found live: exporting a page that predates this sprint and was
never touched/re-saved in the current session produced JSON missing
enabled/status entirely - the editor UI and storefront resolver both
normalize-on-read so nothing was actually broken live, but Export/Import
fidelity should match what the editor shows. Verified fixed live (export
now includes "enabled":true,"status":"published" for an untouched legacy
page) and via the full gate.
- Added the missing adminCategories.chooseImage i18n key (interface +
en/ru/hy). Found live: the media-picker "choose image" button rendered as
the literal string "adminCategories.chooseImage" - a pre-existing,
repo-wide bug (5 templates reference this key; none of the locale files
ever defined it) that I propagated into a 3rd/4th/5th... well, 2 new
occurrences by copying the existing branding-section/footer-section
pattern into static-pages-editor. Fixed the actual defect (missing
translation) rather than renaming the key, which would have required
touching 2 unrelated admin components outside this sprint's scope.
Live-verified this pass: Static Pages editor renders with all new fields;
create page works (page count 4->confirmed); device preview toggles
desktop/tablet/mobile widths correctly; navigation "Insert page link"
creates a real type:'staticPage' nav item end-to-end (confirmed in the
exported JSON); export includes all Sprint X+2 fields after the fix; no
console errors throughout.
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 11:27:29 +04:00
|
|
|
};
|
2026-07-16 00:19:41 +04:00
|
|
|
adminProducts: {
|
|
|
|
|
emptyTitle: string;
|
|
|
|
|
emptyDescription: string;
|
|
|
|
|
};
|
|
|
|
|
adminUsers: {
|
|
|
|
|
emptyTitle: string;
|
|
|
|
|
emptyDescription: string;
|
|
|
|
|
invitationsEmptyTitle: string;
|
|
|
|
|
};
|
|
|
|
|
adminMonitoring: {
|
|
|
|
|
eventsEmptyTitle: string;
|
|
|
|
|
eventsEmptyDescription: string;
|
|
|
|
|
};
|
|
|
|
|
adminAnalytics: {
|
|
|
|
|
topProductsEmptyTitle: string;
|
|
|
|
|
topProductsEmptyDescription: string;
|
|
|
|
|
};
|
2026-02-26 23:09:20 +04:00
|
|
|
}
|