Skip to content

Instantly share code, notes, and snippets.

@codebykyle
Last active July 14, 2019 09:22
Show Gist options
  • Save codebykyle/1bba6ab1666e56cef6b8748af68d5831 to your computer and use it in GitHub Desktop.
Save codebykyle/1bba6ab1666e56cef6b8748af68d5831 to your computer and use it in GitHub Desktop.
Breaking up nova field definitions
<?php
namespace App\Nova;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\Heading;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Resource as NovaResource;
use Laravel\Nova\Http\Requests\NovaRequest;
abstract class Resource extends NovaResource
{
/**
* Build an "index" query for the given resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function indexQuery(NovaRequest $request, $query)
{
return $query;
}
/**
* Build a Scout search query for the given resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Laravel\Scout\Builder $query
* @return \Laravel\Scout\Builder
*/
public static function scoutQuery(NovaRequest $request, $query)
{
return $query;
}
/**
* Build a "detail" query for the given resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function detailQuery(NovaRequest $request, $query)
{
return parent::detailQuery($request, $query);
}
/**
* Build a "relatable" query for the given resource.
*
* This query determines which instances of the model may be attached to other resources.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public static function relatableQuery(NovaRequest $request, $query)
{
return parent::relatableQuery($request, $query);
}
/**
* Get the fields displayed by the resource.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function fields(Request $request)
{
return $this->processAllFields($request);
}
/**
* Get system fields for this resource
*
* @param Request $request
* @return array
*/
public function fieldsSystem(Request $request) {
return [
Heading::make('System Information')->onlyOnDetail(),
ID::make()->onlyOnDetail(),
];
}
/**
* Manually controlled fields for this resource
*
* @param Request $request
* @return array
*/
public function defaultFields(Request $request) {
return [];
}
/**
* Fields which are available on the create and edit form by default
* This can be overwrote by using fieldsCreate and fieldsUpdate if you want
* to control specific forms
*
* @param Request $request
* @return array
*/
public function fieldsForm(Request $request) {
return [];
}
/**
* Fields available on the default index view
*
* @param Request $request
* @return array
*/
public function fieldsIndex(Request $request) {
return [];
}
/**
* Fields to display when viewing the resource
*
* @param Request $request
* @return array
*/
public function fieldsDisplay(Request $request) {
return [];
}
/**
* Fields which are available on the create page for this resource
* Defaults to fieldsForm
*
* @param Request $request
* @return array
*/
public function fieldsCreate(Request $request) {
return $this->fieldsForm($request);
}
/**
* Fields which are available on the update page for this resource
* Defaults to fieldsForm
*
* @param Request $request
* @return array
*/
public function fieldsUpdate(Request $request) {
return $this->fieldsForm($request);
}
/**
* Merge and process the available field functions
*
* @param Request $request
* @return array
*/
protected function processAllFields(Request $request) {
return array_merge(
$this->processSystemFields($request),
$this->processIndexFields($request),
$this->processCreateFields($request),
$this->processUpdateFields($request),
$this->processDisplayFields($request),
$this->processDefaultFields($request)
);
}
/**
* Process the index fields visibility
*
* @param Request $request
* @return array
*/
protected function processIndexFields(Request $request) {
return collect($this->fieldsIndex($request))->map(function ($field) {
if(method_exists($field, 'onlyOnIndex')) {
return $field->onlyOnIndex();
}
return $field;
})->toArray();
}
/**
* Process the display fields visibility
*
* @param Request $request
* @return array
*/
protected function processDisplayFields(Request $request) {
return collect($this->fieldsDisplay($request))->map(function ($field) {
if(method_exists($field, 'onlyOnDetail')) {
return $field->onlyOnDetail();
}
return $field;
})->toArray();
}
/**
* Process the create fields visibility
*
* @param Request $request
* @return array
*/
protected function processCreateFields(Request $request) {
return collect($this->fieldsCreate($request))->map(function ($field) {
if(method_exists($field, 'onlyOnForms')) {
return $field->onlyOnForms()->hideWhenUpdating();
}
return $field;
})->toArray();
}
/**
* Process the update fields visibility
*
* @param Request $request
* @return array
*/
protected function processUpdateFields(Request $request) {
return collect($this->fieldsUpdate($request))->map(function ($field) {
if(method_exists($field, 'onlyOnForms')) {
return $field->onlyOnForms()->hideWhenCreating();
}
return $field;
})->toArray();
}
/**
* Process manually controlled default fields
*
* @param Request $request
* @return array
*/
protected function processDefaultFields(Request $request) {
return $this->defaultFields($request);
}
/**
* Process system fields
*
* @param Request $request
* @return array
*/
protected function processSystemFields(Request $request) {
return $this->fieldsSystem($request);
}
}
@codebykyle
Copy link
Author

codebykyle commented Jul 14, 2019

