Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion resources/views/components/tools/filter-pills.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
@if ($filterPillData->hasCustomPillBlade)
@include($filterPillData->getCustomPillBlade(), ['filter' => $this->getFilterByKey($filterKey), 'filterPillData' => $filterPillData])
@else
<x-livewire-tables::tools.filter-pills.pills-item :$filterKey :$filterPillData :shouldWatch="$filterPillData->isAnExternalLivewireFilter" />
<x-livewire-tables::filter-pill :$filterKey :$filterPillData />
@endif
@endtableloop

Expand Down
22 changes: 22 additions & 0 deletions resources/views/includes/filter-pill.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@aware(['tableName','isTailwind','isBootstrap4','isBootstrap5'])

<div x-data="filterPillsHandler(@js($setupData))" x-bind="trigger"
wire:key="{{ $tableName }}-filter-pill-{{ $filterKey }}" {{
$attributes->merge($filterPillsItemAttributes)
->class([
'inline-flex items-center px-2.5 py-0.5 rounded-full leading-4' => $isTailwind && ($filterPillsItemAttributes['default-styling'] ?? true),
'text-xs font-medium capitalize' => $isTailwind && ($filterPillsItemAttributes['default-text'] ?? ($filterPillsItemAttributes['default-styling'] ?? true)),
'bg-indigo-100 text-indigo-800 dark:bg-indigo-200 dark:text-indigo-900' => $isTailwind && ($filterPillsItemAttributes['default-colors'] ?? true),
'badge badge-pill badge-info d-inline-flex align-items-center' => $isBootstrap4 && ($filterPillsItemAttributes['default-styling'] ?? true),
'badge rounded-pill bg-info d-inline-flex align-items-center' => $isBootstrap5 && ($filterPillsItemAttributes['default-styling'] ?? true),
])
->except(['default', 'default-styling', 'default-colors'])
}}
>
<span {{ $attributes->merge($pillTitleDisplayDataArray) }}></span>

<span {{ $attributes->merge($pillDisplayDataArray) }}></span>

<x-livewire-tables::tools.filter-pills.buttons.reset-filter :$filterKey :$filterPillData/>

</div>
122 changes: 64 additions & 58 deletions src/DataTransferObjects/Filters/FilterPillData.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,142 +6,147 @@

class FilterPillData
{
public string $separatedValues = '';

public function __construct(
protected string $filterKey,
protected string $filterPillTitle,
protected string $filterSelectName,
protected string|array|null $filterPillValue,
protected string $separator,
public bool $isAnExternalLivewireFilter,
public bool $hasCustomPillBlade,
protected ?string $customPillBlade,
protected array $filterPillsItemAttributes,
protected ?string $separatedValues,
protected bool $renderPillsAsHtml,
protected bool $watchForEvents,
protected array $customResetButtonAttributes, ) {}
protected array $customResetButtonAttributes,
protected bool $renderPillsTitleAsHtml) {}

public static function make(string $filterPillTitle, string $filterSelectName, string|array|null $filterPillValue, string $separator = ', ', bool $isAnExternalLivewireFilter = false, bool $hasCustomPillBlade = false, ?string $customPillBlade = null, array $filterPillsItemAttributes = [], ?string $separatedValues = null, bool $renderPillsAsHtml = false, bool $watchForEvents = false, array $customResetButtonAttributes = []): FilterPillData
public static function make(string $filterKey, string $filterPillTitle, string|array|null $filterPillValue, string $separator = ', ', bool $isAnExternalLivewireFilter = false, bool $hasCustomPillBlade = false, ?string $customPillBlade = null, array $filterPillsItemAttributes = [], bool $renderPillsAsHtml = false, bool $watchForEvents = false, array $customResetButtonAttributes = [], bool $renderPillsTitleAsHtml = false): FilterPillData
{
if ($isAnExternalLivewireFilter) {
$watchForEvents = true;
}

return new self($filterPillTitle, $filterSelectName, $filterPillValue, $separator, $isAnExternalLivewireFilter, $hasCustomPillBlade, $customPillBlade, $filterPillsItemAttributes, $separatedValues, $renderPillsAsHtml, $watchForEvents, $customResetButtonAttributes);
return new self($filterKey, $filterPillTitle, $filterPillValue, $separator, $isAnExternalLivewireFilter, $hasCustomPillBlade, $customPillBlade, $filterPillsItemAttributes, $renderPillsAsHtml, $watchForEvents, $customResetButtonAttributes, $renderPillsTitleAsHtml);
}

