diff --git a/app/DataTables/WorklistDataTable.php b/app/DataTables/WorklistDataTable.php index 2d3d718..a7e877d 100644 --- a/app/DataTables/WorklistDataTable.php +++ b/app/DataTables/WorklistDataTable.php @@ -4,8 +4,13 @@ use App\DAL\Studies\WorklistFactory; use App\Models\Study; +use App\Models\User; +use App\Services\ACL\AccessControl; +use App\Services\ACL\WorklistButton; +use App\Services\ACL\WorklistColumn; use Carbon\Carbon; use Carbon\CarbonImmutable; +use Closure; use Illuminate\Database\Eloquent\Builder as QueryBuilder; use Illuminate\Support\Facades\Blade; use Illuminate\Support\Str; @@ -26,6 +31,22 @@ private static function dtFormat(Carbon|CarbonImmutable|null $dt): ?string public function dataTable(QueryBuilder $query): EloquentDataTable { + $table = new EloquentDataTable($query); + $rawColumns = [ + 'priority_icon', + 'report_status_led', + ]; + foreach ($this->customColumns() as $column => $content) { + $table->editColumn($column, $content); + $rawColumns[] = $column; + } + $table + ->orderColumn('patient_name', 'patient_name $1') + ->rawColumns($rawColumns) + ->setRowId('id'); + + return $table; + return (new EloquentDataTable($query)) ->addColumn('action', 'worklist.action') ->editColumn('patient_name', fn (Study $study) => $study->sanitizedPatientName()) @@ -136,6 +157,72 @@ public function html(): HtmlBuilder */ public function getColumns(): array { + $cols_allowed = AccessControl::worklistColumns(); + $columns = []; + foreach ($cols_allowed as $allowed) { + switch ($allowed) { + case WorklistColumn::Priority: + $columns[] = Column::make($allowed->value) + ->searchable(false) + ->hidden(); + $columns[] = Column::make('priority_icon') + ->searchable(false) + ->orderable(false) + ->addClass('text-center') + ->width('20px') + ->title(''); + break; + case WorklistColumn::ReportStatus: + case WorklistColumn::History: + $columns[] = Column::make($allowed->value) + ->searchable(false) + ->orderable(false) + ->addClass('text-center') + ->width('20px') + ->title(''); + break; + case WorklistColumn::PatientSexAge: + $columns[] = Column::make($allowed->value) + ->searchable(false) + ->orderable(false) + ->addClass('text-center') + ->title('Age'); + break; + case WorklistColumn::StudyDate: + $columns[] = Column::make($allowed->value)->searchable(false)->title('Scan Dt'); + break; + case WorklistColumn::ReceiveDate: + $columns[] = Column::make($allowed->value)->searchable(false)->title('Received'); + break; + case WorklistColumn::ReportDate: + $columns[] = Column::make($allowed->value)->searchable(false)->title('Read At'); + break; + case WorklistColumn::AssignedPhysician: + $columns[] = Column::make($allowed->value) + ->searchable(false) + ->title('Assigned'); + break; + case WorklistColumn::ReadingPhysician: + $columns[] = Column::make($allowed->value) + ->searchable(false) + ->title('Read By'); + break; + case WorklistColumn::ActionButtons: + $columns[] = Column::computed('action') + ->exportable(false) + ->printable(false) + ->width(60) + ->addClass('text-center') + ->title(''); + break; + default: + $columns[] = Column::make($allowed->value)->title(Str::title($allowed->value)); + break; + } + } + + return $columns; + return [ Column::make('priority')->hidden(), Column::make('priority_icon') @@ -171,7 +258,8 @@ public function getColumns(): array Column::make('study_description') ->title('Study'), - Column::make('show_study')->searchable(false) + Column::make('show_study') + ->searchable(false) ->orderable(false) ->addClass('text-center') ->width('20px') @@ -218,4 +306,110 @@ protected function filename(): string return Str::slug(implode(' ', $parts), '_'); } + + private function physicianColumn(?User $user, Carbon|CarbonImmutable|null $dt): ?string + { + if ($user === null) { + return null; + } + + return Blade::render('staff.worklist.partials._radiologist-listing', + [ + 'avatar_url' => $user->avatar(), + 'name' => $user->display_name, + 'time' => $dt?->diffForHumans() ?? '~', + ] + ); + } + + /** + * @return array + */ + private function customColumns(): array + { + $columns = []; + + foreach (AccessControl::worklistColumns() as $col) { + switch ($col) { + case WorklistColumn::PatientName: + $columns[$col->value] = fn (Study $study) => $study->sanitizedPatientName(); + break; + case WorklistColumn::StudyDescription: + $columns[$col->value] = fn (Study $study) => $study->sanitizedStudyDescription(); + break; + case WorklistColumn::AssignedPhysician: + $columns[$col->value] = fn (Study $study) => $this->physicianColumn($study->assignedPhysician, $study->assigned_at); + break; + case WorklistColumn::ReadingPhysician: + $columns[$col->value] = fn (Study $study) => $this->physicianColumn($study->readingPhysician, $study->reported_at); + break; + case WorklistColumn::Series: + $columns[$col->value] = fn (Study $study) => $study->numInstances() . '' . human_filesize($study->disk_size) . ''; + break; + case WorklistColumn::StudyDate: + case WorklistColumn::ReceiveDate: + case WorklistColumn::ReportDate: + case WorklistColumn::AssignDate: + case WorklistColumn::AuthorizeDate: + case WorklistColumn::ArchiveDate: + $columns[$col->value] = fn (Study $study) => $study->{$col->value}?->format(self::DATE_FORMAT); + break; + case WorklistColumn::History: + $columns[$col->value] = fn (Study $study) => sprintf(' + + + +', blank($study->body_part_examined) ? 'text-muted' : 'text-primary'); + break; + case WorklistColumn::ActionButtons: + $columns[$col->value] = fn (Study $study) => $this->generateButtons($study); + break; + } + } + + return $columns; + } + + private function renderButton(string $data_id, string $fa_icon, string $data_class, string $text, string $url = '#'): string + { + return Blade::render('staff.worklist.partials._column-button', + [ + 'data_id' => $data_id, + 'url' => $url, + 'fa_icon' => $fa_icon, + 'data_class' => $data_class, + 'text' => $text, + ] + ); + } + + private function generateButtons(Study $study): string + { + $btns = []; + foreach (AccessControl::worklistButtons() as $button) { + switch ($button) { + case WorklistButton::StudyMetadata: + $btns[] = $this->renderButton($study->hash, 'fa-circle-info', 'showStudy btn-outline-facebook', 'Info'); + break; + case WorklistButton::History: + $btns[] = $this->renderButton($study->hash, 'fa-pen-to-square', 'btn-outline-primary', 'Edit', route('staff.history.edit', $study->hash)); + break; + case WorklistButton::Notes: + $btns[] = $this->renderButton($study->hash, 'fa-user-doctor', 'btn-outline-youtube show-assign', 'Assign'); + break; + case WorklistButton::Attachment: + $btns[] = $this->renderButton($study->hash, 'fa-trash', 'btn-danger archive-study', 'Archive'); + break; + } + } + + return implode("\r", $btns); + + $btn = 'Show'; + $btn .= 'Edit'; + $btn .= ' Assign'; + $btn .= ' Delete'; + + return $btn; + } } diff --git a/app/Services/ACL/AccessControl.php b/app/Services/ACL/AccessControl.php index 798fd03..79f3f03 100644 --- a/app/Services/ACL/AccessControl.php +++ b/app/Services/ACL/AccessControl.php @@ -1,43 +1,48 @@ user(); - $columns = [ - 'patient_name', - 'patient_id', - 'study_date', - 'study_time', - 'modality', - 'study_description', - 'accession_number', - 'referring_physician', - 'status', - 'priority', - 'created_at', - 'updated_at', - ]; + $columns = collect([ + WorklistColumn::Priority, + WorklistColumn::ReportStatus, + WorklistColumn::History, + WorklistColumn::Modality, + WorklistColumn::PatientId, + WorklistColumn::PatientName, + WorklistColumn::PatientSexAge, + WorklistColumn::StudyDescription, + WorklistColumn::StudyDate, + WorklistColumn::AssignedPhysician, + WorklistColumn::ReadingPhysician, + WorklistColumn::ReportDate, + WorklistColumn::Series, + WorklistColumn::ReceiveDate, + WorklistColumn::ActionButtons, + ]); + + return $columns; + } + + public static function worklistButtons(?int $user_id = null): Collection + { + $user = $user_id !== null ? User::findOrFail($user_id) : auth()->user(); + $buttons = collect([ + WorklistButton::StudyMetadata, + WorklistButton::History, + WorklistButton::Notes, + WorklistButton::Attachment, + WorklistButton::Assign, + WorklistButton::Report, + ]); + + return $buttons; } } diff --git a/app/Services/ACL/WorklistButton.php b/app/Services/ACL/WorklistButton.php new file mode 100644 index 0000000..b9e9ec7 --- /dev/null +++ b/app/Services/ACL/WorklistButton.php @@ -0,0 +1,13 @@ + + + {{ $text }} +