Skip to content

Commit

Permalink
EZP-28509: Design improvements for Section list
Browse files Browse the repository at this point in the history
  • Loading branch information
mikadamczyk committed Dec 13, 2017
1 parent 7036e95 commit 61cfe03
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 37 deletions.
78 changes: 65 additions & 13 deletions src/bundle/Controller/SectionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionContentAssignData;
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionCreateData;
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionDeleteData;
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionsDeleteData;
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionUpdateData;
use EzSystems\EzPlatformAdminUi\Form\DataMapper\SectionCreateMapper;
use EzSystems\EzPlatformAdminUi\Form\DataMapper\SectionUpdateMapper;
Expand Down Expand Up @@ -117,20 +118,18 @@ public function listAction(): Response

$contentCountBySectionId = [];
$deletableSections = [];
$deleteFormsBySectionId = [];
$assignContentFormsBySectionId = [];

$deleteSectionsForm = $this->formFactory->deleteSections(
new SectionsDeleteData($this->getSectionsNumbers($sectionList))
);

$assignContentForms = $this->formFactory->assignContentSectionForm(
new SectionContentAssignData()
);

foreach ($sectionList as $section) {
$contentCountBySectionId[$section->id] = $this->sectionService->countAssignedContents($section);
$deletableSections[$section->id] = !$this->sectionService->isSectionUsed($section);

$deleteFormsBySectionId[$section->id] = $this->formFactory->deleteSection(
new SectionDeleteData($section)
)->createView();

$assignContentFormsBySectionId[$section->id] = $this->formFactory->assignContentSectionForm(
new SectionContentAssignData($section)
)->createView();
}

return $this->render('EzPlatformAdminUiBundle:admin/section:list.html.twig', [
Expand All @@ -139,8 +138,8 @@ public function listAction(): Response
'sections' => $sectionList,
'content_count' => $contentCountBySectionId,
'deletable' => $deletableSections,
'form_section_delete' => $deleteFormsBySectionId,
'form_section_content_assign' => $assignContentFormsBySectionId,
'form_sections_delete' => $deleteSectionsForm->createView(),
'form_section_content_assign' => $assignContentForms->createView(),
]);
}

Expand Down Expand Up @@ -258,6 +257,47 @@ public function deleteAction(Request $request, Section $section): Response
return $this->redirect($this->generateUrl('ezplatform.section.list'));
}

/**
* Handles removing sections based on submitted form.
*
* @param Request $request
*
* @return Response
*
* @throws \InvalidArgumentException
*/
public function bulkDeleteAction(Request $request): Response
{
$form = $this->formFactory->deleteSections(
new SectionsDeleteData()
);
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
$result = $this->submitHandler->handle($form, function (SectionsDeleteData $data) {
foreach ($data->getSections() as $sectionId => $selected) {
$section = $this->sectionService->loadSection($sectionId);
$this->sectionService->deleteSection($section);

$this->notificationHandler->success(
$this->translator->trans(
/** @Desc("Section '%name%' removed.") */
'section.delete.success',
['%name%' => $section->name],
'section'
)
);
}
});

if ($result instanceof Response) {
return $result;
}
}

return $this->redirect($this->generateUrl('ezplatform.section.list'));
}

/**
* @param Request $request
* @param Section $section
Expand All @@ -267,7 +307,7 @@ public function deleteAction(Request $request, Section $section): Response
public function assignContentAction(Request $request, Section $section): Response
{
$form = $this->formFactory->assignContentSectionForm(
new SectionContentAssignData($section)
new SectionContentAssignData()
);
$form->handleRequest($request);

Expand Down Expand Up @@ -388,4 +428,16 @@ public function updateAction(Request $request, Section $section): Response
'form_section_update' => $form->createView(),
]);
}

/**
* @param Section[] $sections
*
* @return array
*/
private function getSectionsNumbers(array $sections): array
{
$sectionsNumbers = array_column($sections, 'id');

return array_combine($sectionsNumbers, array_fill_keys($sectionsNumbers, false));
}
}
6 changes: 6 additions & 0 deletions src/bundle/Resources/config/routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ ezplatform.section.delete:
defaults:
_controller: 'EzPlatformAdminUiBundle:Section:delete'

ezplatform.section.bulk_delete:
path: /section/bulk-delete
methods: ['POST']
defaults:
_controller: 'EzPlatformAdminUiBundle:Section:bulkDelete'

