Refactor auto start tour for new user (#6685)

* Refactor auto start tour for new user

* Revert "Auxiliary commit to revert individual files from b63f530b8626802c66e10a241ba4ddfa670f8c65"

This reverts commit c9ebfdc71d1dd2f1d2dd3927ae464ff3f2f0b939.

* Activate test for auto tour

* Fix test

* Fix test

* Refactor displaying of dashboard sidebar tour widget

* Refactor auto start tour for new registered user

* Don't use session for displaying of dashboard sidebar tour widget

* Fix auto tour test

* Don't redirect after init auto start tour

* Update deprecated actions

---------

Co-authored-by: Lucas Bartholemy <luke-@users.noreply.github.com>
This commit is contained in:
Yuriy Bakhtin 2023-12-11 11:44:33 +01:00 committed by GitHub
parent b047a6c4d4
commit 6a59ba2943
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 173 additions and 98 deletions

View File

@ -59,8 +59,8 @@ jobs:
run: |
docker run --detach --net=host --shm-size="2g" selenium/standalone-chrome
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
# - name: Setup cache environment
# id: cache-env
@ -71,7 +71,7 @@ jobs:
# key: ${{ env.key }}
# - name: Cache extensions
# uses: actions/cache@v1
# uses: actions/cache@v3
# with:
# path: ${{ steps.cache-env.outputs.dir }}
# key: ${{ steps.cache-env.outputs.key }}
@ -92,7 +92,7 @@ jobs:
run: composer validate
- name: Cache dependencies installed with composer
uses: actions/cache@v1
uses: actions/cache@v3
with:
path: ${{ env.COMPOSER_CACHE_DIR }}
key: php${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }}

View File

@ -17,6 +17,7 @@ HumHub Changelog
- Fix #6674: Fix visibility of draft and scheduled content on dashboard
- Fix #6679: On the space invitation by link page, the language chooser doesn't save the selected language
- Fix #6677: Do not check mobile push module in requirements check on installation
- Fix #6678: Refactor auto start tour for new user
- Fix #6694: Remove the "Offline" tooltip when my own "Online" status is not displayed
- Fix #6700: Reload theme variable `@baseTheme` after flushing cache

View File

@ -0,0 +1,49 @@
<?php
/**
* @link https://www.humhub.org/
* @copyright Copyright (c) HumHub GmbH & Co. KG
* @license https://www.humhub.com/licences
*/
namespace humhub\modules\tour;
use humhub\modules\dashboard\widgets\Sidebar;
use humhub\modules\tour\widgets\Dashboard as DashboardWidget;
use humhub\modules\tour\widgets\Tour;
use humhub\modules\user\models\User;
use Yii;
/**
* Events provides callbacks for all defined module events.
*
* @since 1.15
*/
class Events
{
public static function onDashboardSidebarInit($event)
{
if (Yii::$app->user->isGuest) {
return;
}
if (DashboardWidget::isVisible()) {
/* @var Sidebar $sidebar */
$sidebar = $event->sender;
$sidebar->addWidget(DashboardWidget::class, [], ['sortOrder' => 100]);
}
}
public static function onUserBeforeLogin($event)
{
if ($event->identity instanceof User && self::shouldStartWelcomeTour($event->identity)) {
Tour::enableAutoStart('dashboard', $event->identity);
}
}
private static function shouldStartWelcomeTour(?User $user = null): bool
{
return $user->last_login === null && // Force auto start only for new created user who is logged in first time after registration
DashboardWidget::isVisible($user) && // Start it only when the dashboard sidebar widget is visible for the user
!Yii::$app->getModule('tour')->showWelcomeWindow($user); // No need auto start because it will be done by dashboard widget
}
}

View File

