format(self::DATE_FORMAT); } 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()) ->editColumn('study_description', fn (Study $study) => $study->sanitizedStudyDescription()) ->editColumn('reader', function (Study $study) { if ($study->readingPhysician == null) { return ''; } return Blade::render('staff.worklist.partials._radiologist-listing', [ 'avatar_url' => $study->readingPhysician->avatar(), 'name' => $study->readingPhysician->display_name, 'time' => $study->read_at->diffForHumans(), ] ); }) ->editColumn('assigned_to', function (Study $study) { if ($study->assignedPhysician == null) { return ''; } return Blade::render('staff.worklist.partials._radiologist-listing', [ 'avatar_url' => $study->assignedPhysician->avatar(), 'name' => $study->assignedPhysician->display_name, 'time' => $study->assigned_at->diffForHumans(), ] ); }) ->editColumn('images', function (Study $study) { return $study->numInstances() . '' . human_filesize($study->disk_size) . ''; }) ->editColumn('study_date', function (Study $study) { return self::dtFormat($study->study_date); }) ->editColumn('reported_at', function (Study $study) { return self::dtFormat($study->reported_at); }) ->editColumn('received_at', function (Study $study) { return self::dtFormat($study->received_at); }) ->editColumn('show_study', function (Study $study) { $btn = 'Show'; $btn .= 'Edit'; $btn .= ' Assign'; $btn .= ' Delete'; return $btn; }) ->editColumn('history', function (Study $study) { return sprintf(' ', blank($study->body_part_examined) ? 'text-muted' : 'text-primary'); }) ->orderColumn('patient_name', 'patient_name $1') ->rawColumns(['priority_icon', 'report_status_led', 'images', 'reader', 'assigned_to', 'history', 'show_study']) ->setRowId('id'); } /** * Get the query source of dataTable. */ public function query(Study $model): QueryBuilder { return WorklistFactory::getLister()->query(); // return $model->newQuery(); } /** * Optional method if you want to use the html builder. */ public function html(): HtmlBuilder { return $this->builder() ->setTableId('worklist-table') ->columns($this->getColumns()) ->minifiedAjax() ->searchPanes(SearchPane::make(['show' => true, 'hideCount' => true])) ->parameters( [ // 'dom' => 'Pfrtip', // 'dom' => 'Bfrtip', 'buttons' => [ 'searchPanes', 'excel', // 'csv', // 'pdf', // 'print', // 'reset', // 'reload', ], 'order' => [ [0, 'desc'], [8, 'desc'], ], ]) // ->selectStyleSingle() ->pageLength(15) ->lengthMenu([15, 25, 50, 100, 250]); } /** * Get the dataTable columns definition. */ 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') ->searchable(false) ->orderable(false) ->addClass('text-center') ->width('20px') ->title(''), Column::make('report_status_led') ->searchable(false) ->orderable(false) ->addClass('text-center') ->width('20px') ->title(''), Column::make('history') ->searchable(false) ->orderable(false) ->addClass('text-center') ->width('20px') ->title(''), Column::make('modality')->title('Mo'), Column::make('patient_id')->title('MRN'), Column::make('patient_name')->title('Patient'), Column::make('sex_age') ->searchable(false) ->orderable(false) ->addClass('text-center') ->title('Age'), Column::make('study_description') ->title('Study'), Column::make('show_study') ->searchable(false) ->orderable(false) ->addClass('text-center') ->width('20px') ->title(''), Column::make('study_date')->searchable(false)->title('Scan Dt'), Column::make('assigned_to') ->searchable(false) ->title('Assigned'), Column::make('reader') ->searchable(false) ->title('Read by'), Column::make('reported_at')->searchable(false)->title('Read At'), // Column::make('body_part_examined'), Column::make('images') ->searchable(false) ->orderable(false) ->addClass('text-center') ->title('Images'), Column::make('received_at')->searchable(false)->title('Received'), // Column::make('xxx'), Column::computed('action') ->exportable(false) ->printable(false) ->width(60) ->addClass('text-center'), ]; } /** * Get the filename for export. */ protected function filename(): string { $parts = [ config('app.name'), 'worklist', date('YmdHi'), ]; 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; } }