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;