new: [instance:search_all] Early work on search all feature
parent
91db0afd9a
commit
b3c25f0cae
|
@ -14,12 +14,16 @@ use Cake\Error\Debugger;
|
||||||
|
|
||||||
class AuthKeysController extends AppController
|
class AuthKeysController extends AppController
|
||||||
{
|
{
|
||||||
|
public $filterFields = ['Users.username', 'authkey', 'comment', 'Users.id'];
|
||||||
|
public $quickFilterFields = ['authkey', ['comment' => true]];
|
||||||
|
public $containFields = ['Users'];
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'filters' => ['Users.username', 'authkey', 'comment', 'Users.id'],
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => ['authkey', 'comment'],
|
'quickFilters' => $this->quickFilterFields,
|
||||||
'contain' => ['Users'],
|
'contain' => $this->containFields,
|
||||||
'exclude_fields' => ['authkey']
|
'exclude_fields' => ['authkey']
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
|
|
|
@ -10,17 +10,21 @@ use Cake\ORM\TableRegistry;
|
||||||
|
|
||||||
class BroodsController extends AppController
|
class BroodsController extends AppController
|
||||||
{
|
{
|
||||||
|
public $filterFields = ['Broods.name', 'Broods.uuid', 'Broods.url', 'Broods.description', 'Organisations.id', 'Broods.trusted', 'pull', 'authkey'];
|
||||||
|
public $quickFilterFields = [['Broods.name' => true], 'Broods.uuid', ['Broods.description' => true]];
|
||||||
|
public $containFields = ['Organisations'];
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'filters' => ['Broods.name', 'Broods.uuid', 'Broods.url', 'Broods.description', 'Organisations.id', 'Broods.trusted', 'pull', 'authkey'],
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => [['Broods.name' => true], 'Broods.uuid', ['Broods.description' => true]],
|
'quickFilters' => $this->quickFilterFields,
|
||||||
'contextFilters' => [
|
'contextFilters' => [
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'pull',
|
'pull',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'contain' => ['Organisations']
|
'contain' => $this->containFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -494,7 +494,7 @@ class CRUDComponent extends Component
|
||||||
return $massagedFilters;
|
return $massagedFilters;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function setQuickFilters(array $params, \Cake\ORM\Query $query, array $quickFilterFields): \Cake\ORM\Query
|
public function setQuickFilters(array $params, \Cake\ORM\Query $query, array $quickFilterFields): \Cake\ORM\Query
|
||||||
{
|
{
|
||||||
$queryConditions = [];
|
$queryConditions = [];
|
||||||
$this->Controller->set('quickFilter', empty($quickFilterFields) ? [] : $quickFilterFields);
|
$this->Controller->set('quickFilter', empty($quickFilterFields) ? [] : $quickFilterFields);
|
||||||
|
|
|
@ -17,6 +17,10 @@ class NavigationComponent extends Component
|
||||||
public function initialize(array $config): void
|
public function initialize(array $config): void
|
||||||
{
|
{
|
||||||
$this->request = $config['request'];
|
$this->request = $config['request'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function beforeFilter($event)
|
||||||
|
{
|
||||||
$this->fullBreadcrumb = $this->genBreadcrumb();
|
$this->fullBreadcrumb = $this->genBreadcrumb();
|
||||||
$this->breadcrumb = $this->getBreadcrumb();
|
$this->breadcrumb = $this->getBreadcrumb();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,17 +14,21 @@ use Cake\Error\Debugger;
|
||||||
|
|
||||||
class EncryptionKeysController extends AppController
|
class EncryptionKeysController extends AppController
|
||||||
{
|
{
|
||||||
|
public $filterFields = ['owner_model', 'organisation_id', 'individual_id', 'encryption_key'];
|
||||||
|
public $quickFilterFields = ['encryption_key'];
|
||||||
|
public $containFields = ['Individuals', 'Organisations'];
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'quickFilters' => ['encryption_key'],
|
'quickFilters' => $this->quickFilterFields,
|
||||||
'filters' => ['owner_model', 'organisation_id', 'individual_id', 'encryption_key'],
|
'filters' => $this->filterFields,
|
||||||
'contextFilters' => [
|
'contextFilters' => [
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'type'
|
'type'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'contain' => ['Individuals', 'Organisations']
|
'contain' => $this->containFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -16,7 +16,9 @@ use Cake\Http\Exception\ForbiddenException;
|
||||||
|
|
||||||
class InboxController extends AppController
|
class InboxController extends AppController
|
||||||
{
|
{
|
||||||
public $filters = ['scope', 'action', 'title', 'origin', 'comment'];
|
public $filterFields = ['scope', 'action', 'title', 'origin', 'comment'];
|
||||||
|
public $quickFilterFields = ['scope', 'action', ['title' => true], ['comment' => true]];
|
||||||
|
public $containFields = ['Users'];
|
||||||
|
|
||||||
public function beforeFilter(EventInterface $event)
|
public function beforeFilter(EventInterface $event)
|
||||||
{
|
{
|
||||||
|
@ -28,14 +30,14 @@ class InboxController extends AppController
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'filters' => $this->filters,
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => ['scope', 'action', ['title' => true], ['comment' => true]],
|
'quickFilters' => $this->quickFilterFields,
|
||||||
'contextFilters' => [
|
'contextFilters' => [
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'scope',
|
'scope',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'contain' => ['Users']
|
'contain' => $this->containFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -12,17 +12,21 @@ use Cake\Http\Exception\ForbiddenException;
|
||||||
|
|
||||||
class IndividualsController extends AppController
|
class IndividualsController extends AppController
|
||||||
{
|
{
|
||||||
|
public $quickFilterFields = ['uuid', ['email' => true], ['first_name' => true], ['last_name' => true], 'position'];
|
||||||
|
public $filterFields = ['uuid', 'email', 'first_name', 'last_name', 'position', 'Organisations.id', 'Alignments.type'];
|
||||||
|
public $containFields = ['Alignments' => 'Organisations'];
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'filters' => ['uuid', 'email', 'first_name', 'last_name', 'position', 'Organisations.id', 'Alignments.type'],
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => ['uuid', 'email', 'first_name', 'last_name', 'position'],
|
'quickFilters' => $this->quickFilterFields,
|
||||||
'contextFilters' => [
|
'contextFilters' => [
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'Alignments.type'
|
'Alignments.type'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'contain' => ['Alignments' => 'Organisations']
|
'contain' => $this->containFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ use App\Controller\AppController;
|
||||||
use Cake\Utility\Hash;
|
use Cake\Utility\Hash;
|
||||||
use Cake\Utility\Text;
|
use Cake\Utility\Text;
|
||||||
use \Cake\Database\Expression\QueryExpression;
|
use \Cake\Database\Expression\QueryExpression;
|
||||||
|
use Cake\ORM\TableRegistry;
|
||||||
use Cake\Event\EventInterface;
|
use Cake\Event\EventInterface;
|
||||||
|
|
||||||
class InstanceController extends AppController
|
class InstanceController extends AppController
|
||||||
|
@ -18,7 +19,7 @@ class InstanceController extends AppController
|
||||||
|
|
||||||
public function home()
|
public function home()
|
||||||
{
|
{
|
||||||
$this->set('md', file_get_contents(ROOT . '/README.md'));
|
// $this->set('md', file_get_contents(ROOT . '/README.md'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function status()
|
public function status()
|
||||||
|
@ -29,6 +30,19 @@ class InstanceController extends AppController
|
||||||
return $this->RestResponse->viewData($data, 'json');
|
return $this->RestResponse->viewData($data, 'json');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function searchAll()
|
||||||
|
{
|
||||||
|
$searchValue = $this->request->getQuery('search');
|
||||||
|
$data = [];
|
||||||
|
if (!empty($searchValue)) {
|
||||||
|
$data = $this->Instance->searchAll($searchValue);
|
||||||
|
}
|
||||||
|
if ($this->ParamHandler->isRest()) {
|
||||||
|
return $this->RestResponse->viewData($data, 'json');
|
||||||
|
}
|
||||||
|
$this->set('data', $data);
|
||||||
|
}
|
||||||
|
|
||||||
public function migrationIndex()
|
public function migrationIndex()
|
||||||
{
|
{
|
||||||
$migrationStatus = $this->Instance->getMigrationStatus();
|
$migrationStatus = $this->Instance->getMigrationStatus();
|
||||||
|
|
|
@ -9,11 +9,15 @@ use \Cake\Database\Expression\QueryExpression;
|
||||||
|
|
||||||
class MetaTemplateFieldsController extends AppController
|
class MetaTemplateFieldsController extends AppController
|
||||||
{
|
{
|
||||||
|
public $quickFilterFields = ['field', 'type'];
|
||||||
|
public $filterFields = ['field', 'type', 'meta_template_id'];
|
||||||
|
public $containFields = [];
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'filters' => ['field', 'type', 'meta_template_id'],
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => ['field', 'type']
|
'quickFilters' => $this->quickFilterFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -9,6 +9,9 @@ use \Cake\Database\Expression\QueryExpression;
|
||||||
|
|
||||||
class MetaTemplatesController extends AppController
|
class MetaTemplatesController extends AppController
|
||||||
{
|
{
|
||||||
|
public $quickFilterFields = ['name', 'uuid', 'scope'];
|
||||||
|
public $filterFields = ['name', 'uuid', 'scope', 'namespace'];
|
||||||
|
public $containFields = ['MetaTemplateFields'];
|
||||||
|
|
||||||
public function update()
|
public function update()
|
||||||
{
|
{
|
||||||
|
@ -34,8 +37,8 @@ class MetaTemplatesController extends AppController
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'filters' => ['name', 'uuid', 'scope', 'namespace'],
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => ['name', 'uuid', 'scope'],
|
'quickFilters' => $this->quickFilterFields,
|
||||||
'contextFilters' => [
|
'contextFilters' => [
|
||||||
'fields' => ['scope'],
|
'fields' => ['scope'],
|
||||||
'custom' => [
|
'custom' => [
|
||||||
|
@ -49,7 +52,7 @@ class MetaTemplatesController extends AppController
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'contain' => ['MetaTemplateFields']
|
'contain' => $this->containFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -13,13 +13,15 @@ use Cake\Http\Exception\ForbiddenException;
|
||||||
class OrganisationsController extends AppController
|
class OrganisationsController extends AppController
|
||||||
{
|
{
|
||||||
|
|
||||||
public $filters = ['name', 'uuid', 'nationality', 'sector', 'type', 'url', 'Alignments.id', 'MetaFields.field', 'MetaFields.value', 'MetaFields.MetaTemplates.name'];
|
public $quickFilterFields = [['name' => true], 'uuid', 'nationality', 'sector', 'type', 'url'];
|
||||||
|
public $filterFields = ['name', 'uuid', 'nationality', 'sector', 'type', 'url', 'Alignments.id', 'MetaFields.field', 'MetaFields.value', 'MetaFields.MetaTemplates.name'];
|
||||||
|
public $containFields = ['Alignments' => 'Individuals'];
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'filters' => $this->filters,
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => [['name' => true], 'uuid', 'nationality', 'sector', 'type', 'url'],
|
'quickFilters' => $this->quickFilterFields,
|
||||||
'contextFilters' => [
|
'contextFilters' => [
|
||||||
'custom' => [
|
'custom' => [
|
||||||
[
|
[
|
||||||
|
@ -57,7 +59,7 @@ class OrganisationsController extends AppController
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'contain' => ['Alignments' => 'Individuals']
|
'contain' => $this->containFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -16,7 +16,9 @@ use Cake\Http\Exception\ForbiddenException;
|
||||||
|
|
||||||
class OutboxController extends AppController
|
class OutboxController extends AppController
|
||||||
{
|
{
|
||||||
public $filters = ['scope', 'action', 'title', 'comment'];
|
public $filterFields = ['scope', 'action', 'title', 'comment'];
|
||||||
|
public $quickFilterFields = ['scope', 'action', ['title' => true], ['comment' => true]];
|
||||||
|
public $containFields = ['Users'];
|
||||||
|
|
||||||
public function beforeFilter(EventInterface $event)
|
public function beforeFilter(EventInterface $event)
|
||||||
{
|
{
|
||||||
|
@ -28,14 +30,14 @@ class OutboxController extends AppController
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'filters' => $this->filters,
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => ['scope', 'action', ['title' => true], ['comment' => true]],
|
'quickFilters' => $this->quickFilterFields,
|
||||||
'contextFilters' => [
|
'contextFilters' => [
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'scope',
|
'scope',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'contain' => ['Users']
|
'contain' => $this->containFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -12,11 +12,15 @@ use Cake\Http\Exception\ForbiddenException;
|
||||||
|
|
||||||
class RolesController extends AppController
|
class RolesController extends AppController
|
||||||
{
|
{
|
||||||
|
public $filterFields = ['name', 'uuid', 'perm_admin', 'Users.id'];
|
||||||
|
public $quickFilterFields = ['name'];
|
||||||
|
public $containFields = [];
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'filters' => ['name', 'uuid', 'perm_admin', 'Users.id'],
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => ['name']
|
'quickFilters' => $this->quickFilterFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -10,11 +10,16 @@ use Cake\Error\Debugger;
|
||||||
|
|
||||||
class SharingGroupsController extends AppController
|
class SharingGroupsController extends AppController
|
||||||
{
|
{
|
||||||
|
public $filterFields = ['SharingGroups.uuid', 'SharingGroups.name', 'description', 'releasability', 'Organisations.name', 'Organisations.uuid'];
|
||||||
|
public $quickFilterFields = ['SharingGroups.uuid', ['SharingGroups.name' => true], ['description' => true], ['releasability' => true]];
|
||||||
|
public $containFields = ['SharingGroupOrgs', 'Organisations', 'Users' => ['fields' => ['id', 'username']]];
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'contain' => ['SharingGroupOrgs', 'Organisations', 'Users' => ['fields' => ['id', 'username']]],
|
'contain' => $this->containFields,
|
||||||
'filters' => ['uuid', 'description', 'releasability', 'Organisations.name', 'Organisations.uuid']
|
'filters' => $this->filterFields,
|
||||||
|
'quickFilters' => $this->quickFilterFields
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -9,12 +9,16 @@ use \Cake\Database\Expression\QueryExpression;
|
||||||
|
|
||||||
class UsersController extends AppController
|
class UsersController extends AppController
|
||||||
{
|
{
|
||||||
|
public $filterFields = ['Individuals.uuid', 'username', 'Individuals.email', 'Individuals.first_name', 'Individuals.last_name'];
|
||||||
|
public $quickFilterFields = ['Individuals.uuid', ['username' => true], ['Individuals.first_name' => true], ['Individuals.last_name' => true], 'Individuals.email'];
|
||||||
|
public $containFields = ['Individuals', 'Roles'];
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$this->CRUD->index([
|
$this->CRUD->index([
|
||||||
'contain' => ['Individuals', 'Roles'],
|
'contain' => $this->containFields,
|
||||||
'filters' => ['Users.email', 'uuid'],
|
'filters' => $this->filterFields,
|
||||||
'quickFilters' => ['uuid', ['username' => true], ['Individuals.first_name' => true], ['Individuals.last_name' => true], 'Individuals.email'],
|
'quickFilters' => $this->quickFilterFields,
|
||||||
]);
|
]);
|
||||||
$responsePayload = $this->CRUD->getResponsePayload();
|
$responsePayload = $this->CRUD->getResponsePayload();
|
||||||
if (!empty($responsePayload)) {
|
if (!empty($responsePayload)) {
|
||||||
|
|
|
@ -4,11 +4,16 @@ namespace App\Model\Table;
|
||||||
|
|
||||||
use App\Model\Table\AppTable;
|
use App\Model\Table\AppTable;
|
||||||
use Cake\ORM\Table;
|
use Cake\ORM\Table;
|
||||||
|
use Cake\ORM\TableRegistry;
|
||||||
use Cake\Validation\Validator;
|
use Cake\Validation\Validator;
|
||||||
use Migrations\Migrations;
|
use Migrations\Migrations;
|
||||||
|
use Cake\Http\Exception\MethodNotAllowedException;
|
||||||
|
|
||||||
class InstanceTable extends AppTable
|
class InstanceTable extends AppTable
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public $seachAllTables = ['Broods', 'Individuals', 'Organisations', 'SharingGroups', 'Users', 'EncryptionKeys', ];
|
||||||
|
|
||||||
public function initialize(array $config): void
|
public function initialize(array $config): void
|
||||||
{
|
{
|
||||||
parent::initialize($config);
|
parent::initialize($config);
|
||||||
|
@ -19,6 +24,52 @@ class InstanceTable extends AppTable
|
||||||
return $validator;
|
return $validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function searchAll($value)
|
||||||
|
{
|
||||||
|
$results = [];
|
||||||
|
foreach ($this->seachAllTables as $tableName) {
|
||||||
|
$controller = $this->getController($tableName);
|
||||||
|
$table = TableRegistry::get($tableName);
|
||||||
|
$query = $table->find();
|
||||||
|
$quickFilterOptions = $this->getQuickFiltersFieldsFromController($controller);
|
||||||
|
$containFields = $this->getContainFieldsFromController($controller);
|
||||||
|
if (empty($quickFilterOptions)) {
|
||||||
|
continue; // make sure we are filtering on something
|
||||||
|
}
|
||||||
|
$params = ['quickFilter' => $value];
|
||||||
|
$query = $controller->CRUD->setQuickFilters($params, $query, $quickFilterOptions);
|
||||||
|
if (!empty($containFields)) {
|
||||||
|
$query->contain($containFields);
|
||||||
|
}
|
||||||
|
$result = $query->limit(5)->all()->toList();
|
||||||
|
if (!empty($result)) {
|
||||||
|
$results[$tableName] = $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getController($name)
|
||||||
|
{
|
||||||
|
$controllerName = "\\App\\Controller\\{$name}Controller";
|
||||||
|
if (!class_exists($controllerName)) {
|
||||||
|
throw new MethodNotAllowedException(__('Model `{0}` does not exists', $model));
|
||||||
|
}
|
||||||
|
$controller = new $controllerName;
|
||||||
|
return $controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuickFiltersFieldsFromController($controller)
|
||||||
|
{
|
||||||
|
return !empty($controller->quickFilterFields) ? $controller->quickFilterFields : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getContainFieldsFromController($controller)
|
||||||
|
{
|
||||||
|
return !empty($controller->containFields) ? $controller->containFields : [];
|
||||||
|
}
|
||||||
|
|
||||||
public function getMigrationStatus()
|
public function getMigrationStatus()
|
||||||
{
|
{
|
||||||
$migrations = new Migrations();
|
$migrations = new Migrations();
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<ul>
|
||||||
|
<?php foreach ($data as $table => $tableResult): ?>
|
||||||
|
<li><strong><?= h($table) ?></strong></li>
|
||||||
|
<ul>
|
||||||
|
<?php foreach ($tableResult as $entry): ?>
|
||||||
|
<li><strong><?= h($entry['id']) ?></strong></li>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</ul>
|
|
@ -47,6 +47,7 @@ Configure::write('sidebarVariant', $sidebarVariant);
|
||||||
<?= $this->Html->script('popper.min.js') ?>
|
<?= $this->Html->script('popper.min.js') ?>
|
||||||
<?= $this->Html->script('bootstrap.bundle.js') ?>
|
<?= $this->Html->script('bootstrap.bundle.js') ?>
|
||||||
<?= $this->Html->script('main.js') ?>
|
<?= $this->Html->script('main.js') ?>
|
||||||
|
<?= $this->Html->script('utils.js') ?>
|
||||||
<?= $this->Html->script('bootstrap-helper.js') ?>
|
<?= $this->Html->script('bootstrap-helper.js') ?>
|
||||||
<?= $this->Html->script('api-helper.js') ?>
|
<?= $this->Html->script('api-helper.js') ?>
|
||||||
<?= $this->fetch('meta') ?>
|
<?= $this->fetch('meta') ?>
|
||||||
|
|
|
@ -99,9 +99,32 @@ function syntaxHighlightJson(json, indent) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function performGlobalSearch() {
|
||||||
|
const $input = $('#globalSearch')
|
||||||
|
// const $resultContainer = $('.global-search-result-container')
|
||||||
|
const $resultContainer = $('.content')
|
||||||
|
const value = $input.val()
|
||||||
|
const endpoint = '/instance/searchAll'
|
||||||
|
const searchParams = new URLSearchParams({search: value});
|
||||||
|
const url = endpoint + '?' + searchParams
|
||||||
|
const options = {
|
||||||
|
statusNode: $resultContainer
|
||||||
|
}
|
||||||
|
|
||||||
|
$resultContainer.dropdown('show')
|
||||||
|
AJAXApi.quickFetchURL(url, options).then((theHTML) => {
|
||||||
|
$resultContainer.html(theHTML)
|
||||||
|
$input.focus()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
var UI
|
var UI
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
if (typeof UIFactory !== "undefined") {
|
if (typeof UIFactory !== "undefined") {
|
||||||
UI = new UIFactory()
|
UI = new UIFactory()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const debouncedGlobalSearch = debounce(performGlobalSearch, 400)
|
||||||
|
$('#globalSearch').keypress(debouncedGlobalSearch);
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
// https://github.com/lodash/lodash/blob/master/debounce.js
|
||||||
|
function debounce(func, wait, options) {
|
||||||
|
let lastArgs,
|
||||||
|
lastThis,
|
||||||
|
maxWait,
|
||||||
|
result,
|
||||||
|
timerId,
|
||||||
|
lastCallTime
|
||||||
|
|
||||||
|
let lastInvokeTime = 0
|
||||||
|
let leading = false
|
||||||
|
let maxing = false
|
||||||
|
let trailing = true
|
||||||
|
|
||||||
|
// Bypass `requestAnimationFrame` by explicitly setting `wait=0`.
|
||||||
|
const useRAF = (!wait && wait !== 0 && typeof root.requestAnimationFrame === 'function')
|
||||||
|
|
||||||
|
if (typeof func !== 'function') {
|
||||||
|
throw new TypeError('Expected a function')
|
||||||
|
}
|
||||||
|
wait = +wait || 0
|
||||||
|
if (typeof options === 'objects') {
|
||||||
|
leading = !!options.leading
|
||||||
|
maxing = 'maxWait' in options
|
||||||
|
maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait
|
||||||
|
trailing = 'trailing' in options ? !!options.trailing : trailing
|
||||||
|
}
|
||||||
|
|
||||||
|
function invokeFunc(time) {
|
||||||
|
const args = lastArgs
|
||||||
|
const thisArg = lastThis
|
||||||
|
|
||||||
|
lastArgs = lastThis = undefined
|
||||||
|
lastInvokeTime = time
|
||||||
|
result = func.apply(thisArg, args)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTimer(pendingFunc, wait) {
|
||||||
|
if (useRAF) {
|
||||||
|
root.cancelAnimationFrame(timerId)
|
||||||
|
return root.requestAnimationFrame(pendingFunc)
|
||||||
|
}
|
||||||
|
return setTimeout(pendingFunc, wait)
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancelTimer(id) {
|
||||||
|
if (useRAF) {
|
||||||
|
return root.cancelAnimationFrame(id)
|
||||||
|
}
|
||||||
|
clearTimeout(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
function leadingEdge(time) {
|
||||||
|
// Reset any `maxWait` timer.
|
||||||
|
lastInvokeTime = time
|
||||||
|
// Start the timer for the trailing edge.
|
||||||
|
timerId = startTimer(timerExpired, wait)
|
||||||
|
// Invoke the leading edge.
|
||||||
|
return leading ? invokeFunc(time) : result
|
||||||
|
}
|
||||||
|
|
||||||
|
function remainingWait(time) {
|
||||||
|
const timeSinceLastCall = time - lastCallTime
|
||||||
|
const timeSinceLastInvoke = time - lastInvokeTime
|
||||||
|
const timeWaiting = wait - timeSinceLastCall
|
||||||
|
|
||||||
|
return maxing
|
||||||
|
? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
|
||||||
|
: timeWaiting
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldInvoke(time) {
|
||||||
|
const timeSinceLastCall = time - lastCallTime
|
||||||
|
const timeSinceLastInvoke = time - lastInvokeTime
|
||||||
|
|
||||||
|
// Either this is the first call, activity has stopped and we're at the
|
||||||
|
// trailing edge, the system time has gone backwards and we're treating
|
||||||
|
// it as the trailing edge, or we've hit the `maxWait` limit.
|
||||||
|
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
|
||||||
|
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait))
|
||||||
|
}
|
||||||
|
|
||||||
|
function timerExpired() {
|
||||||
|
const time = Date.now()
|
||||||
|
if (shouldInvoke(time)) {
|
||||||
|
return trailingEdge(time)
|
||||||
|
}
|
||||||
|
// Restart the timer.
|
||||||
|
timerId = startTimer(timerExpired, remainingWait(time))
|
||||||
|
}
|
||||||
|
|
||||||
|
function trailingEdge(time) {
|
||||||
|
timerId = undefined
|
||||||
|
|
||||||
|
// Only invoke if we have `lastArgs` which means `func` has been
|
||||||
|
// debounced at least once.
|
||||||
|
if (trailing && lastArgs) {
|
||||||
|
return invokeFunc(time)
|
||||||
|
}
|
||||||
|
lastArgs = lastThis = undefined
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancel() {
|
||||||
|
if (timerId !== undefined) {
|
||||||
|
cancelTimer(timerId)
|
||||||
|
}
|
||||||
|
lastInvokeTime = 0
|
||||||
|
lastArgs = lastCallTime = lastThis = timerId = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function flush() {
|
||||||
|
return timerId === undefined ? result : trailingEdge(Date.now())
|
||||||
|
}
|
||||||
|
|
||||||
|
function pending() {
|
||||||
|
return timerId !== undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function debounced(...args) {
|
||||||
|
const time = Date.now()
|
||||||
|
const isInvoking = shouldInvoke(time)
|
||||||
|
|
||||||
|
lastArgs = args
|
||||||
|
lastThis = this
|
||||||
|
lastCallTime = time
|
||||||
|
|
||||||
|
if (isInvoking) {
|
||||||
|
if (timerId === undefined) {
|
||||||
|
return leadingEdge(lastCallTime)
|
||||||
|
}
|
||||||
|
if (maxing) {
|
||||||
|
// Handle invocations in a tight loop.
|
||||||
|
timerId = startTimer(timerExpired, wait)
|
||||||
|
return invokeFunc(lastCallTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (timerId === undefined) {
|
||||||
|
timerId = startTimer(timerExpired, wait)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
debounced.cancel = cancel
|
||||||
|
debounced.flush = flush
|
||||||
|
debounced.pending = pending
|
||||||
|
return debounced
|
||||||
|
}
|
Loading…
Reference in New Issue