@ -2,9 +2,8 @@
namespace humhub\modules\tour;
use Yii;
use humhub\modules\tour\widgets\Dashboard;
use humhub\modules\user\models\User;
use Yii;
/**
* This module shows an introduction tour for new users
@ -25,68 +24,20 @@ class Module extends \humhub\components\Module
public $isCoreModule = true;
/**
* @var bool enable auto-start tour for new accounts
* @since 1.15
*/
public $autoStartOnNewAccounts = false;
/**
* Check is first login
* @since 1.15
* Check if the welcome tour window should be displayed automatically
*
* @param User $user
* @param User|null $user
* @return bool
*/
private function getIsFirstLogin(User $user): bool
public function showWelcomeWindow(?User $user = null): bool
{
$settings = Yii::$app->getModule('tour')->settings;
$showWelcome = (
$user->id == 1 &&
if ($user === null && !Yii::$app->user->isGuest) {
$user = Yii::$app->user->identity;
}
return $user instanceof User &&
$user->id === 1 &&
Yii::$app->getModule('installer')->settings->get('sampleData') != 1 &&
$settings->user()->get('welcome') != 1
);
return (
!$showWelcome &&
$user->updated_by === null &&
$user->created_at === $user->updated_at
);
}
/**
* Set updated_by for current user
* @since 1.15
*
* @param User $user
* @return void
*/
private function setFirstLoginDone(User $user)
{
$user->updateAttributes(['updated_by' => $user->id]);
}
/**
* Event Callback
*/
public static function onDashboardSidebarInit($event)
{
if (Yii::$app->user->isGuest) {
return;
}
/** @var Module $module */
$module = Yii::$app->getModule('tour');
$settings = $module->settings;
if ($settings->get('enable') == 1 && $settings->user()->get("hideTourPanel") != 1) {
$module->autoStartOnNewAccounts = $module->getIsFirstLogin(Yii::$app->user->identity);
if ($module->autoStartOnNewAccounts) {
$module->setFirstLoginDone(Yii::$app->user->identity);
Yii::$app->getResponse()->redirect(['/dashboard/dashboard', 'tour' => true]);
} else {
$event->sender->addWidget(Dashboard::class, [], ['sortOrder' => 100]);
}
}
$this->settings->user($user)->get('welcome') != 1;
}
}

View File

@ -1,13 +1,16 @@
<?php
use humhub\modules\dashboard\widgets\Sidebar;
use humhub\modules\tour\Events;
use humhub\modules\tour\Module;
use yii\web\User;
return [
'id' => 'tour',
'class' => Module::class,
'isCoreModule' => true,
'events' => [
['class' => Sidebar::class, 'event' => Sidebar::EVENT_INIT, 'callback' => [Module::class, 'onDashboardSidebarInit']],
[Sidebar::class, Sidebar::EVENT_INIT, [Events::class, 'onDashboardSidebarInit']],
[User::class, User::EVENT_BEFORE_LOGIN, [Events::class, 'onUserBeforeLogin']],
],
];

View File

@ -20,3 +20,6 @@ modules:
browser: chrome
port: 4444
window_size: 1600x900
capabilities:
chromeOptions:
args: ["--lang=en-US"]

View File

