From e283c08b4ea49dc8d97a2c24682960312e9f6135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ramon=20do=20Ros=C3=A1rio?= Date: Tue, 10 Sep 2024 15:58:21 -0300 Subject: [PATCH 1/9] feat: start sku matrix --- packages/components/src/index.ts | 17 +- .../organisms/SKUMatrix/SKUMatrixSidebar.tsx | 89 ++++++++++ .../organisms/SKUMatrix/SKUMatrixTrigger.tsx | 23 +++ .../src/organisms/SKUMatrix/index.ts | 5 + .../src/components/SKUMatrix/SKUMatrix.tsx | 40 +++++ .../core/src/components/SKUMatrix/index.ts | 1 + .../components/SKUMatrix/section.module.scss | 21 +++ packages/core/src/pages/component.tsx | 11 ++ packages/core/src/styles/global/index.scss | 3 + .../organisms/SKUMatrix/styles.scss | 26 +++ packages/ui/src/styles/components.scss | 162 +++++++++--------- 11 files changed, 311 insertions(+), 87 deletions(-) create mode 100644 packages/components/src/organisms/SKUMatrix/SKUMatrixSidebar.tsx create mode 100644 packages/components/src/organisms/SKUMatrix/SKUMatrixTrigger.tsx create mode 100644 packages/components/src/organisms/SKUMatrix/index.ts create mode 100644 packages/core/src/components/SKUMatrix/SKUMatrix.tsx create mode 100644 packages/core/src/components/SKUMatrix/index.ts create mode 100644 packages/core/src/components/SKUMatrix/section.module.scss create mode 100644 packages/core/src/pages/component.tsx create mode 100644 packages/ui/src/components/organisms/SKUMatrix/styles.scss diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 3764572943..9cb02eca27 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -67,12 +67,8 @@ export type { CarouselBulletsProps, } from './molecules/Carousel' -export { - default as Card -} from './molecules/Card' -export type { - CardProps -} from './molecules/Card' +export { default as Card } from './molecules/Card' +export type { CardProps } from './molecules/Card' export { default as CartItem, @@ -360,3 +356,12 @@ export type { SlideOverProps, SlideOverHeaderProps, } from './organisms/SlideOver' + +export { + default as SKUMatrixTrigger, + SKUMatrixSidebar, +} from './organisms/SKUMatrix' +export type { + SKUMatrixTriggerProps, + SKUMatrixSidebarProps, +} from './organisms/SKUMatrix' diff --git a/packages/components/src/organisms/SKUMatrix/SKUMatrixSidebar.tsx b/packages/components/src/organisms/SKUMatrix/SKUMatrixSidebar.tsx new file mode 100644 index 0000000000..6aa620f547 --- /dev/null +++ b/packages/components/src/organisms/SKUMatrix/SKUMatrixSidebar.tsx @@ -0,0 +1,89 @@ +import React from 'react' +import type { ReactNode, HTMLAttributes } from 'react' +import SlideOver, { SlideOverHeader } from '../SlideOver' +import { SlideOverDirection, SlideOverWidthSize } from '../SlideOver' +import { useFadeEffect } from '../../hooks' +import { OverlayProps } from '../..' + +export interface SKUMatrixSidebarProps extends HTMLAttributes { + /** + * ID to find this component in testing tools (e.g.: cypress, + * testing-library, and jest). + */ + testId?: string + /** + * Title for the SKUMatrixSidebar component. + */ + title?: string + /** + * Represents the side that the SKUMatrixSidebar comes from. + */ + direction?: SlideOverDirection + /** + * Represents the size of the SKUMatrixSidebar. + */ + size?: SlideOverWidthSize + /** + * Total of selected item in the Matrix. + */ + // totalitems: number + /** + * A React component that will be rendered as an icon on the Alert component. + */ + alertIcon?: ReactNode + /** + * The content for Alert component. + */ + alertText?: string + /** + * Props forwarded to the `Overlay` component. + */ + overlayProps?: OverlayProps + /** + * Show slide over. + */ + isOpen: boolean + /** + * Function called when Close Button is clicked. + */ + onClose: () => void +} + +function SKUMatrixSidebar({ + direction = 'rightSide', + title, + overlayProps, + size = 'full', + isOpen, + children, + // totalitems = 0, + onClose, + ...otherProps +}: SKUMatrixSidebarProps) { + const { fade } = useFadeEffect() + + return ( + + { + onClose() + }} + data-fs-sku-matrix-sidebar-title + > +

{title}

+
+ + {children} +
+ ) +} + +export default SKUMatrixSidebar diff --git a/packages/components/src/organisms/SKUMatrix/SKUMatrixTrigger.tsx b/packages/components/src/organisms/SKUMatrix/SKUMatrixTrigger.tsx new file mode 100644 index 0000000000..3d0babcdc0 --- /dev/null +++ b/packages/components/src/organisms/SKUMatrix/SKUMatrixTrigger.tsx @@ -0,0 +1,23 @@ +import React from 'react' +import type { ReactNode } from 'react' +import Button from '../../atoms/Button' +import type { ButtonProps } from '../../atoms/Button' + +export interface SKUMatrixTriggerProps extends Pick { + children: ReactNode + onClick(): void +} + +function SKUMatrixTrigger({ + children, + variant = 'secondary', + onClick, +}: SKUMatrixTriggerProps) { + return ( + + ) +} + +export default SKUMatrixTrigger diff --git a/packages/components/src/organisms/SKUMatrix/index.ts b/packages/components/src/organisms/SKUMatrix/index.ts new file mode 100644 index 0000000000..d2743e257c --- /dev/null +++ b/packages/components/src/organisms/SKUMatrix/index.ts @@ -0,0 +1,5 @@ +export { default } from './SKUMatrixTrigger' +export type { SKUMatrixTriggerProps } from './SKUMatrixTrigger' + +export { default as SKUMatrixSidebar } from './SKUMatrixSidebar' +export type { SKUMatrixSidebarProps } from './SKUMatrixSidebar' diff --git a/packages/core/src/components/SKUMatrix/SKUMatrix.tsx b/packages/core/src/components/SKUMatrix/SKUMatrix.tsx new file mode 100644 index 0000000000..30198316da --- /dev/null +++ b/packages/core/src/components/SKUMatrix/SKUMatrix.tsx @@ -0,0 +1,40 @@ +import { useState } from 'react' + +import { + SKUMatrixSidebar as SKUMatrixSidebar, + SKUMatrixTrigger as UISKUMatrixTrigger, +} from '@faststore/ui' +import styles from './section.module.scss' + +interface SKUMatrixProps { + button: { + label: string + } +} + +function SKUMatrix({ button: { label } }: SKUMatrixProps) { + const [isOpen, setIsOpen] = useState(false) + + return ( +
+ setIsOpen(true)}> + {label} + + setIsOpen(false)} + overlayProps={{ className: styles.section }} + > +
    +
  • Item 01
  • +
  • Item 02
  • +
  • Item 03
  • +
  • Item 04
  • +
