Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

LineItemRepeater.php 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. namespace App\Filament\Forms\Components;
  3. use Awcodes\TableRepeater\Components\TableRepeater;
  4. use Closure;
  5. use Filament\Forms\ComponentContainer;
  6. use Filament\Forms\Components\Component;
  7. class LineItemRepeater extends TableRepeater
  8. {
  9. protected array | Closure $nestedSchema = [];
  10. protected ?string $nestedColumn = null;
  11. /**
  12. * Set nested schema and optionally the column it belongs to.
  13. *
  14. * @param array<Component> | Closure $components
  15. */
  16. public function withNestedSchema(array | Closure $components, ?string $underColumn = null): static
  17. {
  18. $this->nestedSchema = $components;
  19. $this->nestedColumn = $underColumn;
  20. return $this;
  21. }
  22. /**
  23. * Get the nested schema.
  24. *
  25. * @return array<Component>
  26. */
  27. public function getNestedSchema(): array
  28. {
  29. return $this->evaluate($this->nestedSchema);
  30. }
  31. /**
  32. * Get the column under which the nested schema should be rendered.
  33. */
  34. public function getNestedColumn(): ?string
  35. {
  36. return $this->nestedColumn;
  37. }
  38. /**
  39. * Determine if there is a nested schema defined.
  40. */
  41. public function hasNestedSchema(): bool
  42. {
  43. return ! empty($this->getNestedSchema());
  44. }
  45. public function getNestedSchemaMap(): array
  46. {
  47. return collect($this->getNestedSchema())
  48. ->keyBy(fn ($component) => $component->getKey())
  49. ->all();
  50. }
  51. /**
  52. * Get all child components, including nested schema.
  53. *
  54. * @return array<Component>
  55. */
  56. public function getChildComponents(): array
  57. {
  58. $components = parent::getChildComponents();
  59. if ($this->hasNestedSchema()) {
  60. $components = array_merge($components, $this->getNestedSchema());
  61. }
  62. return $components;
  63. }
  64. public function getChildComponentContainers(bool $withHidden = false): array
  65. {
  66. if ((! $withHidden) && $this->isHidden()) {
  67. return [];
  68. }
  69. $relationship = $this->getRelationship();
  70. $records = $relationship ? $this->getCachedExistingRecords() : null;
  71. $containers = [];
  72. foreach ($this->getState() ?? [] as $itemKey => $itemData) {
  73. $containers[$itemKey] = $this
  74. ->getChildComponentContainer()
  75. ->statePath($itemKey)
  76. ->model($relationship ? $records[$itemKey] ?? $this->getRelatedModel() : null)
  77. ->inlineLabel(false)
  78. ->getClone();
  79. }
  80. return $containers;
  81. }
  82. public function getChildComponentContainersWithoutNestedSchema(bool $withHidden = false): array
  83. {
  84. if ((! $withHidden) && $this->isHidden()) {
  85. return [];
  86. }
  87. $relationship = $this->getRelationship();
  88. $records = $relationship ? $this->getCachedExistingRecords() : null;
  89. $containers = [];
  90. $childComponentsWithoutNestedSchema = $this->getChildComponentsWithoutNestedSchema();
  91. foreach ($this->getState() ?? [] as $itemKey => $itemData) {
  92. $containers[$itemKey] = ComponentContainer::make($this->getLivewire())
  93. ->parentComponent($this)
  94. ->statePath($itemKey)
  95. ->model($relationship ? $records[$itemKey] ?? $this->getRelatedModel() : null)
  96. ->components($childComponentsWithoutNestedSchema)
  97. ->inlineLabel(false)
  98. ->getClone();
  99. }
  100. return $containers;
  101. }
  102. public function getChildComponentContainer($key = null): ComponentContainer
  103. {
  104. if (filled($key) && array_key_exists($key, $containers = $this->getChildComponentContainers())) {
  105. return $containers[$key];
  106. }
  107. return ComponentContainer::make($this->getLivewire())
  108. ->parentComponent($this)
  109. ->components($this->getChildComponents());
  110. }
  111. public function getChildComponentsWithoutNestedSchema(): array
  112. {
  113. // Fetch the nested schema components.
  114. $nestedSchema = $this->getNestedSchema();
  115. // Filter out the nested schema components.
  116. return array_filter($this->getChildComponents(), function ($component) use ($nestedSchema) {
  117. return ! in_array($component, $nestedSchema, true);
  118. });
  119. }
  120. public function getNestedComponents(): array
  121. {
  122. // Fetch the nested schema components.
  123. $nestedSchema = $this->getNestedSchema();
  124. // Separate and return only the nested schema components.
  125. return array_filter($this->getChildComponents(), function ($component) use ($nestedSchema) {
  126. return in_array($component, $nestedSchema, true);
  127. });
  128. }
  129. public function getView(): string
  130. {
  131. return 'filament.forms.components.line-item-repeater';
  132. }
  133. }