Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container Navigator #17

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions src/bundle/Controller/ContainerNavigatorController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace AdrienDupuis\EzPlatformAdminBundle\Controller;

use AdrienDupuis\EzPlatformAdminBundle\Service\ContainerNavigatorService;
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
use EzSystems\EzPlatformAdminUiBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

class ContainerNavigatorController extends Controller
{
/** @var ContainerNavigatorService */
private $containerNavigatorService;

public function __construct(ContainerNavigatorService $containerNavigatorService)
{
$this->containerNavigatorService = $containerNavigatorService;
}

public function mainAction(): Response
{
return $this->render('@ezdesign/container_navigator/main.html.twig');
}

public function detailAction(string $name, string $type = 'auto'): Response
{
switch ($type) {
case 'service':
$data = $this->getService($name);
break;
case 'tag':
$data = $this->getTag($name);
break;
case 'event':
$data = $this->getEvent($name);
break;
case 'auto':
$data = $this->getAuto($name, false /* no need to search, it was a try */);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$data = $this->getAuto($name, false /* no need to search, it was a try */);
$data = $this->getAuto($name, false /* not here to search, just to try the 3 types */);

break;
default:
throw new InvalidArgumentException('type', 'unknown type: '.$type);
}

if (empty($data) && 'auto' !== $type) {
// If a type was given, it is known to exist
$data = $this->getAuto($name, true);
}

if (!empty($data) && array_key_exists('type', $data)) {
return $this->render("@ezdesign/container_navigator/detail/{$type}.html.twig", $data);
} else {
$response = $this->render('@ezdesign/container_navigator/detail/unknown.html.twig', ['name' => $name, 'type' => $type]);
$response->setStatusCode('404');

return $response;
}
}

private function getService($name): ?array
{
return $this->containerNavigatorService->getService($name);
}

private function getTag($name): ?array
{
return $this->containerNavigatorService->getTag($name);
}

private function getEvent($name): ?array
{
return $this->containerNavigatorService->getEvent($name);
}

private function getAuto($name, $search = false): ?array
{
return $this->containerNavigatorService->getAuto($name, $search, !$search);
}
}
10 changes: 10 additions & 0 deletions src/bundle/Resources/config/routing.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,13 @@ ad_admin.identification:
path: /identification
defaults:
_controller: AdrienDupuis\EzPlatformAdminBundle\Controller\IdentificationController::identificationAction

container_navigator.main:
path: /container-navigator
defaults:
_controller: AdrienDupuis\EzPlatformAdminBundle\Controller\ContainerNavigatorController::mainAction

container_navigator.detail:
path: /container-navigator/{name}/{type}
defaults:
_controller: AdrienDupuis\EzPlatformAdminBundle\Controller\ContainerNavigatorController::detailAction
5 changes: 5 additions & 0 deletions src/bundle/Resources/config/services/container_navigator.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
services:
AdrienDupuis\EzPlatformAdminBundle\Service\ContainerNavigatorService:
arguments:
- '@kernel'
- '@debug.event_dispatcher'
6 changes: 6 additions & 0 deletions src/bundle/Resources/encore/ez.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,11 @@ module.exports = (Encore) => {
.addEntry('ad-admin-identification-css', [
path.resolve(__dirname, '../public/scss/identification.scss'),
])
.addEntry('ad-admin-container-navigator-css', [
path.resolve(__dirname, '../public/scss/container_navigator.scss'),
])
.addEntry('ad-admin-container-navigator-js', [
path.resolve(__dirname, '../public/js/ContainerNavigator.js'),
])
};
// Note: jQuery is provided by https://github.com/ezsystems/ezplatform-admin-ui-assets/tree/v5.0.0/Resources/public/vendors/jquery
71 changes: 71 additions & 0 deletions src/bundle/Resources/public/js/ContainerNavigator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
class ContainerNavigator {
constructor(baseUrl, container, text, submit, errors) {
this.baseUrl = baseUrl;
this.container = $(container);
this.text = $(text);
this.errors = $(errors);
this.submit = $(submit).click(this.onSubmit.bind(this));
}

onSubmit(event) {
event.preventDefault();
let text = $('#container_navigator_text').val();
if (text.length) {
this.load(text);
} else {
this.displayError('Enter a service, a service tag or an event.');
}
}

disableSubmit(state) {
this.submit.prop('disabled', state);
}

wrapInto(html, element, direction) {
return $('ul' === element.prop('tagName') ? '<li>' : '<div>')[direction + 'To'](element).append(html);
}

displayError(msg) {
this.wrapInto(msg, this.errors, 'prepend').fadeIn(200).delay(1000).fadeOut(1000);
}

load(text, type = 'auto') {
this.loadHtml(this.baseUrl + '/' + encodeURI(text) + '/' + type);
}

loadHtml(url) {
if (!url) { return; }
this.disableSubmit(true);
$.ajax({
url: url,
success: function (data, textStatus, jqXHR) {
if (data) {
let newElt = this.wrapInto(data, this.container, 'append');
newElt.find('a').click(function (event) {
event.preventDefault();
let target = $(event.target);
if (target.data('name')) {
this.load(target.data('name'), target.data('type'));
} else {
this.loadHtml(target.attr('href'));
}
}.bind(this));
newElt.find('.container_navigator_close').click(function(event) {
event.preventDefault();
$(event.target).closest('div, li').remove();
});
} else {
this.displayError();
}
this.disableSubmit(false);
}.bind(this),
error: function (jqXHR, textStatus, errorThrown) {
this.displayError(errorThrown);
this.disableSubmit(false);
}.bind(this),
})
}
}

