Как передать информацию через кнопку в конструкторе таблиц в конструктор форм? - PullRequest
0 голосов
/ 05 июля 2018

Для упрощения, у меня есть компании и работники, прикрепленные к ним в моем приложении Pyrocms. В компаниях (созданных создателем таблиц в панели администратора автоматически) есть кнопки в каждой из компаний. Кнопка edit - одна из них, поставляемая из коробки. Поэтому я хочу добавить еще одну кнопку, скажем «Добавить работника», и открыть страницу создания работника, которую я успешно выполнил. Между компаниями и работниками существует связь multiple, поскольку работник может работать в нескольких компаниях. Вы можете думать об этом как о категориях любого поста. Я хочу, чтобы на странице формы создания работника я хотел, чтобы компания, чья кнопка «Добавить работника» была нажата , автоматически появлялась в поле «Работающие компании» . Как правильно реализовать эту идею? Я могу передать атрибуты HTML кнопке, используя attributes, но не знаю, поможет ли это.

Это массив $ buttons в CompanyTableBuilder.

/**
 * The table buttons.
 * @var array|string
 */
protected $buttons = [
    'edit',
    'add_worker' => [
        'attributes' => [
            'href' => '/admin/crm/workers/create',
        ],
        'text' => 'Add worker',
        'type' => 'success',
    ]
];

1 Ответ

0 голосов
/ 05 июля 2018

Представим, что у вас есть две группы клиентов: рабочие и плательщики

class ClientTableBuilder extends \Anomaly\UsersModule\User\Table\UserTableBuilder
{

    /**
     * The table model
     *
     * @var string
     */
    protected $model = UserModel::class;

    /**
     * The table views.
     *
     * @var array
     */
    protected $views = [
        'workers' => [
            'query'   => WorkersQuery::class,
            'buttons' => [
                'jobs' => [
                    'type' => 'info',
                ],
            ],
        ],
        'payers'  => [
            'query'   => PayersQuery::class,
            'buttons' => [
                'payments' => [
                    'type' => 'info',
                ],
            ],
        ],
    ];

}

Когда вы нажмете кнопку задания, вы перейдете на маршрут admin/{addon}/clients/jobs/{user_id}. Поэтому вам потребуется следующий контроллер:

class ClientsController extends AdminController
{

    /**
     * Shows the clients list.
     *
     * @param   ClientTableBuilder  $table  The table
     * @return  Response
     */
    public function clients(ClientTableBuilder $table)
    {
        return $table->render();
    }

    /**
     * Shows the client's jobs list.
     *
     * @param   UserRepositoryInterface  $users  The users
     * @param   ClientJobsTableBuilder   $table  The table
     * @param                            $id     The identifier
     * @return  Response
     */
    public function assignedJobs(
        UserRepositoryInterface $users,
        ClientJobsTableBuilder $table,
        $id
    ) {
        /* @var UserInterface $user */
        if (!$user = $users->find($id)) {
            return $this->response->json([
                'success' => false,
                'message' => "Can't find user with id {$id}!",
            ]);
        }

        if ($this->request->ajax()) {
            $table->setAjax(true);
        }

        return $table->setUser($user)->render();
    }

    /**
     * Shows modal with unassigned jobs list
     *
     * @param   UserRepositoryInterface       $users  The users
     * @param   ClientJobsLookupTableBuilder  $table  The table
     * @param                                 $id     The identifier
     * @return  Response
     */
    public function unassignedJobs(
        UserRepositoryInterface $users,
        ClientJobsLookupTableBuilder $table,
        $id
    ) {
        /* @var UserInterface $user */
        if (!$user = $users->find($id)) {
            return $this->response->json([
                'success' => false,
                'message' => "Can't find user with id {$id}!",
            ]);
        }

        return $table->setUser($user)->render();
    }

    /**
     * Attach a job to a client
     *
     * @param   int|str       $user  The user's id
     * @param   int|str       $job   The job's id
     * @return  JsonResponse
     */
    public function attach($user, $job)
    {
        if ($error = $this->dispatch(new AttachJobToUser($user, $job))) {
            return $this->response->json([
                'success' => false,
                'message' => $error,
            ]);
        }

        return $this->response->json([
            'success' => true,
            'user'    => (int) $user,
            'job'     => (int) $job,
        ]);
    }

    /**
     * Detach a job from a client
     *
     * @param   int|str       $user  The user's id
     * @param   int|str       $job   The job's id
     * @return  JsonResponse
     */
    public function detach($user, $job)
    {
        if ($error = $this->dispatch(new DetachJobFromUser($user, $job))) {
            return $this->response->json([
                'success' => false,
                'message' => $error,
            ]);
        }

        return $this->response->json([
            'success' => true,
            'user'    => (int) $user,
            'job'     => (int) $job,
        ]);
    }
}

Тогда значение TB выглядит так:

class ClientJobsTableBuilder extends ValueTableBuilder
{

    /**
     * Table's user
     *
     * @var UserInterface|null
     */
    protected $user = null;

    /**
     * Table's columns
     *
     * @var array
     */
    protected $columns = [
        'name' => [
            'heading' => 'Name',
            'value'   => '<strong>{entry.name}</strong>',
        ],
        'type' => [
            'heading' => 'Type',
        ],
        'categories' => [
            'heading' => 'Categories',
            'value'   => 'entry.type.categories.pluck("name")|join("<br>")',
        ],
    ];