+
+
+ ) +} + +export default SKUMatrix diff --git a/packages/core/src/components/SKUMatrix/index.ts b/packages/core/src/components/SKUMatrix/index.ts new file mode 100644 index 0000000000..68cd4ca623 --- /dev/null +++ b/packages/core/src/components/SKUMatrix/index.ts @@ -0,0 +1 @@ +export { default } from './SKUMatrix' diff --git a/packages/core/src/components/SKUMatrix/section.module.scss b/packages/core/src/components/SKUMatrix/section.module.scss new file mode 100644 index 0000000000..ea848c79be --- /dev/null +++ b/packages/core/src/components/SKUMatrix/section.module.scss @@ -0,0 +1,21 @@ +@layer components { + .section { + @import "@faststore/ui/src/components/atoms/Icon/styles.scss"; + @import "@faststore/ui/src/components/atoms/Overlay/styles.scss"; + @import "@faststore/ui/src/components/atoms/Badge/styles.scss"; + @import "@faststore/ui/src/components/atoms/Button/styles.scss"; + @import "@faststore/ui/src/components/atoms/Link/styles.scss"; + @import "@faststore/ui/src/components/atoms/List/styles.scss"; + @import "@faststore/ui/src/components/atoms/Price/styles.scss"; + @import "@faststore/ui/src/components/molecules/Alert/styles.scss"; + @import "@faststore/ui/src/components/molecules/Modal/styles.scss"; + @import "@faststore/ui/src/components/molecules/CartItem/styles.scss"; + @import "@faststore/ui/src/components/molecules/Gift/styles.scss"; + @import "@faststore/ui/src/components/molecules/QuantitySelector/styles.scss"; + @import "@faststore/ui/src/components/molecules/OrderSummary/styles.scss"; + @import "@faststore/ui/src/components/molecules/ProductPrice/styles.scss"; + @import "@faststore/ui/src/components/organisms/EmptyState/styles.scss"; + @import "@faststore/ui/src/components/organisms/SlideOver/styles.scss"; + @import "@faststore/ui/src/components/organisms/SKUMatrix/styles.scss"; + } +} diff --git a/packages/core/src/pages/component.tsx b/packages/core/src/pages/component.tsx new file mode 100644 index 0000000000..f9f9314f74 --- /dev/null +++ b/packages/core/src/pages/component.tsx @@ -0,0 +1,11 @@ +import SKUMatrix from 'src/components/SKUMatrix' + +function Page() { + return ( +
+ +
+ ) +} + +export default Page diff --git a/packages/core/src/styles/global/index.scss b/packages/core/src/styles/global/index.scss index 2b91265cf1..5d7441b820 100644 --- a/packages/core/src/styles/global/index.scss +++ b/packages/core/src/styles/global/index.scss @@ -9,3 +9,6 @@ @import "@faststore/ui/src/components/atoms/Overlay/styles.scss"; @import "@faststore/ui/src/components/atoms/SROnly/styles.scss"; @import "src/components/sections/Section/section.scss"; + +// FIXME - Remover +@import "@faststore/ui/src/components/organisms/SKUMatrix/styles.scss"; diff --git a/packages/ui/src/components/organisms/SKUMatrix/styles.scss b/packages/ui/src/components/organisms/SKUMatrix/styles.scss new file mode 100644 index 0000000000..e3cf577fdc --- /dev/null +++ b/packages/ui/src/components/organisms/SKUMatrix/styles.scss @@ -0,0 +1,26 @@ +[data-fs-sku-matrix-sidebar] { + // -------------------------------------------------------- + // Design Tokens for Cart Sidebar + // -------------------------------------------------------- + + // Default properties + --fs-sku-matrix-sidebar-bkg-color: var(--fs-color-neutral-bkg); + --fs-sku-matrix-sidebar-title-bkg-color: var(--fs-color-neutral-0); + + // -------------------------------------------------------- + // Structural Styles + // -------------------------------------------------------- + + display: flex; + flex-direction: column; + height: 100%; + overflow: auto; + + &[data-fs-slide-over] { + background-color: var(--fs-cart-sidebar-bkg-color); + } + + > * { + flex-shrink: 0; + } +} diff --git a/packages/ui/src/styles/components.scss b/packages/ui/src/styles/components.scss index 798238e2ee..5534a70292 100644 --- a/packages/ui/src/styles/components.scss +++ b/packages/ui/src/styles/components.scss @@ -1,86 +1,86 @@ // Atoms -@import "../components/atoms/Badge/styles"; -@import "../components/atoms/Button/styles"; -@import "../components/atoms/Checkbox/styles"; -@import "../components/atoms/Icon/styles"; -@import "../components/atoms/Input/styles"; -@import "../components/atoms/Link/styles"; -@import "../components/atoms/List/styles"; -@import "../components/atoms/Loader/styles"; -@import "../components/atoms/Logo/styles"; -@import "../components/atoms/Overlay/styles"; -@import "../components/atoms/Price/styles"; -@import "../components/atoms/Radio/styles"; -@import "../components/atoms/Select/styles"; -@import "../components/atoms/Skeleton/styles"; -@import "../components/atoms/Slider/styles"; -@import "../components/atoms/SROnly/styles"; +@import '../components/atoms/Badge/styles'; +@import '../components/atoms/Button/styles'; +@import '../components/atoms/Checkbox/styles'; +@import '../components/atoms/Icon/styles'; +@import '../components/atoms/Input/styles'; +@import '../components/atoms/Link/styles'; +@import '../components/atoms/List/styles'; +@import '../components/atoms/Loader/styles'; +@import '../components/atoms/Logo/styles'; +@import '../components/atoms/Overlay/styles'; +@import '../components/atoms/Price/styles'; +@import '../components/atoms/Radio/styles'; +@import '../components/atoms/Select/styles'; +@import '../components/atoms/Skeleton/styles'; +@import '../components/atoms/Slider/styles'; +@import '../components/atoms/SROnly/styles'; // Molecules -@import "../components/molecules/Accordion/styles"; -@import "../components/molecules/Alert/styles"; -@import "../components/molecules/Breadcrumb/styles"; -@import "../components/molecules/BuyButton/styles"; -@import "../components/molecules/Card/styles"; -@import "../components/molecules/Carousel/styles"; -@import "../components/molecules/CartItem/styles"; -@import "../components/molecules/CheckboxField/styles"; -@import "../components/molecules/DiscountBadge/styles"; -@import "../components/molecules/Dropdown/styles"; -@import "../components/molecules/Gift/styles"; -@import "../components/molecules/InputField/styles"; -@import "../components/molecules/LinkButton/styles"; -@import "../components/molecules/Modal/styles"; -@import "../components/molecules/NavbarLinks/styles"; -@import "../components/molecules/OrderSummary/styles"; -@import "../components/molecules/ProductCard/styles"; -@import "../components/molecules/ProductCardSkeleton/styles"; -@import "../components/molecules/ProductPrice/styles"; -@import "../components/molecules/ProductTile/styles"; -@import "../components/molecules/ProductTitle/styles"; -@import "../components/molecules/QuantitySelector/styles"; -@import "../components/molecules/RadioField/styles"; -@import "../components/molecules/Rating/styles"; -@import "../components/molecules/RegionBar/styles"; -@import "../components/molecules/SearchAutoComplete/styles"; -@import "../components/molecules/SearchDropdown/styles"; -@import "../components/molecules/SearchHistory/styles"; -@import "../components/molecules/SearchInputField/styles"; -@import "../components/molecules/SearchProducts/styles"; -@import "../components/molecules/SearchTop/styles"; -@import "../components/molecules/SelectField/styles"; -@import "../components/molecules/SkuSelector/styles"; -@import "../components/molecules/Table/styles"; -@import "../components/molecules/Tag/styles"; -@import "../components/molecules/Toast/styles"; -@import "../components/molecules/Toggle/styles"; -@import "../components/molecules/ToggleField/styles"; - +@import '../components/molecules/Accordion/styles'; +@import '../components/molecules/Alert/styles'; +@import '../components/molecules/Breadcrumb/styles'; +@import '../components/molecules/BuyButton/styles'; +@import '../components/molecules/Card/styles'; +@import '../components/molecules/Carousel/styles'; +@import '../components/molecules/CartItem/styles'; +@import '../components/molecules/CheckboxField/styles'; +@import '../components/molecules/DiscountBadge/styles'; +@import '../components/molecules/Dropdown/styles'; +@import '../components/molecules/Gift/styles'; +@import '../components/molecules/InputField/styles'; +@import '../components/molecules/LinkButton/styles'; +@import '../components/molecules/Modal/styles'; +@import '../components/molecules/NavbarLinks/styles'; +@import '../components/molecules/OrderSummary/styles'; +@import '../components/molecules/ProductCard/styles'; +@import '../components/molecules/ProductCardSkeleton/styles'; +@import '../components/molecules/ProductPrice/styles'; +@import '../components/molecules/ProductTile/styles'; +@import '../components/molecules/ProductTitle/styles'; +@import '../components/molecules/QuantitySelector/styles'; +@import '../components/molecules/RadioField/styles'; +@import '../components/molecules/Rating/styles'; +@import '../components/molecules/RegionBar/styles'; +@import '../components/molecules/SearchAutoComplete/styles'; +@import '../components/molecules/SearchDropdown/styles'; +@import '../components/molecules/SearchHistory/styles'; +@import '../components/molecules/SearchInputField/styles'; +@import '../components/molecules/SearchProducts/styles'; +@import '../components/molecules/SearchTop/styles'; +@import '../components/molecules/SelectField/styles'; +@import '../components/molecules/SkuSelector/styles'; +@import '../components/molecules/Table/styles'; +@import '../components/molecules/Tag/styles'; +@import '../components/molecules/Toast/styles'; +@import '../components/molecules/Toggle/styles'; +@import '../components/molecules/ToggleField/styles'; // Organisms -@import "../components/organisms/BannerText/styles"; -@import "../components/organisms/BannerNewsletter/styles"; -@import "../components/organisms/CartSidebar/styles"; -@import "../components/organisms/EmptyState/styles"; -@import "../components/organisms/Filter/styles"; -@import "../components/organisms/FilterSkeleton/styles"; -@import "../components/organisms/FilterSlider/styles"; -@import "../components/organisms/Footer/styles"; -@import "../components/organisms/Hero/styles"; -@import "../components/organisms/ImageGallery/styles"; -@import "../components/organisms/Incentives/styles"; -@import "../components/organisms/Navbar/styles"; -@import "../components/organisms/NavbarSlider/styles"; -@import "../components/organisms/Newsletter/styles"; -@import "../components/organisms/OutOfStock/styles"; -@import "../components/organisms/PaymentMethods/styles"; -@import "../components/organisms/PriceRange/styles"; -@import "../components/organisms/ProductDetails/styles"; -@import "../components/organisms/ProductGallery/styles"; -@import "../components/organisms/ProductGrid/styles"; -@import "../components/organisms/ProductShelf/styles"; -@import "../components/organisms/RegionModal/styles"; -@import "../components/organisms/SearchInput/styles"; -@import "../components/organisms/ShippingSimulation/styles"; -@import "../components/organisms/SlideOver/styles"; -@import "../components/organisms/Tiles/styles"; +@import '../components/organisms/BannerText/styles'; +@import '../components/organisms/BannerNewsletter/styles'; +@import '../components/organisms/CartSidebar/styles'; +@import '../components/organisms/EmptyState/styles'; +@import '../components/organisms/Filter/styles'; +@import '../components/organisms/FilterSkeleton/styles'; +@import '../components/organisms/FilterSlider/styles'; +@import '../components/organisms/Footer/styles'; +@import '../components/organisms/Hero/styles'; +@import '../components/organisms/ImageGallery/styles'; +@import '../components/organisms/Incentives/styles'; +@import '../components/organisms/Navbar/styles'; +@import '../components/organisms/NavbarSlider/styles'; +@import '../components/organisms/Newsletter/styles'; +@import '../components/organisms/OutOfStock/styles'; +@import '../components/organisms/PaymentMethods/styles'; +@import '../components/organisms/PriceRange/styles'; +@import '../components/organisms/ProductDetails/styles'; +@import '../components/organisms/ProductGallery/styles'; +@import '../components/organisms/ProductGrid/styles'; +@import '../components/organisms/ProductShelf/styles'; +@import '../components/organisms/RegionModal/styles'; +@import '../components/organisms/SearchInput/styles'; +@import '../components/organisms/ShippingSimulation/styles'; +@import '../components/organisms/SlideOver/styles'; +@import '../components/organisms/Tiles/styles'; +@import '../components/organisms/SKUMatrix/styles'; From 4b3031f46b0da5967bae396d4dca167c2f098589 Mon Sep 17 00:00:00 2001 From: ramondorosario Date: Wed, 11 Sep 2024 08:35:37 -0300 Subject: [PATCH 2/9] Revert "feat: start sku matrix" This reverts commit e283c08b4ea49dc8d97a2c24682960312e9f6135. --- packages/components/src/index.ts | 17 +- .../organisms/SKUMatrix/SKUMatrixSidebar.tsx | 89 ---------- .../organisms/SKUMatrix/SKUMatrixTrigger.tsx | 23 --- .../src/organisms/SKUMatrix/index.ts | 5 - .../src/components/SKUMatrix/SKUMatrix.tsx | 40 ----- .../core/src/components/SKUMatrix/index.ts | 1 - .../components/SKUMatrix/section.module.scss | 21 --- packages/core/src/pages/component.tsx | 11 -- packages/core/src/styles/global/index.scss | 3 - .../organisms/SKUMatrix/styles.scss | 26 --- packages/ui/src/styles/components.scss | 162 +++++++++--------- 11 files changed, 87 insertions(+), 311 deletions(-) delete mode 100644 packages/components/src/organisms/SKUMatrix/SKUMatrixSidebar.tsx delete mode 100644 packages/components/src/organisms/SKUMatrix/SKUMatrixTrigger.tsx delete mode 100644 packages/components/src/organisms/SKUMatrix/index.ts delete mode 100644 packages/core/src/components/SKUMatrix/SKUMatrix.tsx delete mode 100644 packages/core/src/components/SKUMatrix/index.ts delete mode 100644 packages/core/src/components/SKUMatrix/section.module.scss delete mode 100644 packages/core/src/pages/component.tsx delete mode 100644 packages/ui/src/components/organisms/SKUMatrix/styles.scss diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 9cb02eca27..3764572943 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -67,8 +67,12 @@ export type { CarouselBulletsProps, } from './molecules/Carousel' -export { default as Card } from './molecules/Card' -export type { CardProps } from './molecules/Card' +export { + default as Card +} from './molecules/Card' +export type { + CardProps +} from './molecules/Card' export { default as CartItem, @@ -356,12 +360,3 @@ export type { SlideOverProps, SlideOverHeaderProps, } from './organisms/SlideOver' - -export { - default as SKUMatrixTrigger, - SKUMatrixSidebar, -} from './organisms/SKUMatrix' -export type { - SKUMatrixTriggerProps, - SKUMatrixSidebarProps, -} from './organisms/SKUMatrix' diff --git a/packages/components/src/organisms/SKUMatrix/SKUMatrixSidebar.tsx b/packages/components/src/organisms/SKUMatrix/SKUMatrixSidebar.tsx deleted file mode 100644 index 6aa620f547..0000000000 --- a/packages/components/src/organisms/SKUMatrix/SKUMatrixSidebar.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import React from 'react' -import type { ReactNode, HTMLAttributes } from 'react' -import SlideOver, { SlideOverHeader } from '../SlideOver' -import { SlideOverDirection, SlideOverWidthSize } from '../SlideOver' -import { useFadeEffect } from '../../hooks' -import { OverlayProps } from '../..' - -export interface SKUMatrixSidebarProps extends HTMLAttributes { - /** - * ID to find this component in testing tools (e.g.: cypress, - * testing-library, and jest). - */ - testId?: string - /** - * Title for the SKUMatrixSidebar component. - */ - title?: string - /** - * Represents the side that the SKUMatrixSidebar comes from. - */ - direction?: SlideOverDirection - /** - * Represents the size of the SKUMatrixSidebar. - */ - size?: SlideOverWidthSize - /** - * Total of selected item in the Matrix. - */ - // totalitems: number - /** - * A React component that will be rendered as an icon on the Alert component. - */ - alertIcon?: ReactNode - /** - * The content for Alert component. - */ - alertText?: string - /** - * Props forwarded to the `Overlay` component. - */ - overlayProps?: OverlayProps - /** - * Show slide over. - */ - isOpen: boolean - /** - * Function called when Close Button is clicked. - */ - onClose: () => void -} - -function SKUMatrixSidebar({ - direction = 'rightSide', - title, - overlayProps, - size = 'full', - isOpen, - children, - // totalitems = 0, - onClose, - ...otherProps -}: SKUMatrixSidebarProps) { - const { fade } = useFadeEffect() - - return ( - - { - onClose() - }} - data-fs-sku-matrix-sidebar-title - > -

