diff --git a/src/bundle/Controller/ContentController.php b/src/bundle/Controller/ContentController.php
index ce62d4595c..52282d3b83 100644
--- a/src/bundle/Controller/ContentController.php
+++ b/src/bundle/Controller/ContentController.php
@@ -15,6 +15,7 @@
use eZ\Publish\API\Repository\Values\Content\Location;
use eZ\Publish\Core\Base\Exceptions\BadStateException;
use EzSystems\EzPlatformAdminUi\Exception\InvalidArgumentException as AdminInvalidArgumentException;
+use EzSystems\EzPlatformAdminUi\Form\Data\Content\ContentVisibilityUpdateData;
use EzSystems\EzPlatformAdminUi\Form\Data\Content\Draft\ContentCreateData;
use EzSystems\EzPlatformAdminUi\Form\Data\Content\Draft\ContentEditData;
use EzSystems\EzPlatformAdminUi\Form\Data\Content\Location\ContentMainLocationUpdateData;
@@ -23,6 +24,7 @@
use EzSystems\EzPlatformAdminUi\Form\DataMapper\MainTranslationUpdateMapper;
use EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory;
use EzSystems\EzPlatformAdminUi\Form\SubmitHandler;
+use EzSystems\EzPlatformAdminUi\Form\Type\Content\ContentVisibilityUpdateType;
use EzSystems\EzPlatformAdminUi\Form\Type\Content\Translation\MainTranslationUpdateType;
use EzSystems\EzPlatformAdminUi\Notification\NotificationHandlerInterface;
use EzSystems\EzPlatformAdminUi\Siteaccess\SiteaccessResolverInterface;
@@ -279,9 +281,9 @@ public function updateMainLocationAction(Request $request): Response
if (null !== $contentInfo) {
return new RedirectResponse($this->generateUrl('_ezpublishLocation', [
- 'locationId' => $contentInfo->mainLocationId,
- '_fragment' => 'ez-tab-location-view-locations',
- ]));
+ 'locationId' => $contentInfo->mainLocationId,
+ '_fragment' => 'ez-tab-location-view-locations',
+ ]));
}
return $this->redirectToRoute('ezplatform.dashboard');
@@ -381,4 +383,76 @@ public function updateMainTranslationAction(Request $request): Response
return $this->redirectToRoute('ezplatform.dashboard');
}
+
+ /**
+ * @param Symfony\Component\HttpFoundation\Request $request
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
+ */
+ public function updateVisibilityAction(Request $request): Response
+ {
+ $form = $this->createForm(ContentVisibilityUpdateType::class);
+ $form->handleRequest($request);
+ $result = null;
+
+ if ($form->isSubmitted()) {
+ $result = $this->submitHandler->handle($form, function (ContentVisibilityUpdateData $data) {
+ $contentInfo = $data->getContentInfo();
+ $desiredVisibility = $data->getVisible();
+ $location = $data->getLocation();
+
+ if ($contentInfo->isHidden && $desiredVisibility === false) {
+ $this->notificationHandler->success(
+ $this->translator->trans(
+ /** @Desc("Content '%name%' was already hidden.") */
+ 'content.hide.already_hidden',
+ ['%name%' => $contentInfo->name],
+ 'content'
+ )
+ );
+ }
+
+ if (!$contentInfo->isHidden && $desiredVisibility === true) {
+ $this->notificationHandler->success(
+ $this->translator->trans(
+ /** @Desc("Content '%name%' was already visible.") */
+ 'content.reveal.already_visible',
+ ['%name%' => $contentInfo->name],
+ 'content'
+ )
+ );
+ }
+
+ if (!$contentInfo->isHidden && $desiredVisibility === false) {
+ $this->contentService->hideContent($contentInfo);
+
+ $this->notificationHandler->success(
+ $this->translator->trans(
+ /** @Desc("Content '%name%' has been hidden.") */
+ 'content.hide.success',
+ ['%name%' => $contentInfo->name],
+ 'content'
+ )
+ );
+ }
+
+ if ($contentInfo->isHidden && $desiredVisibility === true) {
+ $this->contentService->revealContent($contentInfo);
+
+ $this->notificationHandler->success(
+ $this->translator->trans(
+ /** @Desc("Content '%name%' has been revealed.") */
+ 'content.reveal.success',
+ ['%name%' => $contentInfo->name],
+ 'content'
+ )
+ );
+ }
+
+ return $location === null ? $this->redirectToRoute('ezplatform.dashboard') : $this->redirectToLocation($location);
+ });
+ }
+
+ return $result instanceof Response ? $result : $this->redirectToRoute('ezplatform.dashboard');
+ }
}
diff --git a/src/bundle/Controller/ContentViewController.php b/src/bundle/Controller/ContentViewController.php
index 123c18937d..80247d7437 100644
--- a/src/bundle/Controller/ContentViewController.php
+++ b/src/bundle/Controller/ContentViewController.php
@@ -20,6 +20,7 @@
use eZ\Publish\API\Repository\UserService;
use eZ\Publish\Core\MVC\Symfony\Locale\UserLanguagePreferenceProviderInterface;
use eZ\Publish\Core\MVC\Symfony\View\ContentView;
+use EzSystems\EzPlatformAdminUi\Form\Data\Content\ContentVisibilityUpdateData;
use EzSystems\EzPlatformAdminUi\Form\Data\Content\Draft\ContentCreateData;
use EzSystems\EzPlatformAdminUi\Form\Data\Content\Draft\ContentEditData;
use EzSystems\EzPlatformAdminUi\Form\Data\Location\LocationCopyData;
@@ -31,6 +32,7 @@
use EzSystems\EzPlatformAdminUi\Form\Data\User\UserDeleteData;
use EzSystems\EzPlatformAdminUi\Form\Data\User\UserEditData;
use EzSystems\EzPlatformAdminUi\Form\Factory\FormFactory;
+use EzSystems\EzPlatformAdminUi\Form\Type\Content\ContentVisibilityUpdateType;
use EzSystems\EzPlatformAdminUi\Specification\Content\ContentHaveAssetRelation;
use EzSystems\EzPlatformAdminUi\Specification\Content\ContentHaveUniqueRelation;
use EzSystems\EzPlatformAdminUi\Specification\ContentIsUser;
@@ -38,6 +40,7 @@
use EzSystems\EzPlatformAdminUi\Specification\Location\IsContainer;
use EzSystems\EzPlatformAdminUi\UI\Module\Subitems\ContentViewParameterSupplier as SubitemsContentViewParameterSupplier;
use EzSystems\EzPlatformAdminUi\UI\Service\PathService;
+use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
@@ -91,6 +94,9 @@ class ContentViewController extends Controller
/** @var \eZ\Publish\Core\MVC\Symfony\Locale\UserLanguagePreferenceProviderInterface */
private $userLanguagePreferenceProvider;
+ /** @var \Symfony\Component\Form\FormFactoryInterface */
+ private $sfFormFactory;
+
/**
* @param \eZ\Publish\API\Repository\ContentTypeService $contentTypeService
* @param \eZ\Publish\API\Repository\LanguageService $languageService
@@ -114,6 +120,7 @@ public function __construct(
LanguageService $languageService,
PathService $pathService,
FormFactory $formFactory,
+ FormFactoryInterface $sfFormFactory,
SubitemsContentViewParameterSupplier $subitemsContentViewParameterSupplier,
UserService $userService,
BookmarkService $bookmarkService,
@@ -131,6 +138,7 @@ public function __construct(
$this->languageService = $languageService;
$this->pathService = $pathService;
$this->formFactory = $formFactory;
+ $this->sfFormFactory = $sfFormFactory;
$this->subitemsContentViewParameterSupplier = $subitemsContentViewParameterSupplier;
$this->userService = $userService;
$this->bookmarkService = $bookmarkService;
@@ -178,6 +186,8 @@ public function locationViewAction(Request $request, ContentView $view): Content
$this->supplyIsLocationBookmarked($view);
+ $this->supplyContentReverseRelations($view);
+
return $view;
}
@@ -258,10 +268,20 @@ private function supplyContentActionForms(ContentView $view): void
new LocationCopySubtreeData($location)
);
+ $contentVisibilityUpdateForm = $this->sfFormFactory->create(
+ ContentVisibilityUpdateType::class,
+ new ContentVisibilityUpdateData(
+ $location->getContentInfo(),
+ $location,
+ $location->getContentInfo()->isHidden
+ )
+ );
+
$view->addParameters([
'form_location_copy' => $locationCopyType->createView(),
'form_location_move' => $locationMoveType->createView(),
'form_content_create' => $contentCreateType->createView(),
+ 'form_content_visibility_update' => $contentVisibilityUpdateForm->createView(),
'form_subitems_content_edit' => $subitemsContentEdit->createView(),
'form_location_copy_subtree' => $locationCopySubtreeType->createView(),
]);
@@ -462,4 +482,15 @@ private function supplyIsLocationBookmarked(ContentView $view): void
$view->addParameters(['location_is_bookmarked' => $locationIsBookmarked]);
}
+
+ /**
+ * @param \eZ\Publish\Core\MVC\Symfony\View\ContentView $view
+ */
+ private function supplyContentReverseRelations(ContentView $view): void
+ {
+ $contentInfo = $view->getLocation()->getContentInfo();
+ $relations = $this->contentService->loadReverseRelations($contentInfo);
+
+ $view->addParameters(['content_has_reverse_relations' => count($relations) > 0]);
+ }
}
diff --git a/src/bundle/Resources/config/routing.yml b/src/bundle/Resources/config/routing.yml
index 33b2cc6ec9..40f069194d 100644
--- a/src/bundle/Resources/config/routing.yml
+++ b/src/bundle/Resources/config/routing.yml
@@ -465,6 +465,12 @@ ezplatform.content.update_main_translation:
defaults:
_controller: 'EzPlatformAdminUiBundle:Content:updateMainTranslation'
+ezplatform.content.update_visibility:
+ path: /content/update-visibility
+ methods: ['POST']
+ defaults:
+ _controller: 'EzPlatformAdminUiBundle:Content:updateVisibility'
+
# LocationView / Versions tab
ezplatform.version.remove:
diff --git a/src/bundle/Resources/encore/ez.js.config.js b/src/bundle/Resources/encore/ez.js.config.js
index 7cdd3f58d5..9f264e4e47 100644
--- a/src/bundle/Resources/encore/ez.js.config.js
+++ b/src/bundle/Resources/encore/ez.js.config.js
@@ -185,6 +185,8 @@ module.exports = (Encore) => {
path.resolve('./vendor/ezsystems/ezplatform-admin-ui-assets/Resources/public/vendors/leaflet/dist/leaflet.js'),
path.resolve(__dirname, '../public/js/scripts/admin.location.load.map.js'),
path.resolve(__dirname, '../public/js/scripts/sidebar/btn/content.edit.js'),
+ path.resolve(__dirname, '../public/js/scripts/sidebar/btn/content.hide.js'),
+ path.resolve(__dirname, '../public/js/scripts/sidebar/btn/content.reveal.js'),
path.resolve(__dirname, '../public/js/scripts/admin.location.add.custom_url.js'),
path.resolve(__dirname, '../public/js/scripts/button.state.toggle.js'),
path.resolve(__dirname, '../public/js/scripts/admin.version.edit.conflict.js'),
diff --git a/src/bundle/Resources/public/img/ez-icons.svg b/src/bundle/Resources/public/img/ez-icons.svg
index bee6033ed7..3fb89adc67 100644
--- a/src/bundle/Resources/public/img/ez-icons.svg
+++ b/src/bundle/Resources/public/img/ez-icons.svg
@@ -272,6 +272,9 @@
+
+
+
@@ -470,6 +473,10 @@
+
+
+
+
diff --git a/src/bundle/Resources/public/img/icons/hide.svg b/src/bundle/Resources/public/img/icons/hide.svg
new file mode 100644
index 0000000000..20826df32f
--- /dev/null
+++ b/src/bundle/Resources/public/img/icons/hide.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/bundle/Resources/public/img/icons/reveal.svg b/src/bundle/Resources/public/img/icons/reveal.svg
new file mode 100644
index 0000000000..14257215c1
--- /dev/null
+++ b/src/bundle/Resources/public/img/icons/reveal.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/bundle/Resources/public/js/scripts/sidebar/btn/content.hide.js b/src/bundle/Resources/public/js/scripts/sidebar/btn/content.hide.js
new file mode 100644
index 0000000000..3b04e4eeb0
--- /dev/null
+++ b/src/bundle/Resources/public/js/scripts/sidebar/btn/content.hide.js
@@ -0,0 +1,30 @@
+(function(global, doc, $) {
+ const hideButton = doc.querySelector('.ez-btn--hide');
+ const modal = doc.querySelector('#hide-content-modal');
+ const form = doc.querySelector('form[name="content_visibility_update"]');
+ const visiblity = doc.querySelector('#content_visibility_update_visible');
+
+ if (!hideButton) {
+ return;
+ }
+
+ if (modal) {
+ modal.querySelector('.btn-confirm').addEventListener('click', () => {
+ visiblity.value = 0;
+ form.submit();
+ });
+ }
+
+ hideButton.addEventListener(
+ 'click',
+ () => {
+ if (modal) {
+ $(modal).modal('show');
+ } else {
+ visiblity.value = 0;
+ form.submit();
+ }
+ },
+ false
+ );
+})(window, document, window.jQuery);
diff --git a/src/bundle/Resources/public/js/scripts/sidebar/btn/content.reveal.js b/src/bundle/Resources/public/js/scripts/sidebar/btn/content.reveal.js
new file mode 100644
index 0000000000..b2720e6e4a
--- /dev/null
+++ b/src/bundle/Resources/public/js/scripts/sidebar/btn/content.reveal.js
@@ -0,0 +1,18 @@
+(function(global, doc) {
+ const revealButton = doc.querySelector('.ez-btn--reveal');
+ const form = doc.querySelector('form[name="content_visibility_update"]');
+ const visiblity = doc.querySelector('#content_visibility_update_visible');
+
+ if (!revealButton) {
+ return;
+ }
+
+ revealButton.addEventListener(
+ 'click',
+ () => {
+ visiblity.value = 1;
+ form.submit();
+ },
+ false
+ );
+})(window, document);
diff --git a/src/bundle/Resources/public/scss/_alerts.scss b/src/bundle/Resources/public/scss/_alerts.scss
index acb4b996d6..e9dedb6427 100644
--- a/src/bundle/Resources/public/scss/_alerts.scss
+++ b/src/bundle/Resources/public/scss/_alerts.scss
@@ -5,5 +5,7 @@
padding: 0.35rem 1rem;
border: 0;
font-style: italic;
+ fill: currentColor;
+ vertical-align: middle;
}
-}
+}
\ No newline at end of file
diff --git a/src/bundle/Resources/public/scss/_mixins.scss b/src/bundle/Resources/public/scss/_mixins.scss
index 083acf71f0..aec035743e 100644
--- a/src/bundle/Resources/public/scss/_mixins.scss
+++ b/src/bundle/Resources/public/scss/_mixins.scss
@@ -51,6 +51,11 @@
}
}
+ &.disabled {
+ cursor: inherit;
+ opacity: 0.5;
+ }
+
.ez-checkbox-icon__checkbox {
display: none;
}
diff --git a/src/bundle/Resources/public/scss/_modals.scss b/src/bundle/Resources/public/scss/_modals.scss
index 02fa69c8fa..ce27378feb 100644
--- a/src/bundle/Resources/public/scss/_modals.scss
+++ b/src/bundle/Resources/public/scss/_modals.scss
@@ -116,6 +116,13 @@
}
}
+.ez-modal--content-hide-confirmation {
+ .modal-header {
+ background: $ez-color-base-pale;
+ border-bottom: none;
+ }
+}
+
.ez-modal--version-draft-conflict {
.modal-header {
background: $ez-color-base-pale;
diff --git a/src/bundle/Resources/translations/content.en.xliff b/src/bundle/Resources/translations/content.en.xliff
index 4f610eb3db..5be5e3a971 100644
--- a/src/bundle/Resources/translations/content.en.xliff
+++ b/src/bundle/Resources/translations/content.en.xliff
@@ -26,6 +26,26 @@
User with login '%login%' deleted.
key: user.delete.success
+
+ Content '%name%' has been hidden.
+ Content '%name%' has been hidden.
+ key: content.hide.success
+
+
+ Content '%name%' has been revealed.
+ Content '%name%' has been revealed.
+ key: content.reveal.success
+
+
+ Content '%name%' was already hidden.
+ Content '%name%' has been hidden.
+ key: content.hide.already_hidden
+
+
+ Content '%name%' was already visible.
+ Content '%name%' was already visible.
+ key: content.reveal.already_visible
+