ezplatform.section.assign_content:
path: /section/assign-content/{sectionId}
defaults:
Expand Down
5 changes: 4 additions & 1 deletion src/bundle/Resources/public/js/scripts/admin.section.list.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
const openUDW = (event) => {
event.preventDefault();

const form = event.target.closest('form');
const form = document.querySelector('form[name="section_content_assign"]');
const btn = event.target.closest('a');
form.action = btn.dataset.formAction;
document.querySelector('#section_content_assign_section').value = btn.dataset.sectionId;

ReactDOM.render(React.createElement(eZ.modules.UniversalDiscovery, {
onConfirm: onConfirm.bind(this, form),
Expand Down
29 changes: 29 additions & 0 deletions src/bundle/Resources/public/js/scripts/admin.section.view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
(function () {
const btns = document.querySelectorAll('.btn--open-udw');
const udwContainer = document.getElementById('react-udw');
const token = document.querySelector('meta[name="CSRF-Token"]').content;
const siteaccess = document.querySelector('meta[name="SiteAccess"]').content;
const closeUDW = () => udwContainer.innerHTML = '';
const onConfirm = (form, content) => {
const field = form.querySelector('#' + form.getAttribute('name') + '_locations_location');

field.value = content.map(item => item.id).join();

closeUDW();
form.submit();
};
const onCancel = () => closeUDW();
const openUDW = (event) => {
event.preventDefault();

const form = event.target.closest('form');

ReactDOM.render(React.createElement(eZ.modules.UniversalDiscovery, {
onConfirm: onConfirm.bind(this, form),
onCancel,
restInfo: {token, siteaccess}
}), udwContainer);
};

btns.forEach(btn => btn.addEventListener('click', openUDW, false));
})();
71 changes: 50 additions & 21 deletions src/bundle/Resources/views/admin/section/list.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,31 @@
<div class="ez-table-header">
<div class="ez-table-header__headline">{{ 'section.list.title'|trans|desc('Sections') }}</div>
<div>
<a href="{{ path('ezplatform.section.create') }}" class="btn btn-primary"
data-icon="&#xe616;"{% if not can_edit %} data-disabled{% endif %}>{{ 'section.new'|trans|desc('Create a new Section') }}</a>
<a title="{{ 'section.new'|trans|desc('Create a new Section') }}"
href="{{ path('ezplatform.section.create') }}"
class="btn btn-primary" {% if not can_edit %} data-disabled{% endif %}>
<svg class="ez-icon ez-icon-create">
<use xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="{{ asset('bundles/ezplatformadminui/img/ez-icons.svg') }}#create"></use>
</svg>
</a>
<button id="delete-sections" class="btn btn-danger btn--trigger" disabled data-click="#sections_delete_delete">
<svg class="ez-icon ez-icon-trash">
<use xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="{{ asset('bundles/ezplatformadminui/img/ez-icons.svg') }}#trash"></use>
</svg>
</button>
</div>
</div>

{{ form_start(form_sections_delete, {
'action': path('ezplatform.section.bulk_delete'),
'attr': { 'class': 'ez-toggle-btn-state', 'data-toggle-button-id': '#delete-sections' }
}) }}
<table class="table">
<thead>
<tr>
<th></th>
<th>{{ 'section.name'|trans|desc('Name') }}</th>
<th>{{ 'section.identifier'|trans|desc('Identifier') }}</th>
<th>{{ 'section.id'|trans|desc('ID') }}</th>
Expand All @@ -39,42 +56,54 @@
</thead>
<tbody>
{% for section in sections %}
{% set delete_form = form_section_delete[section.id] %}
{% form_theme form_section_content_assign[section.id] 'EzPlatformAdminUiBundle:parts/form:flat_widgets.html.twig' %}
{% form_theme delete_form 'EzPlatformAdminUiBundle:parts/form:flat_widgets.html.twig' %}

<tr>
<td class="ez-checkbox-cell">
{{ form_widget(form_sections_delete.sections[section.id], {"disabled": not deletable[section.id]}) }}
</td>
<td><a href="{{ path( 'ezplatform.section.view', {'sectionId': section.id} ) }}">{{ section.name }}</a></td>
<td>{{ section.identifier }}</td>
<td>{{ section.id }}</td>
<td>{{ content_count[section.id] }}</td>
<td class="text-right">
{{ form_start(form_section_content_assign[section.id], {
"action": path("ezplatform.section.assign_content", {"sectionId": section.id}),
'attr': {'class': 'd-inline-block'}
}) }}
{{ form_widget(form_section_content_assign[section.id].locations.select_content, {'attr': {'class': 'btn--open-udw btn-secondary'}}) }}
{{ form_widget(form_section_content_assign[section.id].locations.location, {'label': false}) }}
{{ form_end(form_section_content_assign[section.id]) }}
<a href="{{ path('ezplatform.section.update', {'sectionId': section.id}) }}"
class="btn btn-secondary"{% if not can_edit %} data-disabled{% endif %}>{{ 'section.edit'|trans|desc('Edit') }}</a>
{{ form_start(delete_form, {
"action": path("ezplatform.section.delete", {"sectionId": section.id}),
'attr': {'class': 'd-inline-block'}
}) }}
{{ form_widget(delete_form.delete, { 'attr': {'class': 'btn btn-danger', 'disabled': not deletable[section.id] }}) }}
{{ form_end(delete_form) }}
<a title="{{ 'section.assign_content'|trans|desc('Assign content') }}"
href="#"
data-section-id="{{ section.id }}"
data-form-action="{{ path("ezplatform.section.assign_content", {"sectionId": section.id}) }}"
class="btn btn-icon mx-3">
<svg class="ez-icon ez-icon-relations ez-icon--secondary btn--open-udw">
<use xlink:href="{{ asset('bundles/ezplatformadminui/img/ez-icons.svg') }}#relations"></use>
</svg>
</a>

{% if can_edit %}
<a title="{{ 'section.edit'|trans|desc('Edit') }}"
href="{{ path('ezplatform.section.update', {'sectionId': section.id}) }}"
class="btn btn-icon mx-3">
<svg class="ez-icon ez-icon-edit">
<use xlink:href="{{ asset('bundles/ezplatformadminui/img/ez-icons.svg') }}#edit"></use>
</svg>
</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ form_end(form_sections_delete) }}

{{ form_start(form_section_content_assign, {
'attr': {'class': 'd-inline-block'}
}) }}
{{ form_widget(form_section_content_assign.locations.select_content, {'attr': {'hidden': 'hidden'}}) }}
{{ form_widget(form_section_content_assign.locations.location, {'label': false}) }}
{{ form_end(form_section_content_assign) }}
</section>
{% endblock %}

{% block javascripts %}
{% javascripts
'bundles/ezplatformadminui/js/scripts/admin.section.list.js'
'@EzPlatformAdminUiBundle/Resources/public/js/scripts/button.state.toggle.js'
%}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
Expand Down
2 changes: 1 addition & 1 deletion src/bundle/Resources/views/admin/section/view.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@

{% block javascripts %}
{% javascripts
'bundles/ezplatformadminui/js/scripts/admin.section.list.js'
'bundles/ezplatformadminui/js/scripts/admin.section.view.js'
%}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
Expand Down
44 changes: 44 additions & 0 deletions src/lib/Form/Data/Section/SectionsDeleteData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformAdminUi\Form\Data\Section;

use eZ\Publish\API\Repository\Values\Content\Section;

/**
* @todo Add validation
*/
class SectionsDeleteData
{
/** @var array|null */
protected $sections;

/**
* @param Section[]|null $sections
*/
public function __construct(array $sections = [])
{
$this->sections = $sections;
}

/**
* @return array|null
*/
public function getSections(): ?array
{
return $this->sections;
}

/**
* @param array|null $sections
*/
public function setSections(?array $sections)
{
$this->sections = $sections;
}
}
21 changes: 20 additions & 1 deletion src/lib/Form/Factory/FormFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionContentAssignData;
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionCreateData;
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionDeleteData;
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionsDeleteData;
use EzSystems\EzPlatformAdminUi\Form\Data\Section\SectionUpdateData;
use EzSystems\EzPlatformAdminUi\Form\Data\Trash\TrashEmptyData;
use EzSystems\EzPlatformAdminUi\Form\Data\Trash\TrashItemRestoreData;
Expand Down Expand Up @@ -82,6 +83,7 @@
use EzSystems\EzPlatformAdminUi\Form\Type\Section\SectionContentAssignType;
use EzSystems\EzPlatformAdminUi\Form\Type\Section\SectionCreateType;
use EzSystems\EzPlatformAdminUi\Form\Type\Section\SectionDeleteType;
use EzSystems\EzPlatformAdminUi\Form\Type\Section\SectionsDeleteType;
use EzSystems\EzPlatformAdminUi\Form\Type\Section\SectionUpdateType;
use EzSystems\EzPlatformAdminUi\Form\Type\Trash\TrashEmptyType;
use EzSystems\EzPlatformAdminUi\Form\Type\Trash\TrashItemRestoreType;
Expand Down Expand Up @@ -438,7 +440,7 @@ public function assignContentSectionForm(
SectionContentAssignData $data = null,
?string $name = null
): FormInterface {
$name = $name ?: sprintf('content-assign-section-%d', $data->getSection()->id);
$name = $name ?: StringUtil::fqcnToBlockPrefix(SectionContentAssignType::class);

return $this->formFactory->createNamed($name, SectionContentAssignType::class, $data);
}
Expand All @@ -458,6 +460,23 @@ public function deleteSection(
return $this->formFactory->createNamed($name, SectionDeleteType::class, $data);
}

/**
* @param SectionsDeleteData|null $data
* @param null|string $name
*
* @return FormInterface
*
* @throws InvalidOptionsException
*/
public function deleteSections(
SectionsDeleteData $data = null,
?string $name = null
): FormInterface {
$name = $name ?: StringUtil::fqcnToBlockPrefix(SectionsDeleteType::class);

return $this->formFactory->createNamed($name, SectionsDeleteType::class, $data);
}

/**
* @param SectionCreateData|null $data
* @param null|string $name
Expand Down
Loading

0 comments on commit 61cfe03

Please sign in to comment.