From 67dc9ad6bf6d10e700dcaea2faebd743d2187d5a Mon Sep 17 00:00:00 2001 From: Meg G <146496794+stardustmeg@users.noreply.github.com> Date: Sat, 8 Jun 2024 03:45:57 +0300 Subject: [PATCH] feat(RSS-ECOMM-5_11): translate breadcrumbs (#351) * fix: cart table header styles * fix: footer styles * feat: translate breadcrumbs * refactor: product page model component * feat: add scroll to top on pagination click * refactor: replace header heart svg * feat: translate wishlist breadcrumbs * refactor: remove unnecessary check --- .../Pagination/view/PaginationView.ts | 13 ++++- src/pages/CartPage/view/CartPageView.ts | 23 ++++---- .../CartPage/view/cartPageView.module.scss | 7 ++- .../ProductPage/model/ProductPageModel.ts | 58 +++++++++++++------ src/pages/ProductPage/view/ProductPageView.ts | 17 ++++++ .../view/UserProfilePageView.ts | 18 ------ .../WishlistPage/model/WishlistPageModel.ts | 29 +++++++--- .../WishlistPage/view/WishlistPageView.ts | 16 +++++ src/shared/constants/svg.ts | 1 + src/shared/utils/messageTemplates.ts | 3 + .../Footer/view/footerView.module.scss | 7 ++- src/widgets/Header/view/HeaderView.ts | 2 +- .../model/RegistrationFormModel.ts | 2 +- 13 files changed, 136 insertions(+), 60 deletions(-) diff --git a/src/features/Pagination/view/PaginationView.ts b/src/features/Pagination/view/PaginationView.ts index b49380f2..ccbdee69 100644 --- a/src/features/Pagination/view/PaginationView.ts +++ b/src/features/Pagination/view/PaginationView.ts @@ -56,6 +56,7 @@ class PaginationView { } else { this.callback(String(DEFAULT_PAGE + DEFAULT_PAGE)); } + this.scrollToTop(); }); return this.nextPageButton; @@ -67,7 +68,10 @@ class PaginationView { text: page.toString(), }); - btn.getHTML().addEventListener('click', () => this.callback(page.toString())); + btn.getHTML().addEventListener('click', () => { + this.callback(page.toString()); + this.scrollToTop(); + }); this.pageButtons.push(btn); @@ -85,6 +89,7 @@ class PaginationView { if (currentPage) { this.callback(String(Number(currentPage) - DEFAULT_PAGE)); } + this.scrollToTop(); }); return this.prevPageButton; } @@ -100,6 +105,12 @@ class PaginationView { } } + private scrollToTop(): void { + if (window.scrollY !== 0) { + window.scrollTo({ top: 0 }); + } + } + private switchStateNavigationButtons(page: number): void { this.prevPageButton.getHTML().disabled = page === DEFAULT_PAGE; this.nextPageButton.getHTML().disabled = page === this.pageButtons.length; diff --git a/src/pages/CartPage/view/CartPageView.ts b/src/pages/CartPage/view/CartPageView.ts index cf327335..f07b6c9a 100644 --- a/src/pages/CartPage/view/CartPageView.ts +++ b/src/pages/CartPage/view/CartPageView.ts @@ -4,6 +4,7 @@ import type { languageVariants } from '@/shared/types/common'; import type ProductOrderModel from '@/widgets/ProductOrder/model/ProductOrderModel'; import RouterModel from '@/app/Router/model/RouterModel.ts'; +import ButtonModel from '@/shared/Button/model/ButtonModel.ts'; import ConfirmModel from '@/shared/Confirm/model/ConfirmModel.ts'; import InputModel from '@/shared/Input/model/InputModel.ts'; import LinkModel from '@/shared/Link/model/LinkModel.ts'; @@ -12,6 +13,7 @@ import getStore from '@/shared/Store/Store.ts'; import { USER_MESSAGE } from '@/shared/constants/confirmUserMessage.ts'; import { PAGE_ID } from '@/shared/constants/pages.ts'; import createBaseElement from '@/shared/utils/createBaseElement.ts'; +import { cartPrice, minusCartPrice } from '@/shared/utils/messageTemplates.ts'; import styles from './cartPageView.module.scss'; @@ -23,13 +25,13 @@ type textElementsType = { }; const TITLE = { - BUTTON_CHECKOUT: { en: 'Proceed To Checkout', ru: 'Оформить заказ' }, + BUTTON_CHECKOUT: { en: 'Proceed to Checkout', ru: 'Оформить заказ' }, BUTTON_COUPON: { en: 'Apply', ru: 'Применить' }, CART_TOTAL: { en: 'Cart Totals', ru: 'Итого по корзине' }, CLEAR: { en: 'Clear all', ru: 'Очистить' }, CONTINUE: { en: 'Continue Shopping', ru: 'Продолжить покупки' }, - COUPON_APPLY: { en: 'Coupon Apply', ru: 'Применить купон' }, - COUPON_DISCOUNT: { en: 'Cart Coupons', ru: 'Скидки на корзину' }, + COUPON_APPLY: { en: 'Apply Coupon', ru: 'Применить купон' }, + COUPON_DISCOUNT: { en: 'Cart Discount', ru: 'Скидка на корзину' }, EMPTY: { en: `Oops! Looks like you haven't added the item to your cart yet.`, ru: `Ой! Похоже, вы еще не добавили товар в корзину.`, @@ -44,7 +46,7 @@ const TITLE = { class CartPageView { private addDiscountCallback: DiscountCallback; - private clear: LinkModel; + private clear: ButtonModel; private clearCallback: ClearCallback; @@ -103,7 +105,7 @@ class CartPageView { innerContent: TITLE.COUPON_DISCOUNT[this.language], tag: 'p', }); - this.clear = new LinkModel({ classes: [styles.continue, styles.clear], text: TITLE.CLEAR[this.language] }); + this.clear = new ButtonModel({ classes: [styles.continue, styles.clear], text: TITLE.CLEAR[this.language] }); this.totalWrap = this.createWrapHTML(); this.totalWrap.classList.add(styles.total); this.page.append(this.productWrap); @@ -226,8 +228,7 @@ class CartPageView { const tdDelete = createBaseElement({ cssClasses: [styles.th, styles.deleteCell, styles.mainText], tag: 'th' }); this.textElement.push({ element: this.clear.getHTML(), textItem: TITLE.CLEAR }); - this.clear.getHTML().addEventListener('click', (event) => { - event.preventDefault(); + this.clear.getHTML().addEventListener('click', () => { const confirmModel = new ConfirmModel( () => this.clearCallback(), USER_MESSAGE[getStore().getState().currentLanguage].CLEAR_CART, @@ -362,7 +363,7 @@ class CartPageView { }); const couponValue = createBaseElement({ cssClasses: [styles.title], - innerContent: `-$ ${discount.value.toFixed(2)}`, + innerContent: minusCartPrice(discount.value.toFixed(2)), tag: 'p', }); couponItem.append(couponTitle, couponValue); @@ -373,15 +374,15 @@ class CartPageView { const totalDiscountWrap = createBaseElement({ cssClasses: [styles.couponWrap], tag: 'div' }); const totalDiscountValue = createBaseElement({ cssClasses: [styles.title, styles.totalDiscount], - innerContent: `-$ ${totalDiscount.toFixed(2)}`, + innerContent: minusCartPrice(totalDiscount.toFixed(2)), tag: 'p', }); totalDiscountWrap.append(this.totalDiscountTitle, totalDiscountValue); this.discountTotal.append(totalDiscountWrap); } const subTotal = cart.total + totalDiscount; - this.subTotal.innerHTML = `$ ${subTotal.toFixed(2)}`; - this.total.innerHTML = `$ ${cart.total.toFixed(2)}`; + this.subTotal.innerHTML = cartPrice(subTotal.toFixed(2)); + this.total.innerHTML = cartPrice(cart.total.toFixed(2)); } } export default CartPageView; diff --git a/src/pages/CartPage/view/cartPageView.module.scss b/src/pages/CartPage/view/cartPageView.module.scss index f3162ed6..d8f566f7 100644 --- a/src/pages/CartPage/view/cartPageView.module.scss +++ b/src/pages/CartPage/view/cartPageView.module.scss @@ -193,13 +193,18 @@ $color: var(--steam-green-800); width: max-content; height: max-content; text-transform: none; - cursor: pointer; &::after { bottom: var(--five); } } +.clear { + @include link(0 0, $color); + + text-transform: none; +} + .mobileHide { @media (max-width: 768px) { display: none; diff --git a/src/pages/ProductPage/model/ProductPageModel.ts b/src/pages/ProductPage/model/ProductPageModel.ts index 152217e4..4540c106 100644 --- a/src/pages/ProductPage/model/ProductPageModel.ts +++ b/src/pages/ProductPage/model/ProductPageModel.ts @@ -9,7 +9,7 @@ import getStore from '@/shared/Store/Store.ts'; import { setCurrentPage } from '@/shared/Store/actions.ts'; import observeStore, { selectCurrentLanguage } from '@/shared/Store/observer.ts'; import { LANGUAGE_CHOICE } from '@/shared/constants/common.ts'; -import { PAGE_ID } from '@/shared/constants/pages.ts'; +import { PAGE_ID, PAGE_TITLE } from '@/shared/constants/pages.ts'; import { SEARCH_PARAMS_FIELD } from '@/shared/constants/product.ts'; import * as buildPath from '@/shared/utils/buildPathname.ts'; import { showErrorMessage } from '@/shared/utils/userMessage.ts'; @@ -18,7 +18,7 @@ import ProductInfoModel from '@/widgets/ProductInfo/model/ProductInfoModel.ts'; import ProductPageView from '../view/ProductPageView.ts'; class ProductPageModel implements Page { - private breadcrumbs = new BreadcrumbsModel(); + private currentProduct: Product | null = null; private view: ProductPageView; @@ -28,24 +28,27 @@ class ProductPageModel implements Page { } private createBreadcrumbLinks(currentProduct: Product): BreadcrumbLink[] { + const { currentLanguage } = getStore().getState(); + const isRuLanguage = currentLanguage === LANGUAGE_CHOICE.RU; const category = currentProduct.category[0].parent; const subcategory = currentProduct.category[0]; + const links: BreadcrumbLink[] = [ - { link: PAGE_ID.MAIN_PAGE, name: PAGE_ID.MAIN_PAGE.toString() }, - { link: PAGE_ID.CATALOG_PAGE, name: PAGE_ID.CATALOG_PAGE.toString() }, + { link: PAGE_ID.MAIN_PAGE, name: PAGE_TITLE[currentLanguage].main }, + { link: PAGE_ID.CATALOG_PAGE, name: PAGE_TITLE[currentLanguage].catalog }, ]; if (category) { links.push({ link: buildPath.catalogPathWithIDAndQuery(null, { category: [category.id] }), - name: category.name[0].value, + name: category.name[Number(isRuLanguage)].value, }); } if (subcategory && category) { links.push({ link: buildPath.catalogPathWithIDAndQuery(null, { category: [category.id], subcategory: [subcategory.id] }), - name: subcategory.name[0].value, + name: subcategory.name[Number(isRuLanguage)].value, }); } @@ -59,16 +62,8 @@ class ProductPageModel implements Page { .getProductByKey(params.product?.id ?? '') .then((productData) => { if (productData) { - const productInfo = new ProductInfoModel({ - currentSize: currentSize ?? productData.variant[0].size, - ...productData, - }); - this.initBreadcrumbs(productData); - this.getHTML().append(productInfo.getHTML(), this.view.getFullDescriptionWrapper()); - this.view.setFullDescription( - productData.fullDescription[Number(getStore().getState().currentLanguage === LANGUAGE_CHOICE.RU)].value, - ); - this.observeLanguage(productData.fullDescription); + this.currentProduct = productData; + this.updatePageContent(productData, currentSize); } }) .catch(showErrorMessage); @@ -77,8 +72,18 @@ class ProductPageModel implements Page { } private initBreadcrumbs(currentProduct: Product): void { - this.breadcrumbs.addBreadcrumbLinks(this.createBreadcrumbLinks(currentProduct)); - this.getHTML().append(this.breadcrumbs.getHTML()); + const breadcrumbsContainer = this.view.getBreadcrumbsContainer(); + if (!breadcrumbsContainer) { + return; + } + + const breadcrumbs = new BreadcrumbsModel(); + breadcrumbs.addBreadcrumbLinks(this.createBreadcrumbLinks(currentProduct)); + + while (breadcrumbsContainer.firstChild) { + breadcrumbsContainer.removeChild(breadcrumbsContainer.firstChild); + } + breadcrumbsContainer.appendChild(breadcrumbs.getHTML()); } private observeLanguage(fullDescription: localization[]): void { @@ -86,7 +91,24 @@ class ProductPageModel implements Page { this.view.setFullDescription( fullDescription[Number(getStore().getState().currentLanguage === LANGUAGE_CHOICE.RU)].value, ); + if (this.currentProduct) { + this.initBreadcrumbs(this.currentProduct); + } + }); + } + + private updatePageContent(productData: Product, currentSize: null | string): void { + this.initBreadcrumbs(productData); + + const productInfo = new ProductInfoModel({ + currentSize: currentSize ?? productData.variant[0].size, + ...productData, }); + this.getHTML().append(productInfo.getHTML(), this.view.getFullDescriptionWrapper()); + this.view.setFullDescription( + productData.fullDescription[Number(getStore().getState().currentLanguage === LANGUAGE_CHOICE.RU)].value, + ); + this.observeLanguage(productData.fullDescription); } public getHTML(): HTMLDivElement { diff --git a/src/pages/ProductPage/view/ProductPageView.ts b/src/pages/ProductPage/view/ProductPageView.ts index b75c70c3..d47963fd 100644 --- a/src/pages/ProductPage/view/ProductPageView.ts +++ b/src/pages/ProductPage/view/ProductPageView.ts @@ -6,6 +6,8 @@ import createBaseElement from '@/shared/utils/createBaseElement.ts'; import styles from './productPageView.module.scss'; class ProductPageView { + private breadcrumbsContainer: HTMLDivElement; + private fullDescription: HTMLParagraphElement; private fullDescriptionWrapper: HTMLDivElement; @@ -17,12 +19,21 @@ class ProductPageView { constructor(parent: HTMLDivElement) { this.parent = parent; this.parent.innerHTML = ''; + this.breadcrumbsContainer = this.createBreadcrumbsContainer(); this.fullDescription = this.createFullDescription(); this.fullDescriptionWrapper = this.createFullDescriptionWrapper(); this.page = this.createHTML(); window.scrollTo(0, 0); } + private createBreadcrumbsContainer(): HTMLDivElement { + this.breadcrumbsContainer = createBaseElement({ + cssClasses: [styles.breadcrumbsContainer], + tag: 'div', + }); + return this.breadcrumbsContainer; + } + private createFullDescription(): HTMLParagraphElement { this.fullDescription = createBaseElement({ cssClasses: [styles.fullDescription], @@ -56,11 +67,16 @@ class ProductPageView { tag: 'div', }); + this.page.prepend(this.breadcrumbsContainer); this.parent.append(this.page); return this.page; } + public getBreadcrumbsContainer(): HTMLDivElement { + return this.breadcrumbsContainer; + } + public getFullDescriptionWrapper(): HTMLDivElement { return this.fullDescriptionWrapper; } @@ -74,4 +90,5 @@ class ProductPageView { return this.fullDescription; } } + export default ProductPageView; diff --git a/src/pages/UserProfilePage/view/UserProfilePageView.ts b/src/pages/UserProfilePage/view/UserProfilePageView.ts index 10007139..670e39d7 100644 --- a/src/pages/UserProfilePage/view/UserProfilePageView.ts +++ b/src/pages/UserProfilePage/view/UserProfilePageView.ts @@ -31,8 +31,6 @@ class UserProfilePageView { private userProfileWrapper: HTMLDivElement; - private wishListLink: LinkModel; - constructor(parent: HTMLDivElement) { this.parent = parent; clearOutElement(this.parent); @@ -42,7 +40,6 @@ class UserProfilePageView { this.addressesLink = this.createAddressesLink(); this.ordersLink = this.createOrdersLink(); this.supportLink = this.createSupportLink(); - this.wishListLink = this.createWishListLink(); this.accountMenu = this.createAccountMenu(); this.setLinksHandlers(); @@ -168,21 +165,6 @@ class UserProfilePageView { return this.userProfileWrapper; } - private createWishListLink(): LinkModel { - this.wishListLink = new LinkModel({ - attrs: { - href: USER_PROFILE_MENU_LINK.WISHLIST, - }, - classes: [styles.link], - text: USER_INFO_MENU_LINK[getStore().getState().currentLanguage].WISHLIST, - }); - this.links.push(this.wishListLink); - - observeCurrentLanguage(this.wishListLink.getHTML(), USER_INFO_MENU_LINK, USER_INFO_MENU_LINK_KEYS.WISHLIST); - - return this.wishListLink; - } - private setLinksHandlers(): boolean { this.links.forEach((link) => { link.getHTML().addEventListener('click', (event) => { diff --git a/src/pages/WishlistPage/model/WishlistPageModel.ts b/src/pages/WishlistPage/model/WishlistPageModel.ts index 33b595bd..281fe957 100644 --- a/src/pages/WishlistPage/model/WishlistPageModel.ts +++ b/src/pages/WishlistPage/model/WishlistPageModel.ts @@ -4,25 +4,26 @@ import type { Page } from '@/shared/types/page.ts'; import BreadcrumbsModel from '@/features/Breadcrumbs/model/BreadcrumbsModel.ts'; import getStore from '@/shared/Store/Store.ts'; import { setCurrentPage } from '@/shared/Store/actions.ts'; -import { PAGE_ID } from '@/shared/constants/pages.ts'; +import observeStore, { selectCurrentLanguage } from '@/shared/Store/observer.ts'; +import { PAGE_ID, PAGE_TITLE } from '@/shared/constants/pages.ts'; import WishlistPageView from '../view/WishlistPageView.ts'; class WishlistPageModel implements Page { - private breadcrumbs = new BreadcrumbsModel(); - private view: WishlistPageView; constructor(parent: HTMLDivElement) { this.view = new WishlistPageView(parent); this.init(); + + this.observeLanguage(); } private createBreadcrumbLinksData(): BreadcrumbLink[] { return [ - { link: PAGE_ID.MAIN_PAGE, name: PAGE_ID.MAIN_PAGE.toString() }, - { link: PAGE_ID.CATALOG_PAGE, name: PAGE_ID.CATALOG_PAGE.toString() }, - { link: PAGE_ID.WISHLIST_PAGE, name: PAGE_ID.WISHLIST_PAGE.toString() }, + { link: PAGE_ID.MAIN_PAGE, name: PAGE_TITLE[getStore().getState().currentLanguage].main }, + { link: PAGE_ID.CATALOG_PAGE, name: PAGE_TITLE[getStore().getState().currentLanguage].catalog }, + { link: PAGE_ID.WISHLIST_PAGE, name: PAGE_TITLE[getStore().getState().currentLanguage].wishlist }, ]; } @@ -32,8 +33,20 @@ class WishlistPageModel implements Page { } private initBreadcrumbs(): void { - this.breadcrumbs.addBreadcrumbLinks(this.createBreadcrumbLinksData()); - this.getHTML().append(this.breadcrumbs.getHTML()); + const breadcrumbsContainer = this.view.getBreadcrumbsContainer(); + const breadcrumbs = new BreadcrumbsModel(); + breadcrumbs.addBreadcrumbLinks(this.createBreadcrumbLinksData()); + + while (breadcrumbsContainer.firstChild) { + breadcrumbsContainer.removeChild(breadcrumbsContainer.firstChild); + } + breadcrumbsContainer.appendChild(breadcrumbs.getHTML()); + } + + private observeLanguage(): void { + observeStore(selectCurrentLanguage, () => { + this.initBreadcrumbs(); + }); } public getHTML(): HTMLDivElement { diff --git a/src/pages/WishlistPage/view/WishlistPageView.ts b/src/pages/WishlistPage/view/WishlistPageView.ts index eaef7f82..ea961b43 100644 --- a/src/pages/WishlistPage/view/WishlistPageView.ts +++ b/src/pages/WishlistPage/view/WishlistPageView.ts @@ -21,6 +21,8 @@ import { showErrorMessage } from '@/shared/utils/userMessage.ts'; import styles from './wishlistPageView.module.scss'; class WishlistPageView { + private breadcrumbsContainer: HTMLDivElement; + private page: HTMLDivElement; private parent: HTMLDivElement; @@ -30,17 +32,27 @@ class WishlistPageView { constructor(parent: HTMLDivElement) { this.parent = parent; this.parent.innerHTML = ''; + this.breadcrumbsContainer = this.createBreadcrumbsContainer(); this.wishlist = this.createWishlist(); this.page = this.createHTML(); window.scrollTo(0, 0); } + private createBreadcrumbsContainer(): HTMLDivElement { + this.breadcrumbsContainer = createBaseElement({ + cssClasses: [styles.breadcrumbsContainer], + tag: 'div', + }); + return this.breadcrumbsContainer; + } + private createHTML(): HTMLDivElement { this.page = createBaseElement({ cssClasses: [styles.wishlistPage], tag: 'div', }); + this.page.prepend(this.breadcrumbsContainer); this.page.append(this.wishlist); this.parent.append(this.page); @@ -97,6 +109,10 @@ class WishlistPageView { this.switchEmptyList(!shoppingList.products.length); } + public getBreadcrumbsContainer(): HTMLDivElement { + return this.breadcrumbsContainer; + } + public getHTML(): HTMLDivElement { return this.page; } diff --git a/src/shared/constants/svg.ts b/src/shared/constants/svg.ts index b7c75ea9..b711872e 100644 --- a/src/shared/constants/svg.ts +++ b/src/shared/constants/svg.ts @@ -11,6 +11,7 @@ const SVG_DETAILS = { EDIT: 'edit', FILL_HEART: 'heartFill', GO_DETAILS: 'arrow', + HEART_OUTLINE: 'heartOutline', KEY: 'key', LEAVES: 'leaves', LIGHT: 'light', diff --git a/src/shared/utils/messageTemplates.ts b/src/shared/utils/messageTemplates.ts index 4b6d6ece..5c83a844 100644 --- a/src/shared/utils/messageTemplates.ts +++ b/src/shared/utils/messageTemplates.ts @@ -10,6 +10,9 @@ const textTemplate = (beginning: string, variable: number | string, end?: string return `${start}${variable}${ending}`; }; +export const cartPrice = (price: string): string => `$${price}`; +export const minusCartPrice = (price: string): string => `-$${price}`; + export const productAddedToCartMessage = (name: string): string => textTemplate(name, SERVER_MESSAGE[getStore().getState().currentLanguage].SUCCESSFUL_ADD_PRODUCT_TO_CART); diff --git a/src/widgets/Footer/view/footerView.module.scss b/src/widgets/Footer/view/footerView.module.scss index 9c3a24e4..6222b58e 100644 --- a/src/widgets/Footer/view/footerView.module.scss +++ b/src/widgets/Footer/view/footerView.module.scss @@ -20,11 +20,14 @@ .navigateWrap, .goalsSubWrap { display: flex; - flex-wrap: wrap; justify-content: center; padding: var(--extra-small-offset); width: 100%; background-color: var(--white-tr); + + @media (max-width: 587px) { + flex-direction: column; + } } .navigateWrap { @@ -62,6 +65,7 @@ .goalsWrap { display: flex; flex: 1 1 auto; + flex-shrink: 1; flex-basis: 70%; justify-content: space-around; gap: var(--tiny-offset); @@ -75,6 +79,7 @@ .goalTextWrap { display: flex; flex: 1 1 auto; + flex-shrink: 1; flex-direction: column; } diff --git a/src/widgets/Header/view/HeaderView.ts b/src/widgets/Header/view/HeaderView.ts index 4d9368a4..3087cbee 100644 --- a/src/widgets/Header/view/HeaderView.ts +++ b/src/widgets/Header/view/HeaderView.ts @@ -324,7 +324,7 @@ class HeaderView { }); const svg = document.createElementNS(SVG_DETAILS.SVG_URL, 'svg'); - svg.append(createSVGUse(SVG_DETAILS.FILL_HEART)); + svg.append(createSVGUse(SVG_DETAILS.HEART_OUTLINE)); this.toWishlistLink.getHTML().append(svg); diff --git a/src/widgets/RegistrationForm/model/RegistrationFormModel.ts b/src/widgets/RegistrationForm/model/RegistrationFormModel.ts index 1c11bf7e..8ca5ddb8 100644 --- a/src/widgets/RegistrationForm/model/RegistrationFormModel.ts +++ b/src/widgets/RegistrationForm/model/RegistrationFormModel.ts @@ -83,8 +83,8 @@ class RegisterFormModel { this.getHTML().append(this.personalInfoWrapper.getHTML()); this.inputFields.push( - ...this.personalInfoWrapper.getView().getInputFields(), ...this.credentialsWrapper.getView().getInputFields(), + ...this.personalInfoWrapper.getView().getInputFields(), ); Object.values(this.addressWrappers)