diff --git a/assets/css/src/components-plugin/_logs.scss b/assets/css/src/components-plugin/_logs.scss index aa1eb63fad..8d011e825f 100644 --- a/assets/css/src/components-plugin/_logs.scss +++ b/assets/css/src/components-plugin/_logs.scss @@ -9,6 +9,7 @@ .mailpoet-listing-header { align-items: flex-start; display: inline-flex; + flex-wrap: wrap; } .mailpoet-datepicker { @@ -20,4 +21,12 @@ align-items: center; display: inline-flex; } + + .mailpoet-form-input-small { + margin-right: $grid-gap; + } + + .mailpoet-logs-limit .mailpoet-form-input-small { + width: 100px; + } } diff --git a/assets/js/src/logs/list.tsx b/assets/js/src/logs/list.tsx index ea72dbeb9c..23afafb11b 100644 --- a/assets/js/src/logs/list.tsx +++ b/assets/js/src/logs/list.tsx @@ -64,6 +64,8 @@ export type FilterType = { from?: string; to?: string; search?: string; + offset?: string; + limit?: string; } type ListProps = { @@ -71,6 +73,8 @@ type ListProps = { originalFrom?: string; originalTo?: string; originalSearch?: string; + originalOffset?: string; + originalLimit?: string; onFilter: (FilterType) => void; } @@ -80,9 +84,13 @@ export const List: React.FunctionComponent = ({ originalFrom, originalTo, originalSearch, + originalOffset, + originalLimit, }: ListProps) => { const [from, setFrom] = useState(originalFrom ?? undefined); const [to, setTo] = useState(originalTo ?? undefined); + const [offset, setOffset] = useState(originalOffset ?? ''); + const [limit, setLimit] = useState(originalLimit ?? ''); const [search, setSearch] = useState(originalSearch || ''); const dateChanged = curry((setter, value): void => { @@ -105,6 +113,12 @@ export const List: React.FunctionComponent = ({ if (to) { data.to = to; } + if (offset && offset.trim() !== '') { + data.offset = offset; + } + if (limit && limit.trim() !== '') { + data.limit = limit; + } if (search && search.trim() !== '') { data.search = search.trim(); } @@ -113,7 +127,6 @@ export const List: React.FunctionComponent = ({ return (
-
+
+ + setOffset(event.target.value)} + value={offset} + placeholder={MailPoet.I18n.t('offsetLabel')} + /> +
+
+ + setLimit(event.target.value)} + value={limit} + placeholder={MailPoet.I18n.t('limitLabel')} + /> +
diff --git a/assets/js/src/logs/logs.tsx b/assets/js/src/logs/logs.tsx index 2cb4163ca1..2384bd8254 100644 --- a/assets/js/src/logs/logs.tsx +++ b/assets/js/src/logs/logs.tsx @@ -20,10 +20,14 @@ if (logsContainer) { originalFrom={url.searchParams.get('from')} originalTo={url.searchParams.get('to')} originalSearch={url.searchParams.get('search')} + originalOffset={url.searchParams.get('offset')} + originalLimit={url.searchParams.get('limit')} onFilter={(data: FilterType): void => { url.searchParams.delete('from'); url.searchParams.delete('to'); url.searchParams.delete('search'); + url.searchParams.delete('offset'); + url.searchParams.delete('limit'); Object.entries(data).forEach(([key, value]) => { url.searchParams.append(key, value); }); diff --git a/lib/AdminPages/Pages/Logs.php b/lib/AdminPages/Pages/Logs.php index af416e3ce3..c539583a07 100644 --- a/lib/AdminPages/Pages/Logs.php +++ b/lib/AdminPages/Pages/Logs.php @@ -25,6 +25,8 @@ class Logs { $search = isset($_GET['search']) ? $_GET['search'] : null; $from = isset($_GET['from']) ? $_GET['from'] : null; $to = isset($_GET['to']) ? $_GET['to'] : null; + $offset = isset($_GET['offset']) ? $_GET['offset'] : null; + $limit = isset($_GET['limit']) ? $_GET['limit'] : null; $dateFrom = (new Carbon())->subDays(7); if (isset($from)) { $dateFrom = new Carbon($from); @@ -33,7 +35,7 @@ class Logs { if (isset($to)) { $dateTo = new Carbon($to); } - $logs = $this->logRepository->getLogs($dateFrom, $dateTo, $search); + $logs = $this->logRepository->getLogs($dateFrom, $dateTo, $search, $offset, $limit); $data = ['logs' => []]; foreach ($logs as $log) { $data['logs'][] = [ diff --git a/lib/Logging/LogRepository.php b/lib/Logging/LogRepository.php index 520eac7e96..7bcf9b60c7 100644 --- a/lib/Logging/LogRepository.php +++ b/lib/Logging/LogRepository.php @@ -18,9 +18,17 @@ class LogRepository extends Repository { * @param \DateTimeInterface|null $dateFrom * @param \DateTimeInterface|null $dateTo * @param string|null $search + * @param string $offset + * @param string $limit * @return LogEntity[] */ - public function getLogs(\DateTimeInterface $dateFrom = null, \DateTimeInterface $dateTo = null, string $search = null): array { + public function getLogs( + \DateTimeInterface $dateFrom = null, + \DateTimeInterface $dateTo = null, + string $search = null, + string $offset = null, + string $limit = null + ): array { $query = $this->doctrineRepository->createQueryBuilder('l') ->select('l'); @@ -42,6 +50,15 @@ class LogRepository extends Repository { } $query->orderBy('l.createdAt', 'desc'); + if ($offset !== null) { + $query->setFirstResult((int)$offset); + } + if ($limit === null) { + $query->setMaxResults(500); + } else { + $query->setMaxResults((int)$limit); + } + return $query->getQuery()->getResult(); } diff --git a/views/logs.html b/views/logs.html index 7a3041e3c8..e2319bb407 100644 --- a/views/logs.html +++ b/views/logs.html @@ -23,6 +23,8 @@ 'tableHeaderMessage': __('Message'), 'tableHeaderCreatedOn': __('Created On'), 'searchLabel': __('Search'), + 'offsetLabel': __('Offset'), + 'limitLabel': __('Limit'), 'from': _x('From', 'date from'), 'to': _x('To', 'date to'), 'filter': __('Filter'),