public function getTitle(): string
{
return $this->filterPillTitle;
}

public function getSelectName(): string
public function getPillValue(): array|string|null
{
return $this->filterSelectName;
return $this->filterPillValue;
}

public function getPillValue(): array|string|null
public function getHasCustomPillBlade(): bool
{
return $this->filterPillValue;
return $this->hasCustomPillBlade ?? false;
}

public function isPillValueAnArray(): bool
public function getCustomPillBlade(): ?string
{
return ! is_null($this->filterPillValue) && is_array($this->filterPillValue);
return $this->customPillBlade;
}

public function getSeparatedPillValue(): array|string|null
public function getCustomResetButtonAttributes(): array
{
if ($this->isPillValueAnArray()) {
return implode($this->getSeparator(), $this->getPillValue());
} else {
return $this->getPillValue();
}
return $this->customResetButtonAttributes ?? [];
}

public function getValueFromPillData(): array|string|null
public function getIsAnExternalLivewireFilter(): int
{
if ($this->isPillValueAnArray()) {
return implode($this->getSeparator(), $this->getPillValue());
} else {
return $this->getPillValue();
}
return intval($this->isAnExternalLivewireFilter ?? false);
}

public function getHasCustomPillBlade(): bool
public function getSeparator(): string
{
return $this->hasCustomPillBlade ?? false;
return $this->separator ?? ', ';
}

public function getCustomPillBlade(): ?string
public function shouldUsePillsAsHtml(): int
{
return $this->customPillBlade;
return intval($this->renderPillsAsHtml ?? false);
}

public function getIsAnExternalLivewireFilter(): int
public function shouldUsePillsTitleAsHtml(): int
{
return intval($this->isAnExternalLivewireFilter ?? false);
return intval($this->renderPillsTitleAsHtml ?? false);
}

public function getSeparator(): string
public function shouldWatchForEvents(): int
{
return $this->separator ?? ', ';
return intval($this->watchForEvents ?? false);
}

public function getSeparatedValues(): string
public function isPillValueAnArray(): bool
{
return $this->separatedValues ?? $this->getSeparatedPillValue();
return ! is_null($this->filterPillValue) && is_array($this->filterPillValue);
}

public function getFilterPillsItemAttributes(): array
public function getSeparatedPillValue(): ?string
{
return array_merge(['default' => true, 'default-colors' => true, 'default-styling' => true, 'default-text' => true], $this->filterPillsItemAttributes);
if ($this->isPillValueAnArray()) {
return implode($this->getSeparator(), $this->getPillValue());
} else {
return $this->getPillValue();
}
}

public function shouldUsePillsAsHtml(): int
public function getSafeSeparatedPillValue(): ?string
{
return intval($this->renderPillsAsHtml ?? false);
$string = $this->getSeparatedPillValue();

return htmlentities($string, ENT_QUOTES, 'UTF-8');

}

public function shouldWatchForEvents(): int
public function getFilterPillsItemAttributes(): array
{
return intval($this->watchForEvents ?? false);
return array_merge(['default' => true, 'default-colors' => true, 'default-styling' => true, 'default-text' => true], $this->filterPillsItemAttributes);
}

public function getFilterPillDisplayData(): ComponentAttributeBag
public function getFilterPillDisplayDataArray(): array
{
$array = [];
if ($this->getIsAnExternalLivewireFilter()) {
return $this->getExternalFilterPillDisplayData();
return $this->getExternalFilterPillDisplayDataArray($array);

Check warning on line 115 in src/DataTransferObjects/Filters/FilterPillData.php

View check run for this annotation

Codecov / codecov/patch

src/DataTransferObjects/Filters/FilterPillData.php#L115

Added line #L115 was not covered by tests
}

return $this->getInternalFilterPillDisplayData();
return $this->getInternalFilterPillDisplayDataArray($array);
}

public function getInternalFilterPillDisplayData(): ComponentAttributeBag
public function getExternalFilterPillDisplayDataArray(array $array = []): array
{
return new ComponentAttributeBag([
'x-data' => "{ internalDisplayString: ''}",
'x-init' => "internalDisplayString = updatePillValues('".$this->getSeparatedValues()."');",
$this->shouldUsePillsAsHtml() ? 'x-html' : 'x-text' => 'internalDisplayString',
]);
$array[$this->shouldUsePillsAsHtml() ? 'x-html' : 'x-text'] = 'displayString';

return $array;
}

