new: [crud:auditlog] Added auditlogs for entity being viewed
parent
adad45baf6
commit
62b2a1b264
|
@ -33,6 +33,10 @@ class CRUDComponent extends Component
|
|||
|
||||
public function index(array $options): void
|
||||
{
|
||||
$embedInModal = !empty($this->request->getQuery('embedInModal', false));
|
||||
$excludeStats = !empty($this->request->getQuery('excludeStats', false));
|
||||
$skipTableToolbar = !empty($this->request->getQuery('skipTableToolbar', false));
|
||||
|
||||
if (!empty($options['quickFilters'])) {
|
||||
if (empty($options['filters'])) {
|
||||
$options['filters'] = [];
|
||||
|
@ -150,7 +154,7 @@ class CRUDComponent extends Component
|
|||
return $template['enabled'];
|
||||
}));
|
||||
}
|
||||
if (true) { // check if stats are requested
|
||||
if (empty($excludeStats)) { // check if stats are requested
|
||||
$modelStatistics = [];
|
||||
if ($this->Table->hasBehavior('Timestamp')) {
|
||||
$modelStatistics = $this->Table->getActivityStatisticsForModel(
|
||||
|
@ -191,6 +195,8 @@ class CRUDComponent extends Component
|
|||
}
|
||||
$this->Controller->set('model', $this->Table);
|
||||
$this->Controller->set('data', $data);
|
||||
$this->Controller->set('embedInModal', $embedInModal);
|
||||
$this->Controller->set('skipTableToolbar', $skipTableToolbar);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,14 @@ class InboxNavigation extends BaseNavigation
|
|||
'icon' => 'trash',
|
||||
'url' => '/inbox/discard/{{id}}',
|
||||
'url_vars' => ['id' => 'id'],
|
||||
'isPOST' => true,
|
||||
]);
|
||||
$this->bcf->addRoute('Inbox', 'process', [
|
||||
'label' => __('Process message'),
|
||||
'icon' => 'cogs',
|
||||
'url' => '/inbox/process/{{id}}',
|
||||
'url_vars' => ['id' => 'id'],
|
||||
'isPOST' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,12 +15,14 @@ class MetaTemplatesNavigation extends BaseNavigation
|
|||
'icon' => 'check-square',
|
||||
'url' => '/metaTemplates/toggle/{{id}}/enabled',
|
||||
'url_vars' => ['id' => 'id'],
|
||||
'isPOST' => true,
|
||||
]);
|
||||
$this->bcf->addRoute('MetaTemplates', 'set_default', [
|
||||
'label' => __('Set as default'),
|
||||
'icon' => 'check-square',
|
||||
'url' => '/metaTemplates/toggle/{{id}}/default',
|
||||
'url_vars' => ['id' => 'id'],
|
||||
'isPOST' => true,
|
||||
]);
|
||||
|
||||
$totalUpdateCount = 0;
|
||||
|
@ -46,11 +48,13 @@ class MetaTemplatesNavigation extends BaseNavigation
|
|||
'label' => __('Update template'),
|
||||
'icon' => 'download',
|
||||
'url' => '/metaTemplates/update',
|
||||
'isPOST' => true,
|
||||
]);
|
||||
$this->bcf->addRoute('MetaTemplates', 'prune_outdated_template', [
|
||||
'label' => __('Prune outdated template'),
|
||||
'icon' => 'trash',
|
||||
'url' => '/metaTemplates/prune_outdated_template',
|
||||
'isPOST' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,14 @@ class OutboxNavigation extends BaseNavigation
|
|||
'icon' => 'trash',
|
||||
'url' => '/outbox/discard/{{id}}',
|
||||
'url_vars' => ['id' => 'id'],
|
||||
'isPOST' => true,
|
||||
]);
|
||||
$this->bcf->addRoute('Outbox', 'process', [
|
||||
'label' => __('Process message'),
|
||||
'icon' => 'cogs',
|
||||
'url' => '/outbox/process/{{id}}',
|
||||
'url_vars' => ['id' => 'id'],
|
||||
'isPOST' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -217,6 +217,7 @@ class BreadcrumbFactory
|
|||
'label' => __('[new {0}]', $controller),
|
||||
'icon' => 'plus',
|
||||
'url' => "/{$controller}/add",
|
||||
'isPOST' => true,
|
||||
]);
|
||||
} else if ($action === 'edit') {
|
||||
$item = $this->genRouteConfig($controller, $action, [
|
||||
|
@ -224,6 +225,7 @@ class BreadcrumbFactory
|
|||
'icon' => 'edit',
|
||||
'url' => "/{$controller}/edit/{{id}}",
|
||||
'url_vars' => ['id' => 'id'],
|
||||
'isPOST' => true,
|
||||
'textGetter' => !empty($table->getDisplayField()) ? $table->getDisplayField() : 'id',
|
||||
]);
|
||||
} else if ($action === 'delete') {
|
||||
|
@ -232,6 +234,15 @@ class BreadcrumbFactory
|
|||
'icon' => 'trash',
|
||||
'url' => "/{$controller}/delete/{{id}}",
|
||||
'url_vars' => ['id' => 'id'],
|
||||
'isPOST' => true,
|
||||
'textGetter' => !empty($table->getDisplayField()) ? $table->getDisplayField() : 'id',
|
||||
]);
|
||||
} else if ($action === 'audit') {
|
||||
$item = $this->genRouteConfig($controller, $action, [
|
||||
'label' => __('Audit changes'),
|
||||
'icon' => 'history',
|
||||
'url' => "/audit-logs?model={{model}}&model_id={{id}}&sort=created&direction=desc&embedInModal=1&excludeStats=1&skipTableToolbar=1",
|
||||
'url_vars' => ['id' => 'id', 'model' => ['raw' => $table->getAlias()]],
|
||||
'textGetter' => !empty($table->getDisplayField()) ? $table->getDisplayField() : 'id',
|
||||
]);
|
||||
}
|
||||
|
@ -253,6 +264,7 @@ class BreadcrumbFactory
|
|||
$routeConfig = $this->addIfNotEmpty($routeConfig, $config, 'label');
|
||||
$routeConfig = $this->addIfNotEmpty($routeConfig, $config, 'textGetter');
|
||||
$routeConfig = $this->addIfNotEmpty($routeConfig, $config, 'badge');
|
||||
$routeConfig = $this->addIfNotEmpty($routeConfig, $config, 'isPOST');
|
||||
return $routeConfig;
|
||||
}
|
||||
|
||||
|
@ -279,6 +291,7 @@ class BreadcrumbFactory
|
|||
$this->addRoute($controller, 'add', $this->defaultCRUD($controller, 'add'));
|
||||
$this->addRoute($controller, 'edit', $this->defaultCRUD($controller, 'edit'));
|
||||
$this->addRoute($controller, 'delete', $this->defaultCRUD($controller, 'delete'));
|
||||
$this->addRoute($controller, 'audit', $this->defaultCRUD($controller, 'audit'));
|
||||
|
||||
$this->addParent($controller, 'view', $controller, 'index');
|
||||
$this->addParent($controller, 'add', $controller, 'index');
|
||||
|
@ -292,8 +305,10 @@ class BreadcrumbFactory
|
|||
|
||||
$this->addAction($controller, 'view', $controller, 'add');
|
||||
$this->addAction($controller, 'view', $controller, 'delete');
|
||||
$this->addAction($controller, 'view', $controller, 'audit');
|
||||
$this->addAction($controller, 'edit', $controller, 'add');
|
||||
$this->addAction($controller, 'edit', $controller, 'delete');
|
||||
$this->addAction($controller, 'edit', $controller, 'audit');
|
||||
}
|
||||
|
||||
public function get($controller, $action)
|
||||
|
|
|
@ -2,24 +2,24 @@
|
|||
|
||||
use Cake\Utility\Text;
|
||||
/*
|
||||
* echo $this->element('/genericElements/IndexTable/index_table', [
|
||||
* 'top_bar' => (
|
||||
* // search/filter bar information compliant with ListTopBar
|
||||
* ),
|
||||
* 'data' => [
|
||||
// the actual data to be used
|
||||
* ),
|
||||
* 'fields' => [
|
||||
* // field list with information for the paginator, the elements used for the individual cells, etc
|
||||
* ),
|
||||
* 'title' => optional title,
|
||||
* 'description' => optional description,
|
||||
* 'notice' => optional alert to be placed at the top,
|
||||
* 'index_statistics' => optional statistics to be displayed for the index,
|
||||
* 'primary_id_path' => path to each primary ID (extracted and passed as $primary to fields)
|
||||
* ));
|
||||
*
|
||||
*/
|
||||
* echo $this->element('/genericElements/IndexTable/index_table', [
|
||||
* 'top_bar' => (
|
||||
* // search/filter bar information compliant with ListTopBar
|
||||
* ),
|
||||
* 'data' => [
|
||||
// the actual data to be used
|
||||
* ),
|
||||
* 'fields' => [
|
||||
* // field list with information for the paginator, the elements used for the individual cells, etc
|
||||
* ),
|
||||
* 'title' => optional title,
|
||||
* 'description' => optional description,
|
||||
* 'notice' => optional alert to be placed at the top,
|
||||
* 'index_statistics' => optional statistics to be displayed for the index,
|
||||
* 'primary_id_path' => path to each primary ID (extracted and passed as $primary to fields)
|
||||
* ));
|
||||
*
|
||||
*/
|
||||
|
||||
$newMetaFields = [];
|
||||
if (!empty($requestedMetaFields)) { // Create mapping for new index table fields on the fly
|
||||
|
@ -40,49 +40,56 @@ if (!empty($requestedMetaFields)) { // Create mapping for new index table fields
|
|||
$data['fields'] = array_merge($data['fields'], $newMetaFields);
|
||||
|
||||
$tableRandomValue = Cake\Utility\Security::randomString(8);
|
||||
echo '<div id="table-container-' . h($tableRandomValue) . '">';
|
||||
$html = '<div id="table-container-' . h($tableRandomValue) . '">';
|
||||
if (!empty($data['title'])) {
|
||||
echo Text::insert(
|
||||
'<h2 class="fw-light">:title :help</h2>',
|
||||
[
|
||||
'title' => $this->ValueGetter->get($data['title']),
|
||||
'help' => $this->Bootstrap->icon('info', [
|
||||
'class' => ['fs-6', 'align-text-top',],
|
||||
'title' => empty($data['description']) ? '' : h($data['description']),
|
||||
'attrs' => [
|
||||
'data-bs-toggle' => 'tooltip',
|
||||
]
|
||||
]),
|
||||
]
|
||||
);
|
||||
if (empty($embedInModal)) {
|
||||
$html .= Text::insert(
|
||||
'<h2 class="fw-light">:title :help</h2>',
|
||||
[
|
||||
'title' => h($this->ValueGetter->get($data['title'])),
|
||||
'help' => $this->Bootstrap->icon('info', [
|
||||
'class' => ['fs-6', 'align-text-top',],
|
||||
'title' => empty($data['description']) ? '' : h($data['description']),
|
||||
'attrs' => [
|
||||
'data-bs-toggle' => 'tooltip',
|
||||
]
|
||||
]),
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$pageTitle = $this->Bootstrap->node('h5', [], h($this->ValueGetter->get($data['title'])));
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($notice)) {
|
||||
echo $this->Bootstrap->alert($notice);
|
||||
$html .= $this->Bootstrap->alert($notice);
|
||||
}
|
||||
|
||||
if (!empty($modelStatistics)) {
|
||||
echo $this->element('genericElements/IndexTable/Statistics/index_statistic_scaffold', [
|
||||
$html .= $this->element('genericElements/IndexTable/Statistics/index_statistic_scaffold', [
|
||||
'statistics' => $modelStatistics,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
echo '<div class="panel">';
|
||||
$html .= '<div class="panel">';
|
||||
if (!empty($data['html'])) {
|
||||
echo sprintf('<div>%s</div>', $data['html']);
|
||||
$html .= sprintf('<div>%s</div>', $data['html']);
|
||||
}
|
||||
$skipPagination = isset($data['skip_pagination']) ? $data['skip_pagination'] : 0;
|
||||
if (!$skipPagination) {
|
||||
$paginationData = !empty($data['paginatorOptions']) ? $data['paginatorOptions'] : [];
|
||||
echo $this->element(
|
||||
if (!empty($embedInModal)) {
|
||||
$paginationData['update'] = ".modal-main-{$tableRandomValue}";
|
||||
}
|
||||
$html .= $this->element(
|
||||
'/genericElements/IndexTable/pagination',
|
||||
[
|
||||
'paginationOptions' => $paginationData,
|
||||
'tableRandomValue' => $tableRandomValue
|
||||
]
|
||||
);
|
||||
echo $this->element(
|
||||
$html .= $this->element(
|
||||
'/genericElements/IndexTable/pagination_links'
|
||||
);
|
||||
}
|
||||
|
@ -95,8 +102,8 @@ if (!empty($multiSelectData)) {
|
|||
];
|
||||
array_unshift($data['fields'], $multiSelectField);
|
||||
}
|
||||
if (!empty($data['top_bar'])) {
|
||||
echo $this->element(
|
||||
if (!empty($data['top_bar']) && empty($skipTableToolbar)) {
|
||||
$html .= $this->element(
|
||||
'/genericElements/ListTopBar/scaffold',
|
||||
[
|
||||
'data' => $data['top_bar'],
|
||||
|
@ -144,7 +151,7 @@ foreach ($data['data'] as $k => $data_row) {
|
|||
);
|
||||
}
|
||||
$tbody = '<tbody>' . $rows . '</tbody>';
|
||||
echo sprintf(
|
||||
$html .= sprintf(
|
||||
'<table class="table table-hover" id="index-table-%s" data-table-random-value="%s" data-reload-url="%s">%s%s</table>',
|
||||
$tableRandomValue,
|
||||
$tableRandomValue,
|
||||
|
@ -161,11 +168,23 @@ echo sprintf(
|
|||
$tbody
|
||||
);
|
||||
if (!$skipPagination) {
|
||||
echo $this->element('/genericElements/IndexTable/pagination_counter', $paginationData);
|
||||
echo $this->element('/genericElements/IndexTable/pagination_links');
|
||||
$html .= $this->element('/genericElements/IndexTable/pagination_counter', $paginationData);
|
||||
$html .= $this->element('/genericElements/IndexTable/pagination_links');
|
||||
}
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
|
||||
if (!empty($embedInModal)) {
|
||||
echo $this->Bootstrap->modal([
|
||||
'titleHtml' => $pageTitle ?? '',
|
||||
'bodyHtml' => $html,
|
||||
'size' => 'xl',
|
||||
'type' => 'ok-only',
|
||||
'modalClass' => "modal-main-{$tableRandomValue}"
|
||||
]);
|
||||
} else {
|
||||
echo $html;
|
||||
}
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
}
|
||||
$onClick = sprintf(
|
||||
'onClick="executePagination(%s, %s);"',
|
||||
"'" . h($tableRandomValue) . "'",
|
||||
"'" . h($options['update']) . "'",
|
||||
"'{{url}}'"
|
||||
|
||||
);
|
||||
|
|
|
@ -79,10 +79,15 @@ if (!empty($breadcrumb)) {
|
|||
if (!empty($actionEntry['badge'])) {
|
||||
$badgeNumber += 1;
|
||||
}
|
||||
if (!empty($actionEntry['isPOST'])) {
|
||||
$onclickFunction = sprintf('UI.overlayUntilResolve(this, UI.submissionModalAutoGuess(\'%s\'))', h(Router::url($actionEntry['url'])));
|
||||
} else {
|
||||
$onclickFunction = sprintf('UI.overlayUntilResolve(this, UI.modalFromUrl(\'%s\'))', h(Router::url($actionEntry['url'])));
|
||||
}
|
||||
$breadcrumbAction .= sprintf(
|
||||
'<a class="dropdown-item %s" href="#" onclick="%s"><i class="me-1 %s"></i>%s%s</a>',
|
||||
!empty($actionEntry['variant']) ? sprintf('dropdown-item-%s', $actionEntry['variant']) : '',
|
||||
sprintf('UI.overlayUntilResolve(this, UI.submissionModalAutoGuess(\'%s\'))', h(Router::url($actionEntry['url']))),
|
||||
$onclickFunction,
|
||||
!empty($actionEntry['icon']) ? $this->FontAwesome->getClass(h($actionEntry['icon'])) : '',
|
||||
h($actionEntry['label']),
|
||||
!empty($actionEntry['badge']) ? $this->Bootstrap->badge($actionEntry['badge']) : ''
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
function executePagination(randomValue, url) {
|
||||
UI.reload(url, $(`#table-container-${randomValue}`), $(`#table-container-${randomValue} table.table`))
|
||||
function executePagination(selector, url) {
|
||||
UI.reload(url, $(selector), $(selector).find('table.table'))
|
||||
}
|
||||
|
||||
function executeStateDependencyChecks(dependenceSourceSelector) {
|
||||
|
|
Loading…
Reference in New Issue