Filter => FhcApi

This commit is contained in:
cgfhtw
2024-03-11 09:46:39 +01:00
parent 85f9b14326
commit 011b4a83eb
6 changed files with 362 additions and 49 deletions
@@ -0,0 +1,231 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the FilterCmptLib (back-end)
* Provides data to the ajax get calls about the filter component
* Listens to ajax post calls to change the filter data
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Filter extends FHCAPI_Controller
{
const FILTER_UNIQUE_ID = 'filterUniqueId'; // Name of the filter cmpt unique id (mandatory)
const FILTER_TYPE = 'filterType'; // The filter type (PHP filter definition) used (mandatory)
const FILTER_ID = 'filterId'; // The id of the used filter (optional)
/**
* Calls the parent's constructor and loads the FilterCmptLib
*/
public function __construct()
{
// NOTE: FilterCmpt has its own permissions checks
parent::__construct([
'getFilter' => self::PERM_LOGGED,
'removeFilterField' => self::PERM_LOGGED,
'addFilterField' => self::PERM_LOGGED,
'applyFilterFields' => self::PERM_LOGGED,
'removeCustomFilter' => self::PERM_LOGGED,
'saveCustomFilter' => self::PERM_LOGGED,
'reloadDataset' => self::PERM_LOGGED
]);
// Loads the FiltersModel
$this->load->model('system/Filters_model', 'FiltersModel');
// Loads the FilterCmptLib with HTTP GET/POST parameters
$this->_startFilterCmptLib();
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Retrieves data about the current filter from the session and will be written on the output in JSON format
*/
public function getFilter()
{
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$session = $this->filtercmptlib->getSession();
if (is_object($session)) {
// If stdClass it is an retval object
$session = $this->getDataOrTerminateWithError($session);
}
$this->terminateWithSuccess($session);
}
/**
* Remove an applied filter (SQL where condition) from the current filter
*/
public function removeFilterField()
{
$this->form_validation->set_rules('filterField', 'filterField', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->removeFilterField($this->input->post('filterField'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Field removed');
}
/**
* Add a filter (SQL where clause) to be applied to the current filter
*/
public function addFilterField()
{
$this->form_validation->set_rules('filterField', 'filterField', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->addFilterField($this->input->post('filterField'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Field added');
}
/**
* Apply the filter changes
*/
public function applyFilterFields()
{
$this->form_validation->set_rules('filterFields', 'filterFields', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->applyFilterFields($this->input->post('filterFields'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Applied');
}
/**
* Save the current filter as a custom filter for this user with the given description
*/
public function saveCustomFilter()
{
$this->form_validation->set_rules('customFilterName', 'customFilterName', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->saveCustomFilter($this->input->post('customFilterName'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Saved');
}
/**
* Remove a custom filter by its filterId
*/
public function removeCustomFilter()
{
$this->form_validation->set_rules('filterId', 'filterId', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->removeCustomFilter($this->input->post('filterId'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Removed');
}
/**
* Reloads the dataset
*/
public function reloadDataset()
{
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$this->filtercmptlib->reloadDataset();
$this->terminateWithSuccess('Success');
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Loads the FilterCmptLib with the FILTER_UNIQUE_ID parameter
* If the parameter FILTER_UNIQUE_ID is not given then the execution of the controller is terminated and
* an error message is printed
*/
private function _startFilterCmptLib()
{
$filterUniqueId = null;
$filterType = null;
$filterId = null;
$validations = [
[
'field' => self::FILTER_UNIQUE_ID,
'label' => self::FILTER_UNIQUE_ID,
'rules' => 'required'
],
[
'field' => self::FILTER_TYPE,
'label' => self::FILTER_TYPE,
'rules' => 'required'
],
];
$this->load->library('form_validation');
if ($this->input->method() == 'get')
$this->form_validation->set_data($this->input->get());
$this->form_validation->set_rules($validations);
if ($this->form_validation->run()) {
$filterUniqueId = $this->input->post_get(self::FILTER_UNIQUE_ID);
$filterType = $this->input->post_get(self::FILTER_TYPE);
$filterId = $this->input->post_get(self::FILTER_ID);
// Loads the FilterCmptLib that contains all the used logic
$this->load->library(
'FilterCmptLib',
array(
'filterUniqueId' => $filterUniqueId,
'filterType' => $filterType,
'filterId' => $filterId
)
);
// Start the component
$this->filtercmptlib->start();
}
}
}
@@ -9,6 +9,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
* NOTE: extends the FHC_Controller instead of the Auth_Controller because the FilterCmpt has its
* own permissions check
* TODO(chris): deprecated
*/
class Filter extends FHC_Controller
{
+3 -1
View File
@@ -18,9 +18,11 @@
import search from "./search.js";
import phrasen from "./phrasen.js";
import navigation from "./navigation.js";
import filter from "./filter.js";
export default {
search,
phrasen,
navigation
navigation,
filter
};
+89
View File
@@ -0,0 +1,89 @@
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export default {
saveCustomFilter(wsParams) {
return this.$fhcApi.post(
'/api/frontend/v1/filter/saveCustomFilter',
{
filterUniqueId: wsParams.filterUniqueId,
filterType: wsParams.filterType,
customFilterName: wsParams.customFilterName
}
);
},
removeCustomFilter(wsParams) {
return this.$fhcApi.post(
'/api/frontend/v1/filter/removeCustomFilter',
{
filterUniqueId: wsParams.filterUniqueId,
filterType: wsParams.filterType,
filterId: wsParams.filterId
}
);
},
applyFilterFields(wsParams) {
return this.$fhcApi.post(
'/api/frontend/v1/filter/applyFilterFields',
{
filterUniqueId: wsParams.filterUniqueId,
filterType: wsParams.filterType,
filterFields: wsParams.filterFields
}
);
},
addFilterField(wsParams) {
return this.$fhcApi.post(
'/api/frontend/v1/filter/addFilterField',
{
filterUniqueId: wsParams.filterUniqueId,
filterType: wsParams.filterType,
filterField: wsParams.filterField
}
);
},
removeFilterField(wsParams) {
return this.$fhcApi.post(
'/api/frontend/v1/filter/removeFilterField',
{
filterUniqueId: wsParams.filterUniqueId,
filterType: wsParams.filterType,
filterField: wsParams.filterField
}
);
},
getFilterById(wsParams) {
return this.$fhcApi.get(
'/api/frontend/v1/filter/getFilter',
{
filterUniqueId: wsParams.filterUniqueId,
filterType: wsParams.filterType,
filterId: wsParams.filterId
}
);
},
getFilter(wsParams) {
return this.$fhcApi.get(
'/api/frontend/v1/filter/getFilter',
{
filterUniqueId: wsParams.filterUniqueId,
filterType: wsParams.filterType
}
);
}
};
+1 -1
View File
@@ -21,7 +21,7 @@ import {CoreRESTClient} from '../../RESTClient.js';
const CORE_FILTER_CMPT_TIMEOUT = 7000;
/**
*
* TODO(chris): deprecated
*/
export const CoreFilterAPIs = {
/**
+37 -47
View File
@@ -15,8 +15,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {CoreFilterAPIs} from './API.js';
import {CoreRESTClient} from '../../RESTClient.js';
import {CoreFetchCmpt} from '../../components/Fetch.js';
import FilterConfig from './Filter/Config.js';
import FilterColumns from './Filter/Columns.js';
@@ -252,12 +250,12 @@ export const CoreFilterCmpt = {
/**
*
*/
getFilter: function() {
getFilter() {
if (this.selectedFilter === null)
this.startFetchCmpt(CoreFilterAPIs.getFilter, null, this.render);
this.startFetchCmpt(this.$fhcApi.factory.filter.getFilter, null, this.render);
else
this.startFetchCmpt(
CoreFilterAPIs.getFilterById,
this.$fhcApi.factory.filter.getFilterById,
{
filterId: this.selectedFilter
},
@@ -267,55 +265,47 @@ export const CoreFilterCmpt = {
/**
*
*/
render: function(response) {
render(response) {
let data = response;
this.filterName = data.filterName;
this.dataset = data.dataset;
this.datasetMetadata = data.datasetMetadata;
if (CoreRESTClient.hasData(response))
this.fields = data.fields;
this.selectedFields = data.selectedFields;
this.notSelectedFields = this.fields.filter(x => this.selectedFields.indexOf(x) === -1);
this.filterFields = [];
for (let i = 0; i < data.datasetMetadata.length; i++)
{
let data = CoreRESTClient.getData(response);
this.filterName = data.filterName;
this.dataset = data.dataset;
this.datasetMetadata = data.datasetMetadata;
this.fields = data.fields;
this.selectedFields = data.selectedFields;
this.notSelectedFields = this.fields.filter(x => this.selectedFields.indexOf(x) === -1);
this.filterFields = [];
for (let i = 0; i < data.datasetMetadata.length; i++)
for (let j = 0; j < data.filters.length; j++)
{
for (let j = 0; j < data.filters.length; j++)
if (data.datasetMetadata[i].name == data.filters[j].name)
{
if (data.datasetMetadata[i].name == data.filters[j].name)
{
let filter = data.filters[j];
filter.type = data.datasetMetadata[i].type;
let filter = data.filters[j];
filter.type = data.datasetMetadata[i].type;
this.filterFields.push(filter);
//break;
}
this.filterFields.push(filter);
//break;
}
}
}
// If the side menu is active
if (this.sideMenu === true)
{
this.setSideMenu(data);
}
else // otherwise use the dropdown in the filter options
{
this.setDropDownMenu(data);
}
this.updateTabulator();
}
else
// If the side menu is active
if (this.sideMenu === true)
{
console.error(CoreRESTClient.getError(response));
this.setSideMenu(data);
}
else // otherwise use the dropdown in the filter options
{
this.setDropDownMenu(data);
}
this.updateTabulator();
},
/**
* Set the menu
*/
setSideMenu: function(data) {
setSideMenu(data) {
let filters = data.sideMenu.filters;
let personalFilters = data.sideMenu.personalFilters;
let filtersArray = [];
@@ -369,7 +359,7 @@ export const CoreFilterCmpt = {
/**
* Set the drop down menu
*/
setDropDownMenu: function(data) {
setDropDownMenu(data) {
let filters = data.sideMenu.filters;
let personalFilters = data.sideMenu.personalFilters;
let filtersArray = [];
@@ -405,7 +395,7 @@ export const CoreFilterCmpt = {
/**
* Used to start/refresh the FetchCmpt
*/
startFetchCmpt: function(apiFunction, apiFunctionParameters, dataFetchedCallback) {
startFetchCmpt(apiFunction, apiFunctionParameters, dataFetchedCallback) {
// Assign the function api of the FetchCmpt binded property
this.fetchCmptApiFunction = apiFunction;
@@ -431,11 +421,11 @@ export const CoreFilterCmpt = {
/**
*
*/
handlerSaveCustomFilter: function(customFilterName) {
handlerSaveCustomFilter(customFilterName) {
this.selectedFilter = null;
//
this.startFetchCmpt(
CoreFilterAPIs.saveCustomFilter,
this.$fhcApi.factory.filter.saveCustomFilter,
{
customFilterName
},
@@ -445,13 +435,13 @@ export const CoreFilterCmpt = {
/**
*
*/
handlerRemoveCustomFilter: function(event) {
handlerRemoveCustomFilter(event) {
let filterId = event.currentTarget.getAttribute("href").substring(1);
if (filterId === this.selectedFilter)
this.selectedFilter = null;
//
this.startFetchCmpt(
CoreFilterAPIs.removeCustomFilter,
this.$fhcApi.factory.filter.removeCustomFilter,
{
filterId: filterId
},
@@ -488,7 +478,7 @@ export const CoreFilterCmpt = {
applyFilterConfig(filterFields) {
this.selectedFilter = null;
this.startFetchCmpt(
CoreFilterAPIs.applyFilterFields,
this.$fhcApi.factory.filter.applyFilterFields,
{
filterFields
},