Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

CustomTableRepeater.php 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. namespace App\Filament\Forms\Components;
  3. use Awcodes\TableRepeater\Components\TableRepeater;
  4. use Closure;
  5. use Filament\Forms\Components\Actions\Action;
  6. use Filament\Support\Enums\MaxWidth;
  7. use Illuminate\Contracts\Support\Htmlable;
  8. use Illuminate\Contracts\View\View;
  9. class CustomTableRepeater extends TableRepeater
  10. {
  11. protected bool | Closure $spreadsheet = false;
  12. protected bool | Closure $reorderAtStart = false;
  13. protected View | Htmlable | Closure | null $footerItem = null;
  14. /**
  15. * @var array<string> | Closure | null
  16. */
  17. protected array | Closure | null $excludedAttributesForCloning = [
  18. 'id',
  19. 'line_number',
  20. 'created_by',
  21. 'updated_by',
  22. 'created_at',
  23. 'updated_at',
  24. ];
  25. public function spreadsheet(bool | Closure $condition = true): static
  26. {
  27. $this->spreadsheet = $condition;
  28. return $this;
  29. }
  30. public function isSpreadsheet(): bool
  31. {
  32. return (bool) $this->evaluate($this->spreadsheet);
  33. }
  34. public function reorderAtStart(bool | Closure $condition = true): static
  35. {
  36. $this->reorderAtStart = $condition;
  37. return $this;
  38. }
  39. public function isReorderAtStart(): bool
  40. {
  41. return $this->evaluate($this->reorderAtStart) && $this->isReorderable();
  42. }
  43. public function footerItem(View | Htmlable | Closure | null $footer = null): static
  44. {
  45. $this->footerItem = $footer;
  46. return $this;
  47. }
  48. public function getFooterItem(): View | Htmlable | null
  49. {
  50. return $this->evaluate($this->footerItem);
  51. }
  52. public function hasFooterItem(): bool
  53. {
  54. return $this->footerItem !== null;
  55. }
  56. /**
  57. * @param array<string> | Closure | null $attributes
  58. */
  59. public function excludeAttributesForCloning(array | Closure | null $attributes): static
  60. {
  61. $this->excludedAttributesForCloning = $attributes;
  62. return $this;
  63. }
  64. /**
  65. * @return array<string> | null
  66. */
  67. public function getExcludedAttributesForCloning(): ?array
  68. {
  69. return $this->evaluate($this->excludedAttributesForCloning);
  70. }
  71. protected function setUp(): void
  72. {
  73. parent::setUp();
  74. $this->minItems(1);
  75. $this->stackAt(MaxWidth::Large);
  76. $this->extraAttributes(function (): array {
  77. $attributes = [];
  78. if ($this->isSpreadsheet()) {
  79. $attributes['class'] = 'is-spreadsheet';
  80. }
  81. return $attributes;
  82. });
  83. $this->reorderAction(function (Action $action) {
  84. if ($this->isReorderAtStart()) {
  85. $action->icon('heroicon-m-bars-3');
  86. }
  87. return $action;
  88. });
  89. $this->cloneAction(function (Action $action) {
  90. return $action
  91. ->action(function (array $arguments, CustomTableRepeater $component): void {
  92. $newUuid = $component->generateUuid();
  93. $items = $component->getState();
  94. $clone = $items[$arguments['item']];
  95. foreach ($component->getExcludedAttributesForCloning() as $attribute) {
  96. unset($clone[$attribute]);
  97. }
  98. if ($newUuid) {
  99. $items[$newUuid] = $clone;
  100. } else {
  101. $items[] = $clone;
  102. }
  103. $component->state($items);
  104. $component->collapsed(false, shouldMakeComponentCollapsible: false);
  105. $component->callAfterStateUpdated();
  106. });
  107. });
  108. }
  109. public function getView(): string
  110. {
  111. return 'filament.forms.components.custom-table-repeater';
  112. }
  113. }