    /**
     * Table's buttons
     *
     * @var string
     */
    protected $buttons = ClientJobsTableButtons::class;

    /**
     * Table's actions
     *
     * @var array
     */
    protected $actions = [];

    /**
     * Table's options
     *
     * @var array
     */
    protected $options = [
        'sortable' => true,
    ];

    /**
     * Table's assets
     *
     * @var array
     */
    protected $assets = [
        'scripts.js' => [
            '{YOUR_MODULE_FULL_NS}::js/detach.js',
        ],
    ];

    /**
     * Gets the user.
     *
     * @return  UserInterface|null  The user.
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Sets the user.
     *
     * @param   UserInterface  $user  The user
     * @return  self
     */
    public function setUser(UserInterface $user)
    {
        $this->user = $user;

        return $this;
    }

}

затем th valuetablebuttons:

class ClientJobsTableButtons
{

    /**
     * Handle the table buttons
     *
     * @param  ClientJobsTableBuilder  $builder  The builder
     */
    public function handle(ClientJobsTableBuilder $builder)
    {
        /* @var UserInterface $user */
        if (!$user = $builder->getUser()) {
            return;
        }

        $builder->setButtons([
            'detach' => [
                'type'         => 'danger',
                'data-detach'  => '{entry.id}',
                'data-user'    => $user->getId(),
                'data-dismiss' => 'multiple',
            ],
        ]);
    }

}

И то же самое дерьмо для поиска ТБ:

class ClientJobsLookupTableBuilder extends TableBuilder
{

    /**
     * AJAX mode flag
     *
     * @var bool
     */
    protected $ajax = true;

    /**
     * Table's user
     *
     * @var UserInterface|null
     */
    protected $user = null;

    /**
     * Table's columns
     *
     * @var array
     */
    protected $columns = [
        'name' => [
            'heading' => 'Name',
            'value'   => '<strong>{entry.name}</strong>',
        ],
        'type' => [
            'heading' => 'Type',
        ],
        'categories' => [
            'heading' => 'Categories',
            'value'   => 'entry.type.categories.pluck("name")|join("<br>")',
        ],
    ];

    /**
     * Table's buttons
     *
     * @var string
     */
    protected $buttons = ClientJobsLookupTableButtons::class;

    /**
     * Table's actions
     *
     * @var array
     */
    protected $actions = [];

    /**
     * Table's options
     *
     * @var array
     */
    protected $options = [
        'sortable' => false,
    ];

    /**
     * Table's assets
     *
     * @var array
     */
    protected $assets = [
        'scripts.js' => [
            '{YOUR_MODULE_FULL_NS}::js/attach.js',
        ],
    ];

    /**
     * Gets the user.
     *
     * @return  UserInterface|null  The user.
     */
    public function getUser()
    {
        return $this->user;
    }

    /**
     * Sets the user.
     *
     * @param   UserInterface  $user  The user
     * @return  self
     */
    public function setUser(UserInterface $user)
    {
        $this->user = $user;

        return $this;
    }

}

И кнопки поиска ТБ:

class ClientJobsLookupTableButtons
{

    /**
     * Handle the table buttons
     *
     * @param  ClientJobsLookupTableBuilder  $builder  The builder
     */
    public function handle(ClientJobsLookupTableBuilder $builder)
    {
        /* @var UserInterface $user */
        if (!$user = $builder->getUser()) {
            return;
        }

        $builder->setButtons([
            'attach' => [
                'data-attach'  => '{entry.id}',
                'data-user'    => $user->getId(),
                'data-dismiss' => 'multiple',
            ],
        ]);
    }

}

После этого вам нужно всего лишь написать JS для правильного поведения.

UPD: это пример * класса запроса:

class WorkersQuery
{

    /**
     * Handle the query.
     *
     * @param  Builder                  $query  The query builder
     * @param  RoleRepositoryInterface  $roles  The roles repository
     */
    public function handle(Builder $query, RoleRepositoryInterface $roles)
    {
        /* @var RoleInterface $role */
        $role = $roles->findBySlug('worker');

        $query
            ->leftJoin(
                'users_users_roles',
                'users_users_roles.entry_id',
                '=',
                'users_users.id'
            )
            ->where('users_users_roles.related_id', $role->getId());
    }

}

И пример команды AttachJobToUser:

class AttachJobToUser
{

    /**
     * User's identifier
     *
     * @var mixed
     */
    protected $user;

    /**
     * Job's identifier
     *
     * @var mixed
     */
    protected $job;

    /**
     * Create a new instance of AttachJobToUser class
     *
     * @param $user
     * @param $job
     */
    public function __construct($user, $job)
    {
        $this->user = $user;
        $this->job  = $job;
    }

    /**
     * Handle the command
     *
     * @param   UserRepositoryInterface  $users  The users
     * @param   JobRepositoryInterface   $jobs   The jobs
     * @return  boolean|string
     */
    public function handle(
        UserRepositoryInterface $users,
        JobRepositoryInterface $jobs
    ) {
        /* @var UserInterface $user */
        if (!$user = $users->find($this->user)) {
            return "Can't find user with id '{$this->user}'";
        }

        /* @var JobInterface $job */
        if (!$job = $jobs->find($this->job)) {
            return "Can't find job with id '{$this->job}'";
        }

        if (!$job->addWorker($user)) {
            return "Can't attach a job with id '{$this->job}' to a worker with id '{$this->user}'";
        }

        return false;
    }

}
...