');
}
catch (WorkspaceAccessException $e) {
$this->messenger->addError($this->t('You do not have access to activate the %workspace_label workspace.', ['%workspace_label' => $workspace->label()]));
diff --git a/core/modules/workspace/src/WorkspaceListBuilder.php b/core/modules/workspace/src/WorkspaceListBuilder.php
index f6bb9340ec228129436256f5e7bfcb344561ff73..c2140bde7be030e2cd0e40a8c2ba022699a893f9 100644
--- a/core/modules/workspace/src/WorkspaceListBuilder.php
+++ b/core/modules/workspace/src/WorkspaceListBuilder.php
@@ -2,10 +2,13 @@
namespace Drupal\workspace;
+use Drupal\Component\Serialization\Json;
+use Drupal\Core\Ajax\AjaxHelperTrait;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityListBuilder;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -15,6 +18,8 @@
*/
class WorkspaceListBuilder extends EntityListBuilder {
+ use AjaxHelperTrait;
+
/**
* The workspace manager service.
*
@@ -54,7 +59,6 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
public function buildHeader() {
$header['label'] = $this->t('Workspace');
$header['uid'] = $this->t('Owner');
- $header['status'] = $this->t('Status');
return $header + parent::buildHeader();
}
@@ -64,12 +68,17 @@ public function buildHeader() {
*/
public function buildRow(EntityInterface $entity) {
/** @var \Drupal\workspace\WorkspaceInterface $entity */
- $row['label'] = $this->t('@label (@id)', ['@label' => $entity->label(), '@id' => $entity->id()]);
- $row['owner'] = $entity->getOwner()->getDisplayname();
- $active_workspace = $this->workspaceManager->getActiveWorkspace()->id();
- $row['status'] = $active_workspace == $entity->id() ? $this->t('Active') : $this->t('Inactive');
+ $row['data'] = [
+ 'label' => $entity->label(),
+ 'owner' => $entity->getOwner()->getDisplayname(),
+ ];
+ $row['data'] = $row['data'] + parent::buildRow($entity);
- return $row + parent::buildRow($entity);
+ $active_workspace = $this->workspaceManager->getActiveWorkspace();
+ if ($entity->id() === $active_workspace->id()) {
+ $row['class'] = 'active-workspace';
+ }
+ return $row;
}
/**
@@ -85,7 +94,7 @@ public function getDefaultOperations(EntityInterface $entity) {
$active_workspace = $this->workspaceManager->getActiveWorkspace();
if ($entity->id() != $active_workspace->id()) {
$operations['activate'] = [
- 'title' => $this->t('Set Active'),
+ 'title' => $this->t('Switch to @workspace', ['@workspace' => $entity->label()]),
// Use a weight lower than the one of the 'Edit' operation because we
// want the 'Activate' operation to be the primary operation.
'weight' => 0,
@@ -106,4 +115,126 @@ public function getDefaultOperations(EntityInterface $entity) {
return $operations;
}
+ /**
+ * {@inheritdoc}
+ */
+ public function load() {
+ $entities = parent::load();
+ // Make the active workspace more visible by moving it first in the list.
+ $active_workspace = $this->workspaceManager->getActiveWorkspace();
+ $entities = [$active_workspace->id() => $entities[$active_workspace->id()]] + $entities;
+ return $entities;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function render() {
+ $build = parent::render();
+ if ($this->isAjax()) {
+ $this->offCanvasRender($build);
+ }
+ else {
+ $build['#attached'] = [
+ 'library' => ['workspace/drupal.workspace.overview'],
+ ];
+ }
+ return $build;
+ }
+
+ /**
+ * Renders the off canvas elements.
+ *
+ * @param array $build
+ * A render array.
+ */
+ protected function offCanvasRender(array &$build) {
+ $active_workspace = $this->workspaceManager->getActiveWorkspace();
+ $row_count = count($build['table']['#rows']);
+ $build['active_workspace'] = [
+ '#type' => 'container',
+ '#weight' => -20,
+ '#attributes' => [
+ 'class' => [
+ 'active-workspace',
+ $active_workspace->isDefaultWorkspace() ? 'active-workspace--default' : 'active-workspace--not-default',
+ 'active-workspace--' . $active_workspace->id(),
+ ],
+ ],
+ 'label' => [
+ '#type' => 'label',
+ '#prefix' => '' . $this->t('Current workspace:') . '
',
+ '#title' => $active_workspace->label(),
+ '#title_display' => '',
+ '#attributes' => ['class' => 'active-workspace__label'],
+ ],
+ 'manage' => [
+ '#type' => 'link',
+ '#title' => $this->t('Manage workspaces'),
+ '#url' => $active_workspace->toUrl('collection'),
+ '#attributes' => [
+ 'class' => ['active-workspace__manage'],
+ ],
+ ],
+ ];
+ if (!$active_workspace->isDefaultWorkspace()) {
+ $build['active_workspace']['actions'] = [
+ '#type' => 'container',
+ '#weight' => 20,
+ '#attributes' => [
+ 'class' => ['active-workspace__actions'],
+ ],
+ 'deploy' => [
+ '#type' => 'link',
+ '#title' => $this->t('Deploy content'),
+ '#url' => $active_workspace->toUrl('deploy-form', ['query' => ['destination' => $active_workspace->toUrl('collection')->toString()]]),
+ '#attributes' => [
+ 'class' => ['button', 'active-workspace__button'],
+ ],
+ ],
+ ];
+ }
+ if ($row_count > 2) {
+ $build['all_workspaces'] = [
+ '#type' => 'link',
+ '#title' => $this->t('View all @count workspaces', ['@count' => $row_count]),
+ '#url' => $active_workspace->toUrl('collection'),
+ '#attributes' => [
+ 'class' => ['all-workspaces'],
+ ],
+ ];
+ }
+ $items = [];
+ $rows = array_slice($build['table']['#rows'], 0, 5, TRUE);
+ foreach ($rows as $id => $row) {
+ if ($active_workspace->id() !== $id) {
+ $url = Url::fromRoute('entity.workspace.activate_form', ['workspace' => $id]);
+ $default_class = $id === WorkspaceInterface::DEFAULT_WORKSPACE ? 'workspaces__item--default' : 'workspaces__item--not-default';
+ $items[] = [
+ '#type' => 'link',
+ '#title' => $row['data']['label'],
+ '#url' => $url,
+ '#attributes' => [
+ 'class' => ['use-ajax', 'workspaces__item', $default_class],
+ 'data-dialog-type' => 'modal',
+ 'data-dialog-options' => Json::encode([
+ 'width' => 500,
+ ]),
+ ],
+ ];
+ }
+ }
+ $build['workspaces'] = [
+ '#theme' => 'item_list',
+ '#items' => $items,
+ '#wrapper_attributes' => ['class' => ['workspaces']],
+ '#cache' => [
+ 'contexts' => $this->entityType->getListCacheContexts(),
+ 'tags' => $this->entityType->getListCacheTags(),
+ ],
+ ];
+ unset($build['table']);
+ unset($build['pager']);
+ }
+
}
diff --git a/core/modules/workspace/workspace.libraries.yml b/core/modules/workspace/workspace.libraries.yml
index c7aad42bb36f3caf41da3f7c964913b9a8778967..a480f90ef7e4e0529fa08e9afeab19e1b04dc177 100644
--- a/core/modules/workspace/workspace.libraries.yml
+++ b/core/modules/workspace/workspace.libraries.yml
@@ -3,3 +3,8 @@ drupal.workspace.toolbar:
css:
theme:
css/workspace.toolbar.css: {}
+drupal.workspace.overview:
+ version: VERSION
+ css:
+ theme:
+ css/workspace.overview.css: {}
diff --git a/core/modules/workspace/workspace.module b/core/modules/workspace/workspace.module
index ced2be46b4467e0c97637b23bf677404028a0dec..4be4141e4bab1ba068f24e9faee3927eefbb5007 100644
--- a/core/modules/workspace/workspace.module
+++ b/core/modules/workspace/workspace.module
@@ -6,8 +6,6 @@
*/
use Drupal\Component\Serialization\Json;
-use Drupal\Core\Cache\Cache;
-use Drupal\Core\Url;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
@@ -164,16 +162,6 @@ function workspace_toolbar() {
/** @var \Drupal\workspace\WorkspaceInterface $active_workspace */
$active_workspace = \Drupal::service('workspace.manager')->getActiveWorkspace();
- $configure_link = NULL;
- if ($current_user->hasPermission('administer workspaces')) {
- $configure_link = [
- '#type' => 'link',
- '#title' => t('Manage workspaces'),
- '#url' => $active_workspace->toUrl('collection'),
- '#options' => ['attributes' => ['class' => ['manage-workspaces']]],
- ];
- }
-
$items['workspace'] = [
'#type' => 'toolbar_item',
'tab' => [
@@ -182,14 +170,17 @@ function workspace_toolbar() {
'#url' => $active_workspace->toUrl('collection'),
'#attributes' => [
'title' => t('Switch workspace'),
- 'class' => ['toolbar-icon', 'toolbar-icon-workspace'],
+ 'class' => ['use-ajax', 'toolbar-icon', 'toolbar-icon-workspace'],
+ 'data-dialog-type' => 'dialog',
+ 'data-dialog-renderer' => 'off_canvas_top',
+ 'data-dialog-options' => Json::encode([
+ 'height' => 161,
+ 'classes' => [
+ 'ui-dialog' => 'workspace-dialog',
+ ],
+ ]),
],
],
- 'tray' => [
- '#heading' => t('Workspaces'),
- 'workspaces' => workspace_build_renderable_links(),
- 'configure' => $configure_link,
- ],
'#wrapper_attributes' => [
'class' => ['workspace-toolbar-tab'],
],
@@ -207,61 +198,3 @@ function workspace_toolbar() {
return $items;
}
-
-/**
- * Returns an array of workspace activation form links, suitable for rendering.
- *
- * @return array
- * A render array containing links to the workspace activation form.
- */
-function workspace_build_renderable_links() {
- $entity_type_manager = \Drupal::entityTypeManager();
- /** @var \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository */
- $entity_repository = \Drupal::service('entity.repository');
- /** @var \Drupal\workspace\WorkspaceInterface $active_workspace */
- $active_workspace = \Drupal::service('workspace.manager')->getActiveWorkspace();
-
- $links = $cache_tags = [];
- foreach ($entity_type_manager->getStorage('workspace')->loadMultiple() as $workspace) {
- $workspace = $entity_repository->getTranslationFromContext($workspace);
-
- // Add the 'is-active' class for the currently active workspace.
- $options = [];
- if ($workspace->id() === $active_workspace->id()) {
- $options['attributes']['class'][] = 'is-active';
- }
-
- // Get the URL of the workspace activation form and display it in a modal.
- $url = Url::fromRoute('entity.workspace.activate_form', ['workspace' => $workspace->id()], $options);
- if ($url->access()) {
- $links[$workspace->id()] = [
- 'type' => 'link',
- 'title' => $workspace->label(),
- 'url' => $url,
- 'attributes' => [
- 'class' => ['use-ajax'],
- 'data-dialog-type' => 'modal',
- 'data-dialog-options' => Json::encode([
- 'width' => 500,
- ]),
- ],
- ];
- $cache_tags = Cache::mergeTags($cache_tags, $workspace->getCacheTags());
- }
- }
-
- if (!empty($links)) {
- $links = [
- '#theme' => 'links__toolbar_workspaces',
- '#links' => $links,
- '#attributes' => [
- 'class' => ['toolbar-menu'],
- ],
- '#cache' => [
- 'tags' => $cache_tags,
- ],
- ];
- }
-
- return $links;
-}