File "CountryDatatable.js"

Full path: /home/satkhirabarta/public_html/wp-content/plugins/really-simple-ssl/settings/src/Settings/LimitLoginAttempts/CountryDatatable.js
File size: 17.29 B (17.29 KB bytes)
MIME-type: text/x-java
Charset: utf-8

Download   Open   Edit   Advanced Editor &nnbsp; Back

import {useEffect, useState, useCallback} from '@wordpress/element';
import DataTable, {createTheme} from "react-data-table-component";
import CountryDataTableStore from "./CountryDataTableStore";
import EventLogDataTableStore from "../EventLog/EventLogDataTableStore";
import FilterData from "../FilterData";
import Flag from "../../utils/Flag/Flag";
import {__} from '@wordpress/i18n';
import useFields from "../FieldsData";
import SearchBar from "../DynamicDataTable/SearchBar";
import useMenu from "../../Menu/MenuData";

const CountryDatatable = (props) => {
    const {fieldAlreadyEnabled, getFieldValue, getField, showSavedSettingsNotice, saveFields, setHighLightField} = useFields();
    const {
        CountryDataTable,
        dataLoaded,
        fetchData,
        processing,
        handleCountryTableFilter,
        updateRow,
        pagination,
        handleCountryTablePageChange,
        handleCountryTableRowsChange,
        handleCountryTableSort,
        handleCountryTableSearch,
        addRegion,
        resetRegions,
        addRowMultiple,
        resetRow,
        resetMultiRow,
        updateRowRegion,
        dataActions,
        rowCleared,
        setDataActions,
    } = CountryDataTableStore();

    const {setSelectedSubMenuItem} = useMenu();

    const {
        fetchDynamicData,
    } = EventLogDataTableStore();

    const {
        setSelectedFilter,
        getCurrentFilter,
        setProcessingFilter,
    } = FilterData();

    const [rowsSelected, setRowsSelected] = useState([]);
    const moduleName = 'rsssl-group-filter-limit_login_attempts_country';
    const [tableHeight, setTableHeight] = useState(600);  // Starting height
    const rowHeight = 50; // Height of each row.

    useEffect(() => {
        const element = document.getElementById('set_to_captcha_configuration');
        const clickListener = async event => {
            event.preventDefault();
            if (element) {
                await redirectToAddCaptcha(element);
            }
        };

        if (element) {
            element.addEventListener('click', clickListener);
        }

        return () => {
            if (element) {
                element.removeEventListener('click', clickListener);
            }
        };
    }, []);

    const redirectToAddCaptcha = async (element) => {
        // We fetch the props from the menu item
        let menuItem = getField('enabled_captcha_provider');

        // Create a new object based on the menuItem, including the new property
        let highlightingMenuItem = {
            ...menuItem,
            highlight_field_id: 'enabled_captcha_provider',
        };

        setHighLightField(highlightingMenuItem.highlight_field_id);
        let highlightField = getField(highlightingMenuItem.highlight_field_id);
        await setSelectedSubMenuItem(highlightField.menu_id);
    }

    const buildColumn = useCallback((column) => ({
        //if the filter is set to region and the columns = status we do not want to show the column
        omit: getCurrentFilter(moduleName) === 'regions' && column.column === 'status',
        name: column.name,
        sortable: column.sortable,
        searchable: column.searchable,
        width: column.width,
        visible: column.visible,
        column: column.column,
        selector: row => row[column.column],
    }), []);
    let field = props.field;
    const columns = field.columns.map(buildColumn);

    const searchableColumns = columns
        .filter(column => column.searchable)
        .map(column => column.column);

    useEffect(() => {
        const currentFilter = getCurrentFilter(moduleName);
        if (!currentFilter) {
            setSelectedFilter('blocked', moduleName);
        }
        setProcessingFilter(processing);
        handleCountryTableFilter('status', currentFilter);

    }, [moduleName, handleCountryTableFilter, getCurrentFilter(moduleName), setSelectedFilter, CountryDatatable, processing]);

    useEffect(() => {
        if (dataActions.filterColumn === 'status') {
            const {search, searchColumns, ...rest} = dataActions;
            setDataActions(rest);
        }
    }, [dataActions.filterColumn])

    useEffect(() => {
        setRowsSelected([]);
    }, [CountryDataTable]);

    //if the dataActions are changed, we fetch the data
    useEffect(() => {
        //we make sure the dataActions are changed in the store before we fetch the data
        if (dataActions) {
            fetchData(field.action, dataActions)
        }
    }, [dataActions.sortDirection, dataActions.filterValue, dataActions.search, dataActions.page, dataActions.currentRowsPerPage, fieldAlreadyEnabled('enable_limited_login_attempts')]);

    let enabled = getFieldValue('enable_limited_login_attempts');


    useEffect(() => {
        return () => {
            saveFields(false, false)
        };
    }, [enabled]);


    const customStyles = {
        headCells: {
            style: {
                paddingLeft: '0',
                paddingRight: '0',
            },
        },
        cells: {
            style: {
                paddingLeft: '0',
                paddingRight: '0',
            },
        },
    };

    createTheme('really-simple-plugins', {
        divider: {
            default: 'transparent',
        },
    }, 'light');

    const handleSelection = useCallback((state) => {
        setRowsSelected(state.selectedRows);
    }, []);

    const allowRegionByCode = useCallback(async (code, regionName = '') => {
        if (Array.isArray(code)) {
            const ids = code.map(item => item.id);
            const regions = code.map(item => item.iso2_code);
            let no_error = true;
            regions.forEach((code) => {
                resetRegions(code, dataActions).then(
                    (response) => {
                        if (!response.success) {
                            showSavedSettingsNotice(response.message, 'error');
                            no_error = false;
                        }
                    });
            });
            if(no_error) {
                showSavedSettingsNotice(__('Selected regions are now allowed', 'really-simple-ssl'));
            }
            setRowsSelected([]);
        } else {
            await resetRegions(code, dataActions);
            showSavedSettingsNotice(__('%s is now allowed', 'really-simple-ssl')
                .replace('%s', regionName));
        }
        await fetchDynamicData('event_log');
    }, [resetRegions, getCurrentFilter(moduleName), dataActions]);


    const allowMultiple = useCallback((rows) => {
        const ids = rows.map(item => item.id);
        resetMultiRow(ids, dataActions).then((response) => {
            if (response && response.success) {
                showSavedSettingsNotice(response.message);
            } else {
                showSavedSettingsNotice(response.message, 'error');
            }
        });
    }, [resetMultiRow, getCurrentFilter(moduleName), dataActions]);

    const allowById = useCallback((id) => {
        resetRow(id, dataActions).then(
            (response) => {
                if (response.success) {
                    showSavedSettingsNotice(response.message);
                }
            }
        );
    }, [resetRow, getCurrentFilter(moduleName), dataActions]);

    const blockRegionByCode = useCallback(async (code, region = '') => {
        if (Array.isArray(code)) {
            const ids = code.map(item => item.id);
            const regions = code.map(item => item.iso2_code);
            await updateRowRegion(regions, 'blocked', dataActions).then(
                (response) => {
                    if (response.success) {
                        showSavedSettingsNotice(response.message);
                    } else {
                        showSavedSettingsNotice(response.message, 'error');
                    }
                }
            );
        } else {
            updateRowRegion(code, 'blocked', dataActions).then(
                (response) => {
                    if (response.success) {
                        showSavedSettingsNotice(response.message);
                    } else {
                        showSavedSettingsNotice(response.message, 'error');
                    }
                });
        }

        await fetchDynamicData('event_log');

    }, [addRegion, getCurrentFilter(moduleName), dataActions]);

    const blockCountryByCode = useCallback(async (code) => {
        if (Array.isArray(code)) {
            const ids = code.map(item => item.iso2_code);

            await updateRow(ids, 'blocked', dataActions).then(
                (response) => {
                    if (response.success) {
                        showSavedSettingsNotice(response.message);
                    } else {
                        showSavedSettingsNotice(response.message, 'error');
                    }
                }
            );

            setRowsSelected([]);
        } else {
            await updateRow(code, 'blocked', dataActions).then(
                (response) => {
                    if (response.success) {
                        showSavedSettingsNotice(response.message);
                    } else {
                        showSavedSettingsNotice(response.message, 'error');
                    }
                }
            );
        }

        await fetchDynamicData('event_log');

    }, [updateRow, addRowMultiple, dataActions, getCurrentFilter(moduleName)]);

    const data = {...CountryDataTable.data};

    const generateFlag = useCallback((flag, title) => (
        <>
            <Flag
                countryCode={flag}
                style={{
                    fontSize: '2em',
                }}
                title={title}
                continent={(getCurrentFilter(moduleName) === 'regions')}
            />
        </>
    ), []);

    const ActionButton = ({onClick, children, className}) => (
        // <div className={`rsssl-action-buttons__inner`}>
        <button
            className={`button ${className} rsssl-action-buttons__button`}
            onClick={onClick}
            disabled={processing}
        >
            {children}
        </button>
        // </div>
    );

    const generateActionButtons = useCallback((id, status, region_name, db_id ) => (
        <div className="rsssl-action-buttons">
            {getCurrentFilter(moduleName) === 'blocked' && (
                <ActionButton onClick={() => allowById(id)}
                              className="button-secondary">
                    {__("Allow", "really-simple-ssl")}
                </ActionButton>
            )}
            {getCurrentFilter(moduleName) === 'regions' && (
                <>
                    <ActionButton
                        onClick={() => blockRegionByCode(id, region_name)} className="button-primary">
                        {__("Block", "really-simple-ssl")}
                    </ActionButton>
                    <ActionButton
                        onClick={() => allowRegionByCode(id, region_name)} className="button-secondary">
                        {__("Allow", "really-simple-ssl")}
                    </ActionButton>
                </>
            )}
            {getCurrentFilter(moduleName) === 'countries' && (
                <>
                    {status === 'blocked' ? (
                        <ActionButton
                            onClick={() => allowById(db_id)} className="button-secondary">
                            {__("Allow", "really-simple-ssl")}
                        </ActionButton>
                    ) : (
                        <ActionButton
                            onClick={() => blockCountryByCode(id)} className="button-primary">
                            {__("Block", "really-simple-ssl")}
                        </ActionButton>
                    )}
                </>
            )}
        </div>
    ), [getCurrentFilter, moduleName, allowById, blockRegionByCode, allowRegionByCode, blockCountryByCode]);


    for (const key in data) {
        const dataItem = {...data[key]};
        if (getCurrentFilter(moduleName) === 'regions' || getCurrentFilter(moduleName) === 'countries') {
            dataItem.action = generateActionButtons(dataItem.attempt_value, dataItem.status, dataItem.region, dataItem.db_id);
        } else {
            dataItem.action = generateActionButtons(dataItem.id);
        }
        dataItem.attempt_value = generateFlag(dataItem.attempt_value, dataItem.country_name);
        dataItem.status = __(dataItem.status = dataItem.status.charAt(0).toUpperCase() + dataItem.status.slice(1), 'really-simple-ssl');
        data[key] = dataItem;
    }

    const options = Object.entries(props.field.options).map(([value, label]) => ({value, label}));

    let paginationSet;
    paginationSet = typeof pagination !== 'undefined';

    useEffect(() => {
        if (Object.keys(data).length === 0 ) {
            setTableHeight(100); // Adjust depending on your UI measurements
        } else {
            setTableHeight(rowHeight * (paginationSet ? pagination.perPage + 2 : 12)); // Adjust depending on your UI measurements
        }

    }, [paginationSet, pagination?.perPage, data]);

    return (
        <>
            <div className="rsssl-container">
                <div>
                    {/* reserved for left side buttons */}
                </div>
                <SearchBar handleSearch={handleCountryTableSearch} searchableColumns={searchableColumns}/>
            </div>
            {rowsSelected.length > 0 && (
                <div
                    style={{
                        marginTop: '1em',
                        marginBottom: '1em',
                    }}
                >
                    <div className={"rsssl-multiselect-datatable-form rsssl-primary"}>
                        <div>
                            {__("You have selected %s rows", "really-simple-ssl").replace('%s', rowsSelected.length)}
                        </div>
                        <div className="rsssl-action-buttons">
                            {getCurrentFilter(moduleName) === 'countries' && (
                                <>
                                    <ActionButton
                                        onClick={() => blockCountryByCode(rowsSelected)} className="button-primary">
                                        {__("Block", "really-simple-ssl")}
                                    </ActionButton>
                                </>
                            )}
                            {getCurrentFilter(moduleName) === 'blocked' && (
                                <ActionButton
                                    onClick={() => allowMultiple(rowsSelected)}>
                                    {__("Allow", "really-simple-ssl")}
                                </ActionButton>
                            )}
                            {getCurrentFilter(moduleName) === 'regions' && (
                                <>
                                    <ActionButton
                                        onClick={() => blockRegionByCode(rowsSelected)} className="button-primary">
                                        {__("Block", "really-simple-ssl")}
                                    </ActionButton>
                                    <ActionButton
                                        onClick={() => allowRegionByCode(rowsSelected)} className="button-secondary">
                                        {__("Allow", "really-simple-ssl")}
                                    </ActionButton>

                                </>
                            )}
                        </div>
                    </div>
                </div>
            )}
            <DataTable
                columns={columns}
                data={Object.values(data)}
                dense
                pagination={!processing}
                paginationServer
                paginationTotalRows={paginationSet ? pagination.totalRows : 10}
                paginationPerPage={paginationSet ? pagination.perPage : 10}
                paginationDefaultPage={paginationSet ? pagination.currentPage : 1}
                paginationComponentOptions={{
                    rowsPerPageText: __('Rows per page:', 'really-simple-ssl'),
                    rangeSeparatorText: __('of', 'really-simple-ssl'),
                    noRowsPerPage: false,
                    selectAllRowsItem: false,
                    selectAllRowsItemText: __('All', 'really-simple-ssl'),

                }}
                onChangeRowsPerPage={handleCountryTableRowsChange}
                onChangePage={handleCountryTablePageChange}
                sortServer={!processing}
                onSort={handleCountryTableSort}
                paginationRowsPerPageOptions={[10, 25, 50, 100]}
                noDataComponent={__("No results", "really-simple-ssl")}
                persistTableHead
                selectableRows={!processing}
                clearSelectedRows={rowCleared}
                onSelectedRowsChange={handleSelection}
                theme="really-simple-plugins"
                customStyles={customStyles}
            />
            {!enabled && (
                <div className="rsssl-locked">
                    <div className="rsssl-locked-overlay"><span
                        className="rsssl-task-status rsssl-open">{__('Disabled', 'really-simple-ssl')}</span><span>{__('Activate Limit login attempts to enable this block.', 'really-simple-ssl')}</span>
                    </div>
                </div>
            )}
        </>
    );
}

export default CountryDatatable;