@ -14,7 +14,6 @@ use Yii;
class AutoTourCest
{
/**
* @skip
* @param AcceptanceTester $I
* @throws \Exception
*/

View File

@ -20,6 +20,9 @@
namespace humhub\modules\tour\widgets;
use humhub\components\SettingsManager;
use humhub\modules\tour\Module;
use humhub\modules\user\models\User;
use Yii;
use yii\base\Widget;
@ -30,14 +33,25 @@ class Dashboard extends Widget
{
public function run()
{
$settingsManager = Yii::$app->getModule('tour')->settings->user();
/* @var Module $module */
$module = Yii::$app->getModule('tour');
$settingsManager = $module->settings->user();
return $this->render('tourPanel', [
'interface' => $settingsManager->get("interface"),
'spaces' => $settingsManager->get("spaces"),
'profile' => $settingsManager->get("profile"),
'administration' => $settingsManager->get("administration"),
'showWelcome' => (Yii::$app->user->id == 1 && Yii::$app->getModule('installer')->settings->get('sampleData') != 1 && $settingsManager->get('welcome') != 1)
'showWelcome' => $module->showWelcomeWindow()
]);
}
public static function isVisible(?User $user = null): bool
{
/* @var SettingsManager $settings */
$settings = Yii::$app->getModule('tour')->settings;
return $settings->get('enable') == 1 &&
$settings->user($user)->get('hideTourPanel') != 1;
}
}

View File

@ -2,7 +2,15 @@
namespace humhub\modules\tour\widgets;
use humhub\components\SettingsManager;
use humhub\components\Widget;
use humhub\modules\admin\controllers\ModuleController;
use humhub\modules\dashboard\controllers\DashboardController;
use humhub\modules\space\controllers\SpaceController;
use humhub\modules\tour\assets\TourAsset;
use humhub\modules\tour\widgets\Dashboard as DashboardWidget;
use humhub\modules\user\controllers\ProfileController;
use humhub\modules\user\models\User;
use Yii;
/**
@ -12,48 +20,53 @@ use Yii;
* @since 0.5
* @author andystrobel
*/
class Tour extends \humhub\components\Widget
class Tour extends Widget
{
private static function getTypes(): array
{
return [
'dashboard' => ['view' => 'guide_interface', 'controller' => DashboardController::class],
'space' => ['view' => 'guide_spaces', 'controller' => SpaceController::class],
'user' => ['view' => 'guide_profile', 'controller' => ProfileController::class],
'admin' => ['view' => 'guide_administration', 'controller' => ModuleController::class]
];
}
/**
* Executes the widgets
*/
public function run()
{
if (Yii::$app->user->isGuest) {
return;
return '';
}
// Active tour flag not set
if (!isset($_GET['tour'])) {
return;
// Active tour flag is not set and auto start is not enabled
if (!Yii::$app->request->get('tour') && !self::isEnabledAutoStart()) {
return '';
}
// Tour only possible when we are in a module
if (Yii::$app->controller->module === null) {
return;
return '';
}
// Check if tour is activated by admin and users
$settings = Yii::$app->getModule('tour')->settings;
if ($settings->get('enable') == 0 && $settings->user()->get("hideTourPanel") == 1) {
return;
if (!DashboardWidget::isVisible()) {
return '';
}
$type = self::getCurrentType();
if ($type === null) {
return '';
}
self::disableAutoStart($type['type']);
TourAsset::register($this->view);
// save current module and controller id's
$currentModuleId = Yii::$app->controller->module->id;
$currentControllerId = Yii::$app->controller->id;
if ($currentModuleId == "dashboard" && $currentControllerId == "dashboard") {
return $this->render('guide_interface');
} elseif ($currentModuleId == "space" && $currentControllerId == "space") {
return $this->render('guide_spaces', []);
} elseif ($currentModuleId == "user" && $currentControllerId == "profile") {
return $this->render('guide_profile', []);
} elseif ($currentModuleId == "marketplace" && $currentControllerId == "browse") {
return $this->render('guide_administration', []);
}
return $this->render($type['view']);
}
/**
@ -63,4 +76,46 @@ class Tour extends \humhub\components\Widget
{
// Dummy for old template version
}
private static function getSettings(): SettingsManager
{
return Yii::$app->getModule('tour')->settings;
}
public static function isEnabledAutoStart(?string $type = null, ?User $user = null): bool
{
if ($type === null) {
$type = self::getCurrentType();
if ($type === null) {
return false;
}
$type = $type['type'];
}
return (bool) self::getSettings()->user($user)->get('autoStartTour.' . $type, false);
}
public static function enableAutoStart(string $type, ?User $user = null)
{
self::getSettings()->user($user)->set('autoStartTour.' . $type, true);
}
public static function disableAutoStart(string $type, ?User $user = null)
{
if (self::isEnabledAutoStart($type)) {
self::getSettings()->user($user)->delete('autoStartTour.' . $type);
}
}
private static function getCurrentType(): ?array
{
foreach (self::getTypes() as $type => $tour) {
if (Yii::$app->controller instanceof $tour['controller']) {
$tour['type'] = $type;
return $tour;
}
}
return null;
}
}

View File

@ -20,12 +20,12 @@
return [
// Working Users
['id' => 1, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839c', 'status' => '1','username' => 'Admin', 'email' => 'admin@example.com', 'contentcontainer_id' => 1, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-05 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-05 05:36:19', 'updated_by' => '1', 'last_login' => '2014-08-05 05:36:16'],
['id' => 2, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839d', 'status' => '1','username' => 'User1', 'email' => 'user1@example.com', 'contentcontainer_id' => 2, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-07 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-07 05:36:02', 'updated_by' => null, 'last_login' => '2014-08-07 05:36:16'],
['id' => 3, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839e', 'status' => '1','username' => 'User2', 'email' => 'user2@example.com', 'contentcontainer_id' => 3, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:02', 'updated_by' => null, 'last_login' => '2014-08-08 05:36:16'],
['id' => 4, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839f', 'status' => '1','username' => 'User3', 'email' => 'user3@example.com', 'contentcontainer_id' => 8, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => '2014-08-08 05:36:16'],
['id' => 5, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f58399', 'status' => '0','username' => 'DisabledUser', 'email' => 'disabled@example.com', 'contentcontainer_id' => 9, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => '2014-08-07 05:36:16'],
['id' => 6, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f58390', 'status' => '2','username' => 'UnapprovedUser', 'email' => 'unnapproved@example.com', 'contentcontainer_id' => 10, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => '2014-08-07 05:36:16'],
['id' => 7, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f58391', 'status' => '2','username' => 'UnapprovedNoGroup', 'email' => 'unnapprovedNoGroup@example.com', 'contentcontainer_id' => 11, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => '2014-08-07 05:36:16'],
['id' => 8, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f58393', 'status' => '1','username' => 'AdminNotMember', 'email' => 'adminnotmember@example.com', 'contentcontainer_id' => 13, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => '2014-08-05 05:36:16'],
['id' => 1, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839c', 'status' => '1','username' => 'Admin', 'email' => 'admin@example.com', 'contentcontainer_id' => 1, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-05 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-05 05:36:19', 'updated_by' => '1', 'last_login' => null],
['id' => 2, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839d', 'status' => '1','username' => 'User1', 'email' => 'user1@example.com', 'contentcontainer_id' => 2, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-07 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-07 05:36:02', 'updated_by' => null, 'last_login' => null],
['id' => 3, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839e', 'status' => '1','username' => 'User2', 'email' => 'user2@example.com', 'contentcontainer_id' => 3, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:02', 'updated_by' => null, 'last_login' => null],
['id' => 4, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f5839f', 'status' => '1','username' => 'User3', 'email' => 'user3@example.com', 'contentcontainer_id' => 8, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => null],
['id' => 5, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f58399', 'status' => '0','username' => 'DisabledUser', 'email' => 'disabled@example.com', 'contentcontainer_id' => 9, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => null],
['id' => 6, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f58390', 'status' => '2','username' => 'UnapprovedUser', 'email' => 'unnapproved@example.com', 'contentcontainer_id' => 10, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => null],
['id' => 7, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f58391', 'status' => '2','username' => 'UnapprovedNoGroup', 'email' => 'unnapprovedNoGroup@example.com', 'contentcontainer_id' => 11, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => null],
['id' => 8, 'guid' => '01e50e0d-82cd-41fc-8b0c-552392f58393', 'status' => '1','username' => 'AdminNotMember', 'email' => 'adminnotmember@example.com', 'contentcontainer_id' => 13, 'auth_mode' => 'local', 'language' => 'en-US', 'created_at' => '2014-08-08 05:36:02', 'created_by' => null, 'updated_at' => '2014-08-08 05:36:19', 'updated_by' => '1', 'last_login' => null],
];