id) ->where('part_type', $partType) ->exists(); if ($hasOverride) { $rows = ServiceMacroAssignment::with(['macro', 'label']) ->where('service_id', $service->id) ->where('part_type', $partType) ->orderBy('order') ->get(); } else { $rows = MacroAssignment::with(['macro', 'label']) ->where('part_type', $partType) ->orderBy('order') ->get(); } return $rows ->reject(fn ($r) => $r->macro === null || $r->macro->isHidden()) ->reject(fn ($r) => $r->position === 'by_label' && ($r->label === null || $r->label->isHidden())); } /** * Returns the macro export data for macros that apply to a specific slide. * * @param array $slideContext ['index' => int, 'total' => int, 'label_id' => int|null] * @return array */ public function macrosForSlide(Service $service, string $partType, array $slideContext): array { $assignments = $this->resolveAssignmentsForPart($service, $partType); $matched = $assignments->filter(function ($a) use ($slideContext) { return match ($a->position) { 'all_slides' => true, 'first_slide' => $slideContext['index'] === 0, 'last_slide' => $slideContext['index'] === $slideContext['total'] - 1, 'by_label' => isset($slideContext['label_id']) && (int) $a->label_id === (int) $slideContext['label_id'], default => false, }; }); return $matched->map(fn ($a) => $this->toExportArray($a->macro))->values()->all(); } /** * Returns the count of active assignments for a service + part (for UI badges). */ public function countAssignmentsForPart(Service $service, string $partType): int { return $this->resolveAssignmentsForPart($service, $partType)->count(); } private function toExportArray(Macro $macro): array { $collection = $macro->collections()->first(); return [ 'name' => $macro->name, 'uuid' => $macro->uuid, 'collectionName' => $collection?->name ?? '--MAIN--', 'collectionUuid' => $collection?->uuid ?? '8D02FC57-83F8-4042-9B90-81C229728426', ]; } }