Skip to content

Commit

Permalink
Refactor to use data-hub-foundation [WEB-2982]
Browse files Browse the repository at this point in the history
  • Loading branch information
zachgarwood committed Jan 17, 2025
1 parent 9fea028 commit a49a2d3
Show file tree
Hide file tree
Showing 58 changed files with 436 additions and 4,639 deletions.
2 changes: 1 addition & 1 deletion app/Helpers/CollectionHelpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ class CollectionHelpers
*/
public static function collectApi($value = null)
{
return new \App\Libraries\Api\Models\ApiCollection($value);
return new \Aic\Hub\Foundation\Library\Api\Models\ApiCollection($value);
}
}
278 changes: 266 additions & 12 deletions app/Http/Controllers/Twill/BaseApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,52 @@

namespace App\Http\Controllers\Twill;

use A17\Twill\Facades\TwillPermissions;
use A17\Twill\Models\Contracts\TwillModelContract;
use A17\Twill\Services\Forms\Fields\Input;
use A17\Twill\Services\Forms\Fieldset;
use A17\Twill\Services\Forms\Form;
use A17\Twill\Services\Listings\Columns\Boolean;
use A17\Twill\Services\Listings\Columns\FeaturedStatus;
use A17\Twill\Services\Listings\Columns\Languages;
use A17\Twill\Services\Listings\Columns\PublishStatus;
use A17\Twill\Services\Listings\Columns\ScheduledStatus;
use A17\Twill\Services\Listings\Columns\Text;
use A17\Twill\Services\Listings\Filters\BasicFilter;
use A17\Twill\Services\Listings\Filters\QuickFilter;
use A17\Twill\Services\Listings\TableColumns;
use Aic\Hub\Foundation\Library\Api\Controllers\Columns\ApiImage;
use Aic\Hub\Foundation\Library\Api\Filters\Search;
use App\Helpers\UrlHelpers;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;

