{{ seg.text }}
{{ seg.text }}
{{ seg.text }}
{{ entry.state === 'checking' ? 'Checking your saved session…' : (entry.state === 'entering' ? 'Access verified. Entering your authorised departmental workspace.' : 'Your account is verified. Loading your workspace…') }}
{{ entry.state === 'checking' ? 'Verifying your saved session…' : entry.state === 'entering' ? 'Ready to enter.' : entry.accessReady ? 'Loading departmental records…' : 'Confirming your permissions…' }}
Your account has been re-verified on this trusted browser; departmental records remain locked until you continue.
{{ entry.message }}
Account supportRequest a new password using your registered email. For first-time access or a disabled account, contact your administrator.
People, professional roles and near-term operational context.
| Staff member | Role | Current / next | Record status | Actions |
|---|---|---|---|---|
|
{{ nmAvI(staff.full_name) }}
{{ staff.full_name }}
{{ staff.department?.name || staff.departments?.name || staff.primary_dept_name || staff.specialization || 'Department record' }}
|
{{ getStaffResidentDescriptor(staff)?.label || 'Resident' }}
{{ getStaffResidentDescriptor(staff).year }}
·
{{ getStaffResidentDescriptor(staff).origin }}
{{ formatStaffType(staff.staff_type) }}
{{ formatSpecialization(staff.specialization) }}
|
{{ item.title }}{{ item.meta }}
|
{{ getStaffDirectoryRecordState(staff).label }} | |
| No staff records match this view. {{ hasActiveStaffFilters ? 'Clear or adjust the filters to see more people.' : 'Add the first staff record when the department is ready.' }} | ||||
{{ getStaffResidentDescriptor(item)?.label }} · {{ getStaffResidentDescriptor(item).year }}
{{ formatStaffType(item.staff_type) }} · {{ formatSpecialization(item.specialization) }}
From {{ getStaffResidentDescriptor(item).origin }}Schedules, duty logs and monthly review.
| Shift Period | Physician | Type | Status | Actions |
|---|
| Shift Period | Physician | Type | Status | Actions | |
|---|---|---|---|---|---|
|
{{ formatDate(schedule.duty_date) }}
TODAY
+1d
{{ (schedule.start_time||'').slice(0,5) }}
→
{{ (schedule.end_time||'').slice(0,5) }}
{{ schedule.coverage_area?.name || coverageAreas.find(a=>a.id===schedule.coverage_area_id)?.name }}
|
{{ (getPhysicianName(schedule.primary_physician_id)||'??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ getPhysicianName(schedule.primary_physician_id) }}
On duty now
|
{{ {'primary_call':'Primary','weekend_coverage':'Weekend','float_physician':'Float'}[schedule.shift_type] || schedule.shift_type }} | {{ new Date(schedule.duty_date + 'T' + (schedule.start_time||'00:00')) > new Date() ? 'Upcoming' : isToday(schedule.duty_date) ? 'Live' : 'Done' }} |
|
|
|
No schedules found
No results match your filters
No on-call shifts have been scheduled yet
|
|||||
| Physician | Called at | Type | Duration | Reason | |
|---|---|---|---|---|---|
|
{{ (c.staff?.full_name || c.staff_id || '??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ c.staff?.full_name || '—' }}
|
{{ c.called_at ? new Date(c.called_at).toLocaleDateString('es-ES',{day:'2-digit',month:'short',year:'numeric'}) : '—' }}
{{ c.called_at ? new Date(c.called_at).toLocaleTimeString('es-ES',{hour:'2-digit',minute:'2-digit'}) : '' }}
|
{{ calloutTimeTypes[c.time_type] || c.time_type }} | {{ Math.round((new Date(c.end_time) - new Date(c.called_at)) / 60000) }}m — |
{{ calloutReasonLabels[c.reason_category] || c.reason_category }}
{{ c.notes }}
|
|
| Physician | Scheduled on-call | Call-outs | Night | Weekend | Total | vs avg |
|---|---|---|---|---|---|---|
|
{{ (row.name||'??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ row.name }}
{{ formatStaffType(row.staffType) }}
|
{{ row.scheduled }} | {{ row.callouts }} | {{ row.night }} | {{ row.weekend }} | {{ row.total }} |
|
Placements, timelines and rotation records to review.
+ {{ rotationOneDayReviews.length - 3 }} additional one-day records remain available in the rotation table.
+ {{ rotationMissingResidentReviews.length - 3 }} additional unresolved resident relationships remain in the table.
| Resident | Unit | Period | Days Left | Status | Actions |
|---|
| Resident | Unit | Period | Days Left | Status | Supervisor | Actions |
|---|---|---|---|---|---|---|
|
{{ (getResidentName(rotation.resident_id)||'??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ getResidentName(rotation.resident_id) }}
{{ rotation.resident.external_contact_name }}
{}" title="Email contact">
|
{{ getTrainingUnitName(rotation.training_unit_id) }}
{{ rotation.training_unit.dept.name }}
|
{{ formatDateShort(rotation.start_date) }}
→
{{ formatDateShort(rotation.end_date) }}
|
{{ getRotationProgress(rotation).pct }}% · {{ getRotationProgress(rotation).label }}
|
{{ formatRotationStatus(rotation.rotation_status) }} | {{ getSupervisorName(rotation.supervising_attending_id) }} — |
|
|
No rotations found
No results match your filters
No resident rotations have been assigned yet
|
||||||
{{ trainingUnitView==='timeline' ? 'Month-by-month resident capacity across active clinical units' : trainingUnitView==='weekly' ? 'Attending physicians linked to each unit · recorded leave is secondary context' : 'People · resident rotations · capacity · unit details' }}
{{ dashboardSourceLabel('training_units') }}
Capacity cannot be calculated without available rotation records.
Capacity uses overlapping dates in the rotation records your account can access; it may not represent all departmental assignments. Sequential residents in the same month can reuse the same slot.
neumDesk checks every active clinical unit against exact overlapping rotation dates.
You can still inspect linked attending physicians in the unit directory.
Attending links describe the stable clinical team around a unit. Recorded leave is shown as context only; resident capacity and formal residency supervision are separate concepts.
Link the attending physicians who normally work in each unit. Once those structural links exist, recorded leave can add day-by-day context without redefining resident capacity.
Open a unit for attending physicians, current and incoming residents, capacity and unit details.
{{ unit.department?.name || unit.department_name || unit.specialty || 'Clinical unit' }}
Capacity unavailable · rotation records required.
Current attendance, planned leave and coverage review are shown as separate operational states.
| Staff member | Reason | Status | From | Until | Duration | Coverage |
|---|
| Staff member | Reason | Status | From | Until | Duration | Coverage | |
|---|---|---|---|---|---|---|---|
|
{{ (getStaffName(absence.staff_member_id)||'??').split(' ').filter(Boolean).slice(0,2).map(n=>n[0]).join('').toUpperCase() }}
{{ getStaffName(absence.staff_member_id) }}
|
{{ absence.absence_reason ? absence.absence_reason.replace('_',' ') : '—' }} | Absent nowPlannedReturnedCancelled{{ absence.current_status }} | {{ formatDate(absence.actual_start_date || absence.start_date) }} |
{{ formatDate(absence.actual_return_date || absence.end_date) }}
planned {{ formatDate(absence.end_date) }}
|
{{ absence.actual_days || calculateAbsenceDuration(absence.actual_start_date || absence.start_date, absence.actual_return_date || absence.end_date) }} {{ absence.actual_return_date ? 'actual days' : 'planned days' }} | {{ getStaffName(absence.covering_staff_id) }} Covered No coverage |
|
|
No absences found
No results match your filtersNo absence records have been logged yet
|
|||||||
No absences in this period
{{ absences.length === 0 ? 'No absence records have been created yet.' : 'All absences in this window are resolved. Navigate forward or switch to Planning mode.' }}
No staff found
Announcements, departmental updates and operational context.
Nothing posted yet. Be first to update the department.
WORKSPACE ADMINISTRATION
Manage the people and structure of your department.
SCHEDULE IMPORT
Match the spreadsheet to your team and inspect the proposed changes.
⚠ This file only contains past on-call (latest {{ oncallSync.summary.max }}). There are no current or future shifts to sync — add upcoming dates to the Guardias sheet and re-upload.
{{oncallSync.blocked.length}} rows in the file need attention. Rows with invalid dates are visible under Whole file.
02 / REVIEW ASSIGNMENTS
| Apply | Date | Current schedule | From Excel | Review / result |
|---|---|---|---|---|
| {{r.date||'Invalid date'}}{{ new Date(r.date+'T12:00:00').toLocaleDateString('en-GB',{weekday:'long'}) }}Source row {{r.source_row}} | {{r.currentName}}Resident: {{r.currentResident||'None'}}{{oncallSyncType(r.current.shift_type)}}{{r.status==='conflict'?'Multiple assignments':'No assignment'}} | {{r.staffName||r.surname}}Resident: {{r.residentName||r.mir||'None'}}{{oncallSyncType(r.shiftType)}} | {{({inserted:'Added',updated:'Updated',not_saved:'Not saved'})[oncallSync.results[r.date].status]}}{{oncallSync.results[r.date].message}}{{({new:'New',conflict:'Conflict',replacement:'Replacement approved',matching:'Already matches',kept:'Keeping current',blocked:'Needs attention',skipped:'Skipped'})[r.status]}}{{r.issue}}{{oncallSync.checkResults[r.date].status==='ready'?'Checked · Ready to apply':oncallSync.checkResults[r.date].message}}Not confirmed. Reload before retrying. | |
| No assignments match this view. Adjust the period or filters. | ||||
03 / CHECK BEFORE APPLYING
{{oncallSyncReady?'Selected assignments passed the current checks.':oncallSyncChecked?'Some selected assignments need attention. Resolve or deselect those rows, then check again.':'Check your selection for permissions, leave conflicts and overlapping duties.'}}
Checks do not save assignments. The server checks again when you apply.{{oncallSync.checkError}}
DEPARTMENT SETUP
Maintain staff categories, qualifications, rotation services and coverage areas.
Honorifics offered in the staff form (Dr., Dra., Prof., …). The chosen value is shown before the name on the public team page. Removing one here keeps it on anyone who already has it.
PREFERENCES
Department details and platform behaviour in one place.
Define the coverage areas for on-call assignments (e.g. ICU, Hospitalization, General). Each shift is assigned to one area, allowing multiple primaries per day — one per area.
coverage_areas SQL in Supabase before using this feature.
One portfolio for clinical studies, innovation, study requirements and research output.
Programmes that organise the department’s clinical studies, innovation and research output.
{{ line.description }}
{{ selectedLine.description || 'No programme description has been recorded yet.' }}
Studies, trials, cohorts and registries linked to this programme.
{{ (trial.target_diseases||[]).length ? trial.target_diseases.join(' · ') : 'Clinical focus not recorded' }}
Clinical needs moving through development, validation and implementation.
{{ proj.clinical_rationale || proj.description || 'No clinical rationale recorded' }}
{{ selectedLine?.description || 'No description available.' }}
Summary access. Detailed research and clearance fields are restricted.
Recruitment target is not recorded for this study.
{{ selectedStudy.description || selectedStudy.scope_note }}
Summary access. Detailed research and clearance fields are restricted.
{{ selectedProject.description }}
Track study status, enrolment, protocol readiness and ethics / CEIm clearance across Pneumology.
| {{ col[1] }} {{ studiesPreview.sortDir>0?'▲':'▼' }} | |||||||||
|---|---|---|---|---|---|---|---|---|---|
| {{ r.protocol_id || '—' }} | {{ r.line || '—' }} | {{ r.study_type || '—' }} | {{ r.phase || '—' }} | {{ r.status }} — | {{ r.enrolment || '—' }} | {{ r.featured_in_website?'Public':'Private' }} | {{ r.updated || '—' }} | ||
| No studies match the current filters. | |||||||||
{{ (trial.target_diseases||[]).length ? trial.target_diseases.join(' · ') : getResearchLineName(trial.research_line_id) }}
From clinical need to validation, implementation and scale.
| {{ col[1] }} {{ projectsPreview.sortDir>0?'▲':'▼' }} | |||||||
|---|---|---|---|---|---|---|---|
| {{ r.line || '—' }} | {{ r.category || '—' }} | {{ r.stage || '—' }} | {{ r.funding || '—' }} | {{ r.featured_in_website?'Public':'Private' }} | {{ r.updated || '—' }} | ||
| No projects match the current filters. | |||||||
{{ proj.clinical_rationale || proj.description || ((proj.target_diseases||[]).length ? proj.target_diseases.join(' · ') : 'No clinical rationale recorded') }}
Portfolio signals across enrolment, study requirements, programme activity and innovation readiness.
Scientific output, clinical insight and departmental knowledge — connected to the programmes and people that produced them.
No research sets yet. Save a filtered view when you want to return to a working collection.
{{ newsPlainBody(post.body) }}
Read →{{ newsPlainBody(post.body) }}
Open highlight →{{ newsPlainBody(post.body) }}
Open update →No matching records or commands.
{{ newsDisplayPosts.length }} records will be included. Sets are personal to this browser profile and do not alter institutional records.
{{ getResidentTrainingContext(staffProfileModal.staff).summary }}
Current operational context, clinical relationships and professional record.
{{ getResidentTrainingContext(staffProfileModal.staff).summary }}
Host-unit context, resident-management roles and the recorded rotation supervisor are shown as separate relationships. neumDesk does not infer a stricter supervision rule than the records provide.
{{ newsDrawerLead }}
{{ seg.text }}
{{ seg.text }}
{{ newsDrawer.post.body }}
{{ newsDrawer.post.body }}
{{ activity45.model ? 'Recorded departmental activity, responsibilities and portfolio — with retrieval evidence.' : 'Build a permission-scoped view of one person’s recorded departmental activity and professional relationships.' }}
{{ activity45.summary?.narrative }}
{{ activity45DateRange(event) }} · {{ event.role }}
No dated activity is visible in the successfully retrieved sources for this period. Unavailable or restricted sources remain unknown; this does not establish availability.
{{ activity45.summary?.sourceReady || 0 }}sources retrieved
{{ activity45.summary?.issues || 0 }}information caveats
{{ activity45MetricValue('portfolioRelationships') }}professional portfolio relationships
Incomplete dates and source conditions remain visible instead of being converted into assumptions.
On-call duties and rotation spans are person-specific records. Study and innovation milestones are shown as shared milestones unless personal ownership is explicitly established.
{{ event.role }} · {{ event.detail }}
No dated activity is visible in the included, successfully retrieved sources.
These sections show explicit professional relationships. Where dates cannot establish period relevance, the relationship stays visible and is labelled accordingly.
Resident assignment · Supervisor: {{ item.supervisor }}
{{ item.timing || activity45DateRange(item) }}{{ activity45EmptyText('rotations','No resident rotation assignment overlaps this period.') }}
{{ item.title }} · {{ item.role }}
{{ item.timing || activity45DateRange(item) }}{{ activity45EmptyText('rotations','No formal resident-supervision rotation overlaps this period.') }}
{{ item.role }} · {{ item.line }}
{{ item.timing }}{{ activity45EmptyText('studies','No linked studies are established by the retrieved records.') }}
{{ item.role }} · {{ item.line }}
{{ item.timing }}{{ activity45EmptyText('projects','No linked innovation projects are established by the retrieved records.') }}
{{ item.role }}
{{ activity45EmptyText('lines','No programme coordination role is established by the retrieved records.') }}
Source health is part of the result. A restricted or unavailable source means neumDesk cannot establish whether activity exists there.
{{ source.state==='ready' ? (source.matchCount + ' relevant record' + (source.matchCount===1?'':'s') + ' represented in this view') : (source.state + ' — matching activity remains unknown') }}
{{ source.notes.join(' · ') }}This is a record snapshot, not a workload score, performance rating or confirmation of availability. Research and innovation entries represent explicit relationships unless a dated milestone is separately present. Private notes, contact details and leave reasons are excluded.
Choose a staff member and period. neumDesk will separate dated activity from professional relationships, show the evidence behind each, and only then generate a formal brief.