diff --git a/src/Controller/Component/CRUDComponent.php b/src/Controller/Component/CRUDComponent.php index 0342a67..97a0c37 100644 --- a/src/Controller/Component/CRUDComponent.php +++ b/src/Controller/Component/CRUDComponent.php @@ -35,6 +35,9 @@ class CRUDComponent extends Component $options['filters'][] = 'quickFilter'; } $options['filters'][] = 'filteringLabel'; + if ($this->taggingSupported()) { + $options['filters'][] = 'filteringTags'; + } $optionFilters = empty($options['filters']) ? [] : $options['filters']; foreach ($optionFilters as $i => $filter) { @@ -50,6 +53,9 @@ class CRUDComponent extends Component if (!empty($options['contain'])) { $query->contain($options['contain']); } + if ($this->taggingSupported()) { + $query->contain('Tags'); + } if (!empty($options['fields'])) { $query->select($options['fields']); } @@ -73,15 +79,17 @@ class CRUDComponent extends Component $data = $this->Table->{$options['afterFind']}($data); } } - if (!empty($options['contextFilters'])) { - $this->setFilteringContext($options['contextFilters'], $params); - } + $this->setFilteringContext($options['contextFilters'] ?? [], $params); $this->Controller->set('data', $data); } } public function filtering(): void { + if ($this->taggingSupported()) { + $this->Controller->set('taggingEnabled', true); + $this->setAllTags(); + } $filters = !empty($this->Controller->filters) ? $this->Controller->filters : []; $this->Controller->set('filters', $filters); $this->Controller->viewBuilder()->setLayout('ajax'); @@ -246,8 +254,9 @@ class CRUDComponent extends Component $this->getMetaTemplates(); if ($this->taggingSupported()) { $params['contain'][] = 'Tags'; + $this->setAllTags(); } - $data = $this->Table->get($id, isset($params['get']) ? $params['get'] : []); + $data = $this->Table->get($id, isset($params['get']) ? $params['get'] : $params); $data = $this->getMetaFields($id, $data); if (!empty($params['fields'])) { $this->Controller->set('fields', $params['fields']); @@ -676,6 +685,8 @@ class CRUDComponent extends Component { $filteringLabel = !empty($params['filteringLabel']) ? $params['filteringLabel'] : ''; unset($params['filteringLabel']); + $filteringTags = !empty($params['filteringTags']) && $this->taggingSupported() ? $params['filteringTags'] : ''; + unset($params['filteringTags']); $customFilteringFunction = ''; $chosenFilter = ''; if (!empty($options['contextFilters']['custom'])) { @@ -719,10 +730,26 @@ class CRUDComponent extends Component } } } + + if ($this->taggingSupported() && !empty($filteringTags)) { + $activeFilters['filteringTags'] = $filteringTags; + $query = $this->setTagFilters($query, $filteringTags); + } + $this->Controller->set('activeFilters', $activeFilters); return $query; } + protected function setTagFilters($query, $tags) + { + $modelAlias = $this->Table->getAlias(); + $subQuery = $this->Table->find('tagged', [ + 'label' => $tags, + 'forceAnd' => true + ])->select($modelAlias . '.id'); + return $query = $query->where([$modelAlias . '.id IN' => $subQuery]); + } + protected function setNestedRelatedCondition($query, $filterParts, $filterValue) { $modelName = $filterParts[0]; diff --git a/src/Controller/IndividualsController.php b/src/Controller/IndividualsController.php index 046824f..71e4a0f 100644 --- a/src/Controller/IndividualsController.php +++ b/src/Controller/IndividualsController.php @@ -13,10 +13,12 @@ use Cake\ORM\TableRegistry; class IndividualsController extends AppController { + public $filters = ['uuid', 'email', 'first_name', 'last_name', 'position', 'Organisations.id', 'Alignments.type']; + public function index() { $this->CRUD->index([ - 'filters' => ['uuid', 'email', 'first_name', 'last_name', 'position', 'Organisations.id', 'Alignments.type'], + 'filters' => $this->filters, 'quickFilters' => ['uuid', 'email', 'first_name', 'last_name', 'position'], 'contextFilters' => [ 'fields' => [ @@ -33,6 +35,11 @@ class IndividualsController extends AppController $this->set('metaGroup', 'ContactDB'); } + public function filtering() + { + $this->CRUD->filtering(); + } + public function add() { $this->CRUD->add(); diff --git a/src/Controller/TagsController.php b/src/Controller/TagsController.php new file mode 100644 index 0000000..57481e0 --- /dev/null +++ b/src/Controller/TagsController.php @@ -0,0 +1,80 @@ +Table = TableRegistry::getTableLocator()->get('Tags.Tags'); + $this->CRUD->Table = $this->Table; + $this->CRUD->TableAlias = $this->CRUD->Table->getAlias(); + $this->CRUD->ObjectAlias = Inflector::singularize($this->CRUD->TableAlias); + } + + public function index() + { + $this->CRUD->index([ + 'filters' => ['label', 'colour'], + 'quickFilters' => [['label' => true], 'colour'] + ]); + $responsePayload = $this->CRUD->getResponsePayload(); + if (!empty($responsePayload)) { + return $responsePayload; + } + $this->set('metaGroup', $this->isAdmin ? 'Administration' : 'Cerebrate'); + } + + public function add() + { + $this->CRUD->add(); + $responsePayload = $this->CRUD->getResponsePayload(); + if (!empty($responsePayload)) { + return $responsePayload; + } + $this->set('metaGroup', $this->isAdmin ? 'Administration' : 'Cerebrate'); + } + + public function view($id) + { + $this->CRUD->view($id); + $responsePayload = $this->CRUD->getResponsePayload(); + if (!empty($responsePayload)) { + return $responsePayload; + } + $this->set('metaGroup', $this->isAdmin ? 'Administration' : 'Cerebrate'); + } + + public function edit($id) + { + $this->CRUD->edit($id); + $responsePayload = $this->CRUD->getResponsePayload(); + if (!empty($responsePayload)) { + return $responsePayload; + } + $this->set('metaGroup', $this->isAdmin ? 'Administration' : 'Cerebrate'); + $this->render('add'); + } + + public function delete($id) + { + $this->CRUD->delete($id); + $responsePayload = $this->CRUD->getResponsePayload(); + if (!empty($responsePayload)) { + return $responsePayload; + } + $this->set('metaGroup', $this->isAdmin ? 'Administration' : 'Cerebrate'); + } +} diff --git a/src/Model/Table/IndividualsTable.php b/src/Model/Table/IndividualsTable.php index 81d4c65..5693321 100644 --- a/src/Model/Table/IndividualsTable.php +++ b/src/Model/Table/IndividualsTable.php @@ -17,6 +17,7 @@ class IndividualsTable extends AppTable $this->addBehavior('Tags.Tag', [ 'taggedCounter' => false, 'strategy' => 'array', + 'finderField' => 'label', ]); $this->hasMany( 'Alignments', diff --git a/src/View/Helper/TagHelper.php b/src/View/Helper/TagHelper.php index 9b0449b..f601650 100644 --- a/src/View/Helper/TagHelper.php +++ b/src/View/Helper/TagHelper.php @@ -33,14 +33,20 @@ class TagHelper extends Helper 'data-text-colour' => h($tag['text_colour']), ]; }, $options['allTags']) : []; - $selectConfig = [ - 'multiple' => true, - 'class' => ['tag-input', 'd-none'], - 'data-url' => $this->Url->build([ + $classes = ['tag-input', 'flex-grow-1']; + $url = ''; + if (!empty($this->getConfig('editable'))) { + $url = $this->Url->build([ 'controller' => $this->getView()->getName(), 'action' => 'tag', $this->getView()->get('entity')['id'] - ]), + ]); + $classes[] = 'd-none'; + } + $selectConfig = [ + 'multiple' => true, + 'class' => $classes, + 'data-url' => $url, ]; return $this->Form->select($field, $values, $selectConfig); } @@ -48,24 +54,26 @@ class TagHelper extends Helper protected function picker(array $options = []) { $html = $this->Tag->control($options); - $html .= $this->Bootstrap->button([ - 'size' => 'sm', - 'icon' => 'plus', - 'variant' => 'secondary', - 'class' => ['badge'], - 'params' => [ - 'onclick' => 'createTagPicker(this)', - ] - ]); + if (!empty($this->getConfig('editable'))) { + $html .= $this->Bootstrap->button([ + 'size' => 'sm', + 'icon' => 'plus', + 'variant' => 'secondary', + 'class' => ['badge'], + 'params' => [ + 'onclick' => 'createTagPicker(this)', + ] + ]); + } + $html .= ''; return $html; } - public function tags(array $options = []) + public function tags(array $tags = [], array $options = []) { $this->_config = array_merge($this->defaultConfig, $options); - $tags = !empty($options['tags']) ? $options['tags'] : []; $html = '