@extends('layouts.app') @section('content') @php $toolTabs = [ ['label' => 'All Extensions', 'route' => route('extensions.index'), 'active' => request()->routeIs('extensions.index')], ['label' => 'Status', 'route' => route('extensions.status'), 'active' => request()->routeIs('extensions.status')], ['label' => 'Hot Desking', 'route' => route('extensions.hot-desking'), 'active' => $tool === 'hot-desking'], ['label' => 'Import', 'route' => route('extensions.import'), 'active' => $tool === 'import'], ['label' => 'Export', 'route' => route('extensions.export'), 'active' => $tool === 'export'], ['label' => 'Bulk Modification', 'route' => route('extensions.bulk-modification'), 'active' => $tool === 'bulk-modification'], ['label' => 'Bulk Extensions', 'route' => route('extensions.bulk-extensions'), 'active' => $tool === 'bulk-extensions'], ]; $filters = $filters ?? ['q' => '', 'transport' => '', 'device_type' => '']; $selectedExtensions = collect($selectedExtensions ?? [])->map(fn ($id) => (string) $id)->all(); @endphp
Extensions Workspace

{{ $pageTitle }}

{{ $pageSubtitle }}
NobleUI Realtime PBX Tools
@if (session('status')) @endif @if ($errors->any()) @endif @if (session('import_skipped')) @endif @if (session('bulk_skipped')) @endif @if ($tool === 'hot-desking')
PBX-level hot desking
Assignments and login sessions now drive the realtime `from-internal` dial target for each extension.
@csrf
Overview

{{ $extensions->total() }}

Extensions in the internal pool.
Ready For Hot Desk

{{ $extensions->getCollection()->filter(fn($row) => (int) ($row->max_contacts ?? 1) > 1)->count() }}

Extensions already allowing multiple contacts.
Web/Mobile Capable

{{ $extensions->getCollection()->filter(fn($row) => in_array($row->transport, ['transport-wss', 'transport-tcp'], true))->count() }}

Extensions provisioned for roaming-friendly clients.
Currently Logged In

{{ collect($hotDeskAssignments ?? [])->filter(fn($row) => !empty($row->logged_in_user))->count() }}

Active hot desk sessions across assigned devices.
@forelse ($extensions as $extension) @php $assignment = $hotDeskAssignments[$extension->id] ?? null; @endphp @empty @endforelse
Extension Device Type Transport Context Max Contacts Hot Desk Readiness Assignment Actions
{{ $extension->id }} {{ ucfirst(str_replace('_', ' ', $extension->description ?: 'sip_phone')) }} {{ $extension->transport }} {{ $extension->context }} {{ $extension->max_contacts ?? 1 }} @if ((int) ($extension->max_contacts ?? 1) > 1) Ready @else Single Contact @endif @if ($assignment && $assignment->assigned_user)
{{ $assignment->assigned_user }}
{{ $assignment->logged_in_user ? 'Logged in: ' . $assignment->logged_in_user : 'Not logged in' }}
Target: {{ $assignment->logged_in_endpoint ?: ($assignment->assigned_endpoint ?: $extension->id) }}
@else Unassigned @endif
@csrf
@csrf
No extensions found.
@foreach (($hotDeskUsers ?? []) as $userName) @endforeach
{{ $extensions->links() }}
@endif @if ($tool === 'import')
CSV Import
@csrf
Format: extension,password,display_name,device_type,context
Download Template
Import Notes
Supported device types
  • sip_phone
  • web_phone
  • mobile_app
  • teams
@if (!empty($importPreview))
Validation Preview
@foreach ($importPreview as $row) @endforeach
Line Extension Display Name Device Type Context Status
{{ $row['line'] }} {{ $row['id'] }} {{ $row['display_name'] ?: '-' }} {{ $row['device_type'] }} {{ $row['context'] }} @if ($row['valid']) Valid @elseif (!empty($row['exists'])) Existing / Duplicate @else {{ implode(', ', $row['errors']) }} @endif @if (!empty($row['errors']))
{{ implode(', ', $row['errors']) }}
@endif
@endif @endif @if ($tool === 'export')
Extensions Ready

{{ $extensions->total() }}

Inventory items available for CSV export.
WebRTC Endpoints

{{ $extensions->getCollection()->filter(fn($row) => $row->transport === 'transport-wss')->count() }}

Browser/mobile capable extensions in this page set.
CSV Export
Download current extension provisioning details.
Download current extension inventory
Exports core provisioning fields to CSV.
Download CSV
@forelse ($extensions as $extension) @empty @endforelse
Extension Username Context Transport Device Type
{{ $extension->id }} {{ $extension->username ?: $extension->id }} {{ $extension->context }} {{ $extension->transport }} {{ ucfirst(str_replace('_', ' ', $extension->description ?: 'sip_phone')) }}
No extensions available for export.
{{ $extensions->links() }}
@endif @if ($tool === 'bulk-modification')
@csrf
Apply Changes
Selection tools
Use the filters on the right, add visible rows, or capture the full filtered result across all pages.
Saved selection
{{ count($selectedExtensions) }} extension(s) currently selected across pages.
0 ? 'checked' : '' }}>

Automatically route via failover trunk if primary fails
@csrf
@csrf
@csrf
Select Extensions
@forelse ($extensions as $extension) @empty @endforelse
Extension Context Transport Device Type Codecs Max Contacts
id, $selectedExtensions, true) ? 'checked' : '' }}> {{ $extension->id }} {{ $extension->context }} {{ $extension->transport }} {{ ucfirst(str_replace('_', ' ', $extension->description ?: 'sip_phone')) }} {{ $extension->allow }} {{ $extension->max_contacts ?? 1 }}
No extensions available.
{{ $extensions->links() }}
@endif @if ($tool === 'bulk-extensions')
Create Extension Range
@csrf
How it works
Each extension in the range is created with:
  • Auto-generated username matching the extension number
  • Password built from password_prefix + extension
  • Transport defaults based on the selected device type
  • Standard internal PBX defaults used by the existing extension provisioning flow
@endif @endsection @push('scripts') @endpush