{title}

-
- - {children} -
- ) -} - -export default SKUMatrixSidebar diff --git a/packages/components/src/organisms/SKUMatrix/SKUMatrixTrigger.tsx b/packages/components/src/organisms/SKUMatrix/SKUMatrixTrigger.tsx deleted file mode 100644 index 3d0babcdc0..0000000000 --- a/packages/components/src/organisms/SKUMatrix/SKUMatrixTrigger.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react' -import type { ReactNode } from 'react' -import Button from '../../atoms/Button' -import type { ButtonProps } from '../../atoms/Button' - -export interface SKUMatrixTriggerProps extends Pick { - children: ReactNode - onClick(): void -} - -function SKUMatrixTrigger({ - children, - variant = 'secondary', - onClick, -}: SKUMatrixTriggerProps) { - return ( - - ) -} - -export default SKUMatrixTrigger diff --git a/packages/components/src/organisms/SKUMatrix/index.ts b/packages/components/src/organisms/SKUMatrix/index.ts deleted file mode 100644 index d2743e257c..0000000000 --- a/packages/components/src/organisms/SKUMatrix/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { default } from './SKUMatrixTrigger' -export type { SKUMatrixTriggerProps } from './SKUMatrixTrigger' - -export { default as SKUMatrixSidebar } from './SKUMatrixSidebar' -export type { SKUMatrixSidebarProps } from './SKUMatrixSidebar' diff --git a/packages/core/src/components/SKUMatrix/SKUMatrix.tsx b/packages/core/src/components/SKUMatrix/SKUMatrix.tsx deleted file mode 100644 index 30198316da..0000000000 --- a/packages/core/src/components/SKUMatrix/SKUMatrix.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { useState } from 'react' - -import { - SKUMatrixSidebar as SKUMatrixSidebar, - SKUMatrixTrigger as UISKUMatrixTrigger, -} from '@faststore/ui' -import styles from './section.module.scss' - -interface SKUMatrixProps { - button: { - label: string - } -} - -function SKUMatrix({ button: { label } }: SKUMatrixProps) { - const [isOpen, setIsOpen] = useState(false) - - return ( -
- setIsOpen(true)}> - {label} - - setIsOpen(false)} - overlayProps={{ className: styles.section }} - > -
    -
  • Item 01
  • -
  • Item 02
  • -
  • Item 03
  • -
  • Item 04
  • -