public function getExternalFilterPillDisplayData(): ComponentAttributeBag
public function getInternalFilterPillDisplayDataArray(array $array = []): array
{
return new ComponentAttributeBag([
$this->shouldUsePillsAsHtml() ? 'x-html' : 'x-text' => 'displayString',
]);

$array['x-data'] = "{ internalDisplayString: ''}";
$array['x-init'] = 'internalDisplayString = updatePillValues('.json_encode($this->getSafeSeparatedPillValue()).')';
$array[$this->shouldUsePillsAsHtml() ? 'x-html' : 'x-text'] = 'internalDisplayString';

return $array;
}

public function getPillSetupData(string $filterKey = '', bool $shouldWatch = false): array
public function getFilterTitleDisplayDataArray(array $array = []): array
{
$array = array_merge(['filterKey' => $filterKey, 'watchForEvents' => $shouldWatch], $this->toArray());
$array[$this->shouldUsePillsTitleAsHtml() ? 'x-html' : 'x-text'] = "localFilterTitle + ':&nbsp;'";

return $array;
}

public function getCustomResetButtonAttributes(): array
public function getPillSetupData(string $filterKey = '', bool $shouldWatch = false): array
{
return $this->customResetButtonAttributes ?? [];
$array = array_merge(['filterKey' => $filterKey, 'watchForEvents' => $shouldWatch], $this->toArray());

return $array;
}

public function getCalculatedCustomResetButtonAttributes(string $filterKey, array $filterPillsResetFilterButtonAttributes): array
Expand All @@ -163,16 +168,17 @@
public function toArray(): array
{
return [
'filterKey' => $this->filterKey,
'filterPillTitle' => $this->getTitle(),
'filterSelectName' => $this->getSelectName(),
'filterPillValue' => $this->getPillValue(),
'isAnExternalLivewireFilter' => $this->getIsAnExternalLivewireFilter(),
'hasCustomPillBlade' => $this->getHasCustomPillBlade(),
'customPillBlade' => $this->getCustomPillBlade(),
'separator' => $this->getSeparator(),
'separatedValues' => $this->getSafeSeparatedPillValue(),
'filterPillsItemAttributes' => $this->getFilterPillsItemAttributes(),
'separatedValues' => $this->getSeparatedValues(),
'renderPillsAsHtml' => $this->shouldUsePillsAsHtml(),
'renderPillsTitleAsHtml' => $this->shouldUsePillsTitleAsHtml(),
'watchForEvents' => $this->shouldWatchForEvents(),
];
}
Expand Down
1 change: 1 addition & 0 deletions src/LaravelLivewireTablesServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public function boot(): void
$this->addBladeLoopDirective();

$this->loadViewsFrom(__DIR__.'/../resources/views', 'livewire-tables');
Blade::componentNamespace('Rappasoft\\LaravelLivewireTables\\View\\Components', 'livewire-tables');

$this->consoleCommands();

