Discover the purpose of the web-src folder web-src-folder

The web-src folder for this sample app contains many JavaScript files and folders. This folder is used for applications that have a user interface. Not all applications use this feature. For example, a Commerce integration with an external inventory management system may not require a frontend interface and code.

Who is this video for?

  • Developers new to Adobe Commerce with limited experience using Adobe App Builder who are learning about the web-src folder and its contents.

Video content

  • What is the main purpose for the web-src folder?
  • Typically included files and folders
  • How the web-src folder and the contents inside are used in the sample application
Transcript
This video will talk about the web-src folder.
Web-src folder is the folder that contains all the front end code. In our case, we have an src folder that contains our components and our hooks. In this sample extension, we decided to use React as a technology, and more specifically, React Spectrum. In our hooks, we have two hooks, one that retrieves the orders and the other one that retrieves the products. For the orders, we call our action that is called commerce-rest-get that we defined. And we have a REST call to the orders with a searchCriteria of all the orders. In the case of the products, we call the same action, but this time, our operation is different. We call the products with two searchCriteria, one based on the pageSize, and the second one, the page that we want to select. Why do we use paging? Because in App Builder, we have a limited space and a limited memory for the response. We can have some issues if we load all the products at once.
In our components, we have the App. So our App is a browser router that routes to our MainPage. We have a MainPage that contains for now just two tabs. The first tab contains our orders and redirects to an Orders component. And the second tab is for the products that redirects to our Products component. In the Orders component, we create a table using the table view of React Spectrum, and we load our orders in this table. In the case of our Products, we do exactly the same, but this time, for the products.

Code samples

web-src/src/components/Orders.js

/*
 * Copyright 2023 Adobe
 * All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains
 * the property of Adobe and its suppliers, if any. The intellectual
 * and technical concepts contained herein are proprietary to Adobe
 * and its suppliers and are protected by all applicable intellectual
 * property laws, including trade secret and copyright laws.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe.
 */
import {
    Content,
    Heading,
    IllustratedMessage,
    TableView,
    TableHeader,
    TableBody,
    Column,
    Row,
    Cell,
    View,
    Flex,
    ProgressCircle
} from '@adobe/react-spectrum'
import {useCommerceOrders} from '../hooks/useCommerceOrders'

export const Orders = props => {

    const {isLoadingCommerceOrders, commerceOrders} = useCommerceOrders(props)

    const ordersColumns = [
        {name: 'Order Id', uid: 'increment_id'},
        {name: 'Status', uid: 'status'},
        {name: 'Store Name', uid: 'store_name'},
        {name: 'Total Item Count', uid: 'total_item_count'},
        {name: 'Total Quantity', uid: 'total_qty_ordered'},
        {name: 'Total Due', uid: 'total_due'},
        {name: 'Tax', uid: 'tax_amount'},
        {name: 'Created At', uid: 'created_at'}
    ]

    function renderEmptyState() {
        return (
            <IllustratedMessage>
                <Content>No data available</Content>
            </IllustratedMessage>
        )
    }

    return (

        <View>
            {isLoadingCommerceOrders ? (
                <Flex alignItems="center" justifyContent="center" height="100vh">
                    <ProgressCircle size="L" aria-label="Loading…" isIndeterminate/>
                </Flex>
            ) : (
                <View margin={10}>
                    <Heading level={1}>Fetched orders from Adobe Commerce</Heading>
                    <TableView
                        overflowMode="wrap"
                        aria-label="orders table"
                        flex
                        renderEmptyState={renderEmptyState}
                        height="static-size-1000"
                    >
                        <TableHeader columns={ordersColumns}>
                            {column => <Column key={column.uid}>{column.name}</Column>}
                        </TableHeader>
                        <TableBody items={commerceOrders}>
                            {order => (
                                <Row key={order['increment_id']}>{columnKey => <Cell>{order[columnKey]}</Cell>}</Row>
                            )}
                        </TableBody>
                    </TableView>
                </View>
            )}
        </View>
    )
}

web-src/src/hooks/useCommerceOrders.js

CAUTION
When performing API calls, ensure that some sort of searchCriteria is used. You might also consider using pagination. If the result from Adobe Commerce is too large, the Adobe Developer App Builder capacity may be met and cause an unexpected end to the file. The result is a malformed response result as a 400 error.
For example, suppose There is a need to request all the current products from Adobe Commerce. The resulting URL would resemble {{base_url}}rest/V1/products?searchCriteria=all. Depending on the size of the catalog the returned, the json may be too large for App Builder to consume. Instead use pagination and make a few requests to avoid Response is not valid 'message/http'.

In the example below, the code sample is not limiting the request. To avoid a 400 error, reduce the size of the response by using searchCriteria.

?searchCriteria[filter_groups][0][filters][0][field]=created_at&searchCriteria[filter_groups][0][filters][0][value]=2022-12-01&searchCriteria[filter_groups][0][filters][0][condition_type]=gt

/*
 * Copyright 2023 Adobe
 * All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains
 * the property of Adobe and its suppliers, if any. The intellectual
 * and technical concepts contained herein are proprietary to Adobe
 * and its suppliers and are protected by all applicable intellectual
 * property laws, including trade secret and copyright laws.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe.
 */
import { useEffect, useState } from 'react'
import { callAction } from '../utils'

export const useCommerceOrders = props => {
    const [isLoadingCommerceOrders, setIsLoadingCommerceOrders] = useState(true)
    const [commerceOrders, setCommerceOrders] = useState([])

    const fetchCommerceOrders = async () => {
        const commerceOrdersResponse = await callAction(
            props,
            'commerce-rest-get',
            'orders?searchCriteria=all'
        )
        setCommerceOrders(commerceOrdersResponse.error ? [] : commerceOrdersResponse.items)
    }

    useEffect(() => {
        fetchCommerceOrders().then(() => setIsLoadingCommerceOrders(false))
    }, [])

    return { isLoadingCommerceOrders, commerceOrders }
}
recommendation-more-help
3a5f7e19-f383-4af8-8983-d01154c1402f