Files
go-no-go/app/Nova/QuestionResource.php
2026-02-16 16:00:16 +01:00

184 lines
5.1 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Nova;
use Illuminate\Support\Str;
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\DateTime;
use Laravel\Nova\Fields\HasMany;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Number;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Textarea;
use Laravel\Nova\Http\Requests\NovaRequest;
use App\Nova\Actions\DownloadExcel;
final class QuestionResource extends Resource
{
/**
* The model the resource corresponds to.
*
* @var class-string<\App\Models\Question>
*/
public static string $model = \App\Models\Question::class;
/**
* The single value that should be used to represent the resource when being displayed.
*
* @var string
*/
public static $title = 'text';
/**
* The columns that should be searched.
*
* @var array
*/
public static $search = ['id', 'text'];
/**
* Indicates if the resource should be displayed in the sidebar.
*
* @var bool
*/
public static $displayInNavigation = true;
/**
* The group associated with the resource.
*
* @var string
*/
public static $group = 'Questionnaire';
/**
* Get the displayable label of the resource.
*/
public static function label(): string
{
return 'Questions';
}
/**
* Get the displayable singular label of the resource.
*/
public static function singularLabel(): string
{
return 'Question';
}
/**
* Get the fields displayed by the resource.
*
* @return array<int, \Laravel\Nova\Fields\Field|\Laravel\Nova\Panel|\Laravel\Nova\ResourceTool|\Illuminate\Http\Resources\MergeValue>
*/
public function fields(NovaRequest $request): array
{
return [
ID::make()->sortable(),
Text::make('Question', 'text')
->displayUsing(fn ($value) => Str::limit($value, 40))
->onlyOnIndex()
->sortable(),
BelongsTo::make('Question Group', 'questionGroup', QuestionGroupResource::class)
->sortable()
->filterable()
->help('The group this question belongs to. Questions are shown together by group in the questionnaire.'),
Textarea::make('Text')
->rules('required')
->updateRules('required')
->help('The full question text shown to the user in the questionnaire.'),
Boolean::make('Has Yes')
->sortable()
->filterable()
->help('When enabled, a "Yes" answer option is shown for this question.'),
Boolean::make('Has No')
->sortable()
->filterable()
->help('When enabled, a "No" answer option is shown for this question.'),
Boolean::make('Has NA', 'has_na')
->sortable()
->filterable()
->help('When enabled, a "Not Applicable" answer option is shown for this question.'),
Select::make('Details')
->options([
'optional' => 'Optional',
'required' => 'Required',
'req_on_yes' => 'Required on Yes',
'req_on_no' => 'Required on No',
])
->displayUsingLabels()
->nullable()
->sortable()
->filterable()
->help('Controls when the user is asked for additional details. "Required" always asks, "Optional" lets the user choose, "Required on Yes/No" only asks when that answer is selected.'),
Number::make('Sort Order')
->sortable()
->filterable()
->help('Controls the display order within the question group. Lower numbers appear first.'),
Boolean::make('Is Scored')
->sortable()
->filterable()
->help('When enabled, this question counts toward the total score. A "Yes" answer scores 1 point.'),
HasMany::make('Answers', 'answers', AnswerResource::class),
];
}
/**
* Get the cards available for the request.
*
* @return array<int, \Laravel\Nova\Card>
*/
public function cards(NovaRequest $request): array
{
return [];
}
/**
* Get the filters available for the resource.
*
* @return array<int, \Laravel\Nova\Filters\Filter>
*/
public function filters(NovaRequest $request): array
{
return [];
}
/**
* Get the lenses available for the resource.
*
* @return array<int, \Laravel\Nova\Lenses\Lens>
*/
public function lenses(NovaRequest $request): array
{
return [];
}
/**
* Get the actions available for the resource.
*
* @return array<int, \Laravel\Nova\Actions\Action>
*/
public function actions(NovaRequest $request): array
{
return [
new DownloadExcel,
];
}
}