// Expose the class
window.ContainerNavigator = ContainerNavigator;
24 changes: 24 additions & 0 deletions src/bundle/Resources/public/scss/container_navigator.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#container_navigator_container {
& > * {
border: 1px solid grey;
padding: 0 5px;
}

& > table {
width: 100%;
}

th {
vertical-align: top;
}

td.container_navigator_close, span.container_navigator_close {
cursor: pointer;
display: block;
width: 15px;
max-width: 15px;
height: 15px;
font-size: 15px;
line-height: 15px;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<span class="container_navigator_close">✗</span>
<ul>
{% for possibility in possibilities %}
<li>
{{ possibility.type }}:
<a href="{{ path('container_navigator.detail', {'name': possibility.name, 'type': possibility.type}) }}">{{ possibility.name }}</a>
</li>
{% endfor %}
</ul>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<table width="100%">
<tbody>
<tr>
<th width="200px">Event</th>
<td><strong>{{ event }}</strong></td>
<td class="container_navigator_close" width="15px">✗</td>
</tr>
<tr>
<th>Listeners</th>
<td>
<ul>
{% for listener in listeners %}
<li>
<a href="{{ path('container_navigator.detail', {'name': listener.0, 'type': 'service'}) }}">{{ listener.0 }}</a>::{{ listener.1 }}
</li>
{% endfor %}
</ul>
</td>
<td></td>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<table width="100%">
<tbody>
<tr>
<th width="200px">Aliases</th>
<td>
<strong>{{ name }}</strong>
<div>{{ aliases|join(', ') }}</div>
</td>
<td class="container_navigator_close" width="15px">✗</td>
</tr>
<tr>
<th>Class</th>
<td>{{ class }}</td>
</tr>
<tr>
<th>Arguments</th>
<td colspan="2">
<ul>
{% for argument in arguments %}
{% if argument starts with '!tagged_locator ' %}
{% set type = 'tag' %}
{% set argument = argument|replace({'!tagged_locator ': ''}) %}
{% else %}
{% set type = 'service' %}
{% endif %}
<li>
<a href="{{ path('container_navigator.detail', {'name': argument, 'type': type}) }}">{{ argument }}</a>
</li>
{% endfor %}
</ul>
</td>
</tr>
<tr>
<th>Tags</th>
<td colspan="2">
<ul>
{% for tag in tags %}
<li><a href="{{ path('container_navigator.detail', {'name': tag, 'type': 'tag'}) }}">{{ tag }}</a>
</li>
{% endfor %}
</ul>
</td>
</tr>
<tr>
<th>Subscribed Events</th>
<td colspan="2">
<ul>
{% for event in events.subscribed %}
<li>
<a href="{{ path('container_navigator.detail', {'name': event, 'type': 'event'}) }}">{{ event }}</a>
</li>
{% endfor %}
</ul>
</td>
</tr>
<tr>
<th>Dispatched Events</th>
<td colspan="2">
<ul>
{% for event in events.dispatched %}
<li>
<a href="{{ path('container_navigator.detail', {'name': event, 'type': 'event'}) }}">{{ event }}</a>
</li>
{% endfor %}
</ul>
</td>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<table width="100%">
<tbody>
<tr>
<th width="200px">Tag</th>
<td><strong>{{ tag }}</strong></td>
<td class="container_navigator_close" width="15px">✗</td>
</tr>
<tr>
<th>Listeners</th>
<td>
<ul>
{% for class, service in services %}
<li>
<a href="{{ path('container_navigator.detail', {'name': service, 'type': 'service'}) }}">{{ service }}</a>
</li>
{% endfor %}
</ul>
</td>
<td></td>
</tr>
</tbody>
</table>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Unknown name “{{ name }}” (“{{ type }}”)
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{% extends "@ezdesign/ui/layout.html.twig" %}

{% trans_default_domain 'ad_admin_container_navigator' %}

{% block breadcrumbs %}
{% include '@ezdesign/ui/breadcrumbs.html.twig' with { items: [
{ value: 'breadcrumb.admin'|trans(domain='messages')|desc('Admin') },
{ value: 'container_navigator'|trans|desc('Container Navigator') }
]} %}
{% endblock %}

{% block page_title %}
{% include '@ezdesign/ui/page_title.html.twig' with {
title: 'container_navigator'|trans|desc('Container Navigator'),
icon_name: 'information'
} %}
{% endblock %}

{% block stylesheets %}
{{ parent() }}
{{ encore_entry_link_tags('ad-admin-container-navigator-css', null, 'ezplatform') }}
{% endblock %}

{% block javascripts %}
{{ parent() }}
{{ encore_entry_script_tags('ad-admin-container-navigator-js', null, 'ezplatform') }}
<script>
$(function () {
let containerNavigator = new ContainerNavigator(document.location.href, '#container_navigator_container', '#container_navigator_text', '#container_navigator_submit', '#container_navigator_errors');
});
</script>
{% endblock %}

{% block content %}
<section class="container ez-container" style="padding-bottom: 50px;">
<ul id="container_navigator_container"></ul>
<div>
<input type="text" id="container_navigator_text" placeholder="Service, tag or event"/>
<input type="submit" id="container_navigator_submit"/>
</div>
<ul id="container_navigator_errors"></ul>
</section>
{% endblock %}
Loading