Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Kreyu committed Jul 29, 2024
1 parent edd0c4f commit cb95bce
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 116 deletions.
54 changes: 0 additions & 54 deletions assets/controllers/persistence.js

This file was deleted.

41 changes: 41 additions & 0 deletions assets/controllers/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
static values = {
urlQueryParameters: Object,
}

connect() {
this.#appendUrlQueryParameters();
}

#appendUrlQueryParameters() {
const url = new URL(window.location.href);

const parameters = this.#flattenParameters(this.urlQueryParametersValue);

for (const [key, value] of Object.entries(parameters)) {
if (!url.searchParams.has(key)) {
url.searchParams.set(key, String(value));
}
}

window.history.replaceState(null, null, url);
}

#flattenParameters(input, keyName) {
let result = {};

for (const key in input) {
const newKey = keyName ? `${keyName}[${key}]` : key;

if (typeof input[key] === "object" && !Array.isArray(input[key])) {
result = {...result, ...this.#flattenParameters(input[key], newKey)}
} else {
result[newKey] = input[key];
}
}

return result;
}
}
4 changes: 2 additions & 2 deletions assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"fetch": "eager",
"enabled": true
},
"persistence": {
"main": "controllers/persistence.js",
"state": {
"main": "controllers/state.js",
"fetch": "eager",
"enabled": true
}
Expand Down
4 changes: 2 additions & 2 deletions docs/src/docs/features/filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,14 @@ class ProductController extends AbstractController

By default, the filters loaded from the persistence are not visible in the URL.

It is recommended to make sure the **persistence** controller is enabled in your `assets/controllers.json`,
It is recommended to make sure the **state** controller is enabled in your `assets/controllers.json`,
which will automatically append the filters to the URL, even if multiple data tables are visible on the same page.

```json
{
"controllers": {
"@kreyu/data-table-bundle": {
"persistence": {
"state": {
"enabled": true
}
}
Expand Down
19 changes: 19 additions & 0 deletions docs/src/docs/features/pagination.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,25 @@ class ProductController extends AbstractController
```
:::

### Adding pagination loaded from persistence to URL

By default, the pagination loaded from the persistence is not visible in the URL.

It is recommended to make sure the **state** controller is enabled in your `assets/controllers.json`,
which will automatically append the pagination parameters to the URL, even if multiple data tables are visible on the same page.

```json
{
"controllers": {
"@kreyu/data-table-bundle": {
"state": {
"enabled": true
}
}
}
}
```

## Default pagination

The default pagination data can be overridden using the data table builder's `setDefaultPaginationData()` method:
Expand Down
19 changes: 19 additions & 0 deletions docs/src/docs/features/sorting.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,25 @@ class ProductController extends AbstractController
```
:::

### Adding sorting loaded from persistence to URL

By default, the sorting loaded from the persistence is not visible in the URL.

It is recommended to make sure the **state** controller is enabled in your `assets/controllers.json`,
which will automatically append the sorting parameters to the URL, even if multiple data tables are visible on the same page.

```json
{
"controllers": {
"@kreyu/data-table-bundle": {
"state": {
"enabled": true
}
}
}
}
```

## Default sorting

The default sorting data can be overridden using the data table builder's `setDefaultSortingData()` method:
Expand Down
2 changes: 1 addition & 1 deletion docs/src/docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Now, add `@kreyu/data-table-bundle` controllers to your `assets/controllers.json
"personalization": {
"enabled": true
},
"persistence": {
"state": {
"enabled": true
},
"batch": {
Expand Down
7 changes: 4 additions & 3 deletions src/Pagination/PaginationUrlGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Kreyu\Bundle\DataTableBundle\Pagination;

use Kreyu\Bundle\DataTableBundle\DataTableView;
use Kreyu\Bundle\DataTableBundle\Exception\LogicException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
Expand All @@ -17,7 +18,7 @@ public function __construct(
) {
}

public function generate(PaginationView $paginationView, int $page): string
public function generate(DataTableView $dataTableView, int $page): string
{
$request = $this->getRequest();

Expand All @@ -29,9 +30,9 @@ public function generate(PaginationView $paginationView, int $page): string

// Recursively replace/merge with the URL query parameters defined in the data table view.
// This allows the user to define custom query parameters that should be preserved when changing pages.
$parameters = array_replace_recursive($parameters, $paginationView->parent->vars['url_query_parameters'] ?? []);
$parameters = array_replace_recursive($parameters, $dataTableView->vars['url_query_parameters'] ?? []);

$parameters[$paginationView->parent->vars['page_parameter_name']] = $page;
$parameters[$dataTableView->vars['page_parameter_name']] = $page;

return $this->urlGenerator->generate($route, $parameters);
}
Expand Down
4 changes: 3 additions & 1 deletion src/Pagination/PaginationUrlGeneratorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

namespace Kreyu\Bundle\DataTableBundle\Pagination;

use Kreyu\Bundle\DataTableBundle\DataTableView;

interface PaginationUrlGeneratorInterface
{
public function generate(PaginationView $paginationView, int $page): string;
public function generate(DataTableView $dataTableView, int $page): string;
}
2 changes: 1 addition & 1 deletion src/Pagination/PaginationView.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function __construct(
PaginationInterface $pagination,
) {
$this->vars = [
'pagination' => $this,
'data_table' => $this->parent,
'page_parameter_name' => $this->parent->vars['page_parameter_name'],
'current_page_number' => $pagination->getCurrentPageNumber(),
'current_page_item_count' => $pagination->getCurrentPageItemCount(),
Expand Down
28 changes: 15 additions & 13 deletions src/Resources/views/themes/base.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
{# Base HTML Theme #}

{% block kreyu_data_table %}
{% set stimulus_controllers = ['kreyu--data-table-bundle--persistence'] %}
{% set stimulus_controllers = ['kreyu--data-table-bundle--state'] %}

{% if has_batch_actions %}
{% set stimulus_controllers = stimulus_controllers|merge(['kreyu--data-table-bundle--batch']) %}
{% endif %}

<turbo-frame id="kreyu_data_table_{{ name }}" data-controller="{{ stimulus_controllers|join(' ') }}" target="_top"
{% if pagination_enabled %}data-kreyu--data-table-bundle--persistence-pagination-value="{{ { page: pagination.vars.current_page_number, parameter: page_parameter_name }|json_encode }}"{% endif %}
{% if sorting_enabled %}data-kreyu--data-table-bundle--persistence-sorting-value="{{ { columns: sorting_data.columns|map(column => column.direction), parameter: sort_parameter_name }|json_encode }}"{% endif %}
<turbo-frame
id="kreyu_data_table_{{ name }}" target="_top"
data-controller="{{ stimulus_controllers|join(' ') }}"
data-kreyu--data-table-bundle--state-url-parameters-value="{{ url_query_parameters|default({})|json_encode }}"
>
{{ block('action_bar') }}
{{ block('table') }}
Expand All @@ -23,15 +24,16 @@
{% endblock %}

{% block kreyu_data_table_form_aware %}
{% set stimulus_controllers = ['kreyu--data-table-bundle--persistence'] %}
{% set stimulus_controllers = ['kreyu--data-table-bundle--state'] %}

{% if has_batch_actions %}
{% set stimulus_controllers = stimulus_controllers|merge(['kreyu--data-table-bundle--batch']) %}
{% endif %}

<turbo-frame id="kreyu_data_table_{{ name }}" data-controller="{{ stimulus_controllers|join(' ') }}" target="_top"
{% if pagination_enabled %}data-kreyu--data-table-bundle--persistence-pagination-value="{{ { page: pagination.vars.current_page_number, parameter: page_parameter_name }|json_encode }}"{% endif %}
{% if sorting_enabled %}data-kreyu--data-table-bundle--persistence-sorting-value="{{ { columns: sorting_data.columns|map(column => column.direction), parameter: sort_parameter_name }|json_encode }}"{% endif %}
<turbo-frame
id="kreyu_data_table_{{ name }}" target="_top"
data-controller="{{ stimulus_controllers|join(' ') }}"
data-kreyu--data-table-bundle--state-url-parameters-value="{{ url_query_parameters|default({})|json_encode }}"
>
{{ block('action_bar') }}

Expand Down Expand Up @@ -149,11 +151,11 @@

{% block pagination_controls %}
{%- if has_previous_page -%}
{% with { path: data_table_pagination_url(pagination, 1) } %}
{% with { path: data_table_pagination_url(data_table, 1) } %}
{{ block('pagination_first', theme) }}
{% endwith %}

{% with { path: data_table_pagination_url(pagination, current_page_number - 1) } %}
{% with { path: data_table_pagination_url(data_table, current_page_number - 1) } %}
{{ block('pagination_previous', theme) }}
{% endwith %}
{%- else -%}
Expand All @@ -165,18 +167,18 @@
{% if page_number == current_page_number %}
{{ block('pagination_page_active', theme) }}
{% else %}
{% with { path: data_table_pagination_url(pagination, page_number) } %}
{% with { path: data_table_pagination_url(data_table, page_number) } %}
{{ block('pagination_page', theme) }}
{% endwith %}
{% endif %}
{% endfor %}

{%- if has_next_page -%}
{% with { path: data_table_pagination_url(pagination, current_page_number + 1) } %}
{% with { path: data_table_pagination_url(data_table, current_page_number + 1) } %}
{{ block('pagination_next', theme) }}
{% endwith %}

{% with { path: data_table_pagination_url(pagination, page_count) } %}
{% with { path: data_table_pagination_url(data_table, page_count) } %}
{{ block('pagination_last', theme) }}
{% endwith %}
{%- else -%}
Expand Down
4 changes: 2 additions & 2 deletions src/Twig/DataTableExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -328,9 +328,9 @@ public function generateColumnSortUrl(DataTableView $dataTableView, ColumnHeader
return $this->columnSortUrlGenerator->generate($dataTableView, ...$columnHeaderViews);
}

public function generatePaginationUrl(PaginationView $paginationView, int $page): string
public function generatePaginationUrl(DataTableView $dataTableView, int $page): string
{
return $this->paginationUrlGenerator->generate($paginationView, $page);
return $this->paginationUrlGenerator->generate($dataTableView, $page);
}

/**
Expand Down
28 changes: 6 additions & 22 deletions src/Type/DataTableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,24 +122,8 @@ public function buildView(DataTableView $view, DataTableInterface $dataTable, ar
'column_count' => count($view->headerRow),
]);

$urlQueryParameters = [];

if ($dataTable->getConfig()->isFiltrationEnabled()) {
$view->vars['filtration_form'] = $this->createFiltrationFormView($view, $dataTable);

foreach ($view->filters as $filterView) {
if (null === $filterView->data || !$filterView->data->hasValue()) {
continue;
}

$filterParameter = ['value' => $filterView->data?->getValue()];

if ($filterView->vars['operator_selectable']) {
$filterParameter['operator'] = $filterView->data?->getOperator()?->value;
}

$urlQueryParameters[$dataTable->getConfig()->getFiltrationParameterName()][$filterView->vars['name']] = $filterParameter;
}
}

if ($dataTable->getConfig()->isPersonalizationEnabled()) {
Expand Down Expand Up @@ -411,7 +395,7 @@ private function createFormView(FormInterface $form, DataTableView $view, DataTa

private function getUrlQueryParameters(DataTableView $view, DataTableInterface $dataTable): array
{
$urlQueryParameters = [];
$parameters = [];

if ($dataTable->getConfig()->isFiltrationEnabled()) {
foreach ($view->filters as $filterView) {
Expand All @@ -425,21 +409,21 @@ private function getUrlQueryParameters(DataTableView $view, DataTableInterface $
$filterParameter['operator'] = $filterView->data->getOperator()?->value;
}

$urlQueryParameters[$dataTable->getConfig()->getFiltrationParameterName()][$filterView->vars['name']] = $filterParameter;
$parameters[$dataTable->getConfig()->getFiltrationParameterName()][$filterView->vars['name']] = $filterParameter;
}
}

if ($dataTable->getConfig()->isPaginationEnabled()) {
$urlQueryParameters[$dataTable->getConfig()->getPageParameterName()] = $view->pagination->vars['current_page_number'];
$urlQueryParameters[$dataTable->getConfig()->getPerPageParameterName()] = $view->pagination->vars['item_number_per_page'];
$parameters[$dataTable->getConfig()->getPageParameterName()] = $view->pagination->vars['current_page_number'];
$parameters[$dataTable->getConfig()->getPerPageParameterName()] = $view->pagination->vars['item_number_per_page'];
}

if ($dataTable->getConfig()->isSortingEnabled()) {
foreach ($view->vars['sorting_data']->getColumns() as $sortingColumnData) {
$urlQueryParameters[$dataTable->getConfig()->getSortParameterName()][$sortingColumnData->getName()] = $sortingColumnData->getDirection();
$parameters[$dataTable->getConfig()->getSortParameterName()][$sortingColumnData->getName()] = $sortingColumnData->getDirection();
}
}

return $urlQueryParameters;
return $parameters;
}
}
Loading

0 comments on commit cb95bce

Please sign in to comment.