Expand Down
33 changes: 7 additions & 26 deletions src/Traits/Filters/HandlesPillsData.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,21 @@ public function getPillDataForFilter(): array
{
$filters = [];

foreach ($this->getAppliedFiltersWithValuesForPills() as $filterSelectName => $value) {
if (! is_null($filter = $this->getFilterByKey($filterSelectName))) {
if ($filter->isEmpty($value)) {
continue;
}
$customPillBlade = null;
$isAnExternalLivewireFilter = (method_exists($filter, 'isAnExternalLivewireFilter') && $filter->isAnExternalLivewireFilter());
$separator = method_exists($filter, 'getPillsSeparator') ? $filter->getPillsSeparator() : ', ';
$separatedValues = null;

// dd($value);

if ($hasCustomPillBlade = $filter->hasCustomPillBlade()) {
$customPillBlade = $filter->getCustomPillBlade();
}

if (is_array($value) && ! empty($value)) {
$separatedValues = implode($separator, $filter->getFilterPillValue($value));
}

foreach ($this->getAppliedFiltersWithValuesForPills() as $filterKey => $value) {
if (! is_null($filter = $this->getFilterByKey($filterKey))) {
$filters[$filter->getKey()] = FilterPillData::make(
customPillBlade: $customPillBlade,
filterKey: $filter->getKey(),
customPillBlade: $filter->getCustomPillBlade() ?? null,
filterPillsItemAttributes: array_merge($this->getFilterPillsItemAttributes(), ($filter->hasPillAttributes() ? $filter->getPillAttributes() : [])),

filterPillTitle: $filter->getFilterPillTitle(),
filterPillValue: $filter->getFilterPillValue($value),

filterSelectName: $filterSelectName,

hasCustomPillBlade: $hasCustomPillBlade,
isAnExternalLivewireFilter: $isAnExternalLivewireFilter,
separatedValues: $separatedValues,
hasCustomPillBlade: $filter->hasCustomPillBlade(),
isAnExternalLivewireFilter: (method_exists($filter, 'isAnExternalLivewireFilter') && $filter->isAnExternalLivewireFilter()),
separator: method_exists($filter, 'getPillsSeparator') ? $filter->getPillsSeparator() : ', ',
renderPillsAsHtml: $filter->getPillsAreHtml() ?? false,
renderPillsTitleAsHtml: $filter->getFilterPillTitleAsHtml() ?? false,
customResetButtonAttributes: $filter->getPillResetButtonAttributes(),

);
Expand Down
28 changes: 28 additions & 0 deletions src/View/Components/FilterPill.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Rappasoft\LaravelLivewireTables\View\Components;

use Illuminate\View\Component;
use Rappasoft\LaravelLivewireTables\DataTransferObjects\Filters\FilterPillData;

class FilterPill extends Component
{
public bool $shouldWatch = false;

public function __construct(public string $filterKey, public FilterPillData $filterPillData)
{
$this->shouldWatch = $this->filterPillData->shouldWatchForEvents() ?? 0;

Check failure on line 14 in src/View/Components/FilterPill.php

View workflow job for this annotation

GitHub Actions / PHPStan - P8.3 - L11 - prefer-dist - ubuntu-24.04

Expression on left side of ?? is not nullable.

Check failure on line 14 in src/View/Components/FilterPill.php

View workflow job for this annotation

GitHub Actions / PHPStan - P8.3 - L11 - prefer-dist - ubuntu-24.04

Property Rappasoft\LaravelLivewireTables\View\Components\FilterPill::$shouldWatch (bool) does not accept int.
}

public function render(): null|string|\Illuminate\Support\HtmlString|\Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
{
return view('livewire-tables::includes.filter-pill')
->with([
'filterPillsItemAttributes' => $this->filterPillData->getFilterPillsItemAttributes(),
'pillDisplayDataArray' => $this->filterPillData->getFilterPillDisplayDataArray(),
'pillTitleDisplayDataArray' => $this->filterPillData->getFilterTitleDisplayDataArray(),
'setupData' => $this->filterPillData->getPillSetupData($this->filterKey, $this->shouldWatch),
]);

}
}
14 changes: 14 additions & 0 deletions src/Views/Filters/Traits/Styling/HandlesFilterPillsAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
*/
protected array $pillResetButtonAttributes = [];

protected bool $pillTitleAsHtml = false;

public function getPillAttributesBag(): ComponentAttributeBag
{
return new ComponentAttributeBag($this->getPillAttributes());
Expand Down Expand Up @@ -82,4 +84,16 @@
$this->getPillResetButtonAttributes()
);
}

public function setFilterPillTitleAsHtml(bool $pillTitleAsHtml): self

Check warning on line 88 in src/Views/Filters/Traits/Styling/HandlesFilterPillsAttributes.php

View check run for this annotation

Codecov / codecov/patch

src/Views/Filters/Traits/Styling/HandlesFilterPillsAttributes.php#L88

Added line #L88 was not covered by tests
{
$this->pillTitleAsHtml = $pillTitleAsHtml;

Check warning on line 90 in src/Views/Filters/Traits/Styling/HandlesFilterPillsAttributes.php

View check run for this annotation

Codecov / codecov/patch

src/Views/Filters/Traits/Styling/HandlesFilterPillsAttributes.php#L90

Added line #L90 was not covered by tests

return $this;

Check warning on line 92 in src/Views/Filters/Traits/Styling/HandlesFilterPillsAttributes.php

View check run for this annotation

Codecov / codecov/patch

src/Views/Filters/Traits/Styling/HandlesFilterPillsAttributes.php#L92

Added line #L92 was not covered by tests
}

public function getFilterPillTitleAsHtml(): bool
{
return $this->pillTitleAsHtml;
}
}
Loading
Loading