mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-22 11:52:30 +00:00
Added language select to the user create form
- Updated user invite to take language from user. - Added tests to cover. - Added page/tab title to user create view. For #2576 and #2408
This commit is contained in:
parent
f83cc83877
commit
6eadf3efb3
7 changed files with 79 additions and 32 deletions
app
resources/views/users
tests
|
@ -62,6 +62,7 @@ class UserController extends Controller
|
||||||
$this->checkPermission('users-manage');
|
$this->checkPermission('users-manage');
|
||||||
$authMethod = config('auth.method');
|
$authMethod = config('auth.method');
|
||||||
$roles = $this->userRepo->getAllRoles();
|
$roles = $this->userRepo->getAllRoles();
|
||||||
|
$this->setPageTitle(trans('settings.users_add_new'));
|
||||||
|
|
||||||
return view('users.create', ['authMethod' => $authMethod, 'roles' => $roles]);
|
return view('users.create', ['authMethod' => $authMethod, 'roles' => $roles]);
|
||||||
}
|
}
|
||||||
|
@ -78,6 +79,7 @@ class UserController extends Controller
|
||||||
$validationRules = [
|
$validationRules = [
|
||||||
'name' => ['required'],
|
'name' => ['required'],
|
||||||
'email' => ['required', 'email', 'unique:users,email'],
|
'email' => ['required', 'email', 'unique:users,email'],
|
||||||
|
'setting' => ['array'],
|
||||||
];
|
];
|
||||||
|
|
||||||
$authMethod = config('auth.method');
|
$authMethod = config('auth.method');
|
||||||
|
@ -104,6 +106,13 @@ class UserController extends Controller
|
||||||
DB::transaction(function () use ($user, $sendInvite, $request) {
|
DB::transaction(function () use ($user, $sendInvite, $request) {
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
|
// Save user-specific settings
|
||||||
|
if ($request->filled('setting')) {
|
||||||
|
foreach ($request->get('setting') as $key => $value) {
|
||||||
|
setting()->putUser($user, $key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($sendInvite) {
|
if ($sendInvite) {
|
||||||
$this->inviteService->sendInvitation($user);
|
$this->inviteService->sendInvitation($user);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +207,7 @@ class UserController extends Controller
|
||||||
$user->external_auth_id = $request->get('external_auth_id');
|
$user->external_auth_id = $request->get('external_auth_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save an user-specific settings
|
// Save user-specific settings
|
||||||
if ($request->filled('setting')) {
|
if ($request->filled('setting')) {
|
||||||
foreach ($request->get('setting') as $key => $value) {
|
foreach ($request->get('setting') as $key => $value) {
|
||||||
setting()->putUser($user, $key, $value);
|
setting()->putUser($user, $key, $value);
|
||||||
|
|
|
@ -2,35 +2,33 @@
|
||||||
|
|
||||||
namespace BookStack\Notifications;
|
namespace BookStack\Notifications;
|
||||||
|
|
||||||
|
use BookStack\Auth\User;
|
||||||
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
|
||||||
class UserInvite extends MailNotification
|
class UserInvite extends MailNotification
|
||||||
{
|
{
|
||||||
public $token;
|
public $token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new notification instance.
|
* Create a new notification instance.
|
||||||
*
|
|
||||||
* @param string $token
|
|
||||||
*/
|
*/
|
||||||
public function __construct($token)
|
public function __construct(string $token)
|
||||||
{
|
{
|
||||||
$this->token = $token;
|
$this->token = $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the mail representation of the notification.
|
* Get the mail representation of the notification.
|
||||||
*
|
|
||||||
* @param mixed $notifiable
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Notifications\Messages\MailMessage
|
|
||||||
*/
|
*/
|
||||||
public function toMail($notifiable)
|
public function toMail(User $notifiable): MailMessage
|
||||||
{
|
{
|
||||||
$appName = ['appName' => setting('app-name')];
|
$appName = ['appName' => setting('app-name')];
|
||||||
|
$language = setting()->getUser($notifiable, 'language');
|
||||||
|
|
||||||
return $this->newMailMessage()
|
return $this->newMailMessage()
|
||||||
->subject(trans('auth.user_invite_email_subject', $appName))
|
->subject(trans('auth.user_invite_email_subject', $appName, $language))
|
||||||
->greeting(trans('auth.user_invite_email_greeting', $appName))
|
->greeting(trans('auth.user_invite_email_greeting', $appName, $language))
|
||||||
->line(trans('auth.user_invite_email_text'))
|
->line(trans('auth.user_invite_email_text', [], $language))
|
||||||
->action(trans('auth.user_invite_email_action'), url('/register/invite/' . $this->token));
|
->action(trans('auth.user_invite_email_action', [], $language), url('/register/invite/' . $this->token));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
<div class="setting-list">
|
<div class="setting-list">
|
||||||
@include('users.parts.form')
|
@include('users.parts.form')
|
||||||
|
@include('users.parts.language-option-row', ['value' => old('setting.language') ?? config('app.default_locale')])
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group text-right">
|
<div class="form-group text-right">
|
||||||
|
|
|
@ -35,22 +35,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid half gap-xl v-center">
|
@include('users.parts.language-option-row', ['value' => setting()->getUser($user, 'language', config('app.default_locale'))])
|
||||||
<div>
|
|
||||||
<label for="user-language" class="setting-list-label">{{ trans('settings.users_preferred_language') }}</label>
|
|
||||||
<p class="small">
|
|
||||||
{{ trans('settings.users_preferred_language_desc') }}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<select name="setting[language]" id="user-language">
|
|
||||||
@foreach(trans('settings.language_select') as $lang => $label)
|
|
||||||
<option @if(setting()->getUser($user, 'language', config('app.default_locale')) === $lang) selected @endif value="{{ $lang }}">{{ $label }}</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
|
|
18
resources/views/users/parts/language-option-row.blade.php
Normal file
18
resources/views/users/parts/language-option-row.blade.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{{--
|
||||||
|
$value - Currently selected lanuage value
|
||||||
|
--}}
|
||||||
|
<div class="grid half gap-xl v-center">
|
||||||
|
<div>
|
||||||
|
<label for="user-language" class="setting-list-label">{{ trans('settings.users_preferred_language') }}</label>
|
||||||
|
<p class="small">
|
||||||
|
{{ trans('settings.users_preferred_language_desc') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<select name="setting[language]" id="user-language">
|
||||||
|
@foreach(trans('settings.language_select') as $lang => $label)
|
||||||
|
<option @if($value === $lang) selected @endif value="{{ $lang }}">{{ $label }}</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -6,6 +6,7 @@ use BookStack\Auth\Access\UserInviteService;
|
||||||
use BookStack\Auth\User;
|
use BookStack\Auth\User;
|
||||||
use BookStack\Notifications\UserInvite;
|
use BookStack\Notifications\UserInvite;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Notification;
|
use Illuminate\Support\Facades\Notification;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
@ -20,8 +21,8 @@ class UserInviteTest extends TestCase
|
||||||
|
|
||||||
$email = Str::random(16) . '@example.com';
|
$email = Str::random(16) . '@example.com';
|
||||||
$resp = $this->actingAs($admin)->post('/settings/users/create', [
|
$resp = $this->actingAs($admin)->post('/settings/users/create', [
|
||||||
'name' => 'Barry',
|
'name' => 'Barry',
|
||||||
'email' => $email,
|
'email' => $email,
|
||||||
'send_invite' => 'true',
|
'send_invite' => 'true',
|
||||||
]);
|
]);
|
||||||
$resp->assertRedirect('/settings/users');
|
$resp->assertRedirect('/settings/users');
|
||||||
|
@ -34,6 +35,31 @@ class UserInviteTest extends TestCase
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_user_invite_sent_in_selected_language()
|
||||||
|
{
|
||||||
|
Notification::fake();
|
||||||
|
$admin = $this->getAdmin();
|
||||||
|
|
||||||
|
$email = Str::random(16) . '@example.com';
|
||||||
|
$resp = $this->actingAs($admin)->post('/settings/users/create', [
|
||||||
|
'name' => 'Barry',
|
||||||
|
'email' => $email,
|
||||||
|
'send_invite' => 'true',
|
||||||
|
'setting' => [
|
||||||
|
'language' => 'de',
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
$resp->assertRedirect('/settings/users');
|
||||||
|
|
||||||
|
$newUser = User::query()->where('email', '=', $email)->orderBy('id', 'desc')->first();
|
||||||
|
Notification::assertSentTo($newUser, UserInvite::class, function ($notification, $channels, $notifiable) {
|
||||||
|
/** @var MailMessage $mail */
|
||||||
|
$mail = $notification->toMail($notifiable);
|
||||||
|
return 'Du wurdest eingeladen BookStack beizutreten!' === $mail->subject &&
|
||||||
|
'Ein Konto wurde für Sie auf BookStack erstellt.' === $mail->greeting;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public function test_invite_set_password()
|
public function test_invite_set_password()
|
||||||
{
|
{
|
||||||
Notification::fake();
|
Notification::fake();
|
||||||
|
@ -54,7 +80,7 @@ class UserInviteTest extends TestCase
|
||||||
]);
|
]);
|
||||||
$setPasswordResp->assertSee('Password set, you should now be able to login using your set password to access BookStack!');
|
$setPasswordResp->assertSee('Password set, you should now be able to login using your set password to access BookStack!');
|
||||||
$newPasswordValid = auth()->validate([
|
$newPasswordValid = auth()->validate([
|
||||||
'email' => $user->email,
|
'email' => $user->email,
|
||||||
'password' => 'my test password',
|
'password' => 'my test password',
|
||||||
]);
|
]);
|
||||||
$this->assertTrue($newPasswordValid);
|
$this->assertTrue($newPasswordValid);
|
||||||
|
|
|
@ -183,6 +183,16 @@ class UserManagementTest extends TestCase
|
||||||
$resp->assertSee('cannot delete the guest user');
|
$resp->assertSee('cannot delete the guest user');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_user_create_language_reflects_default_system_locale()
|
||||||
|
{
|
||||||
|
$langs = ['en', 'fr', 'hr'];
|
||||||
|
foreach ($langs as $lang) {
|
||||||
|
config()->set('app.locale', $lang);
|
||||||
|
$resp = $this->asAdmin()->get('/settings/users/create');
|
||||||
|
$resp->assertElementExists('select[name="setting[language]"] option[value="' . $lang . '"][selected]');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function test_user_creation_is_not_performed_if_the_invitation_sending_fails()
|
public function test_user_creation_is_not_performed_if_the_invitation_sending_fails()
|
||||||
{
|
{
|
||||||
/** @var User $user */
|
/** @var User $user */
|
||||||
|
|
Loading…
Add table
Reference in a new issue