Example usage:


    public function fieldsIndex(Request $request)
    {
        return array_merge(parent::fieldsIndex($request), [
            Text::make('Account Name','account_name'),
            BelongsTo::make('Account Type', 'accountType'),
            BelongsTo::make('User', 'user'),
            BelongsTo::make('Company', 'company'),
            BelongsTo::make('Currency', 'currency'),
            Select::make('Account Status', 'account_status')
        ]);
    }

@codebykyle
Copy link
Author

Complete example:

<?php

namespace App\Nova\Resources;

use App\Nova\Resource;

use CodeByKyle\Tabs\Tabs;
use Inspheric\NovaDefaultable\HasDefaultableFields;
use Laravel\Nova\Fields\Date;
use Laravel\Nova\Fields\Heading;
use Laravel\Nova\Fields\ID;
use Illuminate\Http\Request;
use Laravel\Nova\Fields\Markdown;
use Laravel\Nova\Fields\PasswordConfirmation;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Gravatar;
use Laravel\Nova\Fields\Password;
use Laravel\Nova\Panel;
use Laravel\Nova\Fields\HasMany;

class User extends Resource
{
    use HasDefaultableFields;

    /**
     * The model the resource corresponds to.
     *
     * @var string
     */
    public static $model = 'App\\User';

    /**
     * The logical group associated with the resource.
     *
     * @var string
     */
    public static $group = 'Users';

    /**
     * The single value that should be used to represent the resource when being displayed.
     *
     * @var string
     */
    public static $title = 'full_name';

    /**
     * Get the displayable label of the resource.
     *
     * @return string
     */
    public static function label()
    {
        return "User";
    }

    /**
     * The columns that should be searched.
     *
     * @var array
     */
    public static $search = [
        'email',
        'first_name',
        'last_name',
    ];

    private $USER_STATUS_OPTIONS = [
        'Active' => 'Active',
        'Archived' => 'Archived'
    ];

    private $PORTAL_ACCESS_OPTIONS = [
        'Allow' => 'Allow',
        'NotAllow' => 'Not Allowed'
    ];

    /**
     * Fields available on the default index view
     *
     * @param Request $request
     * @return array
     */
    public function fieldsIndex(Request $request) {
        return array_merge(parent::fieldsIndex($request), [
            Gravatar::make(),

            Text::make('Full Name', 'full_name'),
            Text::make('Email', 'email')->sortable(),

            Select::make('Status', 'user_status')
                ->options($this->USER_STATUS_OPTIONS)
                ->displayUsingLabels()
                ->sortable(),

            Select::make('Portal Access', 'portal_access')
                ->options($this->PORTAL_ACCESS_OPTIONS)
                ->displayUsingLabels()
                ->sortable(),

            Date::make('Created At', 'created_at')->sortable(),
            Date::make('Updated At', 'updated_at')->sortable(),
        ]);
    }

