選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

CustomTableRepeater.php 3.6KB

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