Giter VIP home page Giter VIP logo

order-manager's Introduction

Order Manager

Centralizes the requests queue to the Checkout API and manages order form data.

Warning ๐Ÿšจ

This repository contains experimental code for VTEX Checkout and should not be used in production.

This code is "experimental" for various reasons:

  • Some are not tested as rigorously as the main code.
  • Some are tested but not maintained.
  • It can suffer from significant changes (breaking changes) without further notice.

Use it at your own risk! โ˜ ๏ธ

Usage

import { OrderQueueProvider, useOrderQueue, useQueueStatus } from 'vtex.order-manager/OrderQueue'
import { OrderFormProvider, useOrderForm } from 'vtex.order-manager/OrderForm'

const MainComponent: FunctionComponent = () => (
  <OrderQueueProvider>
    <OrderFormProvider>
      <MyComponent />
    </OrderFormProvider>
  </OrderQueueProvider>
)

const MyComponent: FunctionComponent = () => {
  const { enqueue, listen } = useOrderQueue()
  const { orderForm, setOrderForm } = useOrderForm()
  const queueStatusRef = useQueueStatus(listen)
  
  //...
}

OrderQueue API

useOrderQueue(): OrderQueueContext

Exposes the API to interact with the order queue. See the items below for more details.

enqueue(task: () => Promise, id?: string): CancellablePromise

Returned by useOrderQueue()

Add a task to the queue of requests to the Checkout API. task will be called when it's the first in the queue.

The optional param id can be used to duplicate requests. Example:

const taskA = () => console.log("Task A ran");
enqueue(taskA, "coupon");

// Task A did not run yet and another task with id `coupon` is added to the queue
const taskB = () => console.log("Task B ran");
enqueue(taskB, "coupon");

// Log: 'Task B ran'
// Order Manager will only run taskB and discard taskA.

The point of this feature is to avoid making requests that are stale.

Returns a promise that resolves when the task is completed. This promise has a method .cancel(). If this function is called, the queue will ignore this task if it hasn't started yet and the promise will immediately reject, returning an object with a property code with value 'TASK_CANCELLED'.

Use cases

  1. If the user submits a coupon code, the task is scheduled, then changes and type another coupon code, we can avoid making the first request since the second will superseed it.

listen(event: QueueStatus, callback: Function): UnsubcribeFunction

Returned by useOrderQueue()

Once this function is called, the callback function will be called whenever the specified event is emitted until the returned function is called.

An event is emitted whenever the queue changes its status (see QueueStatus). For instance, if the queue changes from QueueStatus.FULFILLED to QueueStatus.PENDING, a QueueStatus.PENDING event is emitted.

Returns a function to unsubscribe the callback from the specified event.

Use cases

  1. Makes it possible to add loaders or disable the Checkout button when there are tasks to resolve.

isWaiting(id: string): boolean

Returned by useOrderQueue()

Returns true if there is a task in the queue with the specified id that hasn't been run yet, or false otherwise.

Use cases

  1. If you want to enqueue a task but a similar one is already in the queue, you can use this function to determine whether the older one has already been run. In case it hasn't, you can cancel it, merge both tasks and enqueue the merged task.

QueueStatus

An enum that represents the queue states. The possible values are:

  • QueueStatus.PENDING: There is a task running and there might be other tasks enqueued.
  • QueueStatus.FULFILLED: The queue is empty and no task is being run.

useQueueStatus(listen: ListenFunction): React.MutableRefObject<QueueEvent>

A helper hook that takes the listen function returned by useOrderQueue and returns a ref object whose .current property is a string equal to Pending or Fulfilled indicating the current queue status.

Use cases

  1. Makes it possible to perform actions conditioned on the queue status.

Example

const { QueueStatus, useOrderQueue, useQueueStatus } from 'vtex.order-manager/OrderQueue'

const Component: FunctionComponent = () => {
  const { listen } = useOrderQueue()
  const queueStatusRef = useQueueStatus(listen)

  const handleClick = () => {
    if (queueStatusRef.current === QueueStatus.PENDING) {
      console.log('An action was performed while the queue was busy.')
    }
  }
  
  // ...
}

Notes

  • Keep in mind that mutating the ref object does not trigger a re-render of the React component. If you want to display content depending on the queue status, consider using states controlled by queue events instead.

OrderForm API

useOrderForm(): OrderFormContext

Exposes the API to interact with the order form. See the items below for more details.

loading: boolean

Returned by useOrderForm()

This flag is set to true only when OrderManager is loading the order form during render. In order to know whether a task is ongoing, use listen instead.

Use cases

  1. Make it possible to render a loading state when loading a page.

orderForm: OrderForm

Returned by useOrderForm()

Contains data from the order form. Do not modify this directly, use setOrderForm instead. In case the order form query fails, an empty order form is returned instead (see error).

setOrderForm: (newOrderForm: Partial<OrderForm>) => void

Returned by useOrderForm()

Updates the order form stored in OrderManager. This should be called after each mutation to ensure that client data does not get out of sync with server data and that other OrderManager consumers can react to this update.

error: ApolloError | undefined

Returned by useOrderForm()

A reference to the error object returned by the GraphQL query for the order form.

order-manager's People

Contributors

darlenedms avatar dependabot[bot] avatar dk-portal[bot] avatar evertonstrack avatar jeffersontuc avatar jorgeacostavtex avatar kaisermann avatar klzns avatar lucasecdb avatar marcoskwkm avatar silviasfon avatar tlgimenes avatar victorhmp avatar wdsrocha avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

order-manager's Issues

OrderForm query does not return product with extended warranty

Describe the bug
When you have products in the cart with an extended warranty, the GraphQL query does not return undefined, even if you have products in the checkout

To Reproduce
Steps to reproduce the behavior:

  1. Looking for a product that has an extended warranty on the cart
  2. Go to checkout and add the guarantee
  3. Go back to choose more products
  4. see empty cart

Could anyone understand this problem?

ratesAndBenefitsData element isn't included into orderForm object

Describe the bug
Have my Minicart app customized and need read the ratesAndBenefitsData element with all promotions applied into cart, but this aren't exist... Should be exist why within "priceTags" element is showing the identifiers of each benefit. Bug!

To Reproduce
Steps to reproduce the behavior:

  1. Go to 'Home'
  2. Add one or some products with an active discount promotion, this promotion should that apply immediately.
  3. Internally debug the orderForm from "'vtex.order-manager/OrderForm'",
  4. Checking this latest orderForm noted not exist the ratesAndBenefitsData node.
  5. Go at Cart page and debug vtexjs.checkout.orderForm and if exist the ratesAndBenefitsData node.

Expected behavior
The orderForm that we have available from the browser's DOM... should be a faithful copy of what is Vtex-app should deliver.

Screenshots
ratesAndBenefitsData available in browser's DOM, from orderForm:
image

Missing ratesAndBenefitsData obtain from order-manager:
image

Desktop environment:

Replicate a normal cart flow from a browser and debug linking from a workspace....

We try get the "benefits" from a GraphQL query using:

query benefitsByIdentifier ($field: ProductUniqueIdentifierField!, $values: [ID!], $salesChannel: String) { productsByIdentifier (field: $field, values: $values, salesChannel: $salesChannel) @context(provider: "vtex.search-graphql") { items { itemId name } benefits { id name } } }

...but the response data is for some products.

Another alternative is get ratesAndBenefitsData using VTEX API /api/checkout/pub/orderForm/{orderformId} but isn't optimal....

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.