$dt->format(self::DATE_FORMAT_SHORT),
'subtitle' => $dt->diffForHumans(),
]
);
}
public function dataTable(QueryBuilder $query): EloquentDataTable
{
$data_table = new EloquentDataTable($query);
$rawColumns = [
'priority_icon',
'report_status_led',
];
foreach ($this->renderCustomColumns() as $column => $content) {
$data_table->addColumn($column, $content);
$rawColumns[] = $column;
}
$data_table
->orderColumn(WorklistColumn::PatientName->value, sprintf('%s $1', WorklistColumn::PatientName->value))
->rawColumns($rawColumns)
->setRowId('id');
return $data_table;
}
/**
* 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
{
$columns = [];
foreach (WorklistGuard::worklistColumns() as $col) {
switch ($col) {
case WorklistColumn::Priority:
$columns[] = Column::make($col->value)
->searchable(false)
->hidden();
$columns[] = Column::make('priority_icon')
->searchable(false)
->orderable(false)
->addClass('text-center p-0 ps-1')
->width('18px')
->title('');
break;
case WorklistColumn::ReportStatus:
$columns[] = Column::make($col->value)
->searchable(false)
->hidden();
$columns[] = Column::make('report_status_led')
->searchable(false)
->orderable(false)
->addClass('text-center p-0 ps-2')
->width('18px')
->title('');
break;
case WorklistColumn::History:
$columns[] = Column::make($col->value)
->searchable(false)
->orderable(false)
->addClass('text-center')
->width('16px')
->title('');
break;
case WorklistColumn::PatientSexAge:
$columns[] = Column::make($col->value)
->searchable(false)
->orderable(false)
->addClass('text-center')
->title('Age');
break;
case WorklistColumn::StudyDate:
$columns[] = Column::make($col->value)->searchable(false)->title('Scanned');
break;
case WorklistColumn::ReceiveDate:
$columns[] = Column::make($col->value)->searchable(false)->title('Received');
break;
case WorklistColumn::ReportDate:
$columns[] = Column::make($col->value)->searchable(false)->title('Read At');
break;
case WorklistColumn::AssignedPhysician:
$columns[] = Column::make($col->value)
->searchable(false)
->title('Rad');
break;
case WorklistColumn::ReadingPhysician:
$columns[] = Column::make($col->value)
->searchable(false)
->title('Read By');
break;
case WorklistColumn::ActionButtons:
case WorklistColumn::ViewerButtons:
case WorklistColumn::ReportButtons:
$columns[] = Column::computed($col->value)
->searchable(false)
->orderable(false)
->exportable(false)
->printable(false)
// ->width(60)
->addClass('p-0 ps-2')
->title('');
break;
case WorklistColumn::PatientId:
$columns[] = Column::make($col->value)->title('ID');
break;
case WorklistColumn::PatientName:
$columns[] = Column::make($col->value)->title('Patient');
break;
case WorklistColumn::StudyDescription:
$columns[] = Column::make($col->value)->title('Study');
break;
default:
// dd(Str::slug($col->value, '-'));
$columns[] = Column::make($col->value)->title($this->columTitle($col->value));
break;
}
}
return $columns;
}
/**
* Get the filename for export.
*/
protected function filename(): string
{
$parts = [
config('app.name'),
'worklist',
date('YmdHi'),
];
return Str::slug(implode(' ', $parts), '_');
}
private function columTitle(string $str): string
{
return Str::of($str)->slug()->replace('-', ' ')->title()->toString();
}
private function physicianColumn(Study $study): ?string
{
$user = $study->readingPhysician;
if ($user === null) {
if ($study->assigned_at !== null) {
return '
';
}
return null;
}
$dt = $study->read_at;
return Blade::render('staff.worklist.partials._radiologist-listing',
[
'avatar_url' => $user->avatar(),
'name' => $user->display_name,
'time' => $dt?->format(self::DATE_FORMAT_SHORT) ?? '~',
'human_time' => $dt?->diffForHumans() ?? '',
]
);
}
/**
* @return array
*/
private function renderCustomColumns(): array
{
$columns = [];
foreach (WorklistGuard::worklistColumns() as $col) {
switch ($col) {
case WorklistColumn::PatientName:
$columns[$col->value] = static function (Study $study) {
if (me()->isRadiologist() || ! $study->canEditMetadata()) {
return $study->sanitizedPatientName();
}
return '' . $study->sanitizedPatientName() . '';
};
break;
case WorklistColumn::StudyDescription:
$columns[$col->value] = static fn (Study $study) => $study->sanitizedStudyDescription();
break;
case WorklistColumn::AssignedPhysician:
$columns[$col->value] = static function (Study $study) {
if ($study->assigned_at !== null) {
return '
';
}
return null;
};
break;
case WorklistColumn::ReadingPhysician:
$columns[$col->value] = fn (Study $study) => $this->physicianColumn($study);
break;
case WorklistColumn::Series:
$columns[$col->value] = fn (Study $study) => Blade::render(
'staff.worklist.partials._multi-value-cell',
[
'title' => $study->numInstances(),
'subtitle' => 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) => self::renderDateColumn($study->{$col->value});
break;
case WorklistColumn::History:
$columns[$col->value] = fn (Study $study) => sprintf('
',
$study->hash,
($study->body_part_examined) ? 'text-muted' : 'text-primary');
break;
case WorklistColumn::ActionButtons:
$columns[$col->value] = fn (Study $study) => $this->generateActionButtons($study);
break;
case WorklistColumn::ViewerButtons:
$columns[$col->value] = fn (Study $study) => $this->generateViewerButtons($study);
break;
case WorklistColumn::ReportButtons:
$columns[$col->value] = fn (Study $study) => $this->generateReportingButtons($study);
break;
}
}
return $columns;
}
private function generateReportingButtons(Study $study): string
{
if (me()->isRadiologist() && $study->canEditReport() && ! $study->hasReports()) {
// fresh untouched study, can edit report: take the rad directly to the edit page
return '';
}
return $this->renderButton($study->hash, 'fa-eye', 'show-reports btn-outline', 'R');
}
private function renderButton(string $data_id, string $fa_icon, string $data_class, string $text, string $url = '#', bool $blank = false): 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,
'blank' => $blank,
]
);
}
private function renderImageLink(string $data_id, string $img_src, string $data_class, string $text, string $url = '#', bool $blank = false, int $width = 18): string
{
return Blade::render('staff.worklist.partials._image-link',
[
'data_id' => $data_id,
'url' => $url,
'img_src' => asset('imgs/' . $img_src),
'data_class' => $data_class,
'text' => $text,
'blank' => $blank,
'width' => $width,
]
);
}
private function generateViewerButtons(Study $study): string
{
$btns = [];
$btns[] = $this->renderButton($study->hash, 'fa-eye', 'btn-outline', '', route('viewer.ohif', $study->hash), true);
$btns[] = Blade::render('staff.worklist.partials._dropdown-menu',
[
'items' => [
[
'url' => route('viewer.stone', $study->hash),
'text' => 'Stone',
'blank' => true,
'icon' => 'fa-circle-info',
],
],
]
);
return implode("\r", $btns);
}
private function generateActionButtons(Study $study): string
{
$btns = [];
foreach (WorklistGuard::worklistButtons($study) as $button) {
switch ($button) {
case WorklistButton::StudyMetadata:
$btns[] = $this->renderImageLink($study->hash, 'info.png', 'showStudy', 'Info');
break;
case WorklistButton::Assign:
$btns[] = $this->renderImageLink($study->hash, 'doctor.png', 'show-assign', 'Assign');
break;
case WorklistButton::Notes:
$btns[] = $this->renderImageLink($study->hash, 'chat.png', 'show-notes', 'Chat');
break;
}
}
return implode("\r", $btns);
}
}