    /**
     * Fields to display when viewing the resource
     *
     * @param Request $request
     * @return array
     */
    public function fieldsDisplay(Request $request) {
        return array_merge(parent::fieldsDisplay($request), [
            Heading::make('Login Information'),
            Text::make('Email', 'email'),

            Heading::make('User Information'),
            Text::make('Full Name', 'full_name'),
            Text::make('First Name', 'first_name'),
            Text::make('Last Name', 'last_name'),

            Heading::make('User Photo'),
            Gravatar::make(),

            Heading::make('Contact Details'),
            Text::make('Phone Number', 'phone_number'),
            Text::make('Website', 'website'),

            Heading::make('User Access And Status'),

            Select::make('Status', 'user_status')
                ->options($this->USER_STATUS_OPTIONS)
                ->displayUsingLabels(),

            Select::make('Portal Access', 'portal_access')
                ->options($this->PORTAL_ACCESS_OPTIONS)
                ->displayUsingLabels(),

            Heading::make('User Description'),
            Markdown::make('Description', 'description'),

            Heading::make('Internal Details'),
            Text::make('Department', 'department'),
            Text::make('Job Title', 'job_title'),
            Text::make('Assistant Name', 'assistant_name'),

            Heading::make('Address'),
            Text::make('Address 1', 'address_1'),
            Text::make('Address 2', 'address_2'),
            Text::make('State', 'state'),
            Text::make('Zip', 'zip'),
            Text::make('Country', 'country'),

            Heading::make('Important Dates'),
            Date::make('Birthday', 'birthday'),
            Date::make('Anniversary', 'anniversary'),

            Heading::make('Date Information')->onlyOnDetail(),
            Date::make('Email Verified At', 'email_verified_at'),
            Date::make('Created At', 'created_at'),
            Date::make('Updated At', 'updated_at'),

            (new Tabs('Accounts', [
                HasMany::make('Owned Accounts', 'accounts', Account::class),
                HasMany::make('Shared Accounts', 'sharedAccounts', Account::class),
            ])),

            (new Tabs('Transactions', [
                HasMany::make('Transactions', 'accountTransfers', AccountTransaction::class),
                HasMany::make('Transfers', 'accountTransfers', AccountTransferRule::class),
            ])),

            (new Tabs('Expenses', [
                HasMany::make('Subscriptions', 'subscriptions', AccountSubscription::class),
                HasMany::make('Receipts', 'receipts', Receipt::class)
            ])),

            (new Tabs('Budgets', [
                HasMany::make('Tags', 'tags', Tag::class),
            ])),

            (new Tabs('People', [
                HasMany::make('Companies', 'companies', Company::class),
                HasMany::make('Contacts', 'contacts', Contact::class),
            ])),

            (new Tabs('Purchased Assets', [
                HasMany::make('Purchased Equipment', 'purchasedEquipment', Equipment::class),
                HasMany::make('Purchased Software Licenses', 'purchasedSoftwareLicenses', SoftwareLicenseNumber::class),
            ])),

            (new Tabs('Assigned Assets', [
                HasMany::make('Assigned Equipment', 'assignedEquipment', Equipment::class),
                HasMany::make('Assigned Software Licenses', 'assignedSoftwareLicenses', SoftwareLicenseNumber::class),
            ])),

            (new Tabs('Files', [
                HasMany::make('Attachments', 'attachments', Attachment::class),
                HasMany::make('Transaction Imports', 'transactionImports', AccountTransactionImport::class),
            ])),

            (new Tabs('Rules', [
                HasMany::make('Tag Rules', 'tagRules', TagRule::class),
                HasMany::make('Transfer Rules', 'transferRules', AccountTransferRule::class),
            ])),


            (new Tabs('Maintenance', [
                HasMany::make('Equipment Service Requests', 'equipmentServiceRequests', EquipmentServiceRequest::class),
            ])),

            (new Tabs('Metrics', [
                HasMany::make('User Metrics', 'metrics', UserMetric::class),
            ])),

            (new Tabs('Settings', [
                HasMany::make('Company Types', 'companyTypes', CompanyType::class),
                HasMany::make('Account Types', 'accountTypes', AccountType::class),
                HasMany::make('Equipment Service Request Types', 'equipmentServiceRequestTypes', EquipmentServiceRequestType::class),
            ])),
        ]);
    }

    /**
     * Fields which are available on the create and edit form by default
     * This can be overwrote by using fieldsCreate and fieldsUpdate if you want
     * to control specific forms
     *
     * @param Request $request
     * @return array
     */
    public function fieldsForm(Request $request) {
        return array_merge(parent::fieldsForm($request), [
            Heading::make('Login Information'),

            Text::make('Email', 'email')
                ->rules('required', 'email', 'max:255')
                ->creationRules('unique:users,email')
                ->updateRules('unique:users,email,{{resourceId}}')
                ->sortable(),

            Password::make('Password', 'password')
                ->creationRules('required', 'string', 'min:6')
                ->updateRules('nullable', 'string', 'min:6')
                ->onlyOnForms(),

            PasswordConfirmation::make('Confirm Password', 'confirm_password'),

            Heading::make('User Information'),
            Text::make('First Name', 'first_name'),
            Text::make('Last Name', 'last_name'),

            Heading::make('Contact Details'),
            Text::make('Phone Number', 'phone_number')->nullable(),
            Text::make('Website', 'website')->nullable(),

            Heading::make('User Access And Status'),

            Select::make('Status', 'user_status')
                ->options($this->USER_STATUS_OPTIONS)
                ->displayUsingLabels()
                ->default('Active'),

            Select::make('Portal Access', 'portal_access')
                ->options($this->PORTAL_ACCESS_OPTIONS)
                ->displayUsingLabels()
                ->default('Active'),

            Heading::make('User Description')->nullable(),
            Markdown::make('Description', 'description')->nullable(),

            Heading::make('Internal Details'),
            Text::make('Department', 'department')->nullable(),
            Text::make('Job Title', 'job_title')->nullable(),
            Text::make('Assistant Name', 'assistant_name')->nullable(),

            Heading::make('Address'),
            Text::make('Address 1', 'address_1')->nullable(),
            Text::make('Address 2', 'address_2')->nullable(),
            Text::make('State', 'state')->nullable(),
            Text::make('Zip', 'zip')->nullable(),
            Text::make('Country', 'country')->nullable(),

            Heading::make('Important Dates'),
            Date::make('Birthday', 'birthday')->nullable(),
            Date::make('Anniversary', 'anniversary')->nullable()
        ]);
    }

    /**
     * Get the cards available for the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function cards(Request $request)
    {
        return [];
    }

    /**
     * Get the filters available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function filters(Request $request)
    {
        return [];
    }

    /**
     * Get the lenses available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function lenses(Request $request)
    {
        return [];
    }

    /**
     * Get the actions available for the resource.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function actions(Request $request)
    {
        return [];
    }

    protected function systemFields() {
        return [
            ID::make()
        ];
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment