Initial Drupal 11 with DDEV setup
This commit is contained in:
@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\workspaces_ui\Hook;
|
||||
|
||||
use Drupal\Core\Hook\Attribute\Hook;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\StringTranslation\StringTranslationTrait;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Hook implementations for the workspaces_ui module.
|
||||
*/
|
||||
class WorkspacesUiHooks {
|
||||
|
||||
use StringTranslationTrait;
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
*/
|
||||
#[Hook('help')]
|
||||
public function help($route_name, RouteMatchInterface $route_match): ?string {
|
||||
switch ($route_name) {
|
||||
// Main module help for the Workspaces UI module.
|
||||
case 'help.page.workspaces_ui':
|
||||
$output = '';
|
||||
$output .= '<h2>' . $this->t('About') . '</h2>';
|
||||
$output .= '<p>' . $this->t('The Workspaces UI module provides an interface for managing workspaces for the <a href=":workspaces_module">Workspaces module</a>. For more information, see the <a href=":workspaces">online documentation for the Workspaces UI module</a>.', [':workspaces_module' => Url::fromRoute('help.page', ['name' => 'workspaces'])->toString(), ':workspaces' => 'https://www.drupal.org/docs/8/core/modules/workspace/overview']) . '</p>';
|
||||
return $output;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_toolbar().
|
||||
*/
|
||||
#[Hook('toolbar')]
|
||||
public function toolbar(): array {
|
||||
$items['workspace'] = [
|
||||
'#cache' => [
|
||||
'contexts' => [
|
||||
'user.permissions',
|
||||
],
|
||||
],
|
||||
];
|
||||
$current_user = \Drupal::currentUser();
|
||||
if (!$current_user->hasPermission('administer workspaces')
|
||||
&& !$current_user->hasPermission('view own workspace')
|
||||
&& !$current_user->hasPermission('view any workspace')) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
/** @var \Drupal\workspaces\WorkspaceInterface $active_workspace */
|
||||
$active_workspace = \Drupal::service('workspaces.manager')->getActiveWorkspace();
|
||||
|
||||
$items['workspace'] += [
|
||||
'#type' => 'toolbar_item',
|
||||
'tab' => [
|
||||
'#lazy_builder' => ['workspaces.lazy_builders:renderToolbarTab', []],
|
||||
'#create_placeholder' => TRUE,
|
||||
'#lazy_builder_preview' => [
|
||||
'#type' => 'link',
|
||||
'#title' => $active_workspace ? $active_workspace->label() : $this->t('Live'),
|
||||
'#url' => Url::fromRoute('entity.workspace.collection'),
|
||||
'#attributes' => [
|
||||
'class' => ['toolbar-tray-lazy-placeholder-link'],
|
||||
],
|
||||
],
|
||||
],
|
||||
'#wrapper_attributes' => [
|
||||
'class' => ['workspaces-toolbar-tab'],
|
||||
],
|
||||
'#weight' => 500,
|
||||
];
|
||||
|
||||
// Add a special class to the wrapper if we don't have an active workspace
|
||||
// so we can highlight it with a different color.
|
||||
if (!$active_workspace) {
|
||||
$items['workspace']['#wrapper_attributes']['class'][] = 'workspaces-toolbar-tab--is-default';
|
||||
}
|
||||
|
||||
// \Drupal\toolbar\Element\ToolbarItem::preRenderToolbarItem adds an
|
||||
// #attributes property to each toolbar item's tab child automatically. Lazy
|
||||
// builders don't support an #attributes property so we need to add another
|
||||
// render callback to remove the #attributes property. We start by adding
|
||||
// the defaults, and then we append our own pre render callback.
|
||||
$items['workspace'] += \Drupal::service('plugin.manager.element_info')->getInfo('toolbar_item');
|
||||
$items['workspace']['#pre_render'][] = 'workspaces.lazy_builders:removeTabAttributes';
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\workspaces_ui\Routing;
|
||||
|
||||
use Drupal\Core\Routing\RouteSubscriberBase;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
/**
|
||||
* Subscriber for Workspaces routes.
|
||||
*/
|
||||
class RouteSubscriber extends RouteSubscriberBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function alterRoutes(RouteCollection $collection): void {
|
||||
// Re-enable access to the workspace routes.
|
||||
$workspaces_routes = [
|
||||
'entity.workspace.collection',
|
||||
'entity.workspace.activate_form',
|
||||
'entity.workspace.publish_form',
|
||||
'entity.workspace.merge_form',
|
||||
'workspaces.switch_to_live',
|
||||
];
|
||||
foreach ($workspaces_routes as $workspace_route) {
|
||||
if ($route = $collection->get($workspace_route)) {
|
||||
$requirements = $route->getRequirements();
|
||||
unset($requirements['_access']);
|
||||
$route->setRequirements($requirements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\Tests\workspaces_ui\Functional;
|
||||
|
||||
use Drupal\Tests\system\Functional\Module\GenericModuleTestBase;
|
||||
|
||||
/**
|
||||
* Generic module test for workspaces_ui.
|
||||
*
|
||||
* @group workspaces_ui
|
||||
*/
|
||||
class GenericTest extends GenericModuleTestBase {
|
||||
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\Tests\workspaces_ui\FunctionalJavascript;
|
||||
|
||||
use Drupal\Tests\system\FunctionalJavascript\OffCanvasTestBase;
|
||||
use Drupal\workspaces\Entity\Workspace;
|
||||
|
||||
/**
|
||||
* Tests workspace settings stray integration.
|
||||
*
|
||||
* @group workspaces
|
||||
* @group workspaces_ui
|
||||
*/
|
||||
class WorkspaceToolbarIntegrationTest extends OffCanvasTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['toolbar', 'workspaces', 'workspaces_ui'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $defaultTheme = 'stark';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$admin_user = $this->drupalCreateUser([
|
||||
'administer workspaces',
|
||||
'access toolbar',
|
||||
'access administration pages',
|
||||
]);
|
||||
$this->drupalLogin($admin_user);
|
||||
Workspace::create(['id' => 'stage', 'label' => 'Stage'])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests workspace canvas can be toggled with JavaScript.
|
||||
*/
|
||||
public function testWorkspaceCanvasToggling(): void {
|
||||
$page = $this->getSession()->getPage();
|
||||
$assert_session = $this->assertSession();
|
||||
|
||||
// Set size for horizontal toolbar.
|
||||
$this->getSession()->resizeWindow(1200, 600);
|
||||
$this->drupalGet('<front>');
|
||||
// Wait for toolbar to appear.
|
||||
$this->assertNotEmpty($assert_session->waitForElement('css', 'body.toolbar-horizontal'));
|
||||
|
||||
// Open workspace canvas.
|
||||
$page->clickLink('Switch workspace');
|
||||
$this->waitForOffCanvasToOpen('top');
|
||||
$assert_session->elementExists('css', '.workspaces-dialog');
|
||||
|
||||
// Close Canvas.
|
||||
$page->pressButton('Close');
|
||||
$this->waitForOffCanvasToClose();
|
||||
$assert_session->assertNoElementAfterWait('css', '.workspaces-dialog');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests workspace switch and landing page behavior.
|
||||
*/
|
||||
public function testWorkspaceSwitch(): void {
|
||||
$page = $this->getSession()->getPage();
|
||||
$assert_session = $this->assertSession();
|
||||
|
||||
// Wait for toolbar to appear.
|
||||
$this->getSession()->resizeWindow(1200, 600);
|
||||
$this->drupalGet('admin');
|
||||
|
||||
// Wait for toolbar to appear.
|
||||
$this->assertNotEmpty($assert_session->waitForElement('css', 'body.toolbar-horizontal'));
|
||||
|
||||
// Open workspace canvas.
|
||||
$page->clickLink('Switch workspace');
|
||||
$this->waitForOffCanvasToOpen('top');
|
||||
|
||||
// Click 'stage' workspace and confirm switch.
|
||||
$page->clickLink('Stage');
|
||||
$this->assertElementVisibleAfterWait('css', '.workspace-activate-form.workspace-confirm-form');
|
||||
$page->find('css', '.ui-dialog-buttonset .button--primary')->click();
|
||||
$assert_session->statusMessageContainsAfterWait('Stage is now the active workspace.', 'status');
|
||||
// Make sure we stay on same page after switch.
|
||||
$assert_session->addressEquals('admin');
|
||||
}
|
||||
|
||||
}
|
||||
8
web/core/modules/workspaces_ui/workspaces_ui.info.yml
Normal file
8
web/core/modules/workspaces_ui/workspaces_ui.info.yml
Normal file
@ -0,0 +1,8 @@
|
||||
name: 'Workspaces UI'
|
||||
type: module
|
||||
description: 'Provides a user interface for creating and managing workspaces.'
|
||||
version: VERSION
|
||||
package: Core
|
||||
configure: entity.workspace.collection
|
||||
dependencies:
|
||||
- drupal:workspaces
|
||||
@ -0,0 +1,5 @@
|
||||
services:
|
||||
_defaults:
|
||||
autoconfigure: true
|
||||
workspaces_ui.route_subscriber:
|
||||
class: Drupal\workspaces_ui\Routing\RouteSubscriber
|
||||
Reference in New Issue
Block a user