49 lines
1.2 KiB
PHP
49 lines
1.2 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Prompts;
|
|
|
|
/**
|
|
* Query DTO: a page of prompts with optional search/filter/sort.
|
|
*
|
|
* @readonly
|
|
*/
|
|
final class ListPrompts
|
|
{
|
|
public const SORTABLE_COLUMNS = [
|
|
'created_at',
|
|
'name',
|
|
'usage_count',
|
|
'last_used_at',
|
|
'updated_at',
|
|
];
|
|
|
|
public function __construct(
|
|
public readonly ?string $search = null,
|
|
public readonly ?string $tag = null,
|
|
public readonly bool $favoritesOnly = false,
|
|
public readonly string $sort = 'created_at',
|
|
public readonly string $direction = 'desc',
|
|
) {}
|
|
|
|
/**
|
|
* Sort column, falling back to created_at when not whitelisted.
|
|
*/
|
|
public function normalizedSort(): string
|
|
{
|
|
return in_array($this->sort, self::SORTABLE_COLUMNS, true) ? $this->sort : 'created_at';
|
|
}
|
|
|
|
/**
|
|
* Direction; unknown values fall back to the per-column default
|
|
* (name asc, everything else desc).
|
|
*/
|
|
public function normalizedDirection(): string
|
|
{
|
|
if (in_array($this->direction, ['asc', 'desc'], true)) {
|
|
return $this->direction;
|
|
}
|
|
|
|
return $this->normalizedSort() === 'name' ? 'asc' : 'desc';
|
|
}
|
|
}
|