Hide Specialty sidebar group for desk specialists.
Deploy Ladill Care / deploy (push) Successful in 2m34s
Deploy Ladill Care / deploy (push) Successful in 2m34s
Single-desk specialists already reach their workspace via dashboard cards; the Specialty → Dentistry nav group was redundant. GPs and multi-module roles keep the section. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -180,6 +180,32 @@ class SpecialtyModuleService
|
|||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the sidebar should show the Specialty nav group.
|
||||||
|
*
|
||||||
|
* Desk specialists only receive their own matching module(s), so a
|
||||||
|
* Specialty → Dentistry (etc.) group is redundant — they use dashboard
|
||||||
|
* cards / direct routes instead. GPs, nurses, and other multi-module
|
||||||
|
* roles keep the group for referral and cross-module access.
|
||||||
|
*/
|
||||||
|
public function shouldShowSpecialtyNav(Organization $organization, ?Member $member): bool
|
||||||
|
{
|
||||||
|
if (! $member) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$modules = $this->enabledModulesForMember($organization, $member);
|
||||||
|
if ($modules === []) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->isDeskSpecialist($organization, $member)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 'general'|'limited'|'restricted'
|
* @return 'general'|'limited'|'restricted'
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -78,22 +78,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Specialty modules — role-gated clinical surfaces for floor staff.
|
// Specialty modules — role-gated clinical surfaces for floor staff.
|
||||||
|
// Desk specialists skip this group (redundant single-desk list); dashboard cards remain.
|
||||||
if ($permissions->handlesFloorCare($member) && $organization) {
|
if ($permissions->handlesFloorCare($member) && $organization) {
|
||||||
$specialtyService = app(\App\Services\Care\SpecialtyModuleService::class);
|
$specialtyService = app(\App\Services\Care\SpecialtyModuleService::class);
|
||||||
$specialtyService->ensureDefaultModulesProvisioned(
|
$specialtyService->ensureDefaultModulesProvisioned(
|
||||||
$organization,
|
$organization,
|
||||||
(string) $organization->owner_ref,
|
(string) $organization->owner_ref,
|
||||||
);
|
);
|
||||||
foreach ($specialtyService->enabledModulesForMember($organization, $member) as $item) {
|
if ($specialtyService->shouldShowSpecialtyNav($organization, $member)) {
|
||||||
$key = $item['key'];
|
foreach ($specialtyService->enabledModulesForMember($organization, $member) as $item) {
|
||||||
$label = $item['definition']['nav_label'] ?? $item['definition']['label'] ?? $key;
|
$key = $item['key'];
|
||||||
$nav[] = [
|
$label = $item['definition']['nav_label'] ?? $item['definition']['label'] ?? $key;
|
||||||
'name' => $label,
|
$nav[] = [
|
||||||
'route' => route('care.specialty.workspace', $key),
|
'name' => $label,
|
||||||
'active' => request()->routeIs('care.specialty.*') && request()->route('module') === $key,
|
'route' => route('care.specialty.workspace', $key),
|
||||||
'icon' => $specialtyService->iconSvgPath($key),
|
'active' => request()->routeIs('care.specialty.*') && request()->route('module') === $key,
|
||||||
'group' => 'specialty',
|
'icon' => $specialtyService->iconSvgPath($key),
|
||||||
];
|
'group' => 'specialty',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,15 +189,45 @@ class CareSpecialtyAccessTest extends TestCase
|
|||||||
$this->assertNotContains('blood_bank', $enabledKeys);
|
$this->assertNotContains('blood_bank', $enabledKeys);
|
||||||
$this->assertNotContains('cardiology', $enabledKeys);
|
$this->assertNotContains('cardiology', $enabledKeys);
|
||||||
|
|
||||||
|
// Single-desk specialists: no Specialty sidebar group (dashboard cards remain).
|
||||||
|
$this->assertFalse($this->modules->shouldShowSpecialtyNav($this->organization, $member));
|
||||||
|
|
||||||
$this->actingAs($doctor)
|
$this->actingAs($doctor)
|
||||||
->get(route('care.dashboard'))
|
->get(route('care.dashboard'))
|
||||||
->assertOk()
|
->assertOk()
|
||||||
->assertSee('Dentistry')
|
->assertSee('Dentistry')
|
||||||
|
->assertSee('Specialty modules')
|
||||||
|
->assertDontSee('>Specialty</p>', false)
|
||||||
->assertDontSee('Emergency')
|
->assertDontSee('Emergency')
|
||||||
->assertDontSee('Cardiology')
|
->assertDontSee('Cardiology')
|
||||||
->assertDontSee('Blood Bank');
|
->assertDontSee('Blood Bank');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_gp_keeps_specialty_sidebar_nav(): void
|
||||||
|
{
|
||||||
|
[$doctor, $member] = $this->makeStaff('doctor', 'gp-nav');
|
||||||
|
Practitioner::create([
|
||||||
|
'owner_ref' => $this->owner->public_id,
|
||||||
|
'organization_id' => $this->organization->id,
|
||||||
|
'branch_id' => $this->branch->id,
|
||||||
|
'member_id' => $member->id,
|
||||||
|
'user_ref' => $doctor->public_id,
|
||||||
|
'name' => 'Dr GP Nav',
|
||||||
|
'specialty' => 'General Practice',
|
||||||
|
'is_active' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertFalse($this->modules->isDeskSpecialist($this->organization, $member));
|
||||||
|
$this->assertTrue($this->modules->shouldShowSpecialtyNav($this->organization, $member));
|
||||||
|
|
||||||
|
$this->actingAs($doctor)
|
||||||
|
->get(route('care.dashboard'))
|
||||||
|
->assertOk()
|
||||||
|
->assertSee('>Specialty</p>', false)
|
||||||
|
->assertSee('Emergency')
|
||||||
|
->assertSee('Dentistry');
|
||||||
|
}
|
||||||
|
|
||||||
public function test_dentistry_specialty_does_not_match_ent_keyword(): void
|
public function test_dentistry_specialty_does_not_match_ent_keyword(): void
|
||||||
{
|
{
|
||||||
[$doctor, $member] = $this->makeStaff('doctor', 'dentist-ent-trap');
|
[$doctor, $member] = $this->makeStaff('doctor', 'dentist-ent-trap');
|
||||||
@@ -340,10 +370,12 @@ class CareSpecialtyAccessTest extends TestCase
|
|||||||
$this->assertContains('infusion', $enabledForMember);
|
$this->assertContains('infusion', $enabledForMember);
|
||||||
$this->assertNotContains('cardiology', $enabledForMember);
|
$this->assertNotContains('cardiology', $enabledForMember);
|
||||||
$this->assertNotContains('dentistry', $enabledForMember);
|
$this->assertNotContains('dentistry', $enabledForMember);
|
||||||
|
$this->assertTrue($this->modules->shouldShowSpecialtyNav($this->organization, $pharmacistMember));
|
||||||
|
|
||||||
$this->actingAs($pharmacistUser)
|
$this->actingAs($pharmacistUser)
|
||||||
->get(route('care.dashboard'))
|
->get(route('care.dashboard'))
|
||||||
->assertOk()
|
->assertOk()
|
||||||
|
->assertSee('>Specialty</p>', false)
|
||||||
->assertSee('Emergency')
|
->assertSee('Emergency')
|
||||||
->assertDontSee('Cardiology');
|
->assertDontSee('Cardiology');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user