Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
42 kB
1
Indexable
Never
bulk edit

import { InlineStack, Thumbnail, BlockStack, Text, Button, Page, Icon, Collapsible, Checkbox, Tooltip, ContextualSaveBar, Modal, Card } from '@shopify/polaris';
import React, { useEffect, useMemo, useReducer, useState } from 'react'
import { Table } from 'antd';
import SideSheet from './components/SideSheet/SideSheet';
import Category from './components/Category/Category';
import AnnouncementAlert from './components/Announcement/AnnouncementAlert';
import './styles/bulkedit.css';
import { reducer } from './context/reducer';
import { GLobalProvider } from './context';
import { _ACTIONS } from './context/actions';
import { formatAmazonRecommendations, checkForMutatedStates, isRowElementDisabled, extractPrefilledVariantAttributes, extractEditedCol, manageColHeading, selectedProductsCount, formatShopifyAttributes, extractCurrentSelection } from './helper';
import { _DROPDOWN, _RESET } from '../../assets/iconsSvg';
import { BulkeditI, ModalHandlerI, ResetDataI } from './type/bulkedit.type';
import { useNavigate } from 'react-router-dom';
import getClassNames from './Utility/getClassnames';
import SkeltonBulkEditGrid from './skeltonBulkEdit/SkeltonBulkEditGrid';
import { _SHOPIFYATTRIBTUES, _STATICCOLUMNS } from './helper/constants';
import { ColumnElementStructureI, PopoverPayloadI } from './type';
import { OnCellClickedI, RenderEditableCellI } from './type/rows.type';
import Pagination from './components/Pagination/Pagination';
import { rowData2 } from '../constants/products';
import { ChevronDownMinor, ChevronUpMinor, Columns3Major } from '@shopify/polaris-icons';
import { HTMLElement } from './components/HTMLElement';
import { trimTitle } from './helper/view/bulkeditView';


