fix: corrigir novo campo de skills, adicionado linkedin e links redirect#443
fix: corrigir novo campo de skills, adicionado linkedin e links redirect#443fernanduandrade wants to merge 4 commits into
Conversation
…ect no profile preview
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Central YAML (inherited) Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds LinkedIn support with URL generation, icons, translations, and tests. Localizes profile preview labels in English and Portuguese and renders social handles as external links. Updates skills and social-link repeaters to add rows automatically, makes work-experience validation conditional, and skips empty work-experience rows. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app-modules/panel-app/src/Pages/ProfilePage.php (1)
381-412: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winTreat an end date as partial work-experience data.
end_dateis absent from all partial-row predicates and from$keyFields; an end-date-only row is treated as empty and discarded. Include it in validation triggers and normalization detection.Also applies to: 690-696
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app-modules/panel-app/src/Pages/ProfilePage.php` around lines 381 - 412, Update the work-experience partial-row predicates in the ProfilePage form to include end_date alongside the other fields, so an end-date-only row triggers validation. Also add end_date to the $keyFields used for normalization, ensuring rows containing only an end date are retained rather than discarded.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app-modules/panel-app/src/Pages/ProfilePage.php`:
- Around line 150-156: Update the required predicates for the `skill_id` and
`proficiency` fields in the profile skills form to also consider
`years_experience`, ensuring rows containing only years are rejected rather than
silently discarded by `repeaterToSkills()`.
- Around line 153-195: Update both ProfilePage repeater field handlers at
app-modules/panel-app/src/Pages/ProfilePage.php lines 153-195 and 260-307 so the
shared auto-row creation check runs after either required field changes:
skill_id or proficiency in the skills repeater, and platform or handle in the
platforms repeater. Remove the single-field trigger limitation while preserving
the existing validation that both fields are filled before adding a row.
- Around line 158-194: Type-hint the $component parameter as
Filament\Forms\Components\Component in both afterStateUpdated callbacks,
including the handler containing the repeater auto-add logic, so PHPStan can
resolve getParentRepeater() and getStatePath().
---
Outside diff comments:
In `@app-modules/panel-app/src/Pages/ProfilePage.php`:
- Around line 381-412: Update the work-experience partial-row predicates in the
ProfilePage form to include end_date alongside the other fields, so an
end-date-only row triggers validation. Also add end_date to the $keyFields used
for normalization, ensuring rows containing only an end date are retained rather
than discarded.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 755de64e-c1a8-46b3-afa1-5e5c25d737e3
📒 Files selected for processing (8)
app-modules/panel-app/lang/en/profile.phpapp-modules/panel-app/lang/pt_BR/profile.phpapp-modules/panel-app/resources/views/components/profile-preview-card.blade.phpapp-modules/panel-app/src/Pages/ProfilePage.phpapp-modules/profile/lang/en/enums.phpapp-modules/profile/lang/pt_BR/enums.phpapp-modules/profile/src/Enums/SocialPlatform.phpapp-modules/profile/tests/Unit/SocialPlatformTest.php
| ->afterStateUpdated(function (Get $get, $component): void { | ||
| if (blank($get('skill_id')) || blank($get('proficiency'))) { | ||
| return; | ||
| } | ||
|
|
||
| $repeater = $component->getParentRepeater(); | ||
|
|
||
| if (!$repeater) { | ||
| return; | ||
| } | ||
|
|
||
| $items = $repeater->getRawState(); | ||
|
|
||
| if (blank($items)) { | ||
| return; | ||
| } | ||
|
|
||
| // Only auto-add when filling the last row | ||
| $repeaterPath = $repeater->getStatePath(); | ||
| $currentKey = explode('.', mb_substr((string) $component->getStatePath(), mb_strlen($repeaterPath) + 1))[0]; | ||
|
|
||
| if ($currentKey !== array_key_last($items)) { | ||
| return; | ||
| } | ||
|
|
||
| $newUuid = $repeater->generateUuid(); | ||
|
|
||
| if ($newUuid) { | ||
| $items[$newUuid] = []; | ||
| } else { | ||
| $items[] = []; | ||
| } | ||
|
|
||
| $repeater->rawState($items); | ||
| $repeater->getChildSchema($newUuid ?? array_key_last($items))->fill(); | ||
| $repeater->collapsed(false, shouldMakeComponentCollapsible: false); | ||
| $repeater->callAfterStateUpdated(); |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the target file around the reported lines and its imports/types.
sed -n '1,260p' app-modules/panel-app/src/Pages/ProfilePage.phpRepository: he4rt/heartdevs.com
Length of output: 13460
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the file structure first, then inspect the relevant methods/symbols.
ast-grep outline app-modules/panel-app/src/Pages/ProfilePage.php --view expandedRepository: he4rt/heartdevs.com
Length of output: 1596
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for the concrete class of $component and any PHPStan-related annotations in the module.
rg -n "afterStateUpdated\\(|getParentRepeater\\(|generateUuid\\(|callAfterStateUpdated\\(|\\$component" app-modules/panel-app/src -g '*.php'Repository: he4rt/heartdevs.com
Length of output: 199
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '720,760p' app-modules/panel-app/src/Pages/ProfilePage.php
printf '\n---\n'
rg -n "afterStateUpdated\\(function \\(Get \\$get, [A-Za-z_\\\\][A-Za-z0-9_\\\\]* \\$component" app-modules/panel-app/src -g '*.php'Repository: he4rt/heartdevs.com
Length of output: 1427
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Look for Filament component type hints used in similar callbacks.
rg -n "function \\(Get \\$get, (Select|TextInput|Toggle|Textarea|Repeater|Component|Field) \\$component|function \\((Select|TextInput|Toggle|Textarea|Repeater|Component|Field) \\$component" app-modules/panel-app/src -g '*.php'Repository: he4rt/heartdevs.com
Length of output: 193
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '720,760p' app-modules/panel-app/src/Pages/ProfilePage.php
printf '\n---\n'
rg -n "afterStateUpdated\\(function \\(Get \\$get, [A-Za-z_\\\\][A-Za-z0-9_\\\\]* \\$component" app-modules/panel-app/src -g '*.php'
printf '\n---\n'
rg -n "function \\((Select|TextInput|Toggle|Textarea|Repeater|Component|Field) \\$component" app-modules/panel-app/src -g '*.php'Repository: he4rt/heartdevs.com
Length of output: 1427
🌐 Web query:
Filament afterStateUpdated callback component parameter type Get $get component concrete type getParentRepeater
💡 Result:
In Filament's afterStateUpdated() callback, you can inject various parameters to interact with the component and form state. Component Parameter Type To access the current form component instance (e.g., to call getName(), getStatePath(), or getParentRepeater()), you can type-hint the Filament\Forms\Components\Component class in your callback function [1]. Example: ->afterStateUpdated(function (Component $component, $state, Set $set) { $parentRepeater = $component->getParentRepeater; //... }) Available Utilities The afterStateUpdated() method automatically injects utilities via parameter type-hinting or name matching [2][3]: - $get and $set: Used to interact with field values. In standard forms, they act on the root state. Inside a Repeater or similar nested containers, they are scoped to the current item [4][5]. You can use relative path syntax (e.g., ../field_name) to access data outside the current repeater item [4][5]. - $state: The new value of the field [2][3]. - $old: The previous value of the field [3][6]. getParentRepeater The getParentRepeater() method is available on components that implement the CanBeRepeated concern (which most standard form fields do) [7][8][9]. It returns an instance of Filament\Forms\Components\Repeater or null if the component is not inside a repeater [8][9]. If you are working with deeply nested structures, it effectively traverses the container hierarchy to find the parent repeater [7]. Note: Always ensure you import the correct Filament\Forms\Components\Component namespace if you are using it for type-hinting [1].
Citations:
- 1: How to get name property in Closure $set of afterStateUpdated mehod ? filamentphp/filament#6452
- 2: https://filamentphp.com/docs/4.x/forms/overview
- 3: https://filamentphp.com/docs/3.x/forms/advanced
- 4: https://filamentphp.com/docs/5.x/forms/repeater
- 5: https://filamentphp.com/docs/4.x/forms/repeater
- 6: https://github.com/filamentphp/filament/blob/3.x/packages/forms/src/Components/Concerns/HasState.php
- 7: https://github.com/filamentphp/filament/blob/3.x/packages/forms/src/Components/Concerns/CanBeRepeated.php
- 8: https://filamentphp.com/api/3.x/Filament/Forms/Components/Radio.html
- 9: https://filamentphp.com/api/3.x/Filament/Forms/Components/BaseFileUpload.html
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find existing callbacks that type-hint the generic Filament component.
rg -n 'afterStateUpdated\(function \([^)]*\bComponent \$component\b' app-modules/panel-app/src -g '*.php' || true
printf '\n---\n'
rg -n 'use Filament\\Forms\\Components\\Component;' app-modules/panel-app/src -g '*.php' || true
printf '\n---\n'
rg -n 'getParentRepeater\(\)' app-modules/panel-app/src -g '*.php' || trueRepository: he4rt/heartdevs.com
Length of output: 562
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p = Path('app-modules/panel-app/src/Pages/ProfilePage.php')
text = p.read_text()
start = text.index('->afterStateUpdated(function')
end = text.index('->columnSpan(1)', start)
print(text[start:end])
PYRepository: he4rt/heartdevs.com
Length of output: 2406
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import re
from pathlib import Path
text = Path('app-modules/panel-app/src/Pages/ProfilePage.php').read_text()
m = re.search(r'->afterStateUpdated\(function \(([^)]*)\): void \{', text)
print(m.group(1) if m else 'NO_MATCH')
PYRepository: he4rt/heartdevs.com
Length of output: 178
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '250,290p' app-modules/panel-app/src/Pages/ProfilePage.phpRepository: he4rt/heartdevs.com
Length of output: 2528
Type-hint the repeater callback component Both afterStateUpdated() handlers use untyped $component; type-hint it as Filament\Forms\Components\Component so PHPStan can resolve getParentRepeater() and getStatePath().
🧰 Tools
🪛 GitHub Check: Perform Phpstan Check / Run
[failure] 188-188:
Cannot access an offset on mixed.
[failure] 186-186:
Cannot access offset mixed on mixed.
[failure] 183-183:
Cannot call method generateUuid() on mixed.
[failure] 179-179:
Parameter #1 $array of function array_key_last expects array, mixed given.
[failure] 177-177:
Parameter #1 $string of function mb_strlen expects string, mixed given.
[failure] 177-177:
Cannot cast mixed to string.
[failure] 177-177:
Cannot call method getStatePath() on mixed.
[failure] 176-176:
Cannot call method getStatePath() on mixed.
[failure] 169-169:
Cannot call method getRawState() on mixed.
[failure] 163-163:
Cannot call method getParentRepeater() on mixed.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app-modules/panel-app/src/Pages/ProfilePage.php` around lines 158 - 194,
Type-hint the $component parameter as Filament\Forms\Components\Component in
both afterStateUpdated callbacks, including the handler containing the repeater
auto-add logic, so PHPStan can resolve getParentRepeater() and getStatePath().
Source: Linters/SAST tools
Contexto
Este PR implementa a solução da issue #427 e traz melhorias adicionais relacionadas à experiência de edição do perfil.
Atualmente, a seção Skills exige múltiplos cliques para adicionar várias habilidades e bloqueia o salvamento do perfil quando existem linhas de skills completamente vazias. Esses comportamentos tornam o preenchimento mais lento e geram fricção desnecessária durante a edição do perfil.
Além disso, foram realizadas melhorias complementares na experiência de visualização e gerenciamento de links sociais.
Alterações
Skills
live()eafterStateUpdated()do Filament para monitorar alterações nos campos da skill.Social Media
https://linkedin.com/in/usuario)usuario)Preview do Perfil
Benefícios
Issue relacionada
Closes #427
Links com redirect no preview profile
Linkedin adicionado no socio media
Permite salvar com campos em branco ainda não preenchidos
Adiciona novo campo automático quando a última coluna é preenchida