class BaseApiController extends \App\Http\Controllers\Twill\ModuleController
class BaseApiController extends ModuleController
{
/**
* Option to setup links and the possibility of augmenting a model
*/
protected $hasAugmentedModel = false;

/**
* The prefix for the label of the Datahub Id column.
*/
protected string $idColumnLabelPrefix = 'Datahub';

protected $localElements = [];

protected $defaultFilters = [
'search' => 'search',
];
protected function setUpController(): void
{
$this->disableBulkDelete();
$this->disableBulkEdit();
$this->disableBulkPublish();
$this->disableCreate();
$this->disableDelete();
$this->disableEdit();
$this->disablePermalink();
$this->disablePublish();
$this->disableRestore();
}

public function getIndexTableMainFilters($items, $scopes = [])
{
Expand Down Expand Up @@ -54,6 +86,17 @@ public function augment($datahubId)
return $this->redirectToForm($item->id);
}

public function feature()
{
if (($id = $this->request->get('id'))) {
if ($apiModel = $this->getApiRepository()->getById($id)) {
$augmentedModel = $this->getRepository()->firstOrCreate(['datahub_id' => $apiModel->id]);
$this->request->merge(['id' => $augmentedModel->id]);
}
}
return parent::feature();
}

protected function getRepository(): \A17\Twill\Repositories\ModuleRepository
{
if ($this->hasAugmentedModel) {
Expand All @@ -63,7 +106,12 @@ protected function getRepository(): \A17\Twill\Repositories\ModuleRepository
return $this->getApiRepository();
}

protected function getBrowserTableData(\Illuminate\Support\Collection|\Illuminate\Pagination\LengthAwarePaginator $items, bool $forRepeater = false): array
protected function getApiRepository()
{
return $this->app->make("{$this->namespace}\Repositories\\Api\\" . $this->modelName . 'Repository');
}

protected function getBrowserTableData(Collection|LengthAwarePaginator $items, bool $forRepeater = false): array
{
// Ensure data is an array and not an object to avoid json_encode wrong conversion
$results = array_values(parent::getBrowserTableData($items));
Expand All @@ -80,28 +128,221 @@ protected function getBrowserTableData(\Illuminate\Support\Collection|\Illuminat
return $results;
}

protected function getApiRepository()
public function getIndexItems(array $scopes = [], bool $forcePagination = false): Collection|LengthAwarePaginator
{
return $this->app->make("{$this->namespace}\Repositories\\Api\\" . $this->modelName . 'Repository');
if (TwillPermissions::enabled() && TwillPermissions::getPermissionModule($this->moduleName)) {
$scopes += ['accessible' => true];
}

$requestFilters = $this->getRequestFilters();
$appliedFilters = [];
$this->applyQuickFilters($requestFilters, $appliedFilters);
$this->applyBasicFilters($requestFilters, $appliedFilters);
return $this->transformIndexItems(
$this->getApiData($scopes, $forcePagination, $appliedFilters)
);
}

protected function getIndexItems($scopes = [], $forcePagination = false)
/**
* Get the applied quick filter.
*/
protected function applyQuickFilters(array &$requestFilters, array &$appliedFilters): void
{
if (array_key_exists('status', $requestFilters)) {
$filter = $this->quickFilters()->filter(
fn (QuickFilter $filter) => $filter->getQueryString() === $requestFilters['status']
)->first();

if ($filter !== null) {
$appliedFilters[] = $filter;
}
}
unset($requestFilters['status']);
}

/**
* Get other filters that need to applied. Use the API search filter when
* requested.
*/
protected function applyBasicFilters(array &$requestFilters, array &$appliedFilters): void
{
$perPage = request('offset') ?? $this->perPage ?? 50;
$items = $this->getApiRepository()->get($this->indexWith, $scopes, $this->orderScope(), $perPage, $forcePagination);
foreach ($requestFilters as $filterKey => $filterValue) {
$filter = $this->filters()->filter(
fn (BasicFilter $filter) => $filter->getQueryString() === $filterKey
)->first();

if ($filter !== null) {
$appliedFilters[] = $filter->withFilterValue($filterValue);
} elseif ($filterKey === 'search') {
$appliedFilters[] = Search::make()
->searchFor($filterValue)
->searchColumns($this->searchColumns);
}
}
}

public function getApiData($scopes = [], $forcePagination = false, $appliedFilters = [])
{
return $this->getApiRepository()->get(
with: $this->indexWith,
scopes: $scopes,
orders: $this->orderScope(),
perPage: $this->request->get('offset') ?? $this->perPage,
forcePagination: $forcePagination,
appliedFilters: $appliedFilters
);
}

protected function getIndexTableColumns(): TableColumns
{
$columns = TableColumns::make();

if ($this->getIndexOption('publish')) {
$columns->add(
PublishStatus::make()
->title(twillTrans('twill::lang.listing.columns.published'))
->sortable()
->optional()
);
}

if ($this->getIndexOption('showImage')) {
$columns->add(
ApiImage::make()
->field('thumbnail')
->title(twillTrans('Image'))
);
}

if ($this->getIndexOption('feature') && $this->repository->isFillable('featured')) {
$columns->add(
FeaturedStatus::make()
->title(twillTrans('twill::lang.listing.columns.featured'))
);
}

if ($this->hasAugmentedModel) {
$columns->add(
Boolean::make()
->field('is_augmented')
->optional()
->hide()
);
$columns->add(
Text::make()
->field('id')
->title($this->idColumnLabelPrefix . ' Id')
->optional()
->hide()
);
$columns->add(
Text::make()
->field('source_updated_at')
->optional()
->hide()
);
}

$title = $this->titleColumnKey === 'title' && $this->titleColumnLabel === 'Title'
? twillTrans('twill::lang.main.title')
: $this->titleColumnLabel;
$columns->add(
Text::make()
->field($this->titleColumnKey)
->title($title)
->sortable()
->linkCell(function (TwillModelContract $model) {
if ($model->is_augmented) {
$action = 'edit';
$id = $model->getAugmentedModel()->id;
} else {
$action = 'augment';
$id = $model->id;
}
return moduleRoute($this->moduleName, $this->routePrefix, $action, [$id]);
})
);

$columns = $columns->merge($this->additionalIndexTableColumns());

if ($this->getIndexOption('includeScheduledInList') && $this->repository->isFillable('publish_start_date')) {
$columns->add(
ScheduledStatus::make()
->title(twillTrans('twill::lang.publisher.scheduled'))
->optional()
);
}

if ($this->moduleHas('translations') && count(getLocales()) > 1) {
$columns->add(
Languages::make()
->title(twillTrans('twill::lang.listing.languages'))
->optional()
);
}

return $columns;
}

protected function getBrowserTableColumns(): TableColumns
{
$columns = TableColumns::make();

if ($this->moduleHas('medias')) {
$columns->add(
ApiImage::make()
->field('thumbnail')
->rounded()
->title(twillTrans('Image'))
);
}

$columns = $columns->merge($this->additionalBrowserTableColumns());

return $columns;
}

public function getSideFieldSets(TwillModelContract $model): Form
{
return parent::getSideFieldSets($model)
// For some reason, the side form will not render unless there is a
// field in the default Content fieldset. 🤷
->add(
Input::make()
->name('id')
->disabled()
->note('readonly')
)
->addFieldset(
Fieldset::make()
->id('datahub')
->title('Datahub')
->closed()
->fields([
Input::make()
->name('datahub_id')
->disabled()
->note('readonly'),
Input::make()
->name('source_updated_at')
->disabled()
->note('readonly'),
])
);
}

protected function transformIndexItems(Collection|LengthAwarePaginator $items): Collection|LengthAwarePaginator
{
if ($this->hasAugmentedModel) {
$ids = $items->pluck('id')->toArray();
$this->localElements = $this->repository->whereIn('datahub_id', $ids)->get();
$items->setCollection($items->getCollection()->map(function ($item) {
if ($element = collect($this->localElements)->where('datahub_id', $item->id)->first()) {
$item->setAugmentedModel($element);
}

return $item;
}));
}

return $items;
}

Expand All @@ -127,4 +368,17 @@ protected function indexItemData($item)

return ['edit' => $editRoute];
}

/**
* Option to setup links and the possibility of augmenting a model
*/
protected function enableAugmentedModel(): void
{
$this->hasAugmentedModel = true;
}

protected function setIdColumnLabelPrefix(string $idColumnLabelPrefix): void
{
$this->idColumnLabelPrefix = $idColumnLabelPrefix;
}
}
23 changes: 23 additions & 0 deletions app/Http/Controllers/Twill/BaseController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Http\Controllers\Twill;

use A17\Twill\Models\Contracts\TwillModelContract;

class BaseController extends ModuleController
{
protected function setUpController(): void
{
$this->disablePermalink();
$this->enableSkipCreateModal();
}

public function edit(TwillModelContract|int $id): mixed
{
return parent::edit($id)->with([
'editableTitle' =>
$this->repository->isFillable($this->titleColumnKey)
|| $this->repository->isTranslatable($this->titleColumnKey),
]);
}
}
Loading

0 comments on commit a49a2d3

Please sign in to comment.