export default function BulkEdit(props: Readonly<BulkeditI>) {
    const [announcement, setAnnouncement] = useState(false);
    const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
    const [isSideSheetOpen, setIsSideSheetOpen] = useState(false);
    const [globalState, dispatch] = useReducer(reducer, {
        pagination: {
            page: 1,
            totalPages: 2
        }
    });
    const [selectAllCols, setSelectAllCols] = useState<any>({});
    const [isCollapsible, setIsCollapsible] = useState<any>({});
    const [loading, setLoading] = useState(true);
    const [isVariantGrid, setIsVariantGrid] = useState(false)
    let tempCommencedState: any = {};
    const naviate = useNavigate();
    const isVariantBulkEdit = getParams();
    const [modal, setModal] = useState({
        title: '',
        isOpen: false,
        data: [],
        type: '',
        size: 'medium',
        primaryAction: [],
    })
    const memoizedValue = useMemo(() => ({
        value: globalState,
        dispatch
    }), [globalState, dispatch]);

    const [selectedCell, setSelectedCell] = useState<any>({
        rowIndex: 0,
        columnIndex: 0,
        colName: ''
    })

    const onSelectChange = (newSelectedRowKeys: React.Key[]) => {
        setSelectedRowKeys(newSelectedRowKeys);
    };

    const rowSelection = {
        selectedRowKeys,
        onChange: onSelectChange,
        getCheckboxProps: (record: any) => {
            if (record.index === undefined) {
                return {
                    style: {
                        display: 'none',
                    },
                    disabled: record?.index === undefined
                };
            }
            return {
                disabled: record?.index === undefined//', // Disable checkbox for the first row
            }
        },
    };

    function getParams() {
        return window.location.pathname === '/varian-edit'
    }

    function handleClickOutside(event: MouseEvent) {
        if(!selectedCell.rowIndex && selectedCell.colName ==="") return;
        const popoverContentContainer = document.querySelector<HTMLElement>(".Polaris-Popover__ContentContainer");
        const customMoreActionEles = document.querySelectorAll<HTMLElement>(".selected_cell");
        const isInsidePopover = popoverContentContainer && event.composedPath().includes(popoverContentContainer);
        const isInsideCustomMoreAction = Array.from(customMoreActionEles).some(ele =>
            event.composedPath().includes(ele)
        );
        if (!isInsidePopover && !isInsideCustomMoreAction) {
            resetCell(selectedCell?.columnIndex,selectedCell?.colName)
        }
    };

    function resetCell(index:any,key:any) {
        let tempRows: any = [...(globalState?.rows ?? [])];
        tempRows[index][key]['clicked'] = '';
        setSelectedCell({ rowIndex: null, columnIndex: null,colName:"" });
        dispatch({
            type: _ACTIONS.SET_ROW,
            payload: {
                rows: tempRows
            }
        })
    }

    useEffect(() => {
        window.addEventListener("click", handleClickOutside)
        return () => {
            window.removeEventListener("click", handleClickOutside)
        }
    }, [selectedCell])
    useEffect(() => {
        setLoading(true);
        setTimeout(() => {
            setLoading(false)
            prepareColumns(props.columns);
            prepareRows(
                globalState?.pagination && globalState?.pagination?.page === 2 ? rowData2 : props.rows
            );
            prepareShopifyAttributes()
        }, 500);
    }, [globalState?.pagination, props.rows, props.columns, props.rows])

    function prepareShopifyAttributes() {
        let shhopifyAttributes: any = formatShopifyAttributes(_SHOPIFYATTRIBTUES);
        dispatch({
            type: _ACTIONS.SHOPIFY_ATTRIBUTES,
            payload: {
                shopifyAttributes: shhopifyAttributes
            }
        })
    }

    useEffect(() => {
        setSelectedRowKeys([])
    }, [globalState?.pagination?.page])

    function prepareRows(rows: any) {
        let tempRows: any = [];
        rows.forEach((elem: any, index: number) => {
            let { source_product_id, title, main_image, description, editedData } = elem;
            tempRows.push({
                key: {
                    value: source_product_id
                },
                source_product_id: {
                    value: source_product_id
                },
                title: {
                    value: title ?? 'Title ' + source_product_id
                },
                main_image: {
                    value: main_image
                },
                description: {
                    value: description
                },
                ...(isVariantBulkEdit ? preapreVariantRows(elem) : dynamicCols(elem?.editedData, elem?.container_id)),
                editedData
            })

        });
        dispatch({
            type: _ACTIONS.SET_ROW,
            payload: {
                rows: tempRows,
            }
        });
        commencedState('rows', JSON.parse(JSON.stringify(tempRows)))
    }

    function preapreVariantRows(variantData: any) {
        const tempColumns = prepareColumns(props.columns, 'rows');
        let result: any = {}
        let rows: any = [];
        if (variantData?.edited_variant_attributes)
            rows.push(...(variantData?.edited_variant_attributes ?? []))
        if (variantData?.category_settings?.attributes_mapping?.optional_attribute)
            rows.push(...(variantData?.category_settings?.attributes_mapping?.optional_attribute ?? []))

        tempColumns?.forEach((elem: any, index: number) => {
            if (elem?.dataIndex !== 'ProductDetails' && elem?.dataIndex !== 'sku') {
                result = {
                    ...result,
                    [elem?.dataIndex]: {
                        ...formatColData(elem, rows, elem?._field_data ?? {}),
                        hasAmazonRecommendation: elem?.hasAmazonRecommendation,
                        options: formatAmazonRecommendations(elem?._field_data?.amazon_recommendation ?? {}),
                    },
                }
            }
        })
        return result
    }

    function dynamicCols(editedData: any, p_container_id: string) {
        const tempColumns = prepareColumns(props.columns, 'rows');
        let result: any = {}
        let rows: any = [];
        if (editedData?.length === 1)
            rows.push(
                ...(editedData?.[0]?.category_settings?.attributes_mapping?.optional_attribute ?? []),
                ...(editedData?.[0]?.category_settings?.attributes_mapping?.required_attribute ?? [])
            )
        else {
            editedData?.forEach((elem: any) => {
                if (elem?.source_product_id === p_container_id) {
                    rows.push(...(elem?.category_settings?.attributes_mapping?.optional_attribute ?? []), ...(elem?.category_settings?.attributes_mapping?.required_attribute ?? []))
                }
            })
        }
        tempColumns?.forEach((elem: any, index: number) => {
            if (elem?.dataIndex !== 'ProductDetails' && elem?.dataIndex !== 'sku') {
                result = {
                    ...result,
                    [elem?.dataIndex]: {
                        ...formatColData(elem, rows, elem?._field_data ?? {}),
                        hasAmazonRecommendation: elem?.hasAmazonRecommendation,
                        options: formatAmazonRecommendations(elem?._field_data?.amazon_recommendation ?? {}),
                    },
                    variantLength: editedData?.length
                }
            }
        })
        return result
    }

    function formatColData(col: any, rows: any[], _field_data: any) {
        let data: any = undefined;
        rows.forEach(elem => {
            if (col?.key === elem?.amazon_attribute) {
                data = {
                    isModified: false,
                    isEditable: false,
                    hasAmazonRecommendation: elem?.recommendation !== '',
                    amazonRecommendation: {
                        options: _field_data?.amazon_recommendation,
                        value: elem?.recommendation
                    },
                    shopifySelect: {
                        options: formatShopifyAttributes(_SHOPIFYATTRIBTUES),
                        value: elem?.shopify_attribute ?? ''
                    },
                    customText: {
                        value: elem?.custom_text ?? ''
                    },
                    currentSelection: {
                        ...extractCurrentSelection(elem, _field_data)
                    },
                    columnName: col?.title,
                    clicked: '',
                    displayValue: extractCurrentSelection(elem, _field_data)?.value ?? ''
                }
            }
        })
        if (data === undefined)
            data = {
                value: '',
                options: [],
                isEditable: false,
                isModified: false,
                hasAmazonRecommendation: _field_data?.amazon_recommendation !== undefined,
                amazonRecommendation: {
                    options: _field_data?.amazon_recommendation ?? [],
                    value: ''
                },
                shopifySelect: {
                    options: formatShopifyAttributes(_SHOPIFYATTRIBTUES),
                    value: ''
                },
                customText: {
                    value: ''
                },
                currentSelection: {
                    type: '',
                    value: '',
                    options: []
                },
                columnName: col?.title,
                clicked: '',
                displayValue: ''
            }
        return data
    }

    function prepareColumns(inputObject: any, from?: 'rows' | 'cols') {
        let result: any[] = [..._STATICCOLUMNS];
        let manageColumns: any = {};
        let selectAllCols: any = {};
        let collapsibles: any = {}
        let index: number = 0;

        for (const categoryKey in inputObject) {
            const category = inputObject[categoryKey];
            selectAllCols[categoryKey] = {
                selectAll: extractPrefilledVariantAttributes({
                    categoryKey, isVariantBulkEdit
                })
            }
            collapsibles[categoryKey] = { // to open or to close the manage col's collapsible
                isOpen: extractPrefilledVariantAttributes({
                    categoryKey, isVariantBulkEdit
                })
            }
            for (const fieldKey in category) {
                index++;
                const field = category[fieldKey];
                if (categoryKey === 'Mandantory') {
                    if (!isVariantBulkEdit)
                        manageColumns[categoryKey] = {
                            ...manageColumns[categoryKey],
                            [fieldKey]: {
                                visible: extractPrefilledVariantAttributes({
                                    categoryKey, isVariantBulkEdit
                                }),
                                ...field,
                                type: categoryKey
                            }
                        }
                }
                else
                    manageColumns[categoryKey] = {
                        ...manageColumns[categoryKey],
                        [fieldKey]: {
                            visible: extractPrefilledVariantAttributes({
                                categoryKey, isVariantBulkEdit,
                                rows: props.rows,
                                categoryField: fieldKey
                            }),
                            ...field,
                            type: categoryKey
                        }
                    }
                result.push({
                    _field_data: field,
                    key: fieldKey,
                    type: categoryKey,
                    visible: extractPrefilledVariantAttributes({
                        categoryKey, isVariantBulkEdit,
                        rows: props.rows,
                        categoryField: fieldKey
                    }),
                    title: field?.label,
                    dataIndex: field.label,
                    width: '300px',
                    isModified: false,
                    hasAmazonRecommendation: field?.amazon_recommendation !== undefined,
                    elementIndexKey: index + (field?.definition ?? index)
                });
            }
        }
        if (from) return result
        setSelectAllCols(selectAllCols);
        setIsCollapsible(collapsibles);
        dispatch({
            type: _ACTIONS.COLUMNS,
            payload: {
                [_ACTIONS.MANAGE_COLS]: manageColumns,
                [_ACTIONS.COLUMNS]: result
            }
        });
        commencedState('columns', JSON.parse(JSON.stringify(result)));
    }

    function commencedState(key: string, value: any) {
        tempCommencedState[key] = value;
        dispatch({
            type: _ACTIONS.SET_COMMENCED_STATE,
            payload: {
                commencedState: {
                    ...globalState?.commencedState,
                    ...tempCommencedState
                }
            }
        })
    }

    function columnRenderer(columns: any[]) {
        let structure: any = [];
        columns?.forEach((elem, index) => {
            structure.push({
                ...elem,
                title: <div className="thead-tooltip">
                    {
                        typeof elem?.title === 'string' && elem?.title !== "Product Details" ? <Tooltip content={elem?.title}>
                            <Text as="p" fontWeight="bold">
                                {trimTitle({ title: elem?.title })}
                            </Text>
                        </Tooltip> :
                            <Text as="p" fontWeight="bold">
                                {trimTitle({ title: elem?.title })}
                            </Text>
                    }
                </div>,
                render: (t: any) => {
                    if (t === undefined) return columnElementStructure({
                        element: elem,
                        index
                    })
                    else return t
                },
                key: elem?.title
            })
        })
        return structure
    }

    const triggerOnDataChange = (triggeredFuntion: any, ...params: any) => {
        triggeredFuntion(...params);
    };

    function columnElementStructure(props: ColumnElementStructureI) {
        const { element: elem, index } = props;
        function showEditText(){
            const uniqueIdentifier = elem.dataIndex;
            if (uniqueIdentifier === "ProductDetails") {
                return <div className='edit_describtion'>Edit this row to update selected products</div>
            }
            else if (uniqueIdentifier === "sku" || uniqueIdentifier === "productTitle") {
                return <></>
            }
        }
        return <>
            {rowSelection.selectedRowKeys?.length >= 2 ?
            elem.dataIndex === "ProductDetails" || elem.dataIndex === "sku" ? showEditText():
            <HTMLElement
                type='popover'
                payload={{
                    popover: {
                        hasAmazonRecommendation: elem?._field_data?.amazon_recommendation !== undefined,
                        amazonRecommendation: {
                            options: formatAmazonRecommendations(elem?._field_data?.amazon_recommendation ?? {}),
                            value: ''
                        },
                        shopifySelect: {
                            options: globalState?.shopifyAttributes ?? [],
                            value: ''
                        },
                    },
                    columnName: elem?.title
                }}
                tableElementType='columns'
                onDataChange={(...params) => triggerOnDataChange(updatedHandleBulkEdit, ...params)}
            />
                : <>
                    {elem?.dataIndex === "ProductDetails" ? <div className='select_describtion'><Text as='p'>Select two or more rows to enable Bulk Edit</Text></div> : <></>}
                </>}
            {
                (checkForMutatedStates(globalState?.commencedState, globalState?.rows) && rowSelection.selectedRowKeys?.length >= 2) && (elem?.dataIndex !== "ProductDetails") && (elem?.dataIndex !== "sku") &&
                <Button
                    key={elem?.title}
                    id='reset_btn'
                    disabled={extractEditedCol({
                        initialState: globalState?.commencedState,
                        modifiedState: globalState?.rows,
                        colIdentifier: elem?._field_data?.label ?? ''
                    })}

                    onClick={() => {
                        resetData({
                            index: index,
                            key: typeof elem?.title === 'object' ? elem?.dataIndex : elem?.title,
                            type: 'bulk',
                        })
                    }}
                    variant="plain">Reset</Button>
            }
        </>;
    }

    function updatedHandleBulkEdit(key: string, value: string | number) {
        let tempRows: any = [...(globalState?.rows ?? [])];
        tempRows?.forEach((row: any) => {
            if (rowSelection.selectedRowKeys?.includes(row['key']['value'])) {
                row[key]['displayValue'] = value;
                row[key]['isModified'] = true;
            }
        });

        dispatch({
            type: _ACTIONS.SET_ROW,
            payload: {
                rows: tempRows
            }
        })
    }

    function toggleColumn(key: string, sub_key: string, value: any) {

        let found: boolean = false;
        let tempCols: any = [...(globalState?.columns ?? [])];
        tempCols?.forEach((elem: any) => {
            if (!found && elem?.dataIndex === value) {
                elem.visible = !elem?.visible
            }
        })
        // Updating mangeCols keys
        let tempManageCols: any = { ...(globalState?.manage_columns ?? {}) };
        tempManageCols[key][sub_key]['visible'] = !tempManageCols[key][sub_key]['visible'];
        dispatch({
            type: _ACTIONS.COLUMNS,
            payload: {
                [_ACTIONS.COLUMNS]: tempCols,
                [_ACTIONS.MANAGE_COLS]: tempManageCols
            }
        })
    }

    function selectAllManagedCols(key: string, value: any, sub_key: any) {
        let temp: any = { ...selectAllCols };
        temp[key]['selectAll'] = !value;

        let tempManageCols: any = { ...(globalState?.manage_columns ?? {}) };
        let tempCols: any = [...(globalState?.columns ?? [])];
        Object.keys(tempManageCols[key] ?? [])?.forEach(elem => {
            tempManageCols[key][elem]['visible'] = !value;
        })

        tempCols?.forEach((elem: any) => {
            if (elem?.type === key)
                elem['visible'] = !value;
        })

        dispatch({
            type: _ACTIONS.COLUMNS,
            payload: {
                [_ACTIONS.MANAGE_COLS]: tempManageCols,
                [_ACTIONS.COLUMNS]: tempCols,
            }
        })
        setSelectAllCols(temp)
    }

    function handleCollapsible(key: string): any {
        let tempCollapsibles: any = { ...isCollapsible };
        tempCollapsibles[key]['isOpen'] = !tempCollapsibles?.[key]?.isOpen;
        setIsCollapsible(tempCollapsibles)
    }

    const renderManagedElements = (elem: any) => {
        const header =
            elem === 'Mandantory' ?
                <Text as='h3' fontWeight='bold' variant='headingSm'>Required Attributes</Text> :
                manageColHeading(elem);

        const collapsible = (
            <Collapsible
                open={isCollapsible?.[elem]?.['isOpen']}
                id="basic-collapsible"
                transition={{ duration: '500ms', timingFunction: 'ease-in-out' }}
                expandOnPrint
            >
                <div className='collapsible-inner'>
                    <BlockStack gap={"500"}>
                        <Checkbox
                            label="Select All"
                            checked={selectAllCols[elem]?.['selectAll']}
                            onChange={() => {
                                selectAllManagedCols(elem, selectAllCols[elem]?.['selectAll'], globalState?.[_ACTIONS.MANAGE_COLS][elem])
                            }}
                        />
                        <div className='managecolumns__parent'>
                            {
                                Object.keys(globalState?.[_ACTIONS.MANAGE_COLS]?.[elem])?.map((element: any, index: number) => {
                                    const key = globalState?.[_ACTIONS.MANAGE_COLS]?.[elem][element]?.['definition'] + 'renderManagedElements' + index;
                                    return <div key={key} className='managecolumns__child'>
                                        {globalState?.[_ACTIONS.MANAGE_COLS]?.[elem][element]?.['label'] && <Checkbox
                                            label={trimTitle({
                                                title: globalState?.[_ACTIONS.MANAGE_COLS]?.[elem][element]?.['label'],
                                                length: 30, substringLength: 30,
                                                tooltip: {
                                                    hasTooltip: true,
                                                    tooltipContent: globalState?.[_ACTIONS.MANAGE_COLS]?.[elem][element]?.['label']
                                                }
                                            }) ?? "Select"}

                                            //globalState?.[_ACTIONS.MANAGE_COLS]?.[elem][element]?.['label'], 30, 30, { hasTooltip: true, tooltipContent: globalState?.[_ACTIONS.MANAGE_COLS]?.[elem][element]?.['label'] }
                                            checked={globalState?.[_ACTIONS.MANAGE_COLS]?.[elem][element]?.['visible']}
                                            onChange={() => {
                                                toggleColumn(elem, element, globalState?.[_ACTIONS.MANAGE_COLS]?.[elem][element]?.['label'])
                                            }}
                                        />}
                                    </div>
                                })
                            }
                        </div>
                    </BlockStack>
                </div>
            </Collapsible>
        );

        return (
            <BlockStack gap={"300"} key={elem}>
                {header}
                <div className="custom-dropdown--link side-sheet-contentWrapper">
                    <div
                        role='none'
                        className='collapsible--header'
                        onClick={() => { handleCollapsible(elem) }}>
                        <InlineStack align='space-between' blockAlign='center'>
                            <Text as='h3' fontWeight='bold' variant='headingSm' tone='subdued'>{elem}</Text>
                            <div>
                                {isCollapsible?.[elem]?.['isOpen'] ? (
                                    <Icon source={ChevronUpMinor} tone="base" />
                                ) : (
                                    <Icon source={ChevronDownMinor} tone="base" />
                                )}

                            </div>
                        </InlineStack>
                    </div>
                    {collapsible}
                </div>
            </BlockStack>
        );
    };

    function manageColumnRenderer() {
        let structure: React.ReactNode[] = [];
        if (globalState?.[_ACTIONS.MANAGE_COLS]) {
            Object.keys(globalState?.[_ACTIONS.MANAGE_COLS])?.forEach((elem: any) => {
                if (elem !== 'Variation') {
                    structure.push(renderManagedElements(elem));
                }
            });
        }
        return structure
    }

    function rowsRenderer(rows: any[]) {
        let tempRowRenderer: any = [];
        Object.keys(rows ?? []).forEach((elem: any, index: number) => {
            tempRowRenderer.push({
                ProductDetails: <InlineStack gap={"200"} wrap={false} blockAlign='start' align='start'>
                    <div className={getClassNames({ "without-variant": rows[elem]?.editedData?.length < 2 })} style={{ width: '40px' }}>
                        <Thumbnail
                            source={rows[elem]?.main_image?.value ?? 'https://i.imgur.com/oUVyG2C.png"'}
                            size="small"
                            alt="Black choker necklace"
                        />
                    </div>
                    <BlockStack gap={"100"} align='start'>
                        <div className='product-name'>
                            <Text as="p">
                                {rows[elem]?.title?.value}
                            </Text>
                        </div>
                        {
                            rows[elem]?.editedData?.length > 1 &&
                            <div className='variant-name'>
                                <Button

                                    onClick={() => {
                                        redirectToVariantEdit(rows[elem]?.editedData)
                                        setLoading(true)
                                        setIsVariantGrid(true)
                                    }}
                                    variant="plain">
                                    {`${rows[elem]?.editedData?.length} Variants`}
                                </Button>
                            </div>
                        }
                    </BlockStack>
                </InlineStack>,
                // productTitle: rows[elem]?.title?.value,
                sku: rows[elem]?.source_product_id?.value ?? 'fsd5a6f46asf4as6f4a6sd54f',
                ...addColumnsWithElement(rows[elem], index),
                key: rows[elem]?.key?.value,
                index
            })
        });

        return [...tempRowRenderer];
    }

    function redirectToVariantEdit(variantData: any) {
        prepareRows(variantData)
        naviate('/varian-edit', {
            state: {
                rows: variantData,
                columns: props.columns
            }
        });
    }

    function handleRowUpdate(key: string, value: string | number, index: number | undefined,) {
        let tempRows: any = [...(globalState?.rows ?? [])];
        if (index !== undefined) {
            tempRows[index][key]['isModified'] = value !== globalState?.commencedState['rows'][index][key]['value']
            tempRows[index][key]['displayValue'] = value;
            dispatch({
                type: _ACTIONS.SET_ROW,
                payload: {
                    rows: tempRows
                }
            })
        }
    }

    function resetData(_props: ResetDataI) {
        let obj = {
            single: resetSingleCell,
            bulk: resetBulkEdit,
            defaultvalues: resetToDefaultValues
        }
        const callObj = obj[_props.type];
        callObj((_props))
    }

    function resetToDefaultValues() {
        let tempRows: any = [...(JSON.parse(JSON.stringify(globalState?.commencedState['rows'])) ?? [])];
        dispatch({
            type: _ACTIONS.SET_ROW,
            payload: {
                rows: tempRows
            }
        });
        setSelectedRowKeys([]);
    }

    function resetSingleCell(_props: ResetDataI) {
        let tempRows: any = [...(globalState?.rows ?? [])];
        let { index, key } = _props
        tempRows[index][key]['displayValue'] = globalState?.commencedState['rows'][index][key]['displayValue'];
        tempRows[index][key]['isModified'] = false;
        tempRows[index][key]['clicked'] = '';
        dispatch({
            type: _ACTIONS.SET_ROW,
            payload: {
                rows: tempRows
            }
        })
    }

    function resetBulkEdit(_props: ResetDataI) {
        let tempRows: any = [...(globalState?.rows ?? [])];
        let { key } = _props;
        tempRows?.forEach((elem: any, index: number) => {
            elem[key]['displayValue'] = globalState?.commencedState?.rows[index][key]['displayValue'];
            elem[key]['isModified'] = false;
            tempRows[index][key]['clicked'] = '';
        })
        if (!checkForMutatedStates(globalState?.commencedState, globalState?.rows))
            setSelectedRowKeys([])
        dispatch({
            type: _ACTIONS.SET_ROW,
            payload: {
                rows: tempRows
            }
        })
    }

    const handleCellClick = (props: OnCellClickedI) => {
        let { data, index, parentRowIndex, rows } = props;
        setSelectedCell({
            columnIndex: parentRowIndex,
            rowIndex: index,
            colName: data
        })
        if (!isRowElementDisabled({
            rowSelection: { ...rowSelection },
            key: rows['key']['displayValue']
        })) {
            toggleEditAble(data, parentRowIndex, index);
        }
    };

    const renderEditableCell = (props: RenderEditableCellI) => {
        const { parentRowIndex, rowProps, childIndex } = props;
        return rowProps?.clicked === 'editing' ?
            <div role='none' tabIndex={childIndex}>
                <HTMLElement
                    type='popover'
                    payload={{
                        popover: {
                            hasAmazonRecommendation: rowProps?.hasAmazonRecommendation,
                            amazonRecommendation: {
                                options: formatAmazonRecommendations(rowProps?.amazonRecommendation?.options ?? []),
                                value: rowProps?.amazonRecommendation?.value ?? undefined
                            },
                            shopifySelect: {
                                options: rowProps.shopifySelect.options ?? [],
                                value: rowProps.shopifySelect.value
                            },
                            customText: {
                                value: rowProps?.customText?.value
                            },
                            currentSelection: {
                                ...rowProps.currentSelection
                            },
                            displayValue: rowProps.displayValue,
                            clicked: rowProps?.clicked === 'editing'
                        },
                        columnName: rowProps?.columnName,
                        indexMatrix: {
                            row: parentRowIndex,
                            childIndex: childIndex
                        },
                    }}
                    tableElementType='rows'
                    onDataChange={(...params) => triggerOnDataChange(handleRowUpdate, ...params)}
                    toggleEditAble={toggleEditAble}
                />
            </div> 
            :
            <InlineStack align='space-between' blockAlign='center' gap={'100'}>
                <div>
                    {rowProps.displayValue || '---'}
                </div>
                <InlineStack align='space-between' gap={'400'}>
                    {rowProps.isModified &&
                        <div role='none' className='reset-btn__wrapper' onClick={(e) => e.stopPropagation()}>
                            <Button
                                icon={_RESET}
                                onClick={() => resetData({ type: 'single', index: parentRowIndex, key: rowProps?.columnName })}
                                variant="plain" />
                        </div>
                    }
                    {_DROPDOWN}
                </InlineStack>
            </InlineStack>;
    };


    function addColumnsWithElement(rows: any, parentRowIndex: number) {
        let temp: any = {};
        Object.keys(rows ?? []).forEach((data: string, index: number) => {
            const rowProps: PopoverPayloadI = {
                ...rows[data]
            };
            temp[data] = (
                <div role='none'
                    key={data + 'addColumnsWithElement'}
                    className={
                        getClassNames({
                            "selected_cell":index === selectedCell.rowIndex && parentRowIndex === selectedCell.columnIndex,
                            "rowdata__wrapper":true,
                            "rows__editedcell": rows[data]?.['isModified'],
                        })}
                    // className={(index === selectedCell.rowIndex && parentRowIndex === selectedCell.columnIndex) ? "selected_cell" : 'rowdata__wrapper'}
                    onClick={() => {
                        handleCellClick({ data, index, parentRowIndex, rows });
                    }}
                >
                    {
                        renderEditableCell({ rowProps, parentRowIndex, childIndex: index })
                    }
                </div>
            );
        });

        return temp;
    }

    function toggleEditAble(key: any, parentIndex: number, childIndex: number, resetAll?: boolean) {
        let tempRows: any = [...(globalState?.rows ?? [])];
        tempRows?.forEach((elem: any, parentInd: number) => {
            Object.keys(elem ?? {}).forEach((rowChild: any, childInd: number) => {
                if (elem[rowChild]?.['clicked'] !== undefined) {
                    if ((parentInd === parentIndex && childInd === childIndex) && !resetAll) {
                        updateToggleState({
                            tempRows, parentIndex, key
                        })
                    }
                    else
                        elem[rowChild]['clicked'] = ''
                }
            })
        })

        dispatch({
            type: _ACTIONS.SET_ROW,
            payload: {
                rows: tempRows,
            }
        });
    }

    function updateToggleState(props: any) {
        const { tempRows, parentIndex, key } = props;
        if (tempRows[parentIndex][key]['clicked'] === '') {
            tempRows[parentIndex][key]['clicked'] = 'selected';
        }
        else if (tempRows[parentIndex][key]['clicked'] === 'selected') {
            tempRows[parentIndex][key]['clicked'] = 'editing';
        }
    }

    function modalHandler(props: ModalHandlerI) {
        let tempModal: any = { ...modal };
        tempModal['title'] = props?.title;
        tempModal['isOpen'] = props?.isOpen;
        tempModal['data'] = props?.data;
        tempModal['type'] = props?.type;
        tempModal['size'] = props?.size;
        setModal(tempModal);
    }

    return (
        <GLobalProvider.Provider value={memoizedValue}>
            <Modal
                open={modal.isOpen}
                title={modal.title}
                onClose={() => {
                    setModal({
                        ...modal,
                        isOpen: false
                    })
                }}
                primaryAction={{
                    content: 'Discard',
                    onAction: () => {
                        resetToDefaultValues();
                        modalHandler({ isOpen: false })
                    }
                }}
            >
                <Modal.Section>
                    {modal.data ?? []}
                </Modal.Section>
            </Modal>
            <Page
                fullWidth
                backAction={{ content: 'Products', url: '/bulkedit' }}
                title="Bulk Edit"
                subtitle="This feature allows you to edit product details for multiple products in one go.  It will save your valuable time by enabling you to update title, description, prices, inventory levels, and more across a large inventory. The value you choose in below attributes for selected products will get synchronize on Amazon marketplace"
            >
                {checkForMutatedStates(globalState?.commencedState, globalState?.rows) && <ContextualSaveBar
                    message="Unsaved changes"
                    saveAction={{
                        content: 'Save',
                        onAction: () => console.log('add form submit logic'),
                        loading: false,
                        disabled: false,
                    }}
                    discardAction={{
                        content: 'Discard',
                        onAction: () => {
                            modalHandler({
                                title: 'Discard Action',
                                data: 'All your changes will be lost and the action cannot be reverted.',
                                isOpen: true
                            })
                        },
                    }}
                />}
                <Card padding={'100'}>
                    <div className='card--padding'>
                        <BlockStack gap={"200"}>
                            {loading ? <SkeltonBulkEditGrid isVariantGrid={isVariantGrid} /> :
                                <>
                                    <div className='card-header--padding'>
                                        <InlineStack align='space-between' gap={"200"} blockAlign='center'>
                                            <Text as="h4" fontWeight='bold' variant='headingSm'>
                                                Selected {selectedProductsCount({
                                                    selectedRowKeys: selectedRowKeys
                                                })} items
                                            </Text>
                                            <InlineStack gap={"300"}>
                                                <Category />
                                                <div className='vertical--lines'></div>
                                                <Button onClick={() => { setIsSideSheetOpen(true) }} icon={<Icon
                                                    source={Columns3Major}
                                                />} />
                                            </InlineStack>
                                        </InlineStack>
                                    </div>
                                    <div className='bulkEdit-grid--wrapper'>
                                        <Table
                                            rowClassName={(record, index) => (index === 0 ? 'first__row' : '')}
                                            scroll={{ x: 'max-content' }}
                                            rowSelection={rowSelection}
                                            columns={columnRenderer(globalState?.columns?.filter((elem: { visible: any; }) => elem.visible) ?? [])}
                                            dataSource={[{ test: "test" }, ...(rowsRenderer(globalState?.rows) ?? [])]}
                                            pagination={false}
                                        />
                                    </div>
                                    <InlineStack align='center' blockAlign='center'>
                                        <Pagination />
                                    </InlineStack>
                                </>
                            }
                        </BlockStack>
                    </div>
                </Card>
            </Page >
            <SideSheet isOpen={isSideSheetOpen} onClose={() => { setIsSideSheetOpen(false) }} title="Manage Columns">
                {manageColumnRenderer()}
            </SideSheet>
            {/* <Announcement handleChangeAnnouncement={handleChangeAnnouncement} announcement={announcement} setAnnouncement={setAnnouncement} /> */}
            <AnnouncementAlert announcement={announcement} setAnnouncement={setAnnouncement} />
        </GLobalProvider.Provider>
    );
}
Leave a Comment