/* eslint-disable react/display-name */ /* eslint-disable react/prop-types */ import React, { useEffect } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory, useLocation } from 'react-router-dom'; // @ts-expect-error FIXME: update react-table import ReactTable from 'react-table'; import { getAllBlockedServices, getBlockedServices } from '../../../../actions/services'; import { initSettings } from '../../../../actions'; import { splitByNewLine, countClientsStatistics, sortIp, getService, formatNumber } from '../../../../helpers/helpers'; import { MODAL_TYPE, LOCAL_TIMEZONE_VALUE, TABLES_MIN_ROWS } from '../../../../helpers/constants'; import Card from '../../../ui/Card'; import CellWrap from '../../../ui/CellWrap'; import LogsSearchLink from '../../../ui/LogsSearchLink'; import Modal from '../Modal'; import { LocalStorageHelper, LOCAL_STORAGE_KEYS } from '../../../../helpers/localStorageHelper'; import { Client, NormalizedTopClients, RootState } from '../../../../initialState'; interface ClientsTableProps { clients: Client[]; normalizedTopClients: NormalizedTopClients; toggleClientModal: (...args: unknown[]) => unknown; deleteClient: (...args: unknown[]) => string; addClient: (...args: unknown[]) => string; updateClient: (...args: unknown[]) => string; isModalOpen: boolean; modalType: string; modalClientName: string; processingAdding: boolean; processingDeleting: boolean; processingUpdating: boolean; getStats: (...args: unknown[]) => unknown; supportedTags: string[]; } const ClientsTable = ({ clients, normalizedTopClients, isModalOpen, modalClientName, modalType, addClient, updateClient, deleteClient, toggleClientModal, processingAdding, processingDeleting, processingUpdating, getStats, supportedTags, }: ClientsTableProps) => { const [t] = useTranslation(); const dispatch = useDispatch(); const location = useLocation(); const history = useHistory(); const services = useSelector((state: RootState) => state?.services); const globalSettings = useSelector((state: RootState) => state?.settings.settingsList); const params = new URLSearchParams(location.search); const clientId = params.get('clientId'); useEffect(() => { dispatch(getAllBlockedServices()); dispatch(getBlockedServices()); dispatch(initSettings()); if (clientId) { toggleClientModal({ type: MODAL_TYPE.ADD_CLIENT, }); } }, []); const handleFormAdd = (values: any) => { addClient(values); }; const handleFormUpdate = (values: any, name: any) => { updateClient(values, name); }; const handleSubmit = (values: any) => { const config = { ...values }; if (values) { if (values.blocked_services) { config.blocked_services = Object.keys(values.blocked_services).filter( (service) => values.blocked_services[service], ); } if (values.upstreams && typeof values.upstreams === 'string') { config.upstreams = splitByNewLine(values.upstreams); } else { config.upstreams = []; } if (values.tags) { config.tags = values.tags.map((tag: any) => tag.value); } else { config.tags = []; } if (values.ids) { config.ids = values.ids.map((id) => id.name); } else { config.ids = []; } if (typeof values.upstreams_cache_size === 'string') { config.upstreams_cache_size = 0; } } if (modalType === MODAL_TYPE.EDIT_CLIENT) { handleFormUpdate(config, modalClientName); } else { handleFormAdd(config); } if (clientId) { history.push('/#clients'); } }; const getOptionsWithLabels = (options: any) => options.map((option: any) => ({ value: option, label: option, })); const getClient = (name: any, clients: any) => { const client = clients.find((item: any) => name === item.name); if (client) { const { upstreams, tags, ...values } = client; return { upstreams: (upstreams && upstreams.join('\n')) || '', tags: (tags && getOptionsWithLabels(tags)) || [], ...values, }; } return { ids: [''], tags: [], use_global_settings: true, use_global_blocked_services: true, blocked_services_schedule: { time_zone: LOCAL_TIMEZONE_VALUE, }, safe_search: { ...(globalSettings?.safesearch || {}) }, }; }; const handleDelete = (data: any) => { // eslint-disable-next-line no-alert if (window.confirm(t('client_confirm_delete', { key: data.name }))) { deleteClient(data); getStats(); } }; const handleClose = () => { toggleClientModal(); if (clientId) { history.push('/#clients'); } }; const columns = [ { Header: t('table_client'), accessor: 'ids', minWidth: 150, Cell: (row: any) => { const { value } = row; return (
{value.map((address: any) => (
{address}
))}
); }, sortMethod: sortIp, }, { Header: t('table_name'), accessor: 'name', minWidth: 120, Cell: CellWrap, }, { Header: t('settings'), accessor: 'use_global_settings', minWidth: 120, Cell: ({ value }: any) => { const title = value ? settings_global : settings_custom; return (
{title}
); }, }, { Header: t('blocked_services'), accessor: 'blocked_services', minWidth: 180, Cell: (row: any) => { const { value, original } = row; if (original.use_global_blocked_services) { return settings_global; } if (value && services.allServices) { return (
{value.map((service: any) => { const serviceInfo = getService(services.allServices, service); if (serviceInfo?.icon_svg) { return (
); } return null; })}
); } return
; }, }, { Header: t('upstreams'), accessor: 'upstreams', minWidth: 120, Cell: ({ value }: any) => { const title = value && value.length > 0 ? settings_custom : settings_global; return (
{title}
); }, }, { Header: t('tags_title'), accessor: 'tags', minWidth: 140, Cell: (row: any) => { const { value } = row; if (!value || value.length < 1) { return '–'; } return (
{value.map((tag: any) => (
{tag}
))}
); }, }, { Header: t('requests_count'), id: 'statistics', accessor: (row: any) => countClientsStatistics(row.ids, normalizedTopClients.auto), sortMethod: (a: any, b: any) => b - a, minWidth: 120, Cell: (row: any) => { let content = row.value; if (typeof content === "number") { content = formatNumber(content); } else { content = CellWrap(row); } if (!content) { return content; } return {content}; }, }, { Header: t('actions_table_header'), accessor: 'actions', maxWidth: 100, sortable: false, resizable: false, Cell: (row: any) => { const clientName = row.original.name; return (
); }, }, ]; const currentClientData = getClient(modalClientName, clients); const tagsOptions = getOptionsWithLabels(supportedTags); return ( <> LocalStorageHelper.setItem(LOCAL_STORAGE_KEYS.CLIENTS_PAGE_SIZE, size) } minRows={TABLES_MIN_ROWS} ofText="/" previousText={t('previous_btn')} nextText={t('next_btn')} pageText={t('page_table_footer_text')} rowsText={t('rows_table_footer_text')} loadingText={t('loading_table_status')} noDataText={t('clients_not_found')} /> ); }; export default ClientsTable;