Compare commits

...

25 Commits

Author SHA1 Message Date
Dan Brown
c1d30341e7 Updated version and assets for release v23.08.3 2023-09-15 13:49:40 +01:00
Dan Brown
80d2b4913b Merge branch 'v23-08' into release 2023-09-15 13:49:12 +01:00
Dan Brown
45b8d6cd0c Comments: Fixed wrong identification of parent comment
Would cause comment reply notifications to not be sent to expected user.
Updated test to cover problem case.

For #4548
2023-09-15 13:38:02 +01:00
Dan Brown
99eb3e5f71 Comments: Fixed JS error when lacking commenting permissions
The page comments component would throw an error due to references to
form elements/content, when form elements may not exist due to
permisisons.

For #4531
2023-09-11 18:40:40 +01:00
Dan Brown
15da4b98ef Updated translations with latest Crowdin changes (#4512)
Last translation merge for possible continued v23.08 branch
2023-09-07 15:57:59 +01:00
Dan Brown
21cd2d17f6 Updated sponsors and dev version 2023-09-07 14:43:29 +01:00
Dan Brown
3f473528b1 Updated version and assets for release v23.08.2 2023-09-04 12:06:50 +01:00
Dan Brown
d0dcd4f61b Merge branch 'development' into release 2023-09-04 12:06:15 +01:00
Dan Brown
ad60517536 Updated translations with latest Crowdin changes (#4506) 2023-09-04 11:48:25 +01:00
Dan Brown
2c20abc872 WYSIWYG: Fixed filtering issue causing broken page edits
Could error upon div elements without classes, including drawings.

Related to #4510 and #4509
2023-09-04 11:25:05 +01:00
Dan Brown
bde66a1396 Updated version and assets for release v23.08.1 2023-09-03 17:40:19 +01:00
Dan Brown
4de5a2d9bf Merge branch 'development' into release 2023-09-03 17:39:56 +01:00
Dan Brown
2abbcf5c0f Updated translator attribution before release v23.08.1 2023-09-03 17:35:57 +01:00
Dan Brown
7a48516bf4 Updated translations with latest Crowdin changes (#4481) 2023-09-03 17:23:40 +01:00
Dan Brown
e31b50dabd Preferences: Fixed section screen flexibility
Improved wrapping and flex control to prevent button text force wrapping
to newlines.

For #4502
2023-09-03 16:58:29 +01:00
Dan Brown
817581aa0c Watching: Prevent issues when watchable or user is deleted
- Adds filtering to the watched items list in notification preferences
  so that deleted (recycle bin) items are removed via query.
- Adds relations and logic to properly remove watches upon user and
  entity delete events, to old watches in database do not linger.
- Adds testing to cover the above.

Did not add migration for existing data, since patch will be close to
introduction, and lingering DB entries don't open a security concern,
just some potential confusion in specific potential scenarios.
Probably not work extra migration risk, although could add in future if
concerns/issues are found.

Related to #4499
2023-09-03 14:19:43 +01:00
Dan Brown
1cd19c76ba Merge pull request #4497 from BookStackApp/notification_language
Notifications: User language for notification text
2023-09-02 15:47:26 +01:00
Dan Brown
5d38ae3c97 Merge pull request #4484 from omahs/patch-1
Fix typos
2023-09-02 15:44:01 +01:00
Dan Brown
a720b3725d Testing: Added entity decode flag and phpunit env option
- Passed decode flags to provide consistent behaviour across PHP
  versions during testing.
- Added env option to prevent local option taking action in PHPunit
  tests.
2023-09-02 15:39:45 +01:00
Dan Brown
3847a76134 Notifications: Aligned how user language is used
- This ensures content notifications are not translated to receiver
  language.
- This adds actual plaintext support for content notifications (Was
  previously just HTML as text view).
- Shares same base class across all mail notifications.
- Also cleaned up existing notification classes.

Future cleanup requested via #4501
2023-09-02 15:11:42 +01:00
Dan Brown
f91049a3f2 Notifications: Add test to check notification language 2023-09-01 16:30:37 +01:00
Dan Brown
4e6b74f2a1 WYSIWYG: Added filtering of page pointer elements
For #4474
2023-09-01 13:50:55 +01:00
omahs
976f241ae0 fix typo 2023-08-31 10:01:56 +02:00
omahs
415dab9936 fix typos 2023-08-31 10:00:45 +02:00
omahs
54715d40ef fix typo 2023-08-31 09:58:59 +02:00
100 changed files with 808 additions and 617 deletions

View File

@@ -355,3 +355,5 @@ Flip333 :: German Informal; German
Paulo Henrique (paulohsantos114) :: Portuguese, Brazilian
Dženan (Dzenan) :: Swedish
Péter Péli (peter.peli) :: Hungarian
TWME :: Chinese Traditional
Sascha (Man-in-Black) :: German

View File

@@ -12,10 +12,12 @@ use Illuminate\Database\Eloquent\Relations\MorphTo;
* @property int $id
* @property string $text
* @property string $html
* @property int|null $parent_id
* @property int|null $parent_id - Relates to local_id, not id
* @property int $local_id
* @property string $entity_type
* @property int $entity_id
* @property int $created_by
* @property int $updated_by
*/
class Comment extends Model implements Loggable
{
@@ -38,7 +40,9 @@ class Comment extends Model implements Loggable
*/
public function parent(): BelongsTo
{
return $this->belongsTo(Comment::class);
return $this->belongsTo(Comment::class, 'parent_id', 'local_id', 'parent')
->where('entity_type', '=', $this->entity_type)
->where('entity_id', '=', $this->entity_id);
}
/**

View File

@@ -3,13 +3,14 @@
namespace BookStack\Activity\Notifications\MessageParts;
use Illuminate\Contracts\Support\Htmlable;
use Stringable;
/**
* A line of text with linked text included, intended for use
* in MailMessages. The line should have a ':link' placeholder for
* where the link should be inserted within the line.
*/
class LinkedMailMessageLine implements Htmlable
class LinkedMailMessageLine implements Htmlable, Stringable
{
public function __construct(
protected string $url,
@@ -23,4 +24,10 @@ class LinkedMailMessageLine implements Htmlable
$link = '<a href="' . e($this->url) . '">' . e($this->linkText) . '</a>';
return str_replace(':link', $link, e($this->line));
}
public function __toString(): string
{
$link = "{$this->linkText} ({$this->url})";
return str_replace(':link', $link, $this->line);
}
}

View File

@@ -3,12 +3,13 @@
namespace BookStack\Activity\Notifications\MessageParts;
use Illuminate\Contracts\Support\Htmlable;
use Stringable;
/**
* A bullet point list of content, where the keys of the given list array
* are bolded header elements, and the values follow.
*/
class ListMessageLine implements Htmlable
class ListMessageLine implements Htmlable, Stringable
{
public function __construct(
protected array $list
@@ -23,4 +24,13 @@ class ListMessageLine implements Htmlable
}
return implode("<br>\n", $list);
}
public function __toString(): string
{
$list = [];
foreach ($this->list as $header => $content) {
$list[] = $header . ' ' . $content;
}
return implode("\n", $list);
}
}

View File

@@ -4,12 +4,11 @@ namespace BookStack\Activity\Notifications\Messages;
use BookStack\Activity\Models\Loggable;
use BookStack\Activity\Notifications\MessageParts\LinkedMailMessageLine;
use BookStack\Notifications\MailNotification;
use BookStack\Users\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
abstract class BaseActivityNotification extends Notification
abstract class BaseActivityNotification extends MailNotification
{
use Queueable;
@@ -19,22 +18,6 @@ abstract class BaseActivityNotification extends Notification
) {
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*/
abstract public function toMail(mixed $notifiable): MailMessage;
/**
* Get the array representation of the notification.
*
@@ -52,12 +35,12 @@ abstract class BaseActivityNotification extends Notification
/**
* Build the common reason footer line used in mail messages.
*/
protected function buildReasonFooterLine(): LinkedMailMessageLine
protected function buildReasonFooterLine(string $language): LinkedMailMessageLine
{
return new LinkedMailMessageLine(
url('/preferences/notifications'),
trans('notifications.footer_reason'),
trans('notifications.footer_reason_link'),
trans('notifications.footer_reason', [], $language),
trans('notifications.footer_reason_link', [], $language),
);
}
}

View File

@@ -5,26 +5,29 @@ namespace BookStack\Activity\Notifications\Messages;
use BookStack\Activity\Models\Comment;
use BookStack\Activity\Notifications\MessageParts\ListMessageLine;
use BookStack\Entities\Models\Page;
use BookStack\Users\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
class CommentCreationNotification extends BaseActivityNotification
{
public function toMail(mixed $notifiable): MailMessage
public function toMail(User $notifiable): MailMessage
{
/** @var Comment $comment */
$comment = $this->detail;
/** @var Page $page */
$page = $comment->entity;
return (new MailMessage())
->subject(trans('notifications.new_comment_subject', ['pageName' => $page->getShortName()]))
->line(trans('notifications.new_comment_intro', ['appName' => setting('app-name')]))
$language = $notifiable->getLanguage();
return $this->newMailMessage($language)
->subject(trans('notifications.new_comment_subject', ['pageName' => $page->getShortName()], $language))
->line(trans('notifications.new_comment_intro', ['appName' => setting('app-name')], $language))
->line(new ListMessageLine([
trans('notifications.detail_page_name') => $page->name,
trans('notifications.detail_commenter') => $this->user->name,
trans('notifications.detail_comment') => strip_tags($comment->html),
trans('notifications.detail_page_name', [], $language) => $page->name,
trans('notifications.detail_commenter', [], $language) => $this->user->name,
trans('notifications.detail_comment', [], $language) => strip_tags($comment->html),
]))
->action(trans('notifications.action_view_comment'), $page->getUrl('#comment' . $comment->local_id))
->line($this->buildReasonFooterLine());
->action(trans('notifications.action_view_comment', [], $language), $page->getUrl('#comment' . $comment->local_id))
->line($this->buildReasonFooterLine($language));
}
}

View File

@@ -4,23 +4,26 @@ namespace BookStack\Activity\Notifications\Messages;
use BookStack\Activity\Notifications\MessageParts\ListMessageLine;
use BookStack\Entities\Models\Page;
use BookStack\Users\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
class PageCreationNotification extends BaseActivityNotification
{
public function toMail(mixed $notifiable): MailMessage
public function toMail(User $notifiable): MailMessage
{
/** @var Page $page */
$page = $this->detail;
return (new MailMessage())
->subject(trans('notifications.new_page_subject', ['pageName' => $page->getShortName()]))
->line(trans('notifications.new_page_intro', ['appName' => setting('app-name')]))
$language = $notifiable->getLanguage();
return $this->newMailMessage($language)
->subject(trans('notifications.new_page_subject', ['pageName' => $page->getShortName()], $language))
->line(trans('notifications.new_page_intro', ['appName' => setting('app-name')], $language))
->line(new ListMessageLine([
trans('notifications.detail_page_name') => $page->name,
trans('notifications.detail_created_by') => $this->user->name,
trans('notifications.detail_page_name', [], $language) => $page->name,
trans('notifications.detail_created_by', [], $language) => $this->user->name,
]))
->action(trans('notifications.action_view_page'), $page->getUrl())
->line($this->buildReasonFooterLine());
->action(trans('notifications.action_view_page', [], $language), $page->getUrl())
->line($this->buildReasonFooterLine($language));
}
}

View File

@@ -4,24 +4,27 @@ namespace BookStack\Activity\Notifications\Messages;
use BookStack\Activity\Notifications\MessageParts\ListMessageLine;
use BookStack\Entities\Models\Page;
use BookStack\Users\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
class PageUpdateNotification extends BaseActivityNotification
{
public function toMail(mixed $notifiable): MailMessage
public function toMail(User $notifiable): MailMessage
{
/** @var Page $page */
$page = $this->detail;
return (new MailMessage())
->subject(trans('notifications.updated_page_subject', ['pageName' => $page->getShortName()]))
->line(trans('notifications.updated_page_intro', ['appName' => setting('app-name')]))
$language = $notifiable->getLanguage();
return $this->newMailMessage($language)
->subject(trans('notifications.updated_page_subject', ['pageName' => $page->getShortName()], $language))
->line(trans('notifications.updated_page_intro', ['appName' => setting('app-name')], $language))
->line(new ListMessageLine([
trans('notifications.detail_page_name') => $page->name,
trans('notifications.detail_updated_by') => $this->user->name,
trans('notifications.detail_page_name', [], $language) => $page->name,
trans('notifications.detail_updated_by', [], $language) => $this->user->name,
]))
->line(trans('notifications.updated_page_debounce'))
->action(trans('notifications.action_view_page'), $page->getUrl())
->line($this->buildReasonFooterLine());
->line(trans('notifications.updated_page_debounce', [], $language))
->action(trans('notifications.action_view_page', [], $language), $page->getUrl())
->line($this->buildReasonFooterLine($language));
}
}

View File

@@ -37,7 +37,7 @@ class EntityProvider
* Fetch all core entity types as an associated array
* with their basic names as the keys.
*
* @return array<Entity>
* @return array<string, Entity>
*/
public function all(): array
{

View File

@@ -10,6 +10,7 @@ use BookStack\Activity\Models\Loggable;
use BookStack\Activity\Models\Tag;
use BookStack\Activity\Models\View;
use BookStack\Activity\Models\Viewable;
use BookStack\Activity\Models\Watch;
use BookStack\App\Model;
use BookStack\App\Sluggable;
use BookStack\Entities\Tools\SlugGenerator;
@@ -330,6 +331,14 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
->exists();
}
/**
* Get the related watches for this entity.
*/
public function watches(): MorphMany
{
return $this->morphMany(Watch::class, 'watchable');
}
/**
* {@inheritdoc}
*/

View File

@@ -376,6 +376,7 @@ class TrashCan
$entity->searchTerms()->delete();
$entity->deletions()->delete();
$entity->favourites()->delete();
$entity->watches()->delete();
$entity->referencesTo()->delete();
$entity->referencesFrom()->delete();

View File

@@ -2,28 +2,17 @@
namespace BookStack\Notifications;
use BookStack\Users\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
class ConfirmEmail extends MailNotification
{
public $token;
/**
* Create a new notification instance.
*
* @param string $token
*/
public function __construct($token)
{
$this->token = $token;
public function __construct(
public string $token
) {
}
/**
* 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')];

View File

@@ -2,15 +2,21 @@
namespace BookStack\Notifications;
use BookStack\Users\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class MailNotification extends Notification implements ShouldQueue
abstract class MailNotification extends Notification implements ShouldQueue
{
use Queueable;
/**
* Get the mail representation of the notification.
*/
abstract public function toMail(User $notifiable): MailMessage;
/**
* Get the notification's channels.
*
@@ -25,14 +31,14 @@ class MailNotification extends Notification implements ShouldQueue
/**
* Create a new mail message.
*
* @return MailMessage
*/
protected function newMailMessage()
protected function newMailMessage(string $language = ''): MailMessage
{
$data = ['language' => $language ?: null];
return (new MailMessage())->view([
'html' => 'vendor.notifications.email',
'text' => 'vendor.notifications.email-plain',
]);
], $data);
}
}

View File

@@ -2,31 +2,17 @@
namespace BookStack\Notifications;
use BookStack\Users\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
class ResetPassword extends MailNotification
{
/**
* The password reset token.
*
* @var string
*/
public $token;
/**
* Create a notification instance.
*
* @param string $token
*/
public function __construct($token)
{
$this->token = $token;
public function __construct(
public string $token
) {
}
/**
* Build the mail representation of the notification.
*
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail()
public function toMail(User $notifiable): MailMessage
{
return $this->newMailMessage()
->subject(trans('auth.email_reset_subject', ['appName' => setting('app-name')]))

View File

@@ -2,16 +2,12 @@
namespace BookStack\Notifications;
use BookStack\Users\Models\User;
use Illuminate\Notifications\Messages\MailMessage;
class TestEmail extends MailNotification
{
/**
* 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
{
return $this->newMailMessage()
->subject(trans('settings.maint_send_test_email_mail_subject'))

View File

@@ -7,25 +7,17 @@ use Illuminate\Notifications\Messages\MailMessage;
class UserInvite extends MailNotification
{
public $token;
/**
* Create a new notification instance.
*/
public function __construct(string $token)
{
$this->token = $token;
public function __construct(
public string $token
) {
}
/**
* Get the mail representation of the notification.
*/
public function toMail(User $notifiable): MailMessage
{
$appName = ['appName' => setting('app-name')];
$language = setting()->getUser($notifiable, 'language');
$language = $notifiable->getLanguage();
return $this->newMailMessage()
return $this->newMailMessage($language)
->subject(trans('auth.user_invite_email_subject', $appName, $language))
->greeting(trans('auth.user_invite_email_greeting', $appName, $language))
->line(trans('auth.user_invite_email_text', [], $language))

View File

@@ -3,6 +3,7 @@
namespace BookStack\Permissions;
use BookStack\App\Model;
use BookStack\Entities\EntityProvider;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\Page;
use BookStack\Permissions\Models\EntityPermission;
@@ -11,6 +12,7 @@ use BookStack\Users\Models\HasOwner;
use BookStack\Users\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Query\JoinClause;
use InvalidArgumentException;
class PermissionApplicator
@@ -147,6 +149,42 @@ class PermissionApplicator
});
}
/**
* Filter out items that have related entity relations where
* the entity is marked as deleted.
*/
public function filterDeletedFromEntityRelationQuery(Builder $query, string $tableName, string $entityIdColumn, string $entityTypeColumn): Builder
{
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn];
$entityProvider = new EntityProvider();
$joinQuery = function ($query) use ($entityProvider) {
$first = true;
/** @var Builder $query */
foreach ($entityProvider->all() as $entity) {
$entityQuery = function ($query) use ($entity) {
/** @var Builder $query */
$query->select(['id', 'deleted_at'])
->selectRaw("'{$entity->getMorphClass()}' as type")
->from($entity->getTable())
->whereNotNull('deleted_at');
};
if ($first) {
$entityQuery($query);
$first = false;
} else {
$query->union($entityQuery);
}
}
};
return $query->leftJoinSub($joinQuery, 'deletions', function (JoinClause $join) use ($tableDetails) {
$join->on($tableDetails['tableName'] . '.' . $tableDetails['entityIdColumn'], '=', 'deletions.id')
->on($tableDetails['tableName'] . '.' . $tableDetails['entityTypeColumn'], '=', 'deletions.type');
})->whereNull('deletions.deleted_at');
}
/**
* Add conditions to a query for a model that's a relation of a page, so only the model results
* on visible pages are returned by the query.

View File

@@ -2,6 +2,7 @@
namespace BookStack\Translation;
use BookStack\Users\Models\User;
use Illuminate\Http\Request;
class LanguageManager
@@ -80,6 +81,15 @@ class LanguageManager
return setting()->getUser($user, 'language', $default);
}
/**
* Get the language for the given user.
*/
public function getLanguageForUser(User $user): string
{
$default = config('app.locale');
return setting()->getUser($user, 'language', $default);
}
/**
* Check if the given BookStack language value is a right-to-left language.
*/

View File

@@ -2,7 +2,6 @@
namespace BookStack\Users\Controllers;
use BookStack\Activity\Models\Watch;
use BookStack\Http\Controller;
use BookStack\Permissions\PermissionApplicator;
use BookStack\Settings\UserNotificationPreferences;
@@ -68,8 +67,9 @@ class UserPreferencesController extends Controller
$preferences = (new UserNotificationPreferences(user()));
$query = Watch::query()->where('user_id', '=', user()->id);
$query = user()->watches()->getQuery();
$query = $permissions->restrictEntityRelationQuery($query, 'watches', 'watchable_id', 'watchable_type');
$query = $permissions->filterDeletedFromEntityRelationQuery($query, 'watches', 'watchable_id', 'watchable_type');
$watches = $query->with('watchable')->paginate(20);
$this->setPageTitle(trans('preferences.notifications'));

View File

@@ -6,11 +6,13 @@ use BookStack\Access\Mfa\MfaValue;
use BookStack\Access\SocialAccount;
use BookStack\Activity\Models\Favourite;
use BookStack\Activity\Models\Loggable;
use BookStack\Activity\Models\Watch;
use BookStack\Api\ApiToken;
use BookStack\App\Model;
use BookStack\App\Sluggable;
use BookStack\Entities\Tools\SlugGenerator;
use BookStack\Notifications\ResetPassword;
use BookStack\Translation\LanguageManager;
use BookStack\Uploads\Image;
use Carbon\Carbon;
use Exception;
@@ -290,6 +292,14 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
return $this->hasMany(MfaValue::class);
}
/**
* Get the tracked entity watches for this user.
*/
public function watches(): HasMany
{
return $this->hasMany(Watch::class);
}
/**
* Get the last activity time for this user.
*/
@@ -338,6 +348,14 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
return '';
}
/**
* Get the system language for this user.
*/
public function getLanguage(): string
{
return app()->make(LanguageManager::class)->getLanguageForUser($this);
}
/**
* Send the password reset notification.
*

View File

@@ -18,18 +18,13 @@ use Illuminate\Support\Str;
class UserRepo
{
protected UserAvatars $userAvatar;
protected UserInviteService $inviteService;
/**
* UserRepo constructor.
*/
public function __construct(UserAvatars $userAvatar, UserInviteService $inviteService)
{
$this->userAvatar = $userAvatar;
$this->inviteService = $inviteService;
public function __construct(
protected UserAvatars $userAvatar,
protected UserInviteService $inviteService
) {
}
/**
* Get a user by their email address.
*/
@@ -155,6 +150,7 @@ class UserRepo
$user->apiTokens()->delete();
$user->favourites()->delete();
$user->mfaValues()->delete();
$user->watches()->delete();
$user->delete();
// Delete user profile images

View File

@@ -85,18 +85,18 @@ Will result with `this.$opts` being:
A component has the below shown properties & methods available for use. As mentioned above, most of these should be used within the `setup()` function to make the requirements/dependencies of the component clear.
```javascript
// The root element that the compontent has been applied to.
// The root element that the component has been applied to.
this.$el
// A map of defined element references within the compontent.
// A map of defined element references within the component.
// See "Element References" above.
this.$refs
// A map of defined multi-element references within the compontent.
// A map of defined multi-element references within the component.
// See "Element References" above.
this.$manyRefs
// Options defined for the compontent.
// Options defined for the component.
this.$opts
// The registered name of the component, usually kebab-case.
@@ -160,4 +160,4 @@ window.$components.firstOnElement(element, name);
There are a range of available events that are emitted as part of a public & supported API for accessing or extending JavaScript libraries & components used in the system.
Details on these events can be found in the [JavaScript Public Events file](javascript-public-events.md).
Details on these events can be found in the [JavaScript Public Events file](javascript-public-events.md).

View File

@@ -42,7 +42,7 @@ This event is called before the markdown input editor CodeMirror instance is cre
#### Event Data
- `editorViewConfig` - An [EditorViewConfig](https://codemirror.net/docs/ref/#view.EditorViewConfig) object that will eventially be passed when creating the CodeMirror EditorView instance.
- `editorViewConfig` - An [EditorViewConfig](https://codemirror.net/docs/ref/#view.EditorViewConfig) object that will eventually be passed when creating the CodeMirror EditorView instance.
##### Example
@@ -252,4 +252,4 @@ window.addEventListener('library-cm6::configure-theme', event => {
detail.registerHighlightStyle(highlightStyleBuilder);
});
```
</details>
</details>

View File

@@ -15,7 +15,7 @@ return [
'page_restore' => 'obnovil/a stránku',
'page_restore_notification' => 'Stránka byla úspěšně obnovena',
'page_move' => 'přesunul/a stránku',
'page_move_notification' => 'Page successfully moved',
'page_move_notification' => 'Strana byla úspěšně přesunuta',
// Chapters
'chapter_create' => 'vytvořil/a kapitolu',
@@ -25,7 +25,7 @@ return [
'chapter_delete' => 'odstranila/a kapitolu',
'chapter_delete_notification' => 'Kapitola byla úspěšně odstraněna',
'chapter_move' => 'přesunul/a kapitolu',
'chapter_move_notification' => 'Chapter successfully moved',
'chapter_move_notification' => 'Kapitola byla úspěšně přesunuta',
// Books
'book_create' => 'vytvořil/a knihu',
@@ -50,31 +50,31 @@ return [
'bookshelf_delete_notification' => 'Knihovna byla úspěšně smazána',
// Revisions
'revision_restore' => 'restored revision',
'revision_delete' => 'deleted revision',
'revision_delete_notification' => 'Revision successfully deleted',
'revision_restore' => 'obnovil revizi',
'revision_delete' => 'odstranil revizi',
'revision_delete_notification' => 'Revize byla úspěšně odstraněna',
// Favourites
'favourite_add_notification' => '":name" byla přidána do Vašich oblíbených',
'favourite_remove_notification' => '":name" byla odstraněna z Vašich oblíbených',
// Watching
'watch_update_level_notification' => 'Watch preferences successfully updated',
'watch_update_level_notification' => 'Předvolby sledování úspěšně aktualizovány',
// Auth
'auth_login' => 'logged in',
'auth_register' => 'registered as new user',
'auth_password_reset_request' => 'requested user password reset',
'auth_password_reset_update' => 'reset user password',
'mfa_setup_method' => 'configured MFA method',
'auth_login' => 'se přihlásil',
'auth_register' => 'se zaregistroval jako nový uživatel',
'auth_password_reset_request' => 'zažádal o resetování hesla',
'auth_password_reset_update' => 'zresetoval uživatelské heslo',
'mfa_setup_method' => 'nastavil MFA metodu',
'mfa_setup_method_notification' => 'Vícefaktorová metoda byla úspěšně nakonfigurována',
'mfa_remove_method' => 'removed MFA method',
'mfa_remove_method' => 'odstranil MFA metodu',
'mfa_remove_method_notification' => 'Vícefaktorová metoda byla úspěšně odstraněna',
// Settings
'settings_update' => 'updated settings',
'settings_update_notification' => 'Settings successfully updated',
'maintenance_action_run' => 'ran maintenance action',
'settings_update' => 'aktualizoval nastavení',
'settings_update_notification' => 'Nastavení bylo úspěšně aktualizováno',
'maintenance_action_run' => 'spustil údržbu',
// Webhooks
'webhook_create' => 'vytvořil/a webhook',
@@ -85,39 +85,39 @@ return [
'webhook_delete_notification' => 'Webhook byl úspěšně odstraněn',
// Users
'user_create' => 'created user',
'user_create_notification' => 'User successfully created',
'user_update' => 'updated user',
'user_create' => 'vytvořil uživatele',
'user_create_notification' => 'Uživatel byl úspěšně vytvořen',
'user_update' => 'aktualizoval uživatele',
'user_update_notification' => 'Uživatel byl úspěšně aktualizován',
'user_delete' => 'deleted user',
'user_delete' => 'odstranil uživatele',
'user_delete_notification' => 'Uživatel byl úspěšně odstraněn',
// API Tokens
'api_token_create' => 'created api token',
'api_token_create_notification' => 'API token successfully created',
'api_token_update' => 'updated api token',
'api_token_update_notification' => 'API token successfully updated',
'api_token_delete' => 'deleted api token',
'api_token_delete_notification' => 'API token successfully deleted',
'api_token_create' => 'vytvořil api token',
'api_token_create_notification' => 'API token úspěšně vytvořen',
'api_token_update' => 'aktualizoval api token',
'api_token_update_notification' => 'API token úspěšně aktualizován',
'api_token_delete' => 'odstranil api token',
'api_token_delete_notification' => 'API token úspěšně odstraněn',
// Roles
'role_create' => 'created role',
'role_create' => 'vytvořil roli',
'role_create_notification' => 'Role byla úspěšně vytvořena',
'role_update' => 'updated role',
'role_update' => 'aktualizoval roli',
'role_update_notification' => 'Role byla úspěšně aktualizována',
'role_delete' => 'deleted role',
'role_delete' => 'odstranil roli',
'role_delete_notification' => 'Role byla odstraněna',
// Recycle Bin
'recycle_bin_empty' => 'emptied recycle bin',
'recycle_bin_restore' => 'restored from recycle bin',
'recycle_bin_destroy' => 'removed from recycle bin',
'recycle_bin_empty' => 'vyprázdnil koš',
'recycle_bin_restore' => 'obnovil z koše',
'recycle_bin_destroy' => 'odstranil z koše',
// Comments
'commented_on' => 'okomentoval/a',
'comment_create' => 'added comment',
'comment_update' => 'updated comment',
'comment_delete' => 'deleted comment',
'comment_create' => 'přidal komentář',
'comment_update' => 'aktualizoval komentář',
'comment_delete' => 'odstranil komentář',
// Other
'permissions_update' => 'oprávnění upravena',

View File

@@ -6,7 +6,7 @@ return [
// Buttons
'cancel' => 'Zrušit',
'close' => 'Close',
'close' => 'Zavřít',
'confirm' => 'Potvrdit',
'back' => 'Zpět',
'save' => 'Uložit',
@@ -42,7 +42,7 @@ return [
'remove' => 'Odebrat',
'add' => 'Přidat',
'configure' => 'Nastavit',
'manage' => 'Manage',
'manage' => 'Spravovat',
'fullscreen' => 'Celá obrazovka',
'favourite' => 'Přidat do oblíbených',
'unfavourite' => 'Odebrat z oblíbených',

View File

@@ -49,16 +49,16 @@ return [
// Drawing & Images
'image_upload_error' => 'Nastala chyba během nahrávání souboru',
'image_upload_type_error' => 'Typ nahrávaného obrázku je neplatný.',
'image_upload_replace_type' => 'Image file replacements must be of the same type',
'image_upload_replace_type' => 'Náhrady souboru obrázku musí být stejného typu',
'drawing_data_not_found' => 'Data výkresu nelze načíst. Výkresový soubor již nemusí existovat nebo nemusí mít oprávnění k němu přistupovat.',
// Attachments
'attachment_not_found' => 'Příloha nenalezena',
'attachment_upload_error' => 'An error occurred uploading the attachment file',
'attachment_upload_error' => 'Nastala chyba během nahrávání přiloženého souboru',
// Pages
'page_draft_autosave_fail' => 'Nepovedlo se uložit koncept. Než stránku uložíte, ujistěte se, že jste připojeni k internetu.',
'page_draft_delete_fail' => 'Failed to delete page draft and fetch current page saved content',
'page_draft_delete_fail' => 'Nepodařilo se odstranit koncept stránky a načíst její aktuální obsah',
'page_custom_home_deletion' => 'Nelze odstranit tuto stránku, protože je nastavena jako uvítací stránka',
// Entities
@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Při posílání testovacího e-mailu nastala chyba:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'URL adresa neodpovídá povoleným SSR poskytovatelům',
];

View File

@@ -5,7 +5,7 @@
*/
return [
'preferences' => 'Preferences',
'preferences' => 'Předvolby',
'shortcuts' => 'Zkratky',
'shortcuts_interface' => 'Zobrazit klávesové zkratky',

View File

@@ -163,7 +163,7 @@ return [
'role_manage_settings' => 'Správa nastavení aplikace',
'role_export_content' => 'Exportovat obsah',
'role_editor_change' => 'Změnit editor stránek',
'role_notifications' => 'Receive & manage notifications',
'role_notifications' => 'Přijímat a spravovat oznámení',
'role_asset' => 'Obsahová oprávnění',
'roles_system_warning' => 'Berte na vědomí, že přístup k některému ze tří výše uvedených oprávnění může uživateli umožnit změnit svá vlastní oprávnění nebo oprávnění ostatních uživatelů v systému. Přiřazujte role s těmito oprávněními pouze důvěryhodným uživatelům.',
'role_asset_desc' => 'Tato oprávnění řídí přístup k obsahu napříč systémem. Specifická oprávnění na knihách, kapitolách a stránkách převáží tato nastavení.',

View File

@@ -99,7 +99,7 @@ return [
'tab_content_label' => 'Tab: Hauptinhalt anzeigen',
// Email Content
'email_action_help' => 'Sollte es beim Anklicken der Schaltfläche ":action_text" Probleme geben, öffnen Sie folgende URL in Ihrem Browser:',
'email_action_help' => 'Sollte es beim Anklicken der Schaltfläche ":actionText" Probleme geben, öffnen Sie folgende URL in Ihrem Browser:',
'email_rights' => 'Alle Rechte vorbehalten',
// Footer Link Options

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Fehler beim Versenden einer Test E-Mail:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'Die URL stimmt nicht mit den konfigurierten erlaubten SSR-Hosts überein',
];

View File

@@ -5,7 +5,7 @@
*/
return [
'preferences' => 'Einstellungen',
'preferences' => 'Profil-Einstellungen',
'shortcuts' => 'Tastenkürzel',
'shortcuts_interface' => 'Oberflächen-Tastaturkürzel',

View File

@@ -116,7 +116,7 @@ return [
'book' => 'Buch',
'books' => 'Bücher',
'x_books' => ':count Buch|:count Bücher',
'books_empty' => 'Keine Bücher vorhanden',
'books_empty' => 'Es wurden noch keine Bücher angelegt',
'books_popular' => 'Beliebte Bücher',
'books_recent' => 'Kürzlich angesehene Bücher',
'books_new' => 'Neue Bücher',
@@ -240,7 +240,7 @@ return [
'pages_md_show_preview' => 'Vorschau anzeigen',
'pages_md_sync_scroll' => 'Vorschau synchronisieren',
'pages_drawing_unsaved' => 'Ungespeicherte Zeichnung gefunden',
'pages_drawing_unsaved_confirm' => 'Es wurden ungespeicherte Zeichnungsdaten von einem früheren, fehlgeschlagenen Versuch, die Zeichnung zu speichern, gefunden. Möchten Sie diese ungespeicherte Zeichnung wiederherstellen und weiter bearbeiten?',
'pages_drawing_unsaved_confirm' => 'Es wurden ungespeicherte Zeichnungsdaten von einem früheren, fehlgeschlagenen Versuch, die Zeichnung zu speichern, gefunden. Möchtest du diese ungespeicherte Zeichnung wiederherstellen und weiter bearbeiten?',
'pages_not_in_chapter' => 'Seite ist in keinem Kapitel',
'pages_move' => 'Seite verschieben',
'pages_copy' => 'Seite kopieren',
@@ -413,7 +413,7 @@ return [
'watch_title_ignore' => 'Ignorieren',
'watch_desc_ignore' => 'Ignorieren aller Benachrichtigungen, auch die von den Einstellungen auf Benutzerebene.',
'watch_title_new' => 'Neue Seiten',
'watch_desc_new' => 'Benachrichtigung, wenn eine neue Seite in diesem Element erstellt wird.',
'watch_desc_new' => 'Benachrichtigen, wenn eine neue Seite in diesem Element erstellt wird.',
'watch_title_updates' => 'Alle Seitenupdates',
'watch_desc_updates' => 'Bei allen neuen Seiten und Seitenänderungen benachrichtigen.',
'watch_desc_updates_page' => 'Bei allen Seitenänderungen benachrichtigen.',

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Fehler beim Senden einer Test E-Mail:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'Die URL stimmt nicht mit den konfigurierten erlaubten SSR-Hosts überein',
];

View File

@@ -10,9 +10,9 @@ return [
'new_page_intro' => 'Es wurde eine neue Seite in :appName erstellt:',
'updated_page_subject' => 'Aktualisierte Seite: :pageName',
'updated_page_intro' => 'Eine Seite wurde in :appName aktualisiert:',
'updated_page_debounce' => 'Um eine Flut von Benachrichtigungen zu vermeiden, werden Sie für eine gewisse Zeit keine Benachrichtigungen für weitere Bearbeitungen dieser Seite durch denselben Bearbeiter erhalten.',
'updated_page_debounce' => 'Um eine Flut von Benachrichtigungen zu vermeiden, wirst du für eine gewisse Zeit keine Benachrichtigungen für weitere Bearbeitungen dieser Seite durch denselben Bearbeiter erhalten.',
'detail_page_name' => 'Name der Seite:',
'detail_page_name' => 'Seitenname:',
'detail_commenter' => 'Kommentator:',
'detail_comment' => 'Kommentar:',
'detail_created_by' => 'Erstellt von:',
@@ -21,6 +21,6 @@ return [
'action_view_comment' => 'Kommentar anzeigen',
'action_view_page' => 'Seite anzeigen',
'footer_reason' => 'Diese Benachrichtigung wurde an Sie gesendet, weil :link diese Art von Aktivität für dieses Element abdeckt.',
'footer_reason_link' => 'ihre Benachrichtigungseinstellungen',
'footer_reason' => 'Diese Benachrichtigung wurde an dich gesendet, weil :link diese Art von Aktivität für dieses Element abdeckt.',
'footer_reason_link' => 'deine Benachrichtigungseinstellungen',
];

View File

@@ -6,7 +6,7 @@
*/
return [
'password' => 'Passwörter müssen aus mindestens sechs Zeichen bestehen und mit der eingegebenen Wiederholung übereinstimmen.',
'password' => 'Passwörter müssen aus mindestens acht Zeichen bestehen und mit der eingegebenen Wiederholung übereinstimmen.',
'user' => "Es wurde kein Benutzer mit dieser E-Mail-Adresse gefunden.",
'token' => 'Der Token zum Zurücksetzen des Passworts für diese E-Mail-Adresse ist ungültig.',
'sent' => 'Wir haben dir einen Link zum Zurücksetzen des Passwortes per E-Mail geschickt!',

View File

@@ -5,7 +5,7 @@
*/
return [
'preferences' => 'Einstellungen',
'preferences' => 'Profil-Einstellungen',
'shortcuts' => 'Kürzel',
'shortcuts_interface' => 'Oberflächen-Tastaturkürzel',
@@ -20,14 +20,14 @@ return [
'shortcuts_overview_desc' => 'Verwalten von Tastenkombinationen, die zur Navigation der Benutzeroberfläche verwendet werden können.',
'notifications' => 'Benachrichtigungseinstellungen',
'notifications_desc' => 'Legen Sie fest, welche E-Mail-Benachrichtigungen Sie erhalten, wenn bestimmte Aktivitäten im System durchgeführt werden.',
'notifications_desc' => 'Lege fest, welche E-Mail-Benachrichtigungen du erhältst, wenn bestimmte Aktivitäten im System durchgeführt werden.',
'notifications_opt_own_page_changes' => 'Benachrichtigung bei Änderungen an eigenen Seiten',
'notifications_opt_own_page_comments' => 'Benachrichtigung bei Kommentaren an eigenen Seiten',
'notifications_opt_comment_replies' => 'Bei Antworten auf meine Kommentare benachrichtigen',
'notifications_save' => 'Einstellungen speichern',
'notifications_update_success' => 'Benachrichtigungseinstellungen wurden aktualisiert!',
'notifications_watched' => 'Beobachtete und ignorierte Elemente',
'notifications_watched_desc' => ' Nachfolgend finden Sie die Elemente, für die benutzerdefinierten Überwachungspräferenzen gelten. Um Ihre Einstellungen für diese Elemente zu aktualisieren, sehen Sie sich das Element an und suchen dann die Überwachungsoptionen in der Seitenleiste.',
'notifications_watched_desc' => ' Nachfolgend finden Sie die Elemente, für die benutzerdefinierten Überwachungspräferenzen gelten. Um deine Einstellungen für diese Elemente zu aktualisieren, sieh dir das Element an und suche dann die Überwachungsoptionen in der Seitenleiste.',
'profile_overview_desc' => ' Verwalten Sie die Details Ihres Benutzerprofils einschließlich bevorzugter Sprache und Authentifizierungsoptionen.',
'profile_overview_desc' => ' Verwalte die Details deines Benutzerprofils, einschließlich bevorzugter Sprache und Authentifizierungsoptionen.',
];

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Error al enviar un email de prueba:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'La URL no coincide con los hosts SSR permitidos',
];

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Error al enviar un email de prueba:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'La URL no coincide con los hosts SSR permitidos',
];

View File

@@ -59,7 +59,7 @@ return [
'favourite_remove_notification' => '":name" eemaldati su lemmikute hulgast',
// Watching
'watch_update_level_notification' => 'Watch preferences successfully updated',
'watch_update_level_notification' => 'Jälgimise eelistused edukalt salvestatud',
// Auth
'auth_login' => 'logis sisse',

View File

@@ -42,7 +42,7 @@ return [
'remove' => 'Eemalda',
'add' => 'Lisa',
'configure' => 'Seadista',
'manage' => 'Manage',
'manage' => 'Halda',
'fullscreen' => 'Täisekraan',
'favourite' => 'Lemmik',
'unfavourite' => 'Eemalda lemmik',

View File

@@ -239,7 +239,7 @@ return [
'pages_md_insert_drawing' => 'Lisa joonis',
'pages_md_show_preview' => 'Näita eelvaadet',
'pages_md_sync_scroll' => 'Sünkrooni eelvaate kerimine',
'pages_drawing_unsaved' => 'Unsaved Drawing Found',
'pages_drawing_unsaved' => 'Leiti salvestamata joonis',
'pages_drawing_unsaved_confirm' => 'Unsaved drawing data was found from a previous failed drawing save attempt. Would you like to restore and continue editing this unsaved drawing?',
'pages_not_in_chapter' => 'Leht ei kuulu peatüki alla',
'pages_move' => 'Liiguta leht',
@@ -407,26 +407,26 @@ return [
'references_to_desc' => 'Allpool on kõik teadaolevad lehed, mis sellele objektile viitavad.',
// Watch Options
'watch' => 'Watch',
'watch_title_default' => 'Default Preferences',
'watch' => 'Jälgi',
'watch_title_default' => 'Vaikimisi eelistused',
'watch_desc_default' => 'Revert watching to just your default notification preferences.',
'watch_title_ignore' => 'Ignore',
'watch_desc_ignore' => 'Ignore all notifications, including those from user-level preferences.',
'watch_title_new' => 'New Pages',
'watch_desc_new' => 'Notify when any new page is created within this item.',
'watch_title_updates' => 'All Page Updates',
'watch_desc_updates' => 'Notify upon all new pages and page changes.',
'watch_desc_updates_page' => 'Notify upon all page changes.',
'watch_title_comments' => 'All Page Updates & Comments',
'watch_desc_comments' => 'Notify upon all new pages, page changes and new comments.',
'watch_desc_comments_page' => 'Notify upon page changes and new comments.',
'watch_change_default' => 'Change default notification preferences',
'watch_detail_ignore' => 'Ignoring notifications',
'watch_detail_new' => 'Watching for new pages',
'watch_detail_updates' => 'Watching new pages and updates',
'watch_detail_comments' => 'Watching new pages, updates & comments',
'watch_detail_parent_book' => 'Watching via parent book',
'watch_detail_parent_book_ignore' => 'Ignoring via parent book',
'watch_detail_parent_chapter' => 'Watching via parent chapter',
'watch_detail_parent_chapter_ignore' => 'Ignoring via parent chapter',
'watch_title_ignore' => 'Ignoreeri',
'watch_desc_ignore' => 'Ignoreeri kõiki teavitusi, ka kasutaja tasemel määratud eelistusi.',
'watch_title_new' => 'Uued lehed',
'watch_desc_new' => 'Teavita, kui sellesse objekti lisatakse uus leht.',
'watch_title_updates' => 'Kõik lehed',
'watch_desc_updates' => 'Teavita kõigist uutest lehtedest ja lehtede muudatustest.',
'watch_desc_updates_page' => 'Teavita kõigist lehtede muudatustest.',
'watch_title_comments' => 'Kõik lehed ja kommentaarid',
'watch_desc_comments' => 'Teavita kõigist uutest lehtedest, lehtede muudatustest ja uutest kommentaaridest.',
'watch_desc_comments_page' => 'Teavita lehtede muudatustest ja uutest kommentaaridest.',
'watch_change_default' => 'Muuda vaikimisi teavituste eelistusi',
'watch_detail_ignore' => 'Teavitusi ignoreeritakse',
'watch_detail_new' => 'Jälgitakse uusi lehti',
'watch_detail_updates' => 'Jälgitakse uusi lehti ja muudatusi',
'watch_detail_comments' => 'Jälgitakse uusi lehti, muudatusi ja kommentaare',
'watch_detail_parent_book' => 'Jälgitakse raamatu kaudu',
'watch_detail_parent_book_ignore' => 'Ignoreeritakse raamatu kaudu',
'watch_detail_parent_chapter' => 'Jälgitakse peatüki kaudu',
'watch_detail_parent_chapter_ignore' => 'Ignoreeritakse peatüki kaudu',
];

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Test e-kirja saatmisel tekkis viga:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'URL ei klapi ühegi lubatud SSR hostiga',
];

View File

@@ -4,23 +4,23 @@
*/
return [
'new_comment_subject' => 'New comment on page: :pageName',
'new_comment_intro' => 'A user has commented on a page in :appName:',
'new_page_subject' => 'New page: :pageName',
'new_page_intro' => 'A new page has been created in :appName:',
'updated_page_subject' => 'Updated page: :pageName',
'updated_page_intro' => 'A page has been updated in :appName:',
'updated_page_debounce' => 'To prevent a mass of notifications, for a while you won\'t be sent notifications for further edits to this page by the same editor.',
'new_comment_subject' => 'Uus kommentaar lehel: :pageName',
'new_comment_intro' => 'Rakenduses :appName kommenteeriti lehte:',
'new_page_subject' => 'Uus leht: :pageName',
'new_page_intro' => 'Rakenduses :appName lisati uus leht:',
'updated_page_subject' => 'Muudetud leht: :pageName',
'updated_page_intro' => 'Rakenduses :appName muudeti lehte:',
'updated_page_debounce' => 'Et vältida liigseid teavitusi, ei saadeta sulle mõnda aega teavitusi selle lehe muutmiste kohta sama kasutaja poolt.',
'detail_page_name' => 'Page Name:',
'detail_commenter' => 'Commenter:',
'detail_comment' => 'Comment:',
'detail_created_by' => 'Created By:',
'detail_updated_by' => 'Updated By:',
'detail_page_name' => 'Lehe nimetus:',
'detail_commenter' => 'Kommenteerija:',
'detail_comment' => 'Kommentaar:',
'detail_created_by' => 'Autor:',
'detail_updated_by' => 'Muutja:',
'action_view_comment' => 'View Comment',
'action_view_page' => 'View Page',
'action_view_comment' => 'Vaata kommentaari',
'action_view_page' => 'Vaata lehte',
'footer_reason' => 'This notification was sent to you because :link cover this type of activity for this item.',
'footer_reason_link' => 'your notification preferences',
'footer_reason' => 'See teavitus saadeti sulle, sest :link sisaldavad selle objekti kohta sellist tegevust.',
'footer_reason_link' => 'sinu teavituste eelistused',
];

View File

@@ -5,7 +5,7 @@
*/
return [
'preferences' => 'Preferences',
'preferences' => 'Eelistused',
'shortcuts' => 'Kiirklahvid',
'shortcuts_interface' => 'Kasutajaliidese kiirklahvid',
@@ -17,17 +17,17 @@ return [
'shortcuts_save' => 'Salvesta kiirklahvid',
'shortcuts_overlay_desc' => 'Märkus: Kui kiirklahvid on sisse lülitatud, saab "?" vajutades kuvada abiinfo, mis märgib ära kõigi hetkel ekraanil nähtavate tegevuste kiirklahvid.',
'shortcuts_update_success' => 'Kiirklahvide eelistused on salvestatud!',
'shortcuts_overview_desc' => 'Manage keyboard shortcuts you can use to navigate the system user interface.',
'shortcuts_overview_desc' => 'Halda klaviatuuri kiirklahve süsteemi kasutajaliideses navigeerimiseks.',
'notifications' => 'Notification Preferences',
'notifications_desc' => 'Control the email notifications you receive when certain activity is performed within the system.',
'notifications_opt_own_page_changes' => 'Notify upon changes to pages I own',
'notifications_opt_own_page_comments' => 'Notify upon comments on pages I own',
'notifications_opt_comment_replies' => 'Notify upon replies to my comments',
'notifications_save' => 'Save Preferences',
'notifications_update_success' => 'Notification preferences have been updated!',
'notifications_watched' => 'Watched & Ignored Items',
'notifications_watched_desc' => ' Below are the items that have custom watch preferences applied. To update your preferences for these, view the item then find the watch options in the sidebar.',
'notifications' => 'Teavituste eelistused',
'notifications_desc' => 'Halda e-posti teavitusi, mis saadetakse teatud tegevuste puhul.',
'notifications_opt_own_page_changes' => 'Teavita muudatustest minu lehtedel',
'notifications_opt_own_page_comments' => 'Teavita kommentaaridest minu lehtedel',
'notifications_opt_comment_replies' => 'Teavita vastustest minu kommentaaridele',
'notifications_save' => 'Salvesta eelistused',
'notifications_update_success' => 'Teavituste eelistused on salvestatud!',
'notifications_watched' => 'Jälgitud ja ignoreeritud objektid',
'notifications_watched_desc' => ' Allpool on objektid, millele on määratud kohaldatud jälgimise eelistused. Eelistuste muutmiseks ava vastav objekt ning leia jälgimise valikud külgmenüüs.',
'profile_overview_desc' => ' Manage your user profile details including preferred language and authentication options.',
'profile_overview_desc' => ' Halda oma kasutajaprofiili andmeid, kaasa arvatud keele eelistust ja autentimisvalikuid.',
];

View File

@@ -163,7 +163,7 @@ return [
'role_manage_settings' => 'Rakenduse seadete haldamine',
'role_export_content' => 'Sisu eksport',
'role_editor_change' => 'Lehe redaktori muutmine',
'role_notifications' => 'Receive & manage notifications',
'role_notifications' => 'Võta vastu ja halda teavitusi',
'role_asset' => 'Sisu õigused',
'roles_system_warning' => 'Pane tähele, et ülalolevad kolm õigust võimaldavad kasutajal enda või teiste kasutajate õiguseid muuta. Määra nende õigustega roll ainult usaldusväärsetele kasutajatele.',
'role_asset_desc' => 'Need load kontrollivad vaikimisi ligipääsu süsteemis olevale sisule. Raamatute, peatükkide ja lehtede õigused rakenduvad esmajärjekorras.',

View File

@@ -59,7 +59,7 @@ return [
'favourite_remove_notification' => '":name" a été supprimé de vos favoris',
// Watching
'watch_update_level_notification' => 'Watch preferences successfully updated',
'watch_update_level_notification' => 'Suivre les préférences mises à jour avec succès',
// Auth
'auth_login' => 'connecté',

View File

@@ -42,7 +42,7 @@ return [
'remove' => 'Enlever',
'add' => 'Ajouter',
'configure' => 'Configurer',
'manage' => 'Manage',
'manage' => 'Gérer',
'fullscreen' => 'Plein écran',
'favourite' => 'Favoris',
'unfavourite' => 'Supprimer des favoris',

View File

@@ -239,8 +239,8 @@ return [
'pages_md_insert_drawing' => 'Insérer un dessin',
'pages_md_show_preview' => 'Prévisualisation',
'pages_md_sync_scroll' => 'Défilement prévisualisation',
'pages_drawing_unsaved' => 'Unsaved Drawing Found',
'pages_drawing_unsaved_confirm' => 'Unsaved drawing data was found from a previous failed drawing save attempt. Would you like to restore and continue editing this unsaved drawing?',
'pages_drawing_unsaved' => 'Dessin non enregistré trouvé',
'pages_drawing_unsaved_confirm' => 'Des données de dessin non enregistrées ont été trouvées à partir d\'une tentative de sauvegarde de dessin échouée. Voulez-vous restaurer et continuer à modifier ce dessin non sauvegardé ?',
'pages_not_in_chapter' => 'La page n\'est pas dans un chapitre',
'pages_move' => 'Déplacer la page',
'pages_copy' => 'Copier la page',
@@ -407,26 +407,26 @@ return [
'references_to_desc' => 'Vous trouverez ci-dessous toutes les pages connues du système qui ont un lien vers cet élément.',
// Watch Options
'watch' => 'Watch',
'watch_title_default' => 'Default Preferences',
'watch_desc_default' => 'Revert watching to just your default notification preferences.',
'watch_title_ignore' => 'Ignore',
'watch_desc_ignore' => 'Ignore all notifications, including those from user-level preferences.',
'watch_title_new' => 'New Pages',
'watch_desc_new' => 'Notify when any new page is created within this item.',
'watch_title_updates' => 'All Page Updates',
'watch_desc_updates' => 'Notify upon all new pages and page changes.',
'watch_desc_updates_page' => 'Notify upon all page changes.',
'watch_title_comments' => 'All Page Updates & Comments',
'watch_desc_comments' => 'Notify upon all new pages, page changes and new comments.',
'watch_desc_comments_page' => 'Notify upon page changes and new comments.',
'watch_change_default' => 'Change default notification preferences',
'watch_detail_ignore' => 'Ignoring notifications',
'watch_detail_new' => 'Watching for new pages',
'watch_detail_updates' => 'Watching new pages and updates',
'watch_detail_comments' => 'Watching new pages, updates & comments',
'watch_detail_parent_book' => 'Watching via parent book',
'watch_detail_parent_book_ignore' => 'Ignoring via parent book',
'watch_detail_parent_chapter' => 'Watching via parent chapter',
'watch_detail_parent_chapter_ignore' => 'Ignoring via parent chapter',
'watch' => 'Suivre',
'watch_title_default' => 'Préférences par défaut',
'watch_desc_default' => 'Revenir à vos préférences de notification par défaut.',
'watch_title_ignore' => 'Ignorer',
'watch_desc_ignore' => 'Ignorer toutes les notifications, y compris celles des préférences de niveau utilisateur.',
'watch_title_new' => 'Nouvelles Pages',
'watch_desc_new' => 'Notifier quand une nouvelle page est créée dans cet élément.',
'watch_title_updates' => 'Toutes les mises à jour de page',
'watch_desc_updates' => 'Notifier toutes les nouvelles pages et les changements de page.',
'watch_desc_updates_page' => 'Notifier lors de toutes les modifications de page.',
'watch_title_comments' => 'Toutes les mises à jour et commentaires de page',
'watch_desc_comments' => 'Notifier toutes les nouvelles pages, les changements de page et les nouveaux commentaires.',
'watch_desc_comments_page' => 'Notifier les changements de page et les nouveaux commentaires.',
'watch_change_default' => 'Modifier les préférences de notification par défaut',
'watch_detail_ignore' => 'Ignorer les notifications',
'watch_detail_new' => 'Suivre les nouvelles pages',
'watch_detail_updates' => 'Suivre les nouvelles pages et mises à jour',
'watch_detail_comments' => 'Suivre les nouvelles pages, mises à jour et commentaires',
'watch_detail_parent_book' => 'Suivre via le livre parent',
'watch_detail_parent_book_ignore' => 'Ignorer via le livre parent',
'watch_detail_parent_chapter' => 'Suivre via le chapitre parent',
'watch_detail_parent_chapter_ignore' => 'Ignorer via le chapitre parent',
];

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Erreur émise lors de l\'envoi d\'un e-mail de test :',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'L\'URL ne correspond pas aux hôtes SSR autorisés configurés',
];

View File

@@ -4,23 +4,23 @@
*/
return [
'new_comment_subject' => 'New comment on page: :pageName',
'new_comment_intro' => 'A user has commented on a page in :appName:',
'new_page_subject' => 'New page: :pageName',
'new_page_intro' => 'A new page has been created in :appName:',
'updated_page_subject' => 'Updated page: :pageName',
'updated_page_intro' => 'A page has been updated in :appName:',
'updated_page_debounce' => 'To prevent a mass of notifications, for a while you won\'t be sent notifications for further edits to this page by the same editor.',
'new_comment_subject' => 'Nouveau commentaire sur la page : :pageName',
'new_comment_intro' => 'Un utilisateur a commenté une page dans :appName:',
'new_page_subject' => 'Nouvelle page : :pageName',
'new_page_intro' => 'Une nouvelle page a été créée dans :appName:',
'updated_page_subject' => 'Page mise à jour : :pageName',
'updated_page_intro' => 'Une page a été mise à jour dans :appName:',
'updated_page_debounce' => 'Pour éviter de nombreuses notifications, pendant un certain temps, vous ne recevrez pas de notifications pour d\'autres modifications de cette page par le même éditeur.',
'detail_page_name' => 'Page Name:',
'detail_commenter' => 'Commenter:',
'detail_comment' => 'Comment:',
'detail_created_by' => 'Created By:',
'detail_updated_by' => 'Updated By:',
'detail_page_name' => 'Nom de la page :',
'detail_commenter' => 'Commenta·teur·trice :',
'detail_comment' => 'Commentaire :',
'detail_created_by' => 'Créé par :',
'detail_updated_by' => 'Mis à jour par :',
'action_view_comment' => 'View Comment',
'action_view_page' => 'View Page',
'action_view_comment' => 'Voir le commentaire',
'action_view_page' => 'Afficher la page',
'footer_reason' => 'This notification was sent to you because :link cover this type of activity for this item.',
'footer_reason_link' => 'your notification preferences',
'footer_reason' => 'Cette notification vous a été envoyée car :link couvre ce type d\'activité pour cet élément.',
'footer_reason_link' => 'vos préférences de notification',
];

View File

@@ -5,7 +5,7 @@
*/
return [
'preferences' => 'Preferences',
'preferences' => 'Préférences',
'shortcuts' => 'Raccourcis',
'shortcuts_interface' => 'Raccourcis clavier',
@@ -17,17 +17,17 @@ return [
'shortcuts_save' => 'Sauvegarder les raccourcis',
'shortcuts_overlay_desc' => 'Note : Lorsque les raccourcis sont activés, assistant est disponible en appuyant sur "?" qui mettra en surbrillance les raccourcis disponibles pour les actions actuellement visibles à l\'écran.',
'shortcuts_update_success' => 'Les préférences de raccourci ont été mises à jour !',
'shortcuts_overview_desc' => 'Manage keyboard shortcuts you can use to navigate the system user interface.',
'shortcuts_overview_desc' => 'Gérer les raccourcis clavier que vous pouvez utiliser pour naviguer dans l\'interface utilisateur du système.',
'notifications' => 'Notification Preferences',
'notifications_desc' => 'Control the email notifications you receive when certain activity is performed within the system.',
'notifications_opt_own_page_changes' => 'Notify upon changes to pages I own',
'notifications_opt_own_page_comments' => 'Notify upon comments on pages I own',
'notifications_opt_comment_replies' => 'Notify upon replies to my comments',
'notifications_save' => 'Save Preferences',
'notifications_update_success' => 'Notification preferences have been updated!',
'notifications_watched' => 'Watched & Ignored Items',
'notifications_watched_desc' => ' Below are the items that have custom watch preferences applied. To update your preferences for these, view the item then find the watch options in the sidebar.',
'notifications' => 'Préférences de notification',
'notifications_desc' => 'Contrôlez les notifications par e-mail que vous recevez lorsque certaines activités sont effectuées dans le système.',
'notifications_opt_own_page_changes' => 'Notifier lors des modifications des pages que je possède',
'notifications_opt_own_page_comments' => 'Notifier lorsque les pages que je possède sont commentées',
'notifications_opt_comment_replies' => 'Notifier les réponses à mes commentaires',
'notifications_save' => 'Enregistrer les préférences',
'notifications_update_success' => 'Les préférences de notification ont été mises à jour !',
'notifications_watched' => 'Éléments surveillés et ignorés',
'notifications_watched_desc' => ' Voici les éléments qui ont des préférences de surveillance personnalisées appliquées. Pour mettre à jour vos préférences pour celles-ci, consultez l\'élément puis trouvez les options de surveillance dans la barre latérale.',
'profile_overview_desc' => ' Manage your user profile details including preferred language and authentication options.',
'profile_overview_desc' => ' Gérer les détails de votre profil utilisateur y compris la langue préférée et les options d\'authentification.',
];

View File

@@ -163,7 +163,7 @@ return [
'role_manage_settings' => 'Gérer les préférences de l\'application',
'role_export_content' => 'Exporter le contenu',
'role_editor_change' => 'Changer l\'éditeur de page',
'role_notifications' => 'Receive & manage notifications',
'role_notifications' => 'Recevoir et gérer les notifications',
'role_asset' => 'Permissions des ressources',
'roles_system_warning' => 'Sachez que l\'accès à l\'une des trois permissions ci-dessus peut permettre à un utilisateur de modifier ses propres privilèges ou les privilèges des autres utilisateurs du système. N\'attribuez uniquement des rôles avec ces permissions qu\'à des utilisateurs de confiance.',
'role_asset_desc' => 'Ces permissions contrôlent l\'accès par défaut des ressources dans le système. Les permissions dans les livres, les chapitres et les pages ignoreront ces permissions',

View File

@@ -59,7 +59,7 @@ return [
'favourite_remove_notification' => '".ime" je uspješno maknuta iz tvojih favorita',
// Watching
'watch_update_level_notification' => 'Watch preferences successfully updated',
'watch_update_level_notification' => 'Postavke gledanja uspješno ažurirane',
// Auth
'auth_login' => 'prijavljen',

View File

@@ -42,7 +42,7 @@ return [
'remove' => 'Ukloni',
'add' => 'Dodaj',
'configure' => 'Konfiguriraj',
'manage' => 'Manage',
'manage' => 'Upravljaj',
'fullscreen' => 'Cijeli zaslon',
'favourite' => 'Favorit',
'unfavourite' => 'Ukloni iz favorita',

View File

@@ -239,8 +239,8 @@ return [
'pages_md_insert_drawing' => 'Umetni crtež',
'pages_md_show_preview' => 'Prikaži pregled',
'pages_md_sync_scroll' => 'Sinkroniziraj pomicanje pregleda',
'pages_drawing_unsaved' => 'Unsaved Drawing Found',
'pages_drawing_unsaved_confirm' => 'Unsaved drawing data was found from a previous failed drawing save attempt. Would you like to restore and continue editing this unsaved drawing?',
'pages_drawing_unsaved' => 'Pronađen je Nespremljen Crtež',
'pages_drawing_unsaved_confirm' => 'Pronađeni su nespremljeni podaci crteža iz prethodnog neuspjelog pokušaja spremanja crteža. Želite li obnoviti i nastaviti uređivati ovaj nespremljeni crtež?',
'pages_not_in_chapter' => 'Stranica nije u poglavlju',
'pages_move' => 'Premjesti stranicu',
'pages_copy' => 'Kopiraj stranicu',
@@ -407,26 +407,26 @@ return [
'references_to_desc' => 'U nastavku su prikazane sve poznate stranice u sustavu koje se povezuju s ovom stavkom.',
// Watch Options
'watch' => 'Watch',
'watch_title_default' => 'Default Preferences',
'watch_desc_default' => 'Revert watching to just your default notification preferences.',
'watch_title_ignore' => 'Ignore',
'watch_desc_ignore' => 'Ignore all notifications, including those from user-level preferences.',
'watch_title_new' => 'New Pages',
'watch_desc_new' => 'Notify when any new page is created within this item.',
'watch_title_updates' => 'All Page Updates',
'watch_desc_updates' => 'Notify upon all new pages and page changes.',
'watch_desc_updates_page' => 'Notify upon all page changes.',
'watch_title_comments' => 'All Page Updates & Comments',
'watch_desc_comments' => 'Notify upon all new pages, page changes and new comments.',
'watch_desc_comments_page' => 'Notify upon page changes and new comments.',
'watch_change_default' => 'Change default notification preferences',
'watch_detail_ignore' => 'Ignoring notifications',
'watch_detail_new' => 'Watching for new pages',
'watch_detail_updates' => 'Watching new pages and updates',
'watch_detail_comments' => 'Watching new pages, updates & comments',
'watch_detail_parent_book' => 'Watching via parent book',
'watch_detail_parent_book_ignore' => 'Ignoring via parent book',
'watch_detail_parent_chapter' => 'Watching via parent chapter',
'watch_detail_parent_chapter_ignore' => 'Ignoring via parent chapter',
'watch' => 'Prati',
'watch_title_default' => 'Zadane Postavke',
'watch_desc_default' => 'Vratite praćenje samo na vaše zadane postavke obavijesti.',
'watch_title_ignore' => 'Zanemari',
'watch_desc_ignore' => 'Ignorirajte sve obavijesti, uključujući one iz postavki na razini korisnika.',
'watch_title_new' => 'Nove Stranice',
'watch_desc_new' => 'Obavijesti kada se stvori nova stranica unutar ove stavke.',
'watch_title_updates' => 'Sve Promjene na Stranicama',
'watch_desc_updates' => 'Obavijesti o svim novim stranicama i promjenama na stranicama.',
'watch_desc_updates_page' => 'Obavijesti o svim promjenama na stranicama.',
'watch_title_comments' => 'Sve Promjene na Stranicama i Komentari',
'watch_desc_comments' => 'Obavijesti o svim novim stranicama, promjenama na stranicama i novim komentarima.',
'watch_desc_comments_page' => 'Obavijesti o promjenama na stranicama i novim komentarima.',
'watch_change_default' => 'Promijenite zadane postavke obavijesti',
'watch_detail_ignore' => 'Ignoriranje obavijesti',
'watch_detail_new' => 'Prati nove stranice',
'watch_detail_updates' => 'Prati nove stranice i ažuriranja',
'watch_detail_comments' => 'Prati nove stranice, ažuriranja i komentare',
'watch_detail_parent_book' => 'Prati putem nadređene knjige',
'watch_detail_parent_book_ignore' => 'Ignoriraj putem nadređene knjige',
'watch_detail_parent_chapter' => 'Prati puten nadređenog poglavlja',
'watch_detail_parent_chapter_ignore' => 'Ignoriraj putem nadređenog poglavlja',
];

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Pogreška prilikom slanja testnog email:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'URL se ne podudara s konfiguriranim dozvoljenim SSR domaćinima',
];

View File

@@ -4,23 +4,25 @@
*/
return [
'new_comment_subject' => 'New comment on page: :pageName',
'new_comment_intro' => 'A user has commented on a page in :appName:',
'new_page_subject' => 'New page: :pageName',
'new_page_intro' => 'A new page has been created in :appName:',
'updated_page_subject' => 'Updated page: :pageName',
'updated_page_intro' => 'A page has been updated in :appName:',
'updated_page_debounce' => 'To prevent a mass of notifications, for a while you won\'t be sent notifications for further edits to this page by the same editor.',
'new_comment_subject' => 'Novi komentar na stranici: :pageName',
'new_comment_intro' => 'Korisnik je komentirao stranicu u :appName:',
'new_page_subject' => 'Nova stranica: :pageName',
'new_page_intro' => 'Nova stranica je stvorena u :appName:',
'updated_page_subject' => 'ChatGPT
'detail_page_name' => 'Page Name:',
'detail_commenter' => 'Commenter:',
'detail_comment' => 'Comment:',
'detail_created_by' => 'Created By:',
'detail_updated_by' => 'Updated By:',
Ažurirana stranica: :pageName',
'updated_page_intro' => 'Stranica je ažurirana u :appName:',
'updated_page_debounce' => 'Kako biste spriječili velik broj obavijesti, nećete primati obavijesti o daljnjim izmjenama ove stranice od istog urednika neko vrijeme.',
'action_view_comment' => 'View Comment',
'action_view_page' => 'View Page',
'detail_page_name' => 'Naziv Stranice:',
'detail_commenter' => 'Komentator:',
'detail_comment' => 'Komentar:',
'detail_created_by' => 'Kreirao Korisnik:',
'detail_updated_by' => 'Ažurirao Korisnik:',
'footer_reason' => 'This notification was sent to you because :link cover this type of activity for this item.',
'footer_reason_link' => 'your notification preferences',
'action_view_comment' => 'Pogledaj Komentar',
'action_view_page' => 'Pogledaj Stranicu',
'footer_reason' => 'Ova obavijest vam je poslana jer :link pokriva ovu vrstu aktivnosti za ovu stavku.',
'footer_reason_link' => 'vaše postavke obavijesti',
];

View File

@@ -5,7 +5,7 @@
*/
return [
'preferences' => 'Preferences',
'preferences' => 'Postavke',
'shortcuts' => 'Prečaci',
'shortcuts_interface' => 'Prečaci tipkovnice u Sučelju',
@@ -17,17 +17,19 @@ return [
'shortcuts_save' => 'Spremi prečace',
'shortcuts_overlay_desc' => 'Napomena: Kada su prečaci tastature omogućeni, dostupan je pomoćni prikaz preko pritiska na znak "?" koji će istaknuti dostupne prečace za radnje trenutno vidljive na zaslonu.',
'shortcuts_update_success' => 'Postavke prečaca su ažurirane!',
'shortcuts_overview_desc' => 'Manage keyboard shortcuts you can use to navigate the system user interface.',
'shortcuts_overview_desc' => 'Upravljajte prečacima tastature koje možete koristiti za navigaciju korisničkim sučeljem sustava.',
'notifications' => 'Notification Preferences',
'notifications_desc' => 'Control the email notifications you receive when certain activity is performed within the system.',
'notifications_opt_own_page_changes' => 'Notify upon changes to pages I own',
'notifications_opt_own_page_comments' => 'Notify upon comments on pages I own',
'notifications_opt_comment_replies' => 'Notify upon replies to my comments',
'notifications_save' => 'Save Preferences',
'notifications_update_success' => 'Notification preferences have been updated!',
'notifications_watched' => 'Watched & Ignored Items',
'notifications_watched_desc' => ' Below are the items that have custom watch preferences applied. To update your preferences for these, view the item then find the watch options in the sidebar.',
'notifications' => 'Postavke Obavijesti',
'notifications_desc' => 'Kontrolirajte e-mail obavijesti koje primate kada se određene aktivnosti izvrše unutar sustava.',
'notifications_opt_own_page_changes' => 'Obavijesti o promjenama na stranicama koje posjedujem',
'notifications_opt_own_page_comments' => 'ChatGPT
'profile_overview_desc' => ' Manage your user profile details including preferred language and authentication options.',
Obavijesti o komentarima na stranicama koje posjedujem',
'notifications_opt_comment_replies' => 'Obavijesti o odgovorima na moje komentare',
'notifications_save' => 'Spremi Postavke',
'notifications_update_success' => 'Postavke obavijesti su ažurirane!',
'notifications_watched' => 'Praćene i ignorirane stavke',
'notifications_watched_desc' => ' Ispod su stavke na koje su primijenjene prilagođene postavke praćenja. Da biste ažurirali svoje postavke za ove stavke, pregledajte stavku, a zatim pronađite opcije praćenja u bočnoj traci.',
'profile_overview_desc' => ' Upravljajte detaljima svog korisničkog profila, uključujući željeni jezik i opcije za autentifikaciju.',
];

View File

@@ -163,7 +163,7 @@ return [
'role_manage_settings' => 'Upravljanje postavkama aplikacija',
'role_export_content' => 'Izvoz sadržaja',
'role_editor_change' => 'Promijeni uređivač stranica',
'role_notifications' => 'Receive & manage notifications',
'role_notifications' => 'Primanje i upravljanje obavijestima',
'role_asset' => 'Upravljanje vlasništvom',
'roles_system_warning' => 'Uzmite u obzir da pristup bilo kojem od ovih dopuštenja dozvoljavate korisniku upravljanje dopuštenjima ostalih u sustavu. Ova dopuštenja dodijelite pouzdanim korisnicima.',
'role_asset_desc' => 'Ova dopuštenja kontroliraju zadane pristupe. Dopuštenja za knjige, poglavlja i stranice ih poništavaju.',

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Si è verificato un errore durante l\'invio di una e-mail di prova:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'L\'URL non corrisponde agli host SSR configurati',
];

View File

@@ -59,7 +59,7 @@ return [
'favourite_remove_notification' => '":name"がお気に入りから削除されました',
// Watching
'watch_update_level_notification' => 'Watch preferences successfully updated',
'watch_update_level_notification' => 'ウォッチ設定を更新しました',
// Auth
'auth_login' => 'がログイン',
@@ -115,9 +115,9 @@ return [
// Comments
'commented_on' => 'がコメント:',
'comment_create' => 'added comment',
'comment_update' => 'updated comment',
'comment_delete' => 'deleted comment',
'comment_create' => 'がコメントを追加',
'comment_update' => 'がコメントを更新',
'comment_delete' => 'がコメントを削除',
// Other
'permissions_update' => 'が権限を更新:',

View File

@@ -42,7 +42,7 @@ return [
'remove' => '削除',
'add' => '追加',
'configure' => '設定',
'manage' => 'Manage',
'manage' => '管理',
'fullscreen' => '全画面',
'favourite' => 'お気に入り',
'unfavourite' => 'お気に入りから削除',

View File

@@ -236,11 +236,12 @@ return [
'pages_md_preview' => 'プレビュー',
'pages_md_insert_image' => '画像を挿入',
'pages_md_insert_link' => 'エンティティへのリンクを挿入',
'pages_md_insert_drawing' => '描画を追加',
'pages_md_insert_drawing' => 'を追加',
'pages_md_show_preview' => 'プレビューを表示',
'pages_md_sync_scroll' => 'プレビューとスクロールを同期',
'pages_drawing_unsaved' => 'Unsaved Drawing Found',
'pages_drawing_unsaved_confirm' => 'Unsaved drawing data was found from a previous failed drawing save attempt. Would you like to restore and continue editing this unsaved drawing?',
'pages_drawing_unsaved' => '未保存の図が見つかりました',
'pages_drawing_unsaved_confirm' => '以前に保存操作が失敗した、未保存の図が見つかりました。
未保存の図面を復元して編集を続けますか?',
'pages_not_in_chapter' => 'チャプターが設定されていません',
'pages_move' => 'ページを移動',
'pages_copy' => 'ページをコピー',
@@ -363,7 +364,7 @@ return [
'comments' => 'コメント',
'comment_add' => 'コメント追加',
'comment_placeholder' => 'コメントを記入してください',
'comment_count' => '{0} コメントはありません|[1,*] コメント:count',
'comment_count' => '{0} コメントはありません|[1,*] :count 件のコメント',
'comment_save' => 'コメントを保存',
'comment_new' => '新規コメント作成',
'comment_created' => 'コメントを作成しました :createDiff',
@@ -407,26 +408,26 @@ return [
'references_to_desc' => 'この項目にリンクしている、システム内のすべての既知のページを以下に示します。',
// Watch Options
'watch' => 'Watch',
'watch_title_default' => 'Default Preferences',
'watch_desc_default' => 'Revert watching to just your default notification preferences.',
'watch_title_ignore' => 'Ignore',
'watch_desc_ignore' => 'Ignore all notifications, including those from user-level preferences.',
'watch_title_new' => 'New Pages',
'watch_desc_new' => 'Notify when any new page is created within this item.',
'watch_title_updates' => 'All Page Updates',
'watch_desc_updates' => 'Notify upon all new pages and page changes.',
'watch_desc_updates_page' => 'Notify upon all page changes.',
'watch_title_comments' => 'All Page Updates & Comments',
'watch_desc_comments' => 'Notify upon all new pages, page changes and new comments.',
'watch_desc_comments_page' => 'Notify upon page changes and new comments.',
'watch_change_default' => 'Change default notification preferences',
'watch_detail_ignore' => 'Ignoring notifications',
'watch_detail_new' => 'Watching for new pages',
'watch_detail_updates' => 'Watching new pages and updates',
'watch_detail_comments' => 'Watching new pages, updates & comments',
'watch_detail_parent_book' => 'Watching via parent book',
'watch_detail_parent_book_ignore' => 'Ignoring via parent book',
'watch_detail_parent_chapter' => 'Watching via parent chapter',
'watch_detail_parent_chapter_ignore' => 'Ignoring via parent chapter',
'watch' => 'ウォッチ',
'watch_title_default' => 'デフォルト設定',
'watch_desc_default' => 'デフォルトの通知設定に戻します。',
'watch_title_ignore' => '無効',
'watch_desc_ignore' => 'ユーザーの通知設定に関わらず、すべての通知を無効にします。',
'watch_title_new' => 'ページの作成',
'watch_desc_new' => 'このアイテム内に新しいページが作成されたときに通知します。',
'watch_title_updates' => 'すべてのページ更新',
'watch_desc_updates' => 'ページの作成や更新を通知します。',
'watch_desc_updates_page' => 'ページの更新を通知します。',
'watch_title_comments' => 'すべてのページ更新とコメント',
'watch_desc_comments' => 'ページの作成・更新、およびコメント追加を通知します。',
'watch_desc_comments_page' => 'ページの更新およびコメント追加を通知します。',
'watch_change_default' => 'デフォルトの通知設定を変更する',
'watch_detail_ignore' => '通知無効',
'watch_detail_new' => 'ページ作成をウォッチ',
'watch_detail_updates' => 'ページの作成と更新をウォッチ',
'watch_detail_comments' => 'ページの作成・更新とコメントをウォッチ',
'watch_detail_parent_book' => '親ブックでウォッチ',
'watch_detail_parent_book_ignore' => '親ブックで通知無効',
'watch_detail_parent_chapter' => '親チャプタでウォッチ',
'watch_detail_parent_chapter_ignore' => '親チャプタで通知無効',
];

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'テストメール送信時にエラーが発生しました:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'URLはサーバサイドリクエストが許可されたホストではありません。',
];

View File

@@ -4,23 +4,23 @@
*/
return [
'new_comment_subject' => 'New comment on page: :pageName',
'new_comment_intro' => 'A user has commented on a page in :appName:',
'new_page_subject' => 'New page: :pageName',
'new_page_intro' => 'A new page has been created in :appName:',
'updated_page_subject' => 'Updated page: :pageName',
'updated_page_intro' => 'A page has been updated in :appName:',
'updated_page_debounce' => 'To prevent a mass of notifications, for a while you won\'t be sent notifications for further edits to this page by the same editor.',
'new_comment_subject' => 'ページへのコメント追加: :pageName',
'new_comment_intro' => ':appName でページにコメントが追加されました',
'new_page_subject' => 'ページの作成: :pageName',
'new_page_intro' => ':appName でページが作成されました',
'updated_page_subject' => 'ページの更新: :pageName',
'updated_page_intro' => ':appName でページが更新されました',
'updated_page_debounce' => '大量の通知を防ぐために、しばらくの間は同じユーザがこのページをさらに編集しても通知は送信されません。',
'detail_page_name' => 'Page Name:',
'detail_commenter' => 'Commenter:',
'detail_comment' => 'Comment:',
'detail_created_by' => 'Created By:',
'detail_updated_by' => 'Updated By:',
'detail_page_name' => 'ページ名:',
'detail_commenter' => 'コメントユーザ:',
'detail_comment' => 'コメント:',
'detail_created_by' => '作成ユーザ:',
'detail_updated_by' => '更新ユーザ:',
'action_view_comment' => 'View Comment',
'action_view_page' => 'View Page',
'action_view_comment' => 'コメントを表示',
'action_view_page' => 'ページを表示',
'footer_reason' => 'This notification was sent to you because :link cover this type of activity for this item.',
'footer_reason_link' => 'your notification preferences',
'footer_reason' => 'この項目のアクティビティは :link による対象となっているため、この通知が送信されました。',
'footer_reason_link' => '通知設定',
];

View File

@@ -5,7 +5,7 @@
*/
return [
'preferences' => 'Preferences',
'preferences' => '設定',
'shortcuts' => 'ショートカット',
'shortcuts_interface' => 'インターフェイスのキーボードショートカット',
@@ -16,18 +16,18 @@ return [
'shortcuts_section_actions' => '共通のアクション',
'shortcuts_save' => 'ショートカットを保存',
'shortcuts_overlay_desc' => '注:ショートカットが有効な場合はヘルパーオーバーレイが利用できます。「?」を押すと現在画面に表示されているアクションで利用可能なショートカットをハイライト表示します。',
'shortcuts_update_success' => 'ショートカットの設定更新されました',
'shortcuts_overview_desc' => 'Manage keyboard shortcuts you can use to navigate the system user interface.',
'shortcuts_update_success' => 'ショートカットの設定更新ました',
'shortcuts_overview_desc' => 'システムのユーザーインターフェイスを操作するためのキーボードショートカットを管理します。',
'notifications' => 'Notification Preferences',
'notifications_desc' => 'Control the email notifications you receive when certain activity is performed within the system.',
'notifications_opt_own_page_changes' => 'Notify upon changes to pages I own',
'notifications_opt_own_page_comments' => 'Notify upon comments on pages I own',
'notifications_opt_comment_replies' => 'Notify upon replies to my comments',
'notifications_save' => 'Save Preferences',
'notifications_update_success' => 'Notification preferences have been updated!',
'notifications_watched' => 'Watched & Ignored Items',
'notifications_watched_desc' => ' Below are the items that have custom watch preferences applied. To update your preferences for these, view the item then find the watch options in the sidebar.',
'notifications' => '通知設定',
'notifications_desc' => 'システム内で特定のアクティビティが実行されたときに受信する電子メール通知を制御します。',
'notifications_opt_own_page_changes' => '自分が所有するページの変更を通知する',
'notifications_opt_own_page_comments' => '自分が所有するページへのコメントを通知する',
'notifications_opt_comment_replies' => '自分のコメントへの返信を通知する',
'notifications_save' => '設定を保存',
'notifications_update_success' => '通知設定を更新しました。',
'notifications_watched' => 'ウォッチ/通知無効 項目',
'notifications_watched_desc' => ' 以下はカスタムウォッチの設定が適用されている項目です。 これらの設定を更新するには、項目を表示してサイドバーのウォッチオプションを参照してください。',
'profile_overview_desc' => ' Manage your user profile details including preferred language and authentication options.',
'profile_overview_desc' => ' 言語や認証オプションを含むユーザープロファイルの詳細を管理します。',
];

View File

@@ -163,7 +163,7 @@ return [
'role_manage_settings' => 'アプリケーション設定の管理',
'role_export_content' => 'コンテンツのエクスポート',
'role_editor_change' => 'ページエディタの変更',
'role_notifications' => 'Receive & manage notifications',
'role_notifications' => '通知の受信と管理',
'role_asset' => 'アセット権限',
'roles_system_warning' => '上記の3つの権限のいずれかを付与することは、ユーザーが自分の特権またはシステム内の他のユーザーの特権を変更できる可能性があることに注意してください。これらの権限は信頼できるユーザーにのみ割り当ててください。',
'role_asset_desc' => '各アセットに対するデフォルトの権限を設定します。ここで設定した権限が優先されます。',

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Feil kastet når du sendte en test-e-post:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'URLen samsvarer ikke med de konfigurerte SSR-vertene',
];

View File

@@ -59,7 +59,7 @@ return [
'favourite_remove_notification' => '":name" is verwijderd uit je favorieten',
// Watching
'watch_update_level_notification' => 'Kijkvoorkeuren succesvol aangepast',
'watch_update_level_notification' => 'Volg voorkeuren succesvol aangepast',
// Auth
'auth_login' => 'heeft ingelogd',

View File

@@ -239,8 +239,8 @@ return [
'pages_md_insert_drawing' => 'Tekening invoegen',
'pages_md_show_preview' => 'Toon preview',
'pages_md_sync_scroll' => 'Synchroniseer preview scroll',
'pages_drawing_unsaved' => 'Unsaved Drawing Found',
'pages_drawing_unsaved_confirm' => 'Unsaved drawing data was found from a previous failed drawing save attempt. Would you like to restore and continue editing this unsaved drawing?',
'pages_drawing_unsaved' => 'Niet-opgeslagen Tekening Gevonden',
'pages_drawing_unsaved_confirm' => 'Er zijn niet-opgeslagen tekeninggegevens gevonden van een eerdere mislukte poging om de tekening op te slaan. Wilt u deze niet-opgeslagen tekening herstellen en verder bewerken?',
'pages_not_in_chapter' => 'Deze pagina staat niet in een hoofdstuk',
'pages_move' => 'Pagina verplaatsten',
'pages_copy' => 'Pagina kopiëren',
@@ -407,7 +407,7 @@ return [
'references_to_desc' => 'Hieronder staan alle gekende pagina\'s in het systeem die naar dit item linken.',
// Watch Options
'watch' => 'Kijk',
'watch' => 'Volg',
'watch_title_default' => 'Standaard Voorkeuren',
'watch_desc_default' => 'Terugkeren naar alleen je standaardvoorkeuren voor meldingen.',
'watch_title_ignore' => 'Negeer',

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Fout opgetreden bij het verzenden van een test email:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'De URL komt niet overeen met de geconfigureerde toegestane SSR-hosts',
];

View File

@@ -26,8 +26,8 @@ return [
'notifications_opt_comment_replies' => 'Geef melding van reacties op mijn opmerkingen',
'notifications_save' => 'Voorkeuren opslaan',
'notifications_update_success' => 'Voorkeuren voor meldingen zijn bijgewerkt!',
'notifications_watched' => 'Ingestelde Items',
'notifications_watched_desc' => ' Hieronder staan de items waarvoor aangepaste \'kijk\' voorkeuren zijn toegepast. Om je voorkeuren voor deze items bij te werken, bekijk je het item en zoek je naar de \'kijk\' opties in de zijbalk.',
'notifications_watched' => 'Gevolgde & Genegeerde Items',
'notifications_watched_desc' => ' Hieronder staan de items waarvoor aangepaste \'Volg\'-voorkeuren zijn toegepast. Om je voorkeuren voor deze items bij te werken, bekijk je het item en zoek je naar de \'Volg\' opties in de zijbalk.',
'profile_overview_desc' => ' Beheer de details van je gebruikersprofiel, inclusief de voorkeurstaal en verificatieopties.',
];

View File

@@ -59,7 +59,7 @@ return [
'favourite_remove_notification' => '":name" został usunięty z ulubionych',
// Watching
'watch_update_level_notification' => 'Watch preferences successfully updated',
'watch_update_level_notification' => 'Ustawienia obserwowania pomyślnie zaktualizowane',
// Auth
'auth_login' => 'zalogował się',
@@ -115,9 +115,9 @@ return [
// Comments
'commented_on' => 'skomentował',
'comment_create' => 'added comment',
'comment_update' => 'updated comment',
'comment_delete' => 'deleted comment',
'comment_create' => 'dodał komentarz',
'comment_update' => 'zaktualizował komentarz',
'comment_delete' => 'usunął komentarz',
// Other
'permissions_update' => 'zaktualizował uprawnienia',

View File

@@ -42,7 +42,7 @@ return [
'remove' => 'Usuń',
'add' => 'Dodaj',
'configure' => 'Konfiguruj',
'manage' => 'Manage',
'manage' => 'Zarządzaj',
'fullscreen' => 'Pełny ekran',
'favourite' => 'Ulubione',
'unfavourite' => 'Usuń z ulubionych',

View File

@@ -106,7 +106,7 @@ return [
'shelves_permissions_updated' => 'Uprawnienia półki zostały zaktualizowane',
'shelves_permissions_active' => 'Uprawnienia półki są aktywne',
'shelves_permissions_cascade_warning' => 'Uprawnienia na półkach nie są automatycznie nakładane na zawartych w nich książkach. Dzieje się tak dlatego, że książka może istnieć na wielu półkach. Uprawnienia można jednak skopiować do książek podrzędnych, korzystając z opcji znajdującej się poniżej.',
'shelves_permissions_create' => 'Shelf create permissions are only used for copying permissions to child books using the action below. They do not control the ability to create books.',
'shelves_permissions_create' => 'Uprawnienia tworzenia półki są używane tylko do kopiowania uprawnień do książek podrzędnych za pomocą poniższej czynności. Nie kontrolują możliwości tworzenia książek.',
'shelves_copy_permissions_to_books' => 'Skopiuj uprawnienia do książek',
'shelves_copy_permissions' => 'Skopiuj uprawnienia',
'shelves_copy_permissions_explain' => 'To spowoduje zastosowanie obecnych ustawień uprawnień tej półki na wszystkich książkach w niej zawartych. Przed aktywacją upewnij się, że wszelkie zmiany w uprawnieniach tej półki zostały zapisane.',
@@ -239,8 +239,8 @@ return [
'pages_md_insert_drawing' => 'Wstaw rysunek',
'pages_md_show_preview' => 'Pokaż podgląd',
'pages_md_sync_scroll' => 'Synchronizuj przewijanie podglądu',
'pages_drawing_unsaved' => 'Unsaved Drawing Found',
'pages_drawing_unsaved_confirm' => 'Unsaved drawing data was found from a previous failed drawing save attempt. Would you like to restore and continue editing this unsaved drawing?',
'pages_drawing_unsaved' => 'Znaleziono niezapisany rysunek',
'pages_drawing_unsaved_confirm' => 'Znaleziono niezapisane dane rysowania z poprzedniej nieudanej próby zapisu. Czy chcesz przywrócić i kontynuować edycję tego niezapisanego rysunku?',
'pages_not_in_chapter' => 'Strona nie została umieszczona w rozdziale',
'pages_move' => 'Przenieś stronę',
'pages_copy' => 'Skopiuj stronę',
@@ -270,11 +270,11 @@ return [
'pages_copy_link' => 'Kopiuj link',
'pages_edit_content_link' => 'Przejdź do sekcji w edytorze',
'pages_pointer_enter_mode' => 'Aktywuj tryb wyboru sekcji',
'pages_pointer_label' => 'Page Section Options',
'pages_pointer_permalink' => 'Page Section Permalink',
'pages_pointer_include_tag' => 'Page Section Include Tag',
'pages_pointer_toggle_link' => 'Permalink mode, Press to show include tag',
'pages_pointer_toggle_include' => 'Include tag mode, Press to show permalink',
'pages_pointer_label' => 'Sekcja opcji strony',
'pages_pointer_permalink' => 'Sekcja odnośnika strony',
'pages_pointer_include_tag' => 'Sekcja taga inkludującego',
'pages_pointer_toggle_link' => 'Tryb bezpośredniego linku, naciśnij aby zmienić na tryb tagu do inkludowania',
'pages_pointer_toggle_include' => 'Tryb tagu do inkludowania, naciśnij aby zmienić na tryb bezpośredniego linku',
'pages_permissions_active' => 'Uprawnienia strony są aktywne',
'pages_initial_revision' => 'Pierwsze wydanie',
'pages_references_update_revision' => 'Automatyczna aktualizacja wewnętrznych linków',
@@ -407,26 +407,26 @@ return [
'references_to_desc' => 'Poniżej znajdują się wszystkie znane strony w systemie, które odnoszą się do tego elementu.',
// Watch Options
'watch' => 'Watch',
'watch_title_default' => 'Default Preferences',
'watch_desc_default' => 'Revert watching to just your default notification preferences.',
'watch_title_ignore' => 'Ignore',
'watch_desc_ignore' => 'Ignore all notifications, including those from user-level preferences.',
'watch_title_new' => 'New Pages',
'watch_desc_new' => 'Notify when any new page is created within this item.',
'watch_title_updates' => 'All Page Updates',
'watch_desc_updates' => 'Notify upon all new pages and page changes.',
'watch_desc_updates_page' => 'Notify upon all page changes.',
'watch_title_comments' => 'All Page Updates & Comments',
'watch_desc_comments' => 'Notify upon all new pages, page changes and new comments.',
'watch_desc_comments_page' => 'Notify upon page changes and new comments.',
'watch_change_default' => 'Change default notification preferences',
'watch_detail_ignore' => 'Ignoring notifications',
'watch_detail_new' => 'Watching for new pages',
'watch_detail_updates' => 'Watching new pages and updates',
'watch_detail_comments' => 'Watching new pages, updates & comments',
'watch_detail_parent_book' => 'Watching via parent book',
'watch_detail_parent_book_ignore' => 'Ignoring via parent book',
'watch_detail_parent_chapter' => 'Watching via parent chapter',
'watch_detail_parent_chapter_ignore' => 'Ignoring via parent chapter',
'watch' => 'Obserwuj',
'watch_title_default' => 'Domyślne ustawienia',
'watch_desc_default' => 'Przywróć do tylko domyślnych ustawień powiadomień.',
'watch_title_ignore' => 'Ignoruj',
'watch_desc_ignore' => 'Ignoruj wszystkie powiadomienia, w tym te z preferencji użytkownika.',
'watch_title_new' => 'Nowe strony',
'watch_desc_new' => 'Powiadom o utworzeniu nowej strony w tym elemencie.',
'watch_title_updates' => 'Wszystkie aktualizacje strony',
'watch_desc_updates' => 'Powiadom o wszystkich nowych stronach i zmianach strony.',
'watch_desc_updates_page' => 'Powiadom o wszystkich zmianach strony.',
'watch_title_comments' => 'Wszystkie aktualizacje strony i komentarze',
'watch_desc_comments' => 'Powiadom o wszystkich nowych stronach, zmianach na stronie i nowych komentarzach.',
'watch_desc_comments_page' => 'Powiadom o zmianach strony i nowych komentarzach.',
'watch_change_default' => 'Zmień domyślne ustawienia powiadomień',
'watch_detail_ignore' => 'Ignorowanie powiadomień',
'watch_detail_new' => 'Obserwowanie nowych stron',
'watch_detail_updates' => 'Obserwowanie nowych stron i aktualizacji',
'watch_detail_comments' => 'Obserwowanie nowych stron, aktualizacji i komentarzy',
'watch_detail_parent_book' => 'Obserwowanie przez książkę nadrzędną',
'watch_detail_parent_book_ignore' => 'Ignorowanie przez książkę nadrzędną',
'watch_detail_parent_chapter' => 'Obserwowanie przez rozdział nadrzędny',
'watch_detail_parent_chapter_ignore' => 'Ignorowanie przez rozdział nadrzędny',
];

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => 'Błąd podczas wysyłania testowej wiadomości e-mail:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'Adres URL nie pasuje do skonfigurowanych dozwolonych hostów SSR',
];

View File

@@ -4,23 +4,23 @@
*/
return [
'new_comment_subject' => 'New comment on page: :pageName',
'new_comment_intro' => 'A user has commented on a page in :appName:',
'new_page_subject' => 'New page: :pageName',
'new_page_intro' => 'A new page has been created in :appName:',
'updated_page_subject' => 'Updated page: :pageName',
'updated_page_intro' => 'A page has been updated in :appName:',
'updated_page_debounce' => 'To prevent a mass of notifications, for a while you won\'t be sent notifications for further edits to this page by the same editor.',
'new_comment_subject' => 'Nowy komentarz na stronie: :pageName',
'new_comment_intro' => 'Użytkownik skomentował stronę w :appName:',
'new_page_subject' => 'Nowa strona: :pageName',
'new_page_intro' => 'Nowa strona została utworzona w :appName:',
'updated_page_subject' => 'Zaktualizowano stronę: :pageName',
'updated_page_intro' => 'Strona została zaktualizowana w :appName:',
'updated_page_debounce' => 'Aby zapobiec nadmiarowi powiadomień, przez jakiś czas nie będziesz otrzymywać powiadomień o dalszych edycjach tej strony przez tego samego edytora.',
'detail_page_name' => 'Page Name:',
'detail_commenter' => 'Commenter:',
'detail_comment' => 'Comment:',
'detail_created_by' => 'Created By:',
'detail_updated_by' => 'Updated By:',
'detail_page_name' => 'Nazwa strony:',
'detail_commenter' => 'Skomentował:',
'detail_comment' => 'Komentarz:',
'detail_created_by' => 'Utworzono przez:',
'detail_updated_by' => 'Zaktualizowano przez:',
'action_view_comment' => 'View Comment',
'action_view_page' => 'View Page',
'action_view_comment' => 'Pokaż komentarz',
'action_view_page' => 'Wyświetl stronę',
'footer_reason' => 'This notification was sent to you because :link cover this type of activity for this item.',
'footer_reason_link' => 'your notification preferences',
'footer_reason' => 'To powiadomienie zostało wysłane do Ciebie, ponieważ :link obejmuje ten typ aktywności dla tego elementu.',
'footer_reason_link' => 'ustawienia powiadomień',
];

View File

@@ -5,7 +5,7 @@
*/
return [
'preferences' => 'Preferences',
'preferences' => 'Preferencje',
'shortcuts' => 'Skróty',
'shortcuts_interface' => 'Interfejs Skrótów Klawiszowych',
@@ -17,17 +17,17 @@ return [
'shortcuts_save' => 'Zapisz skróty',
'shortcuts_overlay_desc' => 'Uwaga: Gdy skróty są włączone, przez naciśnięcie "?" może być otworzona nakładka pomocnicza, która podświetli dostępne skróty dla akcji widocznych obecnie na ekranie.',
'shortcuts_update_success' => 'Ustawienia skrótów zostały zaktualizowane!',
'shortcuts_overview_desc' => 'Manage keyboard shortcuts you can use to navigate the system user interface.',
'shortcuts_overview_desc' => 'Zarządzaj skrótami klawiaturowymi, które możesz użyć do nawigacji interfejsu użytkownika systemu.',
'notifications' => 'Notification Preferences',
'notifications_desc' => 'Control the email notifications you receive when certain activity is performed within the system.',
'notifications_opt_own_page_changes' => 'Notify upon changes to pages I own',
'notifications_opt_own_page_comments' => 'Notify upon comments on pages I own',
'notifications_opt_comment_replies' => 'Notify upon replies to my comments',
'notifications_save' => 'Save Preferences',
'notifications_update_success' => 'Notification preferences have been updated!',
'notifications_watched' => 'Watched & Ignored Items',
'notifications_watched_desc' => ' Below are the items that have custom watch preferences applied. To update your preferences for these, view the item then find the watch options in the sidebar.',
'notifications' => 'Preferencje powiadomień',
'notifications_desc' => 'Kontroluj otrzymywane powiadomienia e-mail, gdy określona aktywność jest wykonywana w systemie.',
'notifications_opt_own_page_changes' => 'Powiadom o zmianach na stronach, których jestem właścicielem',
'notifications_opt_own_page_comments' => 'Powiadom o komentarzach na stronach, których jestem właścicielem',
'notifications_opt_comment_replies' => 'Powiadom o odpowiedziach na moje komentarze',
'notifications_save' => 'Zapisz preferencje',
'notifications_update_success' => 'Preferencje powiadomień zostały zaktualizowane!',
'notifications_watched' => 'Obserwowane i ignorowane elementy',
'notifications_watched_desc' => ' Poniżej znajdują się elementy, które mają własne preferencje obserwowania. Aby zaktualizować swoje preferencje, zobacz dany element, a następnie znajdź opcje obserwowania na pasku bocznym.',
'profile_overview_desc' => ' Manage your user profile details including preferred language and authentication options.',
'profile_overview_desc' => ' Zarządzaj szczegółami swojego profilu użytkownika, w tym preferowanym językiem i opcjami uwierzytelniania.',
];

View File

@@ -163,7 +163,7 @@ return [
'role_manage_settings' => 'Zarządzanie ustawieniami aplikacji',
'role_export_content' => 'Eksportuj zawartość',
'role_editor_change' => 'Zmień edytor strony',
'role_notifications' => 'Receive & manage notifications',
'role_notifications' => 'Odbieranie i zarządzanie powiadomieniami',
'role_asset' => 'Zarządzanie zasobami',
'roles_system_warning' => 'Pamiętaj, że dostęp do trzech powyższych uprawnień może pozwolić użytkownikowi na zmianę własnych uprawnień lub uprawnień innych osób w systemie. Przypisz tylko role z tymi uprawnieniami do zaufanych użytkowników.',
'role_asset_desc' => 'Te ustawienia kontrolują zarządzanie zasobami systemu. Uprawnienia książek, rozdziałów i stron nadpisują te ustawienia.',

View File

@@ -117,7 +117,7 @@ return [
'commented_on' => 'прокоментував',
'comment_create' => 'added comment',
'comment_update' => 'updated comment',
'comment_delete' => 'deleted comment',
'comment_delete' => 'видалений коментар',
// Other
'permissions_update' => 'оновив дозволи',

View File

@@ -59,7 +59,7 @@ return [
'favourite_remove_notification' => '":name" 已从您的收藏中删除',
// Watching
'watch_update_level_notification' => 'Watch preferences successfully updated',
'watch_update_level_notification' => '关注偏好设置已更新成功',
// Auth
'auth_login' => '已登录',

View File

@@ -42,7 +42,7 @@ return [
'remove' => '删除',
'add' => '添加',
'configure' => '配置',
'manage' => 'Manage',
'manage' => '管理',
'fullscreen' => '全屏',
'favourite' => '收藏',
'unfavourite' => '取消收藏',

View File

@@ -239,8 +239,8 @@ return [
'pages_md_insert_drawing' => '插入图表',
'pages_md_show_preview' => '显示预览',
'pages_md_sync_scroll' => '同步预览滚动',
'pages_drawing_unsaved' => 'Unsaved Drawing Found',
'pages_drawing_unsaved_confirm' => 'Unsaved drawing data was found from a previous failed drawing save attempt. Would you like to restore and continue editing this unsaved drawing?',
'pages_drawing_unsaved' => '找到未保存的绘图',
'pages_drawing_unsaved_confirm' => '从之前保存失败的绘图中发现了可恢复的数据。您想恢复并继续编辑这个未保存的绘图吗?',
'pages_not_in_chapter' => '本页面不在某章节中',
'pages_move' => '移动页面',
'pages_copy' => '复制页面',
@@ -407,26 +407,26 @@ return [
'references_to_desc' => '下面显示的是系统中所有已知链接到这个项目的页面。',
// Watch Options
'watch' => 'Watch',
'watch_title_default' => 'Default Preferences',
'watch_desc_default' => 'Revert watching to just your default notification preferences.',
'watch_title_ignore' => 'Ignore',
'watch_desc_ignore' => 'Ignore all notifications, including those from user-level preferences.',
'watch_title_new' => 'New Pages',
'watch_desc_new' => 'Notify when any new page is created within this item.',
'watch_title_updates' => 'All Page Updates',
'watch_desc_updates' => 'Notify upon all new pages and page changes.',
'watch_desc_updates_page' => 'Notify upon all page changes.',
'watch_title_comments' => 'All Page Updates & Comments',
'watch_desc_comments' => 'Notify upon all new pages, page changes and new comments.',
'watch_desc_comments_page' => 'Notify upon page changes and new comments.',
'watch_change_default' => 'Change default notification preferences',
'watch_detail_ignore' => 'Ignoring notifications',
'watch_detail_new' => 'Watching for new pages',
'watch_detail_updates' => 'Watching new pages and updates',
'watch_detail_comments' => 'Watching new pages, updates & comments',
'watch_detail_parent_book' => 'Watching via parent book',
'watch_detail_parent_book_ignore' => 'Ignoring via parent book',
'watch_detail_parent_chapter' => 'Watching via parent chapter',
'watch_detail_parent_chapter_ignore' => 'Ignoring via parent chapter',
'watch' => '关注',
'watch_title_default' => '默认偏好设置',
'watch_desc_default' => '将关注设置恢复为默认通知偏好设置。',
'watch_title_ignore' => '忽略',
'watch_desc_ignore' => '忽略所有通知,包括来自用户级偏好的通知。',
'watch_title_new' => '新页面',
'watch_desc_new' => '在此项目中创建任何新页面时通知我。',
'watch_title_updates' => '所有页面更新',
'watch_desc_updates' => '在所有新页面和页面更改时通知我。',
'watch_desc_updates_page' => '在有页面发生更改时通知我。',
'watch_title_comments' => '所有页面更新和评论',
'watch_desc_comments' => '在有新页面、页面更改和新评论时通知我。',
'watch_desc_comments_page' => '在有页面更改和新评论时通知我。',
'watch_change_default' => '更改默认通知偏好',
'watch_detail_ignore' => '忽略通知',
'watch_detail_new' => '已关注新页面',
'watch_detail_updates' => '已关注新页面和更新',
'watch_detail_comments' => '已关注新页面、更新和评论',
'watch_detail_parent_book' => '已关注—继承自父图书',
'watch_detail_parent_book_ignore' => '已忽略—继承自父图书',
'watch_detail_parent_chapter' => '已关注—继承自父章节',
'watch_detail_parent_chapter_ignore' => '已忽略—继承自父章节',
];

View File

@@ -112,5 +112,5 @@ return [
'maintenance_test_email_failure' => '发送测试电子邮件时出现错误:',
// HTTP errors
'http_ssr_url_no_match' => 'The URL does not match the configured allowed SSR hosts',
'http_ssr_url_no_match' => 'URL 与已配置的 SSR 主机不匹配',
];

View File

@@ -4,23 +4,23 @@
*/
return [
'new_comment_subject' => 'New comment on page: :pageName',
'new_comment_intro' => 'A user has commented on a page in :appName:',
'new_page_subject' => 'New page: :pageName',
'new_page_intro' => 'A new page has been created in :appName:',
'updated_page_subject' => 'Updated page: :pageName',
'updated_page_intro' => 'A page has been updated in :appName:',
'updated_page_debounce' => 'To prevent a mass of notifications, for a while you won\'t be sent notifications for further edits to this page by the same editor.',
'new_comment_subject' => '页面上有新评论::pageName',
'new_comment_intro' => '一位用户在 :appName: 的页面上发表了评论',
'new_page_subject' => '新页面::pageName',
'new_page_intro' => ':appName: 中创建了一个新页面',
'updated_page_subject' => '页面更新::pageName',
'updated_page_intro' => ':appName: 中的一个页面已被更新',
'updated_page_debounce' => '为了防止出现大量通知,一段时间内您不会收到同一编辑者再次编辑本页面的通知。',
'detail_page_name' => 'Page Name:',
'detail_commenter' => 'Commenter:',
'detail_comment' => 'Comment:',
'detail_created_by' => 'Created By:',
'detail_updated_by' => 'Updated By:',
'detail_page_name' => '页面名称:',
'detail_commenter' => '评论者:',
'detail_comment' => '评论:',
'detail_created_by' => '创建者:',
'detail_updated_by' => '更新者:',
'action_view_comment' => 'View Comment',
'action_view_page' => 'View Page',
'action_view_comment' => '查看评论',
'action_view_page' => '查看页面',
'footer_reason' => 'This notification was sent to you because :link cover this type of activity for this item.',
'footer_reason_link' => 'your notification preferences',
'footer_reason' => '向您发送此通知是因为 :link 涵盖了该项目的此类活动。',
'footer_reason_link' => '个人通知偏好设置',
];

View File

@@ -5,7 +5,7 @@
*/
return [
'preferences' => 'Preferences',
'preferences' => '偏好设置',
'shortcuts' => '快捷键',
'shortcuts_interface' => '界面键盘快捷键',
@@ -17,17 +17,17 @@ return [
'shortcuts_save' => '保存快捷键',
'shortcuts_overlay_desc' => '注意:当快捷键启用时,可以按"?"键来打开帮助,它将突出显示当前屏幕上可见操作的快捷键。',
'shortcuts_update_success' => '快捷键设置已更新!',
'shortcuts_overview_desc' => 'Manage keyboard shortcuts you can use to navigate the system user interface.',
'shortcuts_overview_desc' => '管理可用于导航系统用户界面的快捷键。',
'notifications' => 'Notification Preferences',
'notifications_desc' => 'Control the email notifications you receive when certain activity is performed within the system.',
'notifications_opt_own_page_changes' => 'Notify upon changes to pages I own',
'notifications_opt_own_page_comments' => 'Notify upon comments on pages I own',
'notifications_opt_comment_replies' => 'Notify upon replies to my comments',
'notifications_save' => 'Save Preferences',
'notifications_update_success' => 'Notification preferences have been updated!',
'notifications_watched' => 'Watched & Ignored Items',
'notifications_watched_desc' => ' Below are the items that have custom watch preferences applied. To update your preferences for these, view the item then find the watch options in the sidebar.',
'notifications' => '通知偏好',
'notifications_desc' => '控制在系统内发生某些活动时您会收到的电子邮件通知。',
'notifications_opt_own_page_changes' => '在我拥有的页面被修改时通知我',
'notifications_opt_own_page_comments' => '在我拥有的页面上有新评论时通知我',
'notifications_opt_comment_replies' => '在有人回复我的频率时通知我',
'notifications_save' => '保存偏好设置',
'notifications_update_success' => '通知偏好设置已更新!',
'notifications_watched' => '已关注和忽略的项目',
'notifications_watched_desc' => ' 下面是已应用自定义关注选项的项目。要更新您的关注设置,请查看该项目,然后在该项目的侧边栏中找到关注选项。',
'profile_overview_desc' => ' Manage your user profile details including preferred language and authentication options.',
'profile_overview_desc' => ' 管理用户个人资料信息,包括首选语言和验证选项。',
];

View File

@@ -163,7 +163,7 @@ return [
'role_manage_settings' => '管理 App 设置',
'role_export_content' => '导出内容',
'role_editor_change' => '更改页面编辑器',
'role_notifications' => 'Receive & manage notifications',
'role_notifications' => '管理和接收通知',
'role_asset' => '资源许可',
'roles_system_warning' => '请注意,拥有以上三个权限中的任何一个都会允许用户更改自己的权限或系统中其他人的权限。 请只将拥有这些权限的角色分配给你信任的用户。',
'role_asset_desc' => '对系统内资源的默认访问许可将由这些权限控制。单独设置在书籍、章节和页面上的权限将覆盖这里的权限设定。',

View File

@@ -15,7 +15,7 @@ return [
'page_restore' => '已還原頁面',
'page_restore_notification' => '頁面已還原成功',
'page_move' => '已移動頁面',
'page_move_notification' => 'Page successfully moved',
'page_move_notification' => '頁面已成功移動',
// Chapters
'chapter_create' => '已建立章節',
@@ -25,7 +25,7 @@ return [
'chapter_delete' => '已刪除章節',
'chapter_delete_notification' => '章節已刪除成功',
'chapter_move' => '已移動章節',
'chapter_move_notification' => 'Chapter successfully moved',
'chapter_move_notification' => '章節已移動成功',
// Books
'book_create' => '已建立書本',

View File

@@ -21,6 +21,7 @@
<server name="APP_AUTO_LANG_PUBLIC" value="true"/>
<server name="APP_URL" value="http://bookstack.dev"/>
<server name="ALLOWED_IFRAME_HOSTS" value=""/>
<server name="ALLOWED_SSR_HOSTS" value="*"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="QUEUE_CONNECTION" value="sync"/>

32
public/dist/app.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -50,8 +50,8 @@ Note: Listed services are not tested, vetted nor supported by the official BookS
#### Bronze Sponsors
<table><tbody><tr>
<td><a href="https://www.stellarhosted.com/bookstack/" target="_blank">
<img width="240" src="https://media.githubusercontent.com/media/BookStackApp/website/main/static/images/sponsors/stellarhosted.png" alt="Stellar Hosted">
<td><a href="https://cloudabove.com/hosting" target="_blank">
<img width="240" src="https://media.githubusercontent.com/media/BookStackApp/website/main/static/images/sponsors/cloudabove.png" alt="Cloudabove">
</a></td>
<td><a href="https://www.practicali.be" target="_blank">
<img width="240" src="https://media.githubusercontent.com/media/BookStackApp/website/main/static/images/sponsors/practicali.png" alt="Practicali">
@@ -102,7 +102,7 @@ Security information for administering a BookStack instance can be found on the
If you'd like to be notified of new potential security concerns you can [sign-up to the BookStack security mailing list](https://updates.bookstackapp.com/signup/bookstack-security-updates).
If you would like to report a security concern, details of doing so can [can be found here](https://github.com/BookStackApp/BookStack/blob/development/.github/SECURITY.md).
If you would like to report a security concern, details of doing so [can be found here](https://github.com/BookStackApp/BookStack/blob/development/.github/SECURITY.md).
## ♿ Accessibility

View File

@@ -27,16 +27,12 @@ export class PageComments extends Component {
// Internal State
this.parentId = null;
this.formReplyText = this.formReplyLink.textContent;
this.formReplyText = this.formReplyLink?.textContent || '';
this.setupListeners();
}
setupListeners() {
this.removeReplyToButton.addEventListener('click', this.removeReplyTo.bind(this));
this.hideFormButton.addEventListener('click', this.hideForm.bind(this));
this.addCommentButton.addEventListener('click', this.showForm.bind(this));
this.elem.addEventListener('page-comment-delete', () => {
this.updateCount();
this.hideForm();
@@ -47,6 +43,9 @@ export class PageComments extends Component {
});
if (this.form) {
this.removeReplyToButton.addEventListener('click', this.removeReplyTo.bind(this));
this.hideFormButton.addEventListener('click', this.hideForm.bind(this));
this.addCommentButton.addEventListener('click', this.showForm.bind(this));
this.form.addEventListener('submit', this.saveComment.bind(this));
}
}
@@ -123,9 +122,8 @@ export class PageComments extends Component {
this.showForm();
this.parentId = commentLocalId;
this.replyToRow.toggleAttribute('hidden', false);
const replyLink = this.replyToRow.querySelector('a');
replyLink.textContent = this.formReplyText.replace('1234', this.parentId);
replyLink.href = `#comment${this.parentId}`;
this.formReplyLink.textContent = this.formReplyText.replace('1234', this.parentId);
this.formReplyLink.href = `#comment${this.parentId}`;
}
removeReplyTo() {

View File

@@ -4,6 +4,7 @@ import {scrollToQueryString} from './scrolling';
import {listenForDragAndPaste} from './drop-paste-handling';
import {getPrimaryToolbar, registerAdditionalToolbars} from './toolbars';
import {registerCustomIcons} from './icons';
import {setupFilters} from './filters';
import {getPlugin as getCodeeditorPlugin} from './plugin-codeeditor';
import {getPlugin as getDrawioPlugin} from './plugin-drawio';
@@ -147,23 +148,6 @@ function fetchCustomHeadContent() {
return headContentLines.slice(startLineIndex + 1, endLineIndex).join('\n');
}
/**
* Setup a serializer filter for <br> tags to ensure they're not rendered
* within code blocks and that we use newlines there instead.
* @param {Editor} editor
*/
function setupBrFilter(editor) {
editor.serializer.addNodeFilter('br', nodes => {
for (const node of nodes) {
if (node.parent && node.parent.name === 'code') {
const newline = window.tinymce.html.Node.create('#text');
newline.value = '\n';
node.replace(newline);
}
}
});
}
/**
* @param {WysiwygConfigOptions} options
* @return {function(Editor)}
@@ -189,7 +173,7 @@ function getSetupCallback(options) {
});
editor.on('PreInit', () => {
setupBrFilter(editor);
setupFilters(editor);
});
// Custom handler hook

View File

@@ -0,0 +1,43 @@
/**
* Setup a serializer filter for <br> tags to ensure they're not rendered
* within code blocks and that we use newlines there instead.
* @param {Editor} editor
*/
function setupBrFilter(editor) {
editor.serializer.addNodeFilter('br', nodes => {
for (const node of nodes) {
if (node.parent && node.parent.name === 'code') {
const newline = window.tinymce.html.Node.create('#text');
newline.value = '\n';
node.replace(newline);
}
}
});
}
/**
* Remove accidentally added pointer elements that are within the content.
* These could have accidentally been added via getting caught in range
* selection within page content.
* @param {Editor} editor
*/
function setupPointerFilter(editor) {
editor.parser.addNodeFilter('div', nodes => {
for (const node of nodes) {
const id = node.attr('id') || '';
const nodeClass = node.attr('class') || '';
if (id === 'pointer' || nodeClass.includes('pointer')) {
node.remove();
}
}
});
}
/**
* Setup global default filters for the given editor instance.
* @param {Editor} editor
*/
export function setupFilters(editor) {
setupBrFilter(editor);
setupPointerFilter(editor);
}

View File

@@ -3,8 +3,8 @@
@section('body')
<div class="container small my-xl">
<section class="card content-wrap auto-height items-center justify-space-between gap-m flex-container-row">
<div>
<section class="card content-wrap auto-height items-center justify-space-between gap-m flex-container-row wrap">
<div class="flex min-width-m">
<h2 class="list-heading">{{ trans('preferences.shortcuts_interface') }}</h2>
<p class="text-muted">{{ trans('preferences.shortcuts_overview_desc') }}</p>
</div>
@@ -14,8 +14,8 @@
</section>
@if(signedInUser() && userCan('receive-notifications'))
<section class="card content-wrap auto-height items-center justify-space-between gap-m flex-container-row">
<div>
<section class="card content-wrap auto-height items-center justify-space-between gap-m flex-container-row wrap">
<div class="flex min-width-m">
<h2 class="list-heading">{{ trans('preferences.notifications') }}</h2>
<p class="text-muted">{{ trans('preferences.notifications_desc') }}</p>
</div>
@@ -26,8 +26,8 @@
@endif
@if(signedInUser())
<section class="card content-wrap auto-height items-center justify-space-between gap-m flex-container-row">
<div>
<section class="card content-wrap auto-height items-center justify-space-between gap-m flex-container-row wrap">
<div class="flex min-width-m">
<h2 class="list-heading">{{ trans('settings.users_edit_profile') }}</h2>
<p class="text-muted">{{ trans('preferences.profile_overview_desc') }}</p>
</div>

View File

@@ -159,7 +159,7 @@ $style = [
<tr>
<td style="{{ $fontFamily }}">
<p style="{{ $style['paragraph-sub'] }}">
{{ trans('common.email_action_help', ['actionText' => $actionText]) }}
{{ trans('common.email_action_help', ['actionText' => $actionText], $language) }}
</p>
<p style="{{ $style['paragraph-sub'] }}">
@@ -187,7 +187,7 @@ $style = [
<p style="{{ $style['paragraph-sub'] }}">
&copy; {{ date('Y') }}
<a style="{{ $style['anchor'] }}" href="{{ url('/') }}" target="_blank">{{ setting('app-name') }}</a>.
{{ trans('common.email_rights') }}
{{ trans('common.email_rights', [], $language) }}
</p>
</td>
</tr>

View File

@@ -2,12 +2,17 @@
namespace Tests\Activity;
use BookStack\Activity\ActivityType;
use BookStack\Activity\Models\Comment;
use BookStack\Activity\Notifications\Messages\BaseActivityNotification;
use BookStack\Activity\Notifications\Messages\CommentCreationNotification;
use BookStack\Activity\Notifications\Messages\PageCreationNotification;
use BookStack\Activity\Notifications\Messages\PageUpdateNotification;
use BookStack\Activity\Tools\ActivityLogger;
use BookStack\Activity\Tools\UserEntityWatchOptions;
use BookStack\Activity\WatchLevels;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Tools\TrashCan;
use BookStack\Settings\UserNotificationPreferences;
use Illuminate\Support\Facades\Notification;
use Tests\TestCase;
@@ -205,16 +210,22 @@ class WatchTest extends TestCase
$prefs = new UserNotificationPreferences($editor);
$prefs->updateFromSettingsArray(['comment-replies' => 'true']);
// Create some existing comments to pad IDs to help potentially error
// on mis-identification of parent via ids used.
Comment::factory()->count(5)
->for($entities['page'], 'entity')
->create(['created_by' => $this->users->admin()->id]);
$notifications = Notification::fake();
$this->actingAs($editor)->post("/comment/{$entities['page']->id}", [
'text' => 'My new comment'
]);
$comment = $entities['page']->comments()->first();
$comment = $entities['page']->comments()->orderBy('id', 'desc')->first();
$this->asAdmin()->post("/comment/{$entities['page']->id}", [
'text' => 'My new comment response',
'parent_id' => $comment->id,
'parent_id' => $comment->local_id,
]);
$notifications->assertSentTo($editor, CommentCreationNotification::class);
}
@@ -253,7 +264,7 @@ class WatchTest extends TestCase
$notifications->assertSentTo($editor, function (CommentCreationNotification $notification) use ($editor, $admin, $entities) {
$mail = $notification->toMail($editor);
$mailContent = html_entity_decode(strip_tags($mail->render()));
$mailContent = html_entity_decode(strip_tags($mail->render()), ENT_QUOTES);
return $mail->subject === 'New comment on page: ' . $entities['page']->getShortName()
&& str_contains($mailContent, 'View Comment')
&& str_contains($mailContent, 'Page Name: ' . $entities['page']->name)
@@ -276,7 +287,7 @@ class WatchTest extends TestCase
$notifications->assertSentTo($editor, function (PageUpdateNotification $notification) use ($editor, $admin) {
$mail = $notification->toMail($editor);
$mailContent = html_entity_decode(strip_tags($mail->render()));
$mailContent = html_entity_decode(strip_tags($mail->render()), ENT_QUOTES);
return $mail->subject === 'Updated page: Updated page'
&& str_contains($mailContent, 'View Page')
&& str_contains($mailContent, 'Page Name: Updated page')
@@ -305,7 +316,7 @@ class WatchTest extends TestCase
$notifications->assertSentTo($editor, function (PageCreationNotification $notification) use ($editor, $admin) {
$mail = $notification->toMail($editor);
$mailContent = html_entity_decode(strip_tags($mail->render()));
$mailContent = html_entity_decode(strip_tags($mail->render()), ENT_QUOTES);
return $mail->subject === 'New page: My new page'
&& str_contains($mailContent, 'View Page')
&& str_contains($mailContent, 'Page Name: My new page')
@@ -313,6 +324,43 @@ class WatchTest extends TestCase
});
}
public function test_notifications_sent_in_right_language()
{
$editor = $this->users->editor();
$admin = $this->users->admin();
setting()->putUser($editor, 'language', 'de');
$entities = $this->entities->createChainBelongingToUser($editor);
$watches = new UserEntityWatchOptions($editor, $entities['book']);
$watches->updateLevelByValue(WatchLevels::COMMENTS);
$activities = [
ActivityType::PAGE_CREATE => $entities['page'],
ActivityType::PAGE_UPDATE => $entities['page'],
ActivityType::COMMENT_CREATE => (new Comment([]))->forceFill(['entity_id' => $entities['page']->id, 'entity_type' => $entities['page']->getMorphClass()]),
];
$notifications = Notification::fake();
$logger = app()->make(ActivityLogger::class);
$this->actingAs($admin);
foreach ($activities as $activityType => $detail) {
$logger->add($activityType, $detail);
}
$sent = $notifications->sentNotifications()[get_class($editor)][$editor->id];
$this->assertCount(3, $sent);
foreach ($sent as $notificationInfo) {
$notification = $notificationInfo[0]['notification'];
$this->assertInstanceOf(BaseActivityNotification::class, $notification);
$mail = $notification->toMail($editor);
$mailContent = html_entity_decode(strip_tags($mail->render()), ENT_QUOTES);
$this->assertStringContainsString('Name der Seite:', $mailContent);
$this->assertStringContainsString('Diese Benachrichtigung wurde', $mailContent);
$this->assertStringContainsString('Sollte es beim Anklicken der Schaltfläche', $mailContent);
}
}
public function test_notifications_not_sent_if_lacking_view_permission_for_related_item()
{
$notifications = Notification::fake();
@@ -329,4 +377,32 @@ class WatchTest extends TestCase
$notifications->assertNothingSentTo($editor);
}
public function test_watches_deleted_on_user_delete()
{
$editor = $this->users->editor();
$page = $this->entities->page();
$watches = new UserEntityWatchOptions($editor, $page);
$watches->updateLevelByValue(WatchLevels::COMMENTS);
$this->assertDatabaseHas('watches', ['user_id' => $editor->id]);
$this->asAdmin()->delete($editor->getEditUrl());
$this->assertDatabaseMissing('watches', ['user_id' => $editor->id]);
}
public function test_watches_deleted_on_item_delete()
{
$editor = $this->users->editor();
$page = $this->entities->page();
$watches = new UserEntityWatchOptions($editor, $page);
$watches->updateLevelByValue(WatchLevels::COMMENTS);
$this->assertDatabaseHas('watches', ['watchable_type' => 'page', 'watchable_id' => $page->id]);
$this->entities->destroy($page);
$this->assertDatabaseMissing('watches', ['watchable_type' => 'page', 'watchable_id' => $page->id]);
}
}

View File

@@ -11,6 +11,7 @@ use BookStack\Entities\Repos\BookRepo;
use BookStack\Entities\Repos\BookshelfRepo;
use BookStack\Entities\Repos\ChapterRepo;
use BookStack\Entities\Repos\PageRepo;
use BookStack\Entities\Tools\TrashCan;
use BookStack\Users\Models\User;
use Illuminate\Database\Eloquent\Builder;
@@ -197,6 +198,16 @@ class EntityProvider
return $draftPage;
}
/**
* Fully destroy the given entity from the system, bypassing the recycle bin
* stage. Still runs through main app deletion logic.
*/
public function destroy(Entity $entity)
{
$trash = app()->make(TrashCan::class);
$trash->destroyEntity($entity);
}
/**
* @param Entity|Entity[] $entities
*/

View File

@@ -124,6 +124,23 @@ class UserPreferencesTest extends TestCase
$resp->assertDontSee('All Page Updates & Comments');
}
public function test_notification_preferences_dont_error_on_deleted_items()
{
$editor = $this->users->editor();
$book = $this->entities->book();
$options = new UserEntityWatchOptions($editor, $book);
$options->updateLevelByValue(WatchLevels::COMMENTS);
$this->actingAs($editor)->delete($book->getUrl());
$book->refresh();
$this->assertNotNull($book->deleted_at);
$resp = $this->actingAs($editor)->get('/preferences/notifications');
$resp->assertOk();
$resp->assertDontSee($book->name);
}
public function test_notification_preferences_not_accessible_to_guest()
{
$this->setSettings(['app-public' => 'true']);

View File

@@ -1 +1 @@
v23.08
v23.08.3