-
-
- ) -} - -export default SKUMatrix diff --git a/packages/core/src/components/SKUMatrix/index.ts b/packages/core/src/components/SKUMatrix/index.ts deleted file mode 100644 index 68cd4ca623..0000000000 --- a/packages/core/src/components/SKUMatrix/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './SKUMatrix' diff --git a/packages/core/src/components/SKUMatrix/section.module.scss b/packages/core/src/components/SKUMatrix/section.module.scss deleted file mode 100644 index ea848c79be..0000000000 --- a/packages/core/src/components/SKUMatrix/section.module.scss +++ /dev/null @@ -1,21 +0,0 @@ -@layer components { - .section { - @import "@faststore/ui/src/components/atoms/Icon/styles.scss"; - @import "@faststore/ui/src/components/atoms/Overlay/styles.scss"; - @import "@faststore/ui/src/components/atoms/Badge/styles.scss"; - @import "@faststore/ui/src/components/atoms/Button/styles.scss"; - @import "@faststore/ui/src/components/atoms/Link/styles.scss"; - @import "@faststore/ui/src/components/atoms/List/styles.scss"; - @import "@faststore/ui/src/components/atoms/Price/styles.scss"; - @import "@faststore/ui/src/components/molecules/Alert/styles.scss"; - @import "@faststore/ui/src/components/molecules/Modal/styles.scss"; - @import "@faststore/ui/src/components/molecules/CartItem/styles.scss"; - @import "@faststore/ui/src/components/molecules/Gift/styles.scss"; - @import "@faststore/ui/src/components/molecules/QuantitySelector/styles.scss"; - @import "@faststore/ui/src/components/molecules/OrderSummary/styles.scss"; - @import "@faststore/ui/src/components/molecules/ProductPrice/styles.scss"; - @import "@faststore/ui/src/components/organisms/EmptyState/styles.scss"; - @import "@faststore/ui/src/components/organisms/SlideOver/styles.scss"; - @import "@faststore/ui/src/components/organisms/SKUMatrix/styles.scss"; - } -} diff --git a/packages/core/src/pages/component.tsx b/packages/core/src/pages/component.tsx deleted file mode 100644 index f9f9314f74..0000000000 --- a/packages/core/src/pages/component.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import SKUMatrix from 'src/components/SKUMatrix' - -function Page() { - return ( -
- -
- ) -} - -export default Page diff --git a/packages/core/src/styles/global/index.scss b/packages/core/src/styles/global/index.scss index 5d7441b820..2b91265cf1 100644 --- a/packages/core/src/styles/global/index.scss +++ b/packages/core/src/styles/global/index.scss @@ -9,6 +9,3 @@ @import "@faststore/ui/src/components/atoms/Overlay/styles.scss"; @import "@faststore/ui/src/components/atoms/SROnly/styles.scss"; @import "src/components/sections/Section/section.scss"; - -// FIXME - Remover -@import "@faststore/ui/src/components/organisms/SKUMatrix/styles.scss"; diff --git a/packages/ui/src/components/organisms/SKUMatrix/styles.scss b/packages/ui/src/components/organisms/SKUMatrix/styles.scss deleted file mode 100644 index e3cf577fdc..0000000000 --- a/packages/ui/src/components/organisms/SKUMatrix/styles.scss +++ /dev/null @@ -1,26 +0,0 @@ -[data-fs-sku-matrix-sidebar] { - // -------------------------------------------------------- - // Design Tokens for Cart Sidebar - // -------------------------------------------------------- - - // Default properties - --fs-sku-matrix-sidebar-bkg-color: var(--fs-color-neutral-bkg); - --fs-sku-matrix-sidebar-title-bkg-color: var(--fs-color-neutral-0); - - // -------------------------------------------------------- - // Structural Styles - // -------------------------------------------------------- - - display: flex; - flex-direction: column; - height: 100%; - overflow: auto; - - &[data-fs-slide-over] { - background-color: var(--fs-cart-sidebar-bkg-color); - } - - > * { - flex-shrink: 0; - } -} diff --git a/packages/ui/src/styles/components.scss b/packages/ui/src/styles/components.scss index 5534a70292..798238e2ee 100644 --- a/packages/ui/src/styles/components.scss +++ b/packages/ui/src/styles/components.scss @@ -1,86 +1,86 @@ // Atoms -@import '../components/atoms/Badge/styles'; -@import '../components/atoms/Button/styles'; -@import '../components/atoms/Checkbox/styles'; -@import '../components/atoms/Icon/styles'; -@import '../components/atoms/Input/styles'; -@import '../components/atoms/Link/styles'; -@import '../components/atoms/List/styles'; -@import '../components/atoms/Loader/styles'; -@import '../components/atoms/Logo/styles'; -@import '../components/atoms/Overlay/styles'; -@import '../components/atoms/Price/styles'; -@import '../components/atoms/Radio/styles'; -@import '../components/atoms/Select/styles'; -@import '../components/atoms/Skeleton/styles'; -@import '../components/atoms/Slider/styles'; -@import '../components/atoms/SROnly/styles'; +@import "../components/atoms/Badge/styles"; +@import "../components/atoms/Button/styles"; +@import "../components/atoms/Checkbox/styles"; +@import "../components/atoms/Icon/styles"; +@import "../components/atoms/Input/styles"; +@import "../components/atoms/Link/styles"; +@import "../components/atoms/List/styles"; +@import "../components/atoms/Loader/styles"; +@import "../components/atoms/Logo/styles"; +@import "../components/atoms/Overlay/styles"; +@import "../components/atoms/Price/styles"; +@import "../components/atoms/Radio/styles"; +@import "../components/atoms/Select/styles"; +@import "../components/atoms/Skeleton/styles"; +@import "../components/atoms/Slider/styles"; +@import "../components/atoms/SROnly/styles"; // Molecules -@import '../components/molecules/Accordion/styles'; -@import '../components/molecules/Alert/styles'; -@import '../components/molecules/Breadcrumb/styles'; -@import '../components/molecules/BuyButton/styles'; -@import '../components/molecules/Card/styles'; -@import '../components/molecules/Carousel/styles'; -@import '../components/molecules/CartItem/styles'; -@import '../components/molecules/CheckboxField/styles'; -@import '../components/molecules/DiscountBadge/styles'; -@import '../components/molecules/Dropdown/styles'; -@import '../components/molecules/Gift/styles'; -@import '../components/molecules/InputField/styles'; -@import '../components/molecules/LinkButton/styles'; -@import '../components/molecules/Modal/styles'; -@import '../components/molecules/NavbarLinks/styles'; -@import '../components/molecules/OrderSummary/styles'; -@import '../components/molecules/ProductCard/styles'; -@import '../components/molecules/ProductCardSkeleton/styles'; -@import '../components/molecules/ProductPrice/styles'; -@import '../components/molecules/ProductTile/styles'; -@import '../components/molecules/ProductTitle/styles'; -@import '../components/molecules/QuantitySelector/styles'; -@import '../components/molecules/RadioField/styles'; -@import '../components/molecules/Rating/styles'; -@import '../components/molecules/RegionBar/styles'; -@import '../components/molecules/SearchAutoComplete/styles'; -@import '../components/molecules/SearchDropdown/styles'; -@import '../components/molecules/SearchHistory/styles'; -@import '../components/molecules/SearchInputField/styles'; -@import '../components/molecules/SearchProducts/styles'; -@import '../components/molecules/SearchTop/styles'; -@import '../components/molecules/SelectField/styles'; -@import '../components/molecules/SkuSelector/styles'; -@import '../components/molecules/Table/styles'; -@import '../components/molecules/Tag/styles'; -@import '../components/molecules/Toast/styles'; -@import '../components/molecules/Toggle/styles'; -@import '../components/molecules/ToggleField/styles'; +@import "../components/molecules/Accordion/styles"; +@import "../components/molecules/Alert/styles"; +@import "../components/molecules/Breadcrumb/styles"; +@import "../components/molecules/BuyButton/styles"; +@import "../components/molecules/Card/styles"; +@import "../components/molecules/Carousel/styles"; +@import "../components/molecules/CartItem/styles"; +@import "../components/molecules/CheckboxField/styles"; +@import "../components/molecules/DiscountBadge/styles"; +@import "../components/molecules/Dropdown/styles"; +@import "../components/molecules/Gift/styles"; +@import "../components/molecules/InputField/styles"; +@import "../components/molecules/LinkButton/styles"; +@import "../components/molecules/Modal/styles"; +@import "../components/molecules/NavbarLinks/styles"; +@import "../components/molecules/OrderSummary/styles"; +@import "../components/molecules/ProductCard/styles"; +@import "../components/molecules/ProductCardSkeleton/styles"; +@import "../components/molecules/ProductPrice/styles"; +@import "../components/molecules/ProductTile/styles"; +@import "../components/molecules/ProductTitle/styles"; +@import "../components/molecules/QuantitySelector/styles"; +@import "../components/molecules/RadioField/styles"; +@import "../components/molecules/Rating/styles"; +@import "../components/molecules/RegionBar/styles"; +@import "../components/molecules/SearchAutoComplete/styles"; +@import "../components/molecules/SearchDropdown/styles"; +@import "../components/molecules/SearchHistory/styles"; +@import "../components/molecules/SearchInputField/styles"; +@import "../components/molecules/SearchProducts/styles"; +@import "../components/molecules/SearchTop/styles"; +@import "../components/molecules/SelectField/styles"; +@import "../components/molecules/SkuSelector/styles"; +@import "../components/molecules/Table/styles"; +@import "../components/molecules/Tag/styles"; +@import "../components/molecules/Toast/styles"; +@import "../components/molecules/Toggle/styles"; +@import "../components/molecules/ToggleField/styles"; + // Organisms -@import '../components/organisms/BannerText/styles'; -@import '../components/organisms/BannerNewsletter/styles'; -@import '../components/organisms/CartSidebar/styles'; -@import '../components/organisms/EmptyState/styles'; -@import '../components/organisms/Filter/styles'; -@import '../components/organisms/FilterSkeleton/styles'; -@import '../components/organisms/FilterSlider/styles'; -@import '../components/organisms/Footer/styles'; -@import '../components/organisms/Hero/styles'; -@import '../components/organisms/ImageGallery/styles'; -@import '../components/organisms/Incentives/styles'; -@import '../components/organisms/Navbar/styles'; -@import '../components/organisms/NavbarSlider/styles'; -@import '../components/organisms/Newsletter/styles'; -@import '../components/organisms/OutOfStock/styles'; -@import '../components/organisms/PaymentMethods/styles'; -@import '../components/organisms/PriceRange/styles'; -@import '../components/organisms/ProductDetails/styles'; -@import '../components/organisms/ProductGallery/styles'; -@import '../components/organisms/ProductGrid/styles'; -@import '../components/organisms/ProductShelf/styles'; -@import '../components/organisms/RegionModal/styles'; -@import '../components/organisms/SearchInput/styles'; -@import '../components/organisms/ShippingSimulation/styles'; -@import '../components/organisms/SlideOver/styles'; -@import '../components/organisms/Tiles/styles'; -@import '../components/organisms/SKUMatrix/styles'; +@import "../components/organisms/BannerText/styles"; +@import "../components/organisms/BannerNewsletter/styles"; +@import "../components/organisms/CartSidebar/styles"; +@import "../components/organisms/EmptyState/styles"; +@import "../components/organisms/Filter/styles"; +@import "../components/organisms/FilterSkeleton/styles"; +@import "../components/organisms/FilterSlider/styles"; +@import "../components/organisms/Footer/styles"; +@import "../components/organisms/Hero/styles"; +@import "../components/organisms/ImageGallery/styles"; +@import "../components/organisms/Incentives/styles"; +@import "../components/organisms/Navbar/styles"; +@import "../components/organisms/NavbarSlider/styles"; +@import "../components/organisms/Newsletter/styles"; +@import "../components/organisms/OutOfStock/styles"; +@import "../components/organisms/PaymentMethods/styles"; +@import "../components/organisms/PriceRange/styles"; +@import "../components/organisms/ProductDetails/styles"; +@import "../components/organisms/ProductGallery/styles"; +@import "../components/organisms/ProductGrid/styles"; +@import "../components/organisms/ProductShelf/styles"; +@import "../components/organisms/RegionModal/styles"; +@import "../components/organisms/SearchInput/styles"; +@import "../components/organisms/ShippingSimulation/styles"; +@import "../components/organisms/SlideOver/styles"; +@import "../components/organisms/Tiles/styles"; From 30f6ccaf3d48889d1f6a03a837dcf3a4ffb149cb Mon Sep 17 00:00:00 2001 From: Hiago Moreira Date: Wed, 18 Sep 2024 14:58:37 -0300 Subject: [PATCH 3/9] feat: add variant product in api --- packages/api/src/__generated__/schema.ts | 2 ++ packages/api/src/platforms/vtex/resolvers/skuVariations.ts | 1 + packages/api/src/typeDefs/skuVariants.graphql | 5 +++++ packages/core/@generated/graphql.ts | 5 +++++ 4 files changed, 13 insertions(+) diff --git a/packages/api/src/__generated__/schema.ts b/packages/api/src/__generated__/schema.ts index 61a55df546..7f52f2c08a 100644 --- a/packages/api/src/__generated__/schema.ts +++ b/packages/api/src/__generated__/schema.ts @@ -588,6 +588,8 @@ export type SkuVariants = { /** SKU property values for the current SKU. */ activeVariations?: Maybe; /** All available options for each SKU variant property, indexed by their name. */ + allVariantProducts?: Maybe>; + /** All available options for each SKU variant property, indexed by their name. */ allVariantsByName?: Maybe; /** * Available options for each varying SKU property, taking into account the diff --git a/packages/api/src/platforms/vtex/resolvers/skuVariations.ts b/packages/api/src/platforms/vtex/resolvers/skuVariations.ts index 81d725dac6..e59fc7794c 100644 --- a/packages/api/src/platforms/vtex/resolvers/skuVariations.ts +++ b/packages/api/src/platforms/vtex/resolvers/skuVariations.ts @@ -40,4 +40,5 @@ export const SkuVariants: Record> = { return filteredFormattedVariations }, + allVariantProducts: (root) => root.isVariantOf.items, } diff --git a/packages/api/src/typeDefs/skuVariants.graphql b/packages/api/src/typeDefs/skuVariants.graphql index 866b3492be..83e4a02c0c 100644 --- a/packages/api/src/typeDefs/skuVariants.graphql +++ b/packages/api/src/typeDefs/skuVariants.graphql @@ -24,6 +24,11 @@ type SkuVariants { considered the dominant one. """ availableVariations(dominantVariantName: String): FormattedVariants + + """ + All available options for each SKU variant property, indexed by their name. + """ + allVariantProducts: [StoreProduct!] } """ diff --git a/packages/core/@generated/graphql.ts b/packages/core/@generated/graphql.ts index b3d289130b..151779eb2d 100644 --- a/packages/core/@generated/graphql.ts +++ b/packages/core/@generated/graphql.ts @@ -576,6 +576,7 @@ export type ShippingSla = { export type SkuVariants = { /** SKU property values for the current SKU. */ activeVariations: Maybe + allVariantProducts: Maybe> /** All available options for each SKU variant property, indexed by their name. */ allVariantsByName: Maybe /** @@ -597,6 +598,10 @@ export type SkuVariants = { slugsMap: Maybe } +export type SkuVariantsAllVariantProductsArgs = { + productID: InputMaybe +} + export type SkuVariantsAvailableVariationsArgs = { dominantVariantName: InputMaybe } From 6e0a18b18d73e09362e53455e03d1fbee94673a1 Mon Sep 17 00:00:00 2001 From: Hiago Moreira Date: Thu, 19 Sep 2024 16:59:08 -0300 Subject: [PATCH 4/9] add data in product query --- packages/core/@generated/gql.ts | 4 ++-- packages/core/@generated/graphql.ts | 11 +++++++++-- .../sections/ProductDetails/ProductDetails.tsx | 4 ++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/core/@generated/gql.ts b/packages/core/@generated/gql.ts index 7364cd0d25..7389a8926d 100644 --- a/packages/core/@generated/gql.ts +++ b/packages/core/@generated/gql.ts @@ -16,7 +16,7 @@ const documents = { types.ProductSummary_ProductFragmentDoc, '\n fragment Filter_facets on StoreFacet {\n ... on StoreFacetRange {\n key\n label\n\n min {\n selected\n absolute\n }\n\n max {\n selected\n absolute\n }\n\n __typename\n }\n ... on StoreFacetBoolean {\n key\n label\n values {\n label\n value\n selected\n quantity\n }\n\n __typename\n }\n }\n': types.Filter_FacetsFragmentDoc, - '\n fragment ProductDetailsFragment_product on StoreProduct {\n id: productID\n sku\n name\n gtin\n description\n unitMultiplier\n isVariantOf {\n name\n productGroupID\n skuVariants {\n activeVariations\n slugsMap\n availableVariations\n }\n }\n\n image {\n url\n alternateName\n }\n\n brand {\n name\n }\n\n offers {\n lowPrice\n lowPriceWithTaxes\n offers {\n availability\n price\n priceWithTaxes\n listPrice\n listPriceWithTaxes\n seller {\n identifier\n }\n }\n }\n\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n\n # Contains necessary info to add this item to cart\n ...CartProductItem\n }\n': + '\n fragment ProductDetailsFragment_product on StoreProduct {\n id: productID\n sku\n name\n gtin\n description\n unitMultiplier\n isVariantOf {\n name\n productGroupID\n skuVariants {\n activeVariations\n slugsMap\n availableVariations\n allVariantProducts {\n name\n productID\n }\n }\n }\n\n image {\n url\n alternateName\n }\n\n brand {\n name\n }\n\n offers {\n lowPrice\n lowPriceWithTaxes\n offers {\n availability\n price\n priceWithTaxes\n listPrice\n listPriceWithTaxes\n seller {\n identifier\n }\n }\n }\n\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n\n # Contains necessary info to add this item to cart\n ...CartProductItem\n }\n': types.ProductDetailsFragment_ProductFragmentDoc, '\n fragment ClientManyProducts on Query {\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n }\n }\n': types.ClientManyProductsFragmentDoc, @@ -74,7 +74,7 @@ export function gql( * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function gql( - source: '\n fragment ProductDetailsFragment_product on StoreProduct {\n id: productID\n sku\n name\n gtin\n description\n unitMultiplier\n isVariantOf {\n name\n productGroupID\n skuVariants {\n activeVariations\n slugsMap\n availableVariations\n }\n }\n\n image {\n url\n alternateName\n }\n\n brand {\n name\n }\n\n offers {\n lowPrice\n lowPriceWithTaxes\n offers {\n availability\n price\n priceWithTaxes\n listPrice\n listPriceWithTaxes\n seller {\n identifier\n }\n }\n }\n\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n\n # Contains necessary info to add this item to cart\n ...CartProductItem\n }\n' + source: '\n fragment ProductDetailsFragment_product on StoreProduct {\n id: productID\n sku\n name\n gtin\n description\n unitMultiplier\n isVariantOf {\n name\n productGroupID\n skuVariants {\n activeVariations\n slugsMap\n availableVariations\n allVariantProducts {\n name\n productID\n }\n }\n }\n\n image {\n url\n alternateName\n }\n\n brand {\n name\n }\n\n offers {\n lowPrice\n lowPriceWithTaxes\n offers {\n availability\n price\n priceWithTaxes\n listPrice\n listPriceWithTaxes\n seller {\n identifier\n }\n }\n }\n\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n\n # Contains necessary info to add this item to cart\n ...CartProductItem\n }\n' ): typeof import('./graphql').ProductDetailsFragment_ProductFragmentDoc /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. diff --git a/packages/core/@generated/graphql.ts b/packages/core/@generated/graphql.ts index 151779eb2d..1f368bff67 100644 --- a/packages/core/@generated/graphql.ts +++ b/packages/core/@generated/graphql.ts @@ -1168,6 +1168,7 @@ export type ProductDetailsFragment_ProductFragment = { activeVariations: any | null slugsMap: any | null availableVariations: any | null + allVariantProducts: Array<{ name: string; productID: string }> | null } | null } image: Array<{ url: string; alternateName: string }> @@ -1276,6 +1277,7 @@ export type ServerProductQueryQuery = { activeVariations: any | null slugsMap: any | null availableVariations: any | null + allVariantProducts: Array<{ name: string; productID: string }> | null } | null } additionalProperty: Array<{ @@ -1504,6 +1506,7 @@ export type ClientProductQueryQuery = { activeVariations: any | null slugsMap: any | null availableVariations: any | null + allVariantProducts: Array<{ name: string; productID: string }> | null } | null } image: Array<{ url: string; alternateName: string }> @@ -1780,6 +1783,10 @@ export const ProductDetailsFragment_ProductFragmentDoc = activeVariations slugsMap availableVariations + allVariantProducts { + name + productID + } } } image { @@ -2029,7 +2036,7 @@ export const ServerCollectionPageQueryDocument = { export const ServerProductQueryDocument = { __meta__: { operationName: 'ServerProductQuery', - operationHash: '46103bee661405bde706d72126fdbf9b0a0c9e6e', + operationHash: 'e855903879c6504e90269e6e010549bc6de933eb', }, } as unknown as TypedDocumentString< ServerProductQueryQuery, @@ -2074,7 +2081,7 @@ export const ClientProductGalleryQueryDocument = { export const ClientProductQueryDocument = { __meta__: { operationName: 'ClientProductQuery', - operationHash: '7d121ef8d4dc99174e64e4429a9b977b8bbebed8', + operationHash: '47aa22eb750cb2c529e5eeafb921bfeadb67db71', }, } as unknown as TypedDocumentString< ClientProductQueryQuery, diff --git a/packages/core/src/components/sections/ProductDetails/ProductDetails.tsx b/packages/core/src/components/sections/ProductDetails/ProductDetails.tsx index 62e262b11a..8591670202 100644 --- a/packages/core/src/components/sections/ProductDetails/ProductDetails.tsx +++ b/packages/core/src/components/sections/ProductDetails/ProductDetails.tsx @@ -280,6 +280,10 @@ export const fragment = gql(` activeVariations slugsMap availableVariations + allVariantProducts { + name + productID + } } } From 98495a6ef52340c1c0f6c1ac528a92cec5ea9a3f Mon Sep 17 00:00:00 2001 From: ramondorosario Date: Thu, 5 Dec 2024 15:05:55 -0300 Subject: [PATCH 5/9] feat: create hasSpecifications property --- packages/api/src/__generated__/schema.ts | 2 ++ .../api/src/platforms/vtex/resolvers/product.ts | 3 +++ packages/api/src/typeDefs/product.graphql | 4 ++++ packages/core/@generated/gql.ts | 4 ++-- packages/core/@generated/graphql.ts | 15 +++++++++------ .../product/ProductCard/ProductCard.tsx | 2 ++ 6 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/api/src/__generated__/schema.ts b/packages/api/src/__generated__/schema.ts index 685d3daf14..95a73cc4cc 100644 --- a/packages/api/src/__generated__/schema.ts +++ b/packages/api/src/__generated__/schema.ts @@ -988,6 +988,8 @@ export type StoreProduct = { description: Scalars['String']; /** Global Trade Item Number. */ gtin: Scalars['String']; + /** Indicates whether the product has specifications. */ + hasSpecifications?: Maybe; /** Array of images. */ image: Array; /** Indicates product group related to this product. */ diff --git a/packages/api/src/platforms/vtex/resolvers/product.ts b/packages/api/src/platforms/vtex/resolvers/product.ts index 0569c7ae60..392a1f8fd9 100644 --- a/packages/api/src/platforms/vtex/resolvers/product.ts +++ b/packages/api/src/platforms/vtex/resolvers/product.ts @@ -155,6 +155,9 @@ export const StoreProduct: Record> & { ...propertyValueAttributes, ] }, + hasSpecifications: ({isVariantOf}) => Boolean( + isVariantOf.skuSpecifications?.length + ), releaseDate: ({ isVariantOf: { releaseDate } }) => releaseDate ?? '', advertisement: ({ isVariantOf: { advertisement } }) => advertisement, } diff --git a/packages/api/src/typeDefs/product.graphql b/packages/api/src/typeDefs/product.graphql index b1a7dfcb50..f4ed485dcc 100644 --- a/packages/api/src/typeDefs/product.graphql +++ b/packages/api/src/typeDefs/product.graphql @@ -74,6 +74,10 @@ type StoreProduct { Advertisement information about the product. """ advertisement: Advertisement + """ + Indicates whether the product has specifications. + """ + hasSpecifications: Boolean } """ diff --git a/packages/core/@generated/gql.ts b/packages/core/@generated/gql.ts index 31b8a8dbb0..39a8339f58 100644 --- a/packages/core/@generated/gql.ts +++ b/packages/core/@generated/gql.ts @@ -12,7 +12,7 @@ import * as types from './graphql' * Therefore it is highly recommended to use the babel or swc plugin for production. */ const documents = { - '\n fragment ProductSummary_product on StoreProduct {\n id: productID\n slug\n sku\n brand {\n brandName: name\n }\n name\n gtin\n\n isVariantOf {\n productGroupID\n name\n }\n\n image {\n url\n alternateName\n }\n\n brand {\n name\n }\n\n offers {\n lowPrice\n lowPriceWithTaxes\n offers {\n availability\n price\n listPrice\n listPriceWithTaxes\n quantity\n seller {\n identifier\n }\n }\n }\n\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n\n advertisement {\n adId\n adResponseId\n }\n }\n': + '\n fragment ProductSummary_product on StoreProduct {\n id: productID\n slug\n sku\n brand {\n brandName: name\n }\n name\n gtin\n\n isVariantOf {\n productGroupID\n name\n }\n\n image {\n url\n alternateName\n }\n\n brand {\n name\n }\n\n offers {\n lowPrice\n lowPriceWithTaxes\n offers {\n availability\n price\n listPrice\n listPriceWithTaxes\n quantity\n seller {\n identifier\n }\n }\n }\n\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n\n hasSpecifications\n\n advertisement {\n adId\n adResponseId\n }\n }\n': types.ProductSummary_ProductFragmentDoc, '\n fragment Filter_facets on StoreFacet {\n ... on StoreFacetRange {\n key\n label\n\n min {\n selected\n absolute\n }\n\n max {\n selected\n absolute\n }\n\n __typename\n }\n ... on StoreFacetBoolean {\n key\n label\n values {\n label\n value\n selected\n quantity\n }\n\n __typename\n }\n }\n': types.Filter_FacetsFragmentDoc, @@ -62,7 +62,7 @@ const documents = { * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function gql( - source: '\n fragment ProductSummary_product on StoreProduct {\n id: productID\n slug\n sku\n brand {\n brandName: name\n }\n name\n gtin\n\n isVariantOf {\n productGroupID\n name\n }\n\n image {\n url\n alternateName\n }\n\n brand {\n name\n }\n\n offers {\n lowPrice\n lowPriceWithTaxes\n offers {\n availability\n price\n listPrice\n listPriceWithTaxes\n quantity\n seller {\n identifier\n }\n }\n }\n\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n\n advertisement {\n adId\n adResponseId\n }\n }\n' + source: '\n fragment ProductSummary_product on StoreProduct {\n id: productID\n slug\n sku\n brand {\n brandName: name\n }\n name\n gtin\n\n isVariantOf {\n productGroupID\n name\n }\n\n image {\n url\n alternateName\n }\n\n brand {\n name\n }\n\n offers {\n lowPrice\n lowPriceWithTaxes\n offers {\n availability\n price\n listPrice\n listPriceWithTaxes\n quantity\n seller {\n identifier\n }\n }\n }\n\n additionalProperty {\n propertyID\n name\n value\n valueReference\n }\n\n hasSpecifications\n\n advertisement {\n adId\n adResponseId\n }\n }\n' ): typeof import('./graphql').ProductSummary_ProductFragmentDoc /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. diff --git a/packages/core/@generated/graphql.ts b/packages/core/@generated/graphql.ts index 69bbb04857..31fe50294e 100644 --- a/packages/core/@generated/graphql.ts +++ b/packages/core/@generated/graphql.ts @@ -598,6 +598,7 @@ export type ShippingSla = { export type SkuVariants = { /** SKU property values for the current SKU. */ activeVariations: Maybe + /** All available options for each SKU variant property, indexed by their name. */ allVariantProducts: Maybe> /** All available options for each SKU variant property, indexed by their name. */ allVariantsByName: Maybe @@ -620,10 +621,6 @@ export type SkuVariants = { slugsMap: Maybe } -export type SkuVariantsAllVariantProductsArgs = { - productID: InputMaybe -} - export type SkuVariantsAvailableVariationsArgs = { dominantVariantName: InputMaybe } @@ -946,6 +943,8 @@ export type StoreProduct = { description: Scalars['String']['output'] /** Global Trade Item Number. */ gtin: Scalars['String']['output'] + /** TODO: Description from hasSpecifications. */ + hasSpecifications: Maybe /** Array of images. */ image: Array /** Indicates product group related to this product. */ @@ -1138,6 +1137,7 @@ export type ProductSummary_ProductFragment = { sku: string name: string gtin: string + hasSpecifications: boolean | null id: string brand: { name: string; brandName: string } isVariantOf: { productGroupID: string; name: string } @@ -1452,6 +1452,7 @@ export type ClientManyProductsQueryQuery = { sku: string name: string gtin: string + hasSpecifications: boolean | null id: string brand: { name: string; brandName: string } isVariantOf: { productGroupID: string; name: string } @@ -1586,6 +1587,7 @@ export type ClientSearchSuggestionsQueryQuery = { sku: string name: string gtin: string + hasSpecifications: boolean | null id: string brand: { name: string; brandName: string } isVariantOf: { productGroupID: string; name: string } @@ -1744,6 +1746,7 @@ export const ProductSummary_ProductFragmentDoc = new TypedDocumentString( value valueReference } + hasSpecifications advertisement { adId adResponseId @@ -2114,7 +2117,7 @@ export const SubscribeToNewsletterDocument = { export const ClientManyProductsQueryDocument = { __meta__: { operationName: 'ClientManyProductsQuery', - operationHash: 'ad2eb78cfccb9dbd5a9f2d1e150cc70fea5da99a', + operationHash: '7acc92a2841addb2fa0bda10ebd632a1eacbb18e', }, } as unknown as TypedDocumentString< ClientManyProductsQueryQuery, @@ -2141,7 +2144,7 @@ export const ClientProductQueryDocument = { export const ClientSearchSuggestionsQueryDocument = { __meta__: { operationName: 'ClientSearchSuggestionsQuery', - operationHash: '47e48eaee91d16a4237eb2c1241bc2ed3e2ad9bb', + operationHash: '62463b17174f63e6fef51a240217a637395daad1', }, } as unknown as TypedDocumentString< ClientSearchSuggestionsQueryQuery, diff --git a/packages/core/src/components/product/ProductCard/ProductCard.tsx b/packages/core/src/components/product/ProductCard/ProductCard.tsx index 86b079fffa..4afbed58f5 100644 --- a/packages/core/src/components/product/ProductCard/ProductCard.tsx +++ b/packages/core/src/components/product/ProductCard/ProductCard.tsx @@ -200,6 +200,8 @@ export const fragment = gql(` valueReference } + hasSpecifications + advertisement { adId adResponseId From 34d79c3a5f47e9ccbe0d9bfb3635eff21d60e090 Mon Sep 17 00:00:00 2001 From: ramondorosario Date: Fri, 13 Dec 2024 16:48:22 -0300 Subject: [PATCH 6/9] feat: useProductComparison --- packages/api/src/__generated__/schema.ts | 46 ++ .../src/platforms/vtex/resolvers/product.ts | 4 +- .../api/src/platforms/vtex/resolvers/query.ts | 26 + packages/api/src/typeDefs/product.graphql | 38 ++ packages/api/src/typeDefs/query.graphql | 9 + packages/core/@generated/gql.ts | 16 + packages/core/@generated/graphql.ts | 517 ++++++++++++++---- .../src/sdk/product/useProductComparison.ts | 64 +++ 8 files changed, 600 insertions(+), 120 deletions(-) create mode 100644 packages/core/src/sdk/product/useProductComparison.ts diff --git a/packages/api/src/__generated__/schema.ts b/packages/api/src/__generated__/schema.ts index 95a73cc4cc..75fd87fb85 100644 --- a/packages/api/src/__generated__/schema.ts +++ b/packages/api/src/__generated__/schema.ts @@ -465,6 +465,8 @@ export type Query = { collection: StoreCollection; /** Returns the details of a product based on the specified locator. */ product: StoreProduct; + /** Returns information about selected products. */ + products: Array; /** Returns if there's a redirect for a search. */ redirect?: Maybe; /** Returns the result of a product, facet, or suggestion search. */ @@ -498,6 +500,11 @@ export type QueryProductArgs = { }; +export type QueryProductsArgs = { + productIds: Array; +}; + + export type QueryRedirectArgs = { selectedFacets?: Maybe>; term?: Maybe; @@ -527,6 +534,21 @@ export type QueryShippingArgs = { postalCode: Scalars['String']; }; +export type SkuSpecificationField = { + __typename?: 'SKUSpecificationField'; + id?: Maybe; + name: Scalars['String']; + originalName?: Maybe; +}; + +export type SkuSpecificationValue = { + __typename?: 'SKUSpecificationValue'; + fieldId?: Maybe; + id?: Maybe; + name: Scalars['String']; + originalName?: Maybe; +}; + /** Search result. */ export type SearchMetadata = { __typename?: 'SearchMetadata'; @@ -606,6 +628,12 @@ export type ShippingSla = { shippingEstimateDate?: Maybe; }; +export type SkuSpecification = { + __typename?: 'SkuSpecification'; + field: SkuSpecificationField; + values: Array; +}; + export type SkuVariants = { __typename?: 'SkuVariants'; /** SKU property values for the current SKU. */ @@ -643,6 +671,20 @@ export type SkuVariantsSlugsMapArgs = { dominantVariantName?: Maybe; }; +export type Specification = { + __typename?: 'Specification'; + name: Scalars['String']; + originalName: Scalars['String']; + values: Array; +}; + +export type SpecificationGroup = { + __typename?: 'SpecificationGroup'; + name: Scalars['String']; + originalName: Scalars['String']; + specifications: Array; +}; + /** Aggregate offer information, for a given SKU that is available to be fulfilled by multiple sellers. */ export type StoreAggregateOffer = { __typename?: 'StoreAggregateOffer'; @@ -1008,8 +1050,12 @@ export type StoreProduct = { seo: StoreSeo; /** Stock Keeping Unit. Merchant-specific ID for the product. */ sku: Scalars['String']; + /** Indicate the specifications of a product. */ + skuSpecifications: Array; /** Corresponding collection URL slug, with which to retrieve this entity. */ slug: Scalars['String']; + /** Indicate the specifications of a group of SKUs. */ + specificationGroups: Array; /** Sku Unit Multiplier */ unitMultiplier?: Maybe; }; diff --git a/packages/api/src/platforms/vtex/resolvers/product.ts b/packages/api/src/platforms/vtex/resolvers/product.ts index 392a1f8fd9..dc98cc176b 100644 --- a/packages/api/src/platforms/vtex/resolvers/product.ts +++ b/packages/api/src/platforms/vtex/resolvers/product.ts @@ -157,7 +157,9 @@ export const StoreProduct: Record> & { }, hasSpecifications: ({isVariantOf}) => Boolean( isVariantOf.skuSpecifications?.length - ), + ), + skuSpecifications: ({isVariantOf: { skuSpecifications }}) => skuSpecifications ?? [], + specificationGroups: ({isVariantOf: { specificationGroups }}) => specificationGroups, releaseDate: ({ isVariantOf: { releaseDate } }) => releaseDate ?? '', advertisement: ({ isVariantOf: { advertisement } }) => advertisement, } diff --git a/packages/api/src/platforms/vtex/resolvers/query.ts b/packages/api/src/platforms/vtex/resolvers/query.ts index 68bf191493..704c6415da 100644 --- a/packages/api/src/platforms/vtex/resolvers/query.ts +++ b/packages/api/src/platforms/vtex/resolvers/query.ts @@ -21,6 +21,7 @@ import type { QuerySellersArgs, QueryShippingArgs, QueryRedirectArgs, + QueryProductsArgs, } from '../../../__generated__/schema' import type { CategoryTree } from '../clients/commerce/types/CategoryTree' import type { Context } from '../index' @@ -201,6 +202,31 @@ export const Query = { })), } }, + products: async ( + _: unknown, + { productIds }: QueryProductsArgs, + ctx: Context + ) => { + const { + clients: { search }, + } = ctx + + if(!productIds.length) { + return [] + } + + const query = `id:${productIds.join(';')}` + const products = await search.products({ + page: 0, + count: productIds.length, + query, + }) + + return products.products + .map((product) => product.items.map((sku) => enhanceSku(sku, product))) + .flat() + .filter((sku) => sku.sellers.length > 0) + }, allCollections: async ( _: unknown, { first, after: maybeAfter }: QueryAllCollectionsArgs, diff --git a/packages/api/src/typeDefs/product.graphql b/packages/api/src/typeDefs/product.graphql index f4ed485dcc..fac6727f73 100644 --- a/packages/api/src/typeDefs/product.graphql +++ b/packages/api/src/typeDefs/product.graphql @@ -78,6 +78,44 @@ type StoreProduct { Indicates whether the product has specifications. """ hasSpecifications: Boolean + """ + Indicate the specifications of a product. + """ + skuSpecifications: [SkuSpecification!]! + """ + Indicate the specifications of a group of SKUs. + """ + specificationGroups: [SpecificationGroup!]! +} + +type SkuSpecification { + field: SKUSpecificationField! + values: [SKUSpecificationValue!]! +} + +type SKUSpecificationValue { + name: String! + id: String + fieldId: String + originalName: String +} + +type SKUSpecificationField { + name: String! + originalName: String + id: String +} + +type SpecificationGroup { + name: String! + originalName: String! + specifications: [Specification!]! +} + +type Specification { + name: String! + originalName: String! + values: [String!]! } """ diff --git a/packages/api/src/typeDefs/query.graphql b/packages/api/src/typeDefs/query.graphql index e00b81fd95..565dd7212d 100644 --- a/packages/api/src/typeDefs/query.graphql +++ b/packages/api/src/typeDefs/query.graphql @@ -264,6 +264,15 @@ type Query { ): StoreProductConnection! @cacheControl(scope: "public", sMaxAge: 120, staleWhileRevalidate: 3600) + """ + Returns information about selected products. + """ + products( + productIds: [String!]! + + ): [StoreProduct!]! + @cacheControl(scope: "public", sMaxAge: 120, staleWhileRevalidate: 3600) + """ Returns information about all collections. """ diff --git a/packages/core/@generated/gql.ts b/packages/core/@generated/gql.ts index 39a8339f58..da2894ad73 100644 --- a/packages/core/@generated/gql.ts +++ b/packages/core/@generated/gql.ts @@ -44,6 +44,10 @@ const documents = { types.SubscribeToNewsletterDocument, '\n query ClientManyProductsQuery(\n $first: Int!\n $after: String\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientManyProducts\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n edges {\n node {\n ...ProductSummary_product\n }\n }\n }\n }\n }\n': types.ClientManyProductsQueryDocument, + '\n query ClientManyProductsComparisonQuery(\n $productIds: [String!]!\n \n ) {\n products(\n productIds: $productIds\n ) {\n ...ProductComparisonFragment_product\n }\n } \n': + types.ClientManyProductsComparisonQueryDocument, + '\n fragment ProductComparisonFragment_product on StoreProduct {\n ...ProductDetailsFragment_product,\n\n skuSpecifications {\n field {\n id\n name\n originalName\n }\n values {\n name\n id\n fieldId\n originalName\n }\n }\n\n specificationGroups {\n name\n originalName\n specifications {\n name\n originalName\n values\n }\n }\n }\n': + types.ProductComparisonFragment_ProductFragmentDoc, '\n query ClientProductGalleryQuery(\n $first: Int!\n $after: String!\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientProductGallery\n redirect(term: $term, selectedFacets: $selectedFacets) {\n url\n }\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n }\n facets {\n ...Filter_facets\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n\n fragment SearchEvent_metadata on SearchMetadata {\n isTermMisspelled\n logicalOperator\n fuzzy\n }\n': types.ClientProductGalleryQueryDocument, '\n query ClientProductQuery($locator: [IStoreSelectedFacet!]!) {\n ...ClientProduct\n product(locator: $locator) {\n ...ProductDetailsFragment_product\n }\n }\n': @@ -154,6 +158,18 @@ export function gql( export function gql( source: '\n query ClientManyProductsQuery(\n $first: Int!\n $after: String\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n ) {\n ...ClientManyProducts\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n ) {\n products {\n pageInfo {\n totalCount\n }\n edges {\n node {\n ...ProductSummary_product\n }\n }\n }\n }\n }\n' ): typeof import('./graphql').ClientManyProductsQueryDocument +/** + * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function gql( + source: '\n query ClientManyProductsComparisonQuery(\n $productIds: [String!]!\n \n ) {\n products(\n productIds: $productIds\n ) {\n ...ProductComparisonFragment_product\n }\n } \n' +): typeof import('./graphql').ClientManyProductsComparisonQueryDocument +/** + * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function gql( + source: '\n fragment ProductComparisonFragment_product on StoreProduct {\n ...ProductDetailsFragment_product,\n\n skuSpecifications {\n field {\n id\n name\n originalName\n }\n values {\n name\n id\n fieldId\n originalName\n }\n }\n\n specificationGroups {\n name\n originalName\n specifications {\n name\n originalName\n values\n }\n }\n }\n' +): typeof import('./graphql').ProductComparisonFragment_ProductFragmentDoc /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/packages/core/@generated/graphql.ts b/packages/core/@generated/graphql.ts index 31fe50294e..535a7af38e 100644 --- a/packages/core/@generated/graphql.ts +++ b/packages/core/@generated/graphql.ts @@ -467,6 +467,8 @@ export type Query = { collection: StoreCollection /** Returns the details of a product based on the specified locator. */ product: StoreProduct + /** Returns information about selected products. */ + products: Array /** Returns if there's a redirect for a search. */ redirect: Maybe /** Returns the result of a product, facet, or suggestion search. */ @@ -495,6 +497,10 @@ export type QueryProductArgs = { locator: Array } +export type QueryProductsArgs = { + productIds: Array +} + export type QueryRedirectArgs = { selectedFacets: InputMaybe> term: InputMaybe @@ -521,6 +527,19 @@ export type QueryShippingArgs = { postalCode: Scalars['String']['input'] } +export type SkuSpecificationField = { + id: Maybe + name: Scalars['String']['output'] + originalName: Maybe +} + +export type SkuSpecificationValue = { + fieldId: Maybe + id: Maybe + name: Scalars['String']['output'] + originalName: Maybe +} + /** Search result. */ export type SearchMetadata = { /** Indicates how the search engine corrected the misspelled word by using fuzzy logic. */ @@ -595,6 +614,11 @@ export type ShippingSla = { shippingEstimateDate: Maybe } +export type SkuSpecification = { + field: SkuSpecificationField + values: Array +} + export type SkuVariants = { /** SKU property values for the current SKU. */ activeVariations: Maybe @@ -629,6 +653,18 @@ export type SkuVariantsSlugsMapArgs = { dominantVariantName: InputMaybe } +export type Specification = { + name: Scalars['String']['output'] + originalName: Scalars['String']['output'] + values: Array +} + +export type SpecificationGroup = { + name: Scalars['String']['output'] + originalName: Scalars['String']['output'] + specifications: Array +} + /** Aggregate offer information, for a given SKU that is available to be fulfilled by multiple sellers. */ export type StoreAggregateOffer = { /** Highest price among all sellers. */ @@ -943,7 +979,7 @@ export type StoreProduct = { description: Scalars['String']['output'] /** Global Trade Item Number. */ gtin: Scalars['String']['output'] - /** TODO: Description from hasSpecifications. */ + /** Indicates whether the product has specifications. */ hasSpecifications: Maybe /** Array of images. */ image: Array @@ -963,8 +999,12 @@ export type StoreProduct = { seo: StoreSeo /** Stock Keeping Unit. Merchant-specific ID for the product. */ sku: Scalars['String']['output'] + /** Indicate the specifications of a product. */ + skuSpecifications: Array /** Corresponding collection URL slug, with which to retrieve this entity. */ slug: Scalars['String']['output'] + /** Indicate the specifications of a group of SKUs. */ + specificationGroups: Array /** Sku Unit Multiplier */ unitMultiplier: Maybe } @@ -1482,6 +1522,126 @@ export type ClientManyProductsQueryQuery = { } } +export type ClientManyProductsComparisonQueryQueryVariables = Exact<{ + productIds: Array | Scalars['String']['input'] +}> + +export type ClientManyProductsComparisonQueryQuery = { + products: Array<{ + sku: string + name: string + gtin: string + description: string + unitMultiplier: number | null + id: string + skuSpecifications: Array<{ + field: { id: string | null; name: string; originalName: string | null } + values: Array<{ + name: string + id: string | null + fieldId: string | null + originalName: string | null + }> + }> + specificationGroups: Array<{ + name: string + originalName: string + specifications: Array<{ + name: string + originalName: string + values: Array + }> + }> + isVariantOf: { + name: string + productGroupID: string + skuVariants: { + activeVariations: any | null + slugsMap: any | null + availableVariations: any | null + allVariantProducts: Array<{ name: string; productID: string }> | null + } | null + } + image: Array<{ url: string; alternateName: string }> + brand: { name: string } + offers: { + lowPrice: number + lowPriceWithTaxes: number + offers: Array<{ + availability: string + price: number + priceWithTaxes: number + listPrice: number + listPriceWithTaxes: number + seller: { identifier: string } + }> + } + additionalProperty: Array<{ + propertyID: string + name: string + value: any + valueReference: any + }> + }> +} + +export type ProductComparisonFragment_ProductFragment = { + sku: string + name: string + gtin: string + description: string + unitMultiplier: number | null + id: string + skuSpecifications: Array<{ + field: { id: string | null; name: string; originalName: string | null } + values: Array<{ + name: string + id: string | null + fieldId: string | null + originalName: string | null + }> + }> + specificationGroups: Array<{ + name: string + originalName: string + specifications: Array<{ + name: string + originalName: string + values: Array + }> + }> + isVariantOf: { + name: string + productGroupID: string + skuVariants: { + activeVariations: any | null + slugsMap: any | null + availableVariations: any | null + allVariantProducts: Array<{ name: string; productID: string }> | null + } | null + } + image: Array<{ url: string; alternateName: string }> + brand: { name: string } + offers: { + lowPrice: number + lowPriceWithTaxes: number + offers: Array<{ + availability: string + price: number + priceWithTaxes: number + listPrice: number + listPriceWithTaxes: number + seller: { identifier: string } + }> + } + additionalProperty: Array<{ + propertyID: string + name: string + value: any + valueReference: any + }> +} + export type ClientProductGalleryQueryQueryVariables = Exact<{ first: Scalars['Int']['input'] after: Scalars['String']['input'] @@ -1786,124 +1946,6 @@ export const Filter_FacetsFragmentDoc = new TypedDocumentString( `, { fragmentName: 'Filter_facets' } ) as unknown as TypedDocumentString -export const CartProductItemFragmentDoc = new TypedDocumentString( - ` - fragment CartProductItem on StoreProduct { - sku - name - unitMultiplier - image { - url - alternateName - } - brand { - name - } - isVariantOf { - productGroupID - name - skuVariants { - activeVariations - slugsMap - availableVariations - } - } - gtin - additionalProperty { - propertyID - name - value - valueReference - } -} - `, - { fragmentName: 'CartProductItem' } -) as unknown as TypedDocumentString -export const ProductDetailsFragment_ProductFragmentDoc = - new TypedDocumentString( - ` - fragment ProductDetailsFragment_product on StoreProduct { - id: productID - sku - name - gtin - description - unitMultiplier - isVariantOf { - name - productGroupID - skuVariants { - activeVariations - slugsMap - availableVariations - allVariantProducts { - name - productID - } - } - } - image { - url - alternateName - } - brand { - name - } - offers { - lowPrice - lowPriceWithTaxes - offers { - availability - price - priceWithTaxes - listPrice - listPriceWithTaxes - seller { - identifier - } - } - } - additionalProperty { - propertyID - name - value - valueReference - } - ...CartProductItem -} - fragment CartProductItem on StoreProduct { - sku - name - unitMultiplier - image { - url - alternateName - } - brand { - name - } - isVariantOf { - productGroupID - name - skuVariants { - activeVariations - slugsMap - availableVariations - } - } - gtin - additionalProperty { - propertyID - name - value - valueReference - } -}`, - { fragmentName: 'ProductDetailsFragment_product' } - ) as unknown as TypedDocumentString< - ProductDetailsFragment_ProductFragment, - unknown - > export const ClientManyProductsFragmentDoc = new TypedDocumentString( ` fragment ClientManyProducts on Query { @@ -2023,6 +2065,39 @@ export const CartMessageFragmentDoc = new TypedDocumentString( `, { fragmentName: 'CartMessage' } ) as unknown as TypedDocumentString +export const CartProductItemFragmentDoc = new TypedDocumentString( + ` + fragment CartProductItem on StoreProduct { + sku + name + unitMultiplier + image { + url + alternateName + } + brand { + name + } + isVariantOf { + productGroupID + name + skuVariants { + activeVariations + slugsMap + availableVariations + } + } + gtin + additionalProperty { + propertyID + name + value + valueReference + } +} + `, + { fragmentName: 'CartProductItem' } +) as unknown as TypedDocumentString export const CartItemFragmentDoc = new TypedDocumentString( ` fragment CartItem on StoreOffer { @@ -2068,6 +2143,201 @@ export const CartItemFragmentDoc = new TypedDocumentString( }`, { fragmentName: 'CartItem' } ) as unknown as TypedDocumentString +export const ProductDetailsFragment_ProductFragmentDoc = + new TypedDocumentString( + ` + fragment ProductDetailsFragment_product on StoreProduct { + id: productID + sku + name + gtin + description + unitMultiplier + isVariantOf { + name + productGroupID + skuVariants { + activeVariations + slugsMap + availableVariations + allVariantProducts { + name + productID + } + } + } + image { + url + alternateName + } + brand { + name + } + offers { + lowPrice + lowPriceWithTaxes + offers { + availability + price + priceWithTaxes + listPrice + listPriceWithTaxes + seller { + identifier + } + } + } + additionalProperty { + propertyID + name + value + valueReference + } + ...CartProductItem +} + fragment CartProductItem on StoreProduct { + sku + name + unitMultiplier + image { + url + alternateName + } + brand { + name + } + isVariantOf { + productGroupID + name + skuVariants { + activeVariations + slugsMap + availableVariations + } + } + gtin + additionalProperty { + propertyID + name + value + valueReference + } +}`, + { fragmentName: 'ProductDetailsFragment_product' } + ) as unknown as TypedDocumentString< + ProductDetailsFragment_ProductFragment, + unknown + > +export const ProductComparisonFragment_ProductFragmentDoc = + new TypedDocumentString( + ` + fragment ProductComparisonFragment_product on StoreProduct { + ...ProductDetailsFragment_product + skuSpecifications { + field { + id + name + originalName + } + values { + name + id + fieldId + originalName + } + } + specificationGroups { + name + originalName + specifications { + name + originalName + values + } + } +} + fragment ProductDetailsFragment_product on StoreProduct { + id: productID + sku + name + gtin + description + unitMultiplier + isVariantOf { + name + productGroupID + skuVariants { + activeVariations + slugsMap + availableVariations + allVariantProducts { + name + productID + } + } + } + image { + url + alternateName + } + brand { + name + } + offers { + lowPrice + lowPriceWithTaxes + offers { + availability + price + priceWithTaxes + listPrice + listPriceWithTaxes + seller { + identifier + } + } + } + additionalProperty { + propertyID + name + value + valueReference + } + ...CartProductItem +} +fragment CartProductItem on StoreProduct { + sku + name + unitMultiplier + image { + url + alternateName + } + brand { + name + } + isVariantOf { + productGroupID + name + skuVariants { + activeVariations + slugsMap + availableVariations + } + } + gtin + additionalProperty { + propertyID + name + value + valueReference + } +}`, + { fragmentName: 'ProductComparisonFragment_product' } + ) as unknown as TypedDocumentString< + ProductComparisonFragment_ProductFragment, + unknown + > export const SearchEvent_MetadataFragmentDoc = new TypedDocumentString( ` fragment SearchEvent_metadata on SearchMetadata { @@ -2123,6 +2393,15 @@ export const ClientManyProductsQueryDocument = { ClientManyProductsQueryQuery, ClientManyProductsQueryQueryVariables > +export const ClientManyProductsComparisonQueryDocument = { + __meta__: { + operationName: 'ClientManyProductsComparisonQuery', + operationHash: '7a7474b129c6315a5ba4dac8df99b59b680e4343', + }, +} as unknown as TypedDocumentString< + ClientManyProductsComparisonQueryQuery, + ClientManyProductsComparisonQueryQueryVariables +> export const ClientProductGalleryQueryDocument = { __meta__: { operationName: 'ClientProductGalleryQuery', diff --git a/packages/core/src/sdk/product/useProductComparison.ts b/packages/core/src/sdk/product/useProductComparison.ts new file mode 100644 index 0000000000..468830e3de --- /dev/null +++ b/packages/core/src/sdk/product/useProductComparison.ts @@ -0,0 +1,64 @@ +import { gql } from '@generated' +import { useQuery } from 'src/sdk/graphql/useQuery' +import { useSession } from 'src/sdk/session' +import { useMemo } from 'react' + +const query = gql(` + query ClientManyProductsComparisonQuery( + $productIds: [String!]! + + ) { + products( + productIds: $productIds + ) { + ...ProductComparisonFragment_product + } + } +`) + +export const useProductComparison = (productIds: string[]) => { + const { channel, locale } = useSession() + const variables = useMemo(() => { + if (!channel) { + throw new Error( + `useProductComparison: 'channel' from session is an empty string.` + ) + } + + return { productIds } + }, [channel, locale, productIds]) + + return useQuery(query, variables, { + onSuccess: (data) => console.log(data), + }) +} + +export const fragment = gql(` + fragment ProductComparisonFragment_product on StoreProduct { + ...ProductDetailsFragment_product, + + skuSpecifications { + field { + id + name + originalName + } + values { + name + id + fieldId + originalName + } + } + + specificationGroups { + name + originalName + specifications { + name + originalName + values + } + } + } +`) From 8135b602ef35a47f7cc1a9a5272a1642e9306104 Mon Sep 17 00:00:00 2001 From: ramondorosario Date: Thu, 19 Dec 2024 14:31:13 -0300 Subject: [PATCH 7/9] fix: sku filter --- packages/api/src/platforms/vtex/resolvers/query.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/api/src/platforms/vtex/resolvers/query.ts b/packages/api/src/platforms/vtex/resolvers/query.ts index 704c6415da..dc8d279716 100644 --- a/packages/api/src/platforms/vtex/resolvers/query.ts +++ b/packages/api/src/platforms/vtex/resolvers/query.ts @@ -215,7 +215,7 @@ export const Query = { return [] } - const query = `id:${productIds.join(';')}` + const query = `id:${productIds.join(';')}` const products = await search.products({ page: 0, count: productIds.length, @@ -225,7 +225,9 @@ export const Query = { return products.products .map((product) => product.items.map((sku) => enhanceSku(sku, product))) .flat() - .filter((sku) => sku.sellers.length > 0) + .filter( + (sku) => productIds.includes(sku.itemId) && sku.sellers.length > 0 + ) }, allCollections: async ( _: unknown, From 7bacf3b0341026664c58d205634303c2c5f949b9 Mon Sep 17 00:00:00 2001 From: ramondorosario Date: Thu, 19 Dec 2024 14:36:03 -0300 Subject: [PATCH 8/9] fix: remove log --- packages/core/src/sdk/product/useProductComparison.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core/src/sdk/product/useProductComparison.ts b/packages/core/src/sdk/product/useProductComparison.ts index 468830e3de..f1523b687b 100644 --- a/packages/core/src/sdk/product/useProductComparison.ts +++ b/packages/core/src/sdk/product/useProductComparison.ts @@ -28,9 +28,7 @@ export const useProductComparison = (productIds: string[]) => { return { productIds } }, [channel, locale, productIds]) - return useQuery(query, variables, { - onSuccess: (data) => console.log(data), - }) + return useQuery(query, variables) } export const fragment = gql(` From f1bb43c1fee919db0c46413f10cd785379b1cfeb Mon Sep 17 00:00:00 2001 From: Hiago Moreira Date: Thu, 2 Jan 2025 15:39:05 -0300 Subject: [PATCH 9/9] feat: adjust by integration --- packages/core/@generated/gql.ts | 8 +++ packages/core/@generated/graphql.ts | 72 +++++++++++++++++++ .../src/sdk/product/useProductComparison.ts | 62 ---------------- .../src/sdk/product/useProductsSelected.ts | 48 +++++++++++++ 4 files changed, 128 insertions(+), 62 deletions(-) delete mode 100644 packages/core/src/sdk/product/useProductComparison.ts create mode 100644 packages/core/src/sdk/product/useProductsSelected.ts diff --git a/packages/core/@generated/gql.ts b/packages/core/@generated/gql.ts index da2894ad73..6ae4c181bd 100644 --- a/packages/core/@generated/gql.ts +++ b/packages/core/@generated/gql.ts @@ -52,6 +52,8 @@ const documents = { types.ClientProductGalleryQueryDocument, '\n query ClientProductQuery($locator: [IStoreSelectedFacet!]!) {\n ...ClientProduct\n product(locator: $locator) {\n ...ProductDetailsFragment_product\n }\n }\n': types.ClientProductQueryDocument, + '\n query ClientManyProductsSelectedQuery(\n $productIds: [String!]!\n\n ) {\n products(\n productIds: $productIds\n ) {\n ...ProductComparisonFragment_product\n }\n }\n': + types.ClientManyProductsSelectedQueryDocument, '\n query ClientSearchSuggestionsQuery(\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]\n ) {\n ...ClientSearchSuggestions\n search(first: 5, term: $term, selectedFacets: $selectedFacets) {\n suggestions {\n terms {\n value\n }\n products {\n ...ProductSummary_product\n }\n }\n products {\n pageInfo {\n totalCount\n }\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n': types.ClientSearchSuggestionsQueryDocument, '\n query ClientTopSearchSuggestionsQuery(\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]\n ) {\n ...ClientTopSearchSuggestions\n search(first: 5, term: $term, selectedFacets: $selectedFacets) {\n suggestions {\n terms {\n value\n }\n }\n }\n }\n': @@ -182,6 +184,12 @@ export function gql( export function gql( source: '\n query ClientProductQuery($locator: [IStoreSelectedFacet!]!) {\n ...ClientProduct\n product(locator: $locator) {\n ...ProductDetailsFragment_product\n }\n }\n' ): typeof import('./graphql').ClientProductQueryDocument +/** + * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function gql( + source: '\n query ClientManyProductsSelectedQuery(\n $productIds: [String!]!\n\n ) {\n products(\n productIds: $productIds\n ) {\n ...ProductComparisonFragment_product\n }\n }\n' +): typeof import('./graphql').ClientManyProductsSelectedQueryDocument /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/packages/core/@generated/graphql.ts b/packages/core/@generated/graphql.ts index 535a7af38e..4835064518 100644 --- a/packages/core/@generated/graphql.ts +++ b/packages/core/@generated/graphql.ts @@ -1733,6 +1733,69 @@ export type ClientProductQueryQuery = { } } +export type ClientManyProductsSelectedQueryQueryVariables = Exact<{ + productIds: Array | Scalars['String']['input'] +}> + +export type ClientManyProductsSelectedQueryQuery = { + products: Array<{ + sku: string + name: string + gtin: string + description: string + unitMultiplier: number | null + id: string + skuSpecifications: Array<{ + field: { id: string | null; name: string; originalName: string | null } + values: Array<{ + name: string + id: string | null + fieldId: string | null + originalName: string | null + }> + }> + specificationGroups: Array<{ + name: string + originalName: string + specifications: Array<{ + name: string + originalName: string + values: Array + }> + }> + isVariantOf: { + name: string + productGroupID: string + skuVariants: { + activeVariations: any | null + slugsMap: any | null + availableVariations: any | null + allVariantProducts: Array<{ name: string; productID: string }> | null + } | null + } + image: Array<{ url: string; alternateName: string }> + brand: { name: string } + offers: { + lowPrice: number + lowPriceWithTaxes: number + offers: Array<{ + availability: string + price: number + priceWithTaxes: number + listPrice: number + listPriceWithTaxes: number + seller: { identifier: string } + }> + } + additionalProperty: Array<{ + propertyID: string + name: string + value: any + valueReference: any + }> + }> +} + export type ClientSearchSuggestionsQueryQueryVariables = Exact<{ term: Scalars['String']['input'] selectedFacets: InputMaybe | IStoreSelectedFacet> @@ -2420,6 +2483,15 @@ export const ClientProductQueryDocument = { ClientProductQueryQuery, ClientProductQueryQueryVariables > +export const ClientManyProductsSelectedQueryDocument = { + __meta__: { + operationName: 'ClientManyProductsSelectedQuery', + operationHash: '8c0585c37d77be260a89de462975a746db7fb7e9', + }, +} as unknown as TypedDocumentString< + ClientManyProductsSelectedQueryQuery, + ClientManyProductsSelectedQueryQueryVariables +> export const ClientSearchSuggestionsQueryDocument = { __meta__: { operationName: 'ClientSearchSuggestionsQuery', diff --git a/packages/core/src/sdk/product/useProductComparison.ts b/packages/core/src/sdk/product/useProductComparison.ts deleted file mode 100644 index f1523b687b..0000000000 --- a/packages/core/src/sdk/product/useProductComparison.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { gql } from '@generated' -import { useQuery } from 'src/sdk/graphql/useQuery' -import { useSession } from 'src/sdk/session' -import { useMemo } from 'react' - -const query = gql(` - query ClientManyProductsComparisonQuery( - $productIds: [String!]! - - ) { - products( - productIds: $productIds - ) { - ...ProductComparisonFragment_product - } - } -`) - -export const useProductComparison = (productIds: string[]) => { - const { channel, locale } = useSession() - const variables = useMemo(() => { - if (!channel) { - throw new Error( - `useProductComparison: 'channel' from session is an empty string.` - ) - } - - return { productIds } - }, [channel, locale, productIds]) - - return useQuery(query, variables) -} - -export const fragment = gql(` - fragment ProductComparisonFragment_product on StoreProduct { - ...ProductDetailsFragment_product, - - skuSpecifications { - field { - id - name - originalName - } - values { - name - id - fieldId - originalName - } - } - - specificationGroups { - name - originalName - specifications { - name - originalName - values - } - } - } -`) diff --git a/packages/core/src/sdk/product/useProductsSelected.ts b/packages/core/src/sdk/product/useProductsSelected.ts new file mode 100644 index 0000000000..6c9cbc5f2e --- /dev/null +++ b/packages/core/src/sdk/product/useProductsSelected.ts @@ -0,0 +1,48 @@ +import { gql } from '@generated' +import { useQuery } from 'src/sdk/graphql/useQuery' +import { useSession } from 'src/sdk/session' +import { useMemo } from 'react' +import { + ClientManyProductsSelectedQueryQuery, + ClientManyProductsSelectedQueryQueryVariables, + ClientSearchSuggestionsQueryQuery, +} from '@generated/graphql' + +const query = gql(` + query ClientManyProductsSelectedQuery( + $productIds: [String!]! + + ) { + products( + productIds: $productIds + ) { + ...ProductComparisonFragment_product + } + } +`) + +export const useProductsSelected = ( + productIds: string[], + enabled: boolean, + processResponse: (data: ClientManyProductsSelectedQueryQuery) => void +) => { + const { channel, locale } = useSession() + const variables = useMemo(() => { + if (!channel) { + throw new Error( + `useProductsSelected: 'channel' from session is an empty string.` + ) + } + + return { productIds } + }, [channel, locale, productIds]) + + return useQuery< + ClientSearchSuggestionsQueryQuery, + ClientManyProductsSelectedQueryQueryVariables + >(query, variables, { + doNotRun: enabled, + onSuccess: (data: ClientManyProductsSelectedQueryQuery) => + processResponse(data), + }) +}