Skip to content

Commit

Permalink
Merge pull request #10 from dachcom-digital/feature/backend-ui
Browse files Browse the repository at this point in the history
Feature/backend UI
  • Loading branch information
benwalch authored Dec 12, 2024
2 parents 5db7ca5 + 146e031 commit d1e0cba
Show file tree
Hide file tree
Showing 16 changed files with 286 additions and 80 deletions.
6 changes: 6 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Upgrade Notes

## 2.0.2
added backend ui (supported in dynamic search >= 4.0.4) [#10](https://github.com/dachcom-digital/pimcore-dynamic-search-index-provider-opensearch/pull/10)

## 2.0.1
size param for aggregation filter [#4](https://github.com/dachcom-digital/pimcore-dynamic-search-index-provider-opensearch/issues/4)

## Migrating from Version 1.x to Version 2.0.0

### Global Changes
Expand Down
6 changes: 6 additions & 0 deletions config/pimcore/routing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ds_opensearch_controller_admin_index_rebuild_mapping:
path: /admin/ds-index-provider-opensearch/index/rebuild-mapping
methods: [ POST ]
defaults: { _controller: DsOpenSearchBundle\Controller\Admin\IndexController::rebuildMappingAction }
options:
expose: true
4 changes: 1 addition & 3 deletions config/services/command.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,5 @@ services:
public: false

DsOpenSearchBundle\Command\RebuildIndexCommand:
arguments:
$dsFullConfiguration: '%dynamic_search.context.full_configuration%'
tags:
- { name: console.command}
- { name: console.command}
10 changes: 10 additions & 0 deletions config/services/controller.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:

_defaults:
autowire: true
autoconfigure: true
public: true

DsOpenSearchBundle\Controller\Admin\IndexController:
tags:
- 'controller.service_arguments'
10 changes: 10 additions & 0 deletions config/services/event_listener.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
services:

_defaults:
autowire: true
autoconfigure: true
public: false

DsOpenSearchBundle\EventListener\Admin\AssetListener:
tags:
- { name: kernel.event_subscriber }
8 changes: 8 additions & 0 deletions config/services/manager.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:

_defaults:
autowire: true
autoconfigure: true
public: false

DsOpenSearchBundle\Manager\IndexManager: ~
94 changes: 94 additions & 0 deletions public/js/backend/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
class DsIndexProviderOpensearch {

addLayoutToDsSettings(event) {

this.dsSettings = event.detail.subject;
this.dsContextFullConfig = pimcore.globalmanager.get('dynamic_search.context.full_configuration') || {};

const dsActionsPanel = new Ext.panel.Panel({
layout: 'hbox',
title: 'DsIndexProviderOpenSearch',
bodyPadding: 10,
items: [

]
});
this.dsSettings.panel.add(dsActionsPanel);

if (Object.keys(this.dsContextFullConfig).length === 0) {
dsActionsPanel.add({
xtype: 'displayfield',
value: 'Error: no dynamic search context configured'
});
return;
}

dsActionsPanel.add({
xtype: 'toolbar',
docked: 'top',
items: [
{
scale: 'small',
margin: '0 10 0 0',
text: t('ds_index_provider_opensearch.actions.index.rebuild_mapping'),
icon: '/bundles/pimcoreadmin/img/flat-color-icons/data_configuration.svg',
menu: this.buildContextButtonMenu( 'rebuild_mapping'),
}
]
});

}

buildContextButtonMenu(action) {
return Object.keys(this.dsContextFullConfig).map(function(context) {
return {
text: context,
handler: function() {
Ext.Msg.confirm(
t(`ds_index_provider_opensearch.actions.index.${action}`) + ': ' + context,
t(`ds_index_provider_opensearch.actions.index.${action}.confirmation.message`),
function (confirmMsg) {

if (confirmMsg !== 'yes') {
return;
}

this.performContextIndexAction(context, action);

}.bind(this)
);
}.bind(this)
}
}.bind(this))
}

performContextIndexAction(context, action) {
let url = '';

try {
url = Routing.generate('ds_opensearch_controller_admin_index_' + action);
} catch (e) {
Ext.Msg.alert('Error', e.message);
return;
}

Ext.Ajax.request({
url: url,
method: 'POST',
params: {
context: context
},
success: function(response) {
if (response.status === 200) {
pimcore.helpers.showNotification(t('success'), t(`ds_index_provider_opensearch.actions.index.${action}.success`), 'success');
} else {
pimcore.helpers.showNotification(t('error'), response.responseText, 'error');
}
}
});
}
}

const dsIndexProviderOpensearch = new DsIndexProviderOpensearch();

document.addEventListener('dynamic_search.event.settings.postBuildLayout', dsIndexProviderOpensearch.addLayoutToDsSettings.bind(dsIndexProviderOpensearch));
86 changes: 17 additions & 69 deletions src/Command/RebuildIndexCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,23 @@

namespace DsOpenSearchBundle\Command;

use DsOpenSearchBundle\Builder\ClientBuilderInterface;
use DsOpenSearchBundle\Service\IndexPersistenceService;
use DynamicSearchBundle\Builder\ContextDefinitionBuilderInterface;
use DynamicSearchBundle\Context\ContextDefinitionInterface;
use DynamicSearchBundle\Generator\IndexDocumentGeneratorInterface;
use DynamicSearchBundle\Provider\PreConfiguredIndexProviderInterface;
use DsOpenSearchBundle\Manager\IndexManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\QuestionHelper;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Contracts\Translation\TranslatorInterface;

class RebuildIndexCommand extends Command
{
protected static $defaultName = 'dynamic-search:os:rebuild-index-mapping';
protected static $defaultDescription = 'Rebuild Index Mapping';

public function __construct(
protected array $dsFullConfiguration,
protected ContextDefinitionBuilderInterface $contextDefinitionBuilder,
protected IndexDocumentGeneratorInterface $indexDocumentGenerator,
protected ClientBuilderInterface $clientBuilder
protected IndexManager $indexManager,
protected TranslatorInterface $translator
) {
parent::__construct();
}
Expand All @@ -40,75 +34,29 @@ protected function execute(InputInterface $input, OutputInterface $output): int

if (empty($contextName)) {
$output->writeln('<error>no context definition name given</error>');
return 0;
return Command::FAILURE;
}

$contextDefinition = $this->contextDefinitionBuilder->buildContextDefinition($contextName, ContextDefinitionInterface::CONTEXT_DISPATCH_TYPE_INDEX);
/** @var QuestionHelper $helper */
$helper = $this->getHelper('question');

if (!$contextDefinition instanceof ContextDefinitionInterface) {
$output->writeln(sprintf('<error>no context definition with name "%s" found</error>', $contextName));
return 0;
}

try {
$indexDocument = $this->indexDocumentGenerator->generateWithoutData($contextDefinition, ['preConfiguredIndexProvider' => true]);
} catch (\Throwable $e) {
$output->writeln(
sprintf(
'%s. (The current context index provider also requires pre-configured indices. Please make sure your document definition implements the "%s" interface)',
$e->getMessage(), PreConfiguredIndexProviderInterface::class
)
);

return 0;
}

if (!$indexDocument->hasIndexFields()) {
$output->writeln(
sprintf(
'No Index Document found. The current context index provider requires pre-configured indices. Please make sure your document definition implements the "%s" interface',
PreConfiguredIndexProviderInterface::class
)
);

return 0;
}

$options = $this->dsFullConfiguration[$contextName]['index_provider']['options'];

$client = $this->clientBuilder->build($options);
$indexService = new IndexPersistenceService($client, $options);

if ($indexService->indexExists()) {

/** @var QuestionHelper $helper */
$helper = $this->getHelper('question');

$text = 'This command will drop the selected index and all data will be lost! Continue?';
$commandText = sprintf(' <info>%s (y/n)</info> [<comment>%s</comment>]:', $text, 'no');
$question = new ConfirmationQuestion($commandText, false);

if (!$helper->ask($input, $output, $question)) {
return 0;
}
$text = $this->translator->trans('ds_index_provider_opensearch.actions.index.rebuild_mapping.confirmation.message', [], 'admin');
$commandText = sprintf(' <info>%s (y/n)</info> [<comment>%s</comment>]:', $text, 'no');
$question = new ConfirmationQuestion($commandText, false);

try {
$indexService->dropIndex();
} catch (\Throwable $e) {
$output->writeln(sprintf('Error while dropping index: %s', $e->getMessage()));
return 0;
}
if (!$helper->ask($input, $output, $question)) {
return Command::SUCCESS;
}

try {
$indexService->createIndex($indexDocument);
$this->indexManager->rebuildIndex($contextName);
} catch (\Throwable $e) {
$output->writeln(sprintf('Error while creating index: %s', $e->getMessage()));
return 0;
$output->writeln(sprintf('<error>Error rebuilding index mapping: %s</error>', $e->getMessage()));
return Command::FAILURE;
}

$output->writeln('<info>Index rebuild was successful</info>');
$output->writeln(sprintf('<info>%s</info>', $this->translator->trans('ds_index_provider_opensearch.actions.index.rebuild_mapping.success', [], 'admin')));

return 0;
return Command::SUCCESS;
}
}
35 changes: 35 additions & 0 deletions src/Controller/Admin/IndexController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace DsOpenSearchBundle\Controller\Admin;

use DsOpenSearchBundle\Manager\IndexManager;
use Pimcore\Bundle\AdminBundle\Controller\AdminAbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class IndexController extends AdminAbstractController
{
public function __construct(
protected IndexManager $indexManager
)
{
}

public function rebuildMappingAction(Request $request): Response
{
$contextName = $request->get('context');

if (empty($contextName)) {
return new Response('no context given', 400);
}

try {
$this->indexManager->rebuildIndex($contextName);
} catch (\Throwable $e) {
return new Response($e->getMessage(), 500);
}

return new Response();
}

}
3 changes: 2 additions & 1 deletion src/DsOpenSearchBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
namespace DsOpenSearchBundle;

use DynamicSearchBundle\Provider\Extension\ProviderBundleInterface;
use Pimcore\Extension\Bundle\AbstractPimcoreBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;

final class DsOpenSearchBundle extends Bundle implements ProviderBundleInterface
final class DsOpenSearchBundle extends AbstractPimcoreBundle implements ProviderBundleInterface
{
public const PROVIDER_NAME = 'opensearch';

Expand Down
25 changes: 25 additions & 0 deletions src/EventListener/Admin/AssetListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace DsOpenSearchBundle\EventListener\Admin;

use Pimcore\Event\BundleManager\PathsEvent;
use Pimcore\Event\BundleManagerEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class AssetListener implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
BundleManagerEvents::JS_PATHS => 'addJsFiles'
];
}

public function addJsFiles(PathsEvent $event): void
{
$event->addPaths([
'/bundles/dsopensearch/js/backend/settings.js',
]);
}

}
Loading

0 comments on commit d1e0cba

Please sign in to comment.