Add offset/limit to logs page
[MAILPOET-3135]
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
.mailpoet-listing-header {
|
.mailpoet-listing-header {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mailpoet-datepicker {
|
.mailpoet-datepicker {
|
||||||
@@ -20,4 +21,12 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mailpoet-form-input-small {
|
||||||
|
margin-right: $grid-gap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mailpoet-logs-limit .mailpoet-form-input-small {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -64,6 +64,8 @@ export type FilterType = {
|
|||||||
from?: string;
|
from?: string;
|
||||||
to?: string;
|
to?: string;
|
||||||
search?: string;
|
search?: string;
|
||||||
|
offset?: string;
|
||||||
|
limit?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListProps = {
|
type ListProps = {
|
||||||
@@ -71,6 +73,8 @@ type ListProps = {
|
|||||||
originalFrom?: string;
|
originalFrom?: string;
|
||||||
originalTo?: string;
|
originalTo?: string;
|
||||||
originalSearch?: string;
|
originalSearch?: string;
|
||||||
|
originalOffset?: string;
|
||||||
|
originalLimit?: string;
|
||||||
onFilter: (FilterType) => void;
|
onFilter: (FilterType) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,9 +84,13 @@ export const List: React.FunctionComponent<ListProps> = ({
|
|||||||
originalFrom,
|
originalFrom,
|
||||||
originalTo,
|
originalTo,
|
||||||
originalSearch,
|
originalSearch,
|
||||||
|
originalOffset,
|
||||||
|
originalLimit,
|
||||||
}: ListProps) => {
|
}: ListProps) => {
|
||||||
const [from, setFrom] = useState(originalFrom ?? undefined);
|
const [from, setFrom] = useState(originalFrom ?? undefined);
|
||||||
const [to, setTo] = useState(originalTo ?? undefined);
|
const [to, setTo] = useState(originalTo ?? undefined);
|
||||||
|
const [offset, setOffset] = useState(originalOffset ?? '');
|
||||||
|
const [limit, setLimit] = useState(originalLimit ?? '');
|
||||||
const [search, setSearch] = useState(originalSearch || '');
|
const [search, setSearch] = useState(originalSearch || '');
|
||||||
|
|
||||||
const dateChanged = curry((setter, value): void => {
|
const dateChanged = curry((setter, value): void => {
|
||||||
@@ -105,6 +113,12 @@ export const List: React.FunctionComponent<ListProps> = ({
|
|||||||
if (to) {
|
if (to) {
|
||||||
data.to = to;
|
data.to = to;
|
||||||
}
|
}
|
||||||
|
if (offset && offset.trim() !== '') {
|
||||||
|
data.offset = offset;
|
||||||
|
}
|
||||||
|
if (limit && limit.trim() !== '') {
|
||||||
|
data.limit = limit;
|
||||||
|
}
|
||||||
if (search && search.trim() !== '') {
|
if (search && search.trim() !== '') {
|
||||||
data.search = search.trim();
|
data.search = search.trim();
|
||||||
}
|
}
|
||||||
@@ -113,7 +127,6 @@ export const List: React.FunctionComponent<ListProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mailpoet-listing mailpoet-logs">
|
<div className="mailpoet-listing mailpoet-logs">
|
||||||
|
|
||||||
<div className="mailpoet-listing-header">
|
<div className="mailpoet-listing-header">
|
||||||
<div className="mailpoet-listing-search">
|
<div className="mailpoet-listing-search">
|
||||||
<label htmlFor="search_input" className="screen-reader-text">
|
<label htmlFor="search_input" className="screen-reader-text">
|
||||||
@@ -148,6 +161,34 @@ export const List: React.FunctionComponent<ListProps> = ({
|
|||||||
dimension="small"
|
dimension="small"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mailpoet-logs-limit">
|
||||||
|
<label htmlFor="offset_input" className="screen-reader-text">
|
||||||
|
{MailPoet.I18n.t('offsetLabel')}
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
dimension="small"
|
||||||
|
id="offset_input"
|
||||||
|
name="o"
|
||||||
|
type="number"
|
||||||
|
onChange={(event): void => setOffset(event.target.value)}
|
||||||
|
value={offset}
|
||||||
|
placeholder={MailPoet.I18n.t('offsetLabel')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mailpoet-logs-limit">
|
||||||
|
<label htmlFor="limit_input" className="screen-reader-text">
|
||||||
|
{MailPoet.I18n.t('limitLabel')}
|
||||||
|
</label>
|
||||||
|
<Input
|
||||||
|
dimension="small"
|
||||||
|
id="limit_input"
|
||||||
|
name="l"
|
||||||
|
type="number"
|
||||||
|
onChange={(event): void => setLimit(event.target.value)}
|
||||||
|
value={limit}
|
||||||
|
placeholder={MailPoet.I18n.t('limitLabel')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<Button dimension="small" onClick={filterClick}>
|
<Button dimension="small" onClick={filterClick}>
|
||||||
{MailPoet.I18n.t('filter')}
|
{MailPoet.I18n.t('filter')}
|
||||||
</Button>
|
</Button>
|
||||||
|
@@ -20,10 +20,14 @@ if (logsContainer) {
|
|||||||
originalFrom={url.searchParams.get('from')}
|
originalFrom={url.searchParams.get('from')}
|
||||||
originalTo={url.searchParams.get('to')}
|
originalTo={url.searchParams.get('to')}
|
||||||
originalSearch={url.searchParams.get('search')}
|
originalSearch={url.searchParams.get('search')}
|
||||||
|
originalOffset={url.searchParams.get('offset')}
|
||||||
|
originalLimit={url.searchParams.get('limit')}
|
||||||
onFilter={(data: FilterType): void => {
|
onFilter={(data: FilterType): void => {
|
||||||
url.searchParams.delete('from');
|
url.searchParams.delete('from');
|
||||||
url.searchParams.delete('to');
|
url.searchParams.delete('to');
|
||||||
url.searchParams.delete('search');
|
url.searchParams.delete('search');
|
||||||
|
url.searchParams.delete('offset');
|
||||||
|
url.searchParams.delete('limit');
|
||||||
Object.entries(data).forEach(([key, value]) => {
|
Object.entries(data).forEach(([key, value]) => {
|
||||||
url.searchParams.append(key, value);
|
url.searchParams.append(key, value);
|
||||||
});
|
});
|
||||||
|
@@ -25,6 +25,8 @@ class Logs {
|
|||||||
$search = isset($_GET['search']) ? $_GET['search'] : null;
|
$search = isset($_GET['search']) ? $_GET['search'] : null;
|
||||||
$from = isset($_GET['from']) ? $_GET['from'] : null;
|
$from = isset($_GET['from']) ? $_GET['from'] : null;
|
||||||
$to = isset($_GET['to']) ? $_GET['to'] : 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);
|
$dateFrom = (new Carbon())->subDays(7);
|
||||||
if (isset($from)) {
|
if (isset($from)) {
|
||||||
$dateFrom = new Carbon($from);
|
$dateFrom = new Carbon($from);
|
||||||
@@ -33,7 +35,7 @@ class Logs {
|
|||||||
if (isset($to)) {
|
if (isset($to)) {
|
||||||
$dateTo = new Carbon($to);
|
$dateTo = new Carbon($to);
|
||||||
}
|
}
|
||||||
$logs = $this->logRepository->getLogs($dateFrom, $dateTo, $search);
|
$logs = $this->logRepository->getLogs($dateFrom, $dateTo, $search, $offset, $limit);
|
||||||
$data = ['logs' => []];
|
$data = ['logs' => []];
|
||||||
foreach ($logs as $log) {
|
foreach ($logs as $log) {
|
||||||
$data['logs'][] = [
|
$data['logs'][] = [
|
||||||
|
@@ -18,9 +18,17 @@ class LogRepository extends Repository {
|
|||||||
* @param \DateTimeInterface|null $dateFrom
|
* @param \DateTimeInterface|null $dateFrom
|
||||||
* @param \DateTimeInterface|null $dateTo
|
* @param \DateTimeInterface|null $dateTo
|
||||||
* @param string|null $search
|
* @param string|null $search
|
||||||
|
* @param string $offset
|
||||||
|
* @param string $limit
|
||||||
* @return LogEntity[]
|
* @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')
|
$query = $this->doctrineRepository->createQueryBuilder('l')
|
||||||
->select('l');
|
->select('l');
|
||||||
|
|
||||||
@@ -42,6 +50,15 @@ class LogRepository extends Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$query->orderBy('l.createdAt', 'desc');
|
$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();
|
return $query->getQuery()->getResult();
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
'tableHeaderMessage': __('Message'),
|
'tableHeaderMessage': __('Message'),
|
||||||
'tableHeaderCreatedOn': __('Created On'),
|
'tableHeaderCreatedOn': __('Created On'),
|
||||||
'searchLabel': __('Search'),
|
'searchLabel': __('Search'),
|
||||||
|
'offsetLabel': __('Offset'),
|
||||||
|
'limitLabel': __('Limit'),
|
||||||
'from': _x('From', 'date from'),
|
'from': _x('From', 'date from'),
|
||||||
'to': _x('To', 'date to'),
|
'to': _x('To', 'date to'),
|
||||||
'filter': __('Filter'),
|
'filter': __('Filter'),
|
||||||
|
Reference in New Issue
Block a user