mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-13 00:18:08 +00:00
Merge branch 'BookStackApp:development' into add-priority
This commit is contained in:
commit
bb3ce845b4
31 changed files with 408 additions and 269 deletions
app
Api
Entities/Controllers
Settings
Users/Controllers
lang/en
resources
js
sass
_blocks.scss_codemirror.scss_colors.scss_components.scss_content.scss_forms.scss_pages.scss_text.scss_tinymce.scss_variables.scssexport-styles.scssstyles.scss
views/pages/parts
routes
tests
|
@ -58,7 +58,6 @@ class UserApiTokenController extends Controller
|
||||||
$token->save();
|
$token->save();
|
||||||
|
|
||||||
session()->flash('api-token-secret:' . $token->id, $secret);
|
session()->flash('api-token-secret:' . $token->id, $secret);
|
||||||
$this->showSuccessNotification(trans('settings.user_api_token_create_success'));
|
|
||||||
$this->logActivity(ActivityType::API_TOKEN_CREATE, $token);
|
$this->logActivity(ActivityType::API_TOKEN_CREATE, $token);
|
||||||
|
|
||||||
return redirect($user->getEditUrl('/api-tokens/' . $token->id));
|
return redirect($user->getEditUrl('/api-tokens/' . $token->id));
|
||||||
|
@ -96,7 +95,6 @@ class UserApiTokenController extends Controller
|
||||||
'expires_at' => $request->get('expires_at') ?: ApiToken::defaultExpiry(),
|
'expires_at' => $request->get('expires_at') ?: ApiToken::defaultExpiry(),
|
||||||
])->save();
|
])->save();
|
||||||
|
|
||||||
$this->showSuccessNotification(trans('settings.user_api_token_update_success'));
|
|
||||||
$this->logActivity(ActivityType::API_TOKEN_UPDATE, $token);
|
$this->logActivity(ActivityType::API_TOKEN_UPDATE, $token);
|
||||||
|
|
||||||
return redirect($user->getEditUrl('/api-tokens/' . $token->id));
|
return redirect($user->getEditUrl('/api-tokens/' . $token->id));
|
||||||
|
@ -123,7 +121,6 @@ class UserApiTokenController extends Controller
|
||||||
[$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId);
|
[$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId);
|
||||||
$token->delete();
|
$token->delete();
|
||||||
|
|
||||||
$this->showSuccessNotification(trans('settings.user_api_token_delete_success'));
|
|
||||||
$this->logActivity(ActivityType::API_TOKEN_DELETE, $token);
|
$this->logActivity(ActivityType::API_TOKEN_DELETE, $token);
|
||||||
|
|
||||||
return redirect($user->getEditUrl('#api_tokens'));
|
return redirect($user->getEditUrl('#api_tokens'));
|
||||||
|
|
|
@ -191,8 +191,6 @@ class ChapterController extends Controller
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->showSuccessNotification(trans('entities.chapter_move_success', ['bookName' => $newBook->name]));
|
|
||||||
|
|
||||||
return redirect($chapter->getUrl());
|
return redirect($chapter->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -389,7 +389,7 @@ class PageController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$parent = $this->pageRepo->move($page, $entitySelection);
|
$this->pageRepo->move($page, $entitySelection);
|
||||||
} catch (PermissionsException $exception) {
|
} catch (PermissionsException $exception) {
|
||||||
$this->showPermissionError();
|
$this->showPermissionError();
|
||||||
} catch (Exception $exception) {
|
} catch (Exception $exception) {
|
||||||
|
@ -398,8 +398,6 @@ class PageController extends Controller
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->showSuccessNotification(trans('entities.pages_move_success', ['parentName' => $parent->name]));
|
|
||||||
|
|
||||||
return redirect($page->getUrl());
|
return redirect($page->getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace BookStack\Entities\Controllers;
|
||||||
use BookStack\Activity\ActivityType;
|
use BookStack\Activity\ActivityType;
|
||||||
use BookStack\Entities\Models\PageRevision;
|
use BookStack\Entities\Models\PageRevision;
|
||||||
use BookStack\Entities\Repos\PageRepo;
|
use BookStack\Entities\Repos\PageRepo;
|
||||||
|
use BookStack\Entities\Repos\RevisionRepo;
|
||||||
use BookStack\Entities\Tools\PageContent;
|
use BookStack\Entities\Tools\PageContent;
|
||||||
use BookStack\Exceptions\NotFoundException;
|
use BookStack\Exceptions\NotFoundException;
|
||||||
use BookStack\Facades\Activity;
|
use BookStack\Facades\Activity;
|
||||||
|
@ -15,11 +16,10 @@ use Ssddanbrown\HtmlDiff\Diff;
|
||||||
|
|
||||||
class PageRevisionController extends Controller
|
class PageRevisionController extends Controller
|
||||||
{
|
{
|
||||||
protected PageRepo $pageRepo;
|
public function __construct(
|
||||||
|
protected PageRepo $pageRepo,
|
||||||
public function __construct(PageRepo $pageRepo)
|
protected RevisionRepo $revisionRepo,
|
||||||
{
|
) {
|
||||||
$this->pageRepo = $pageRepo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,8 +153,18 @@ class PageRevisionController extends Controller
|
||||||
|
|
||||||
$revision->delete();
|
$revision->delete();
|
||||||
Activity::add(ActivityType::REVISION_DELETE, $revision);
|
Activity::add(ActivityType::REVISION_DELETE, $revision);
|
||||||
$this->showSuccessNotification(trans('entities.revision_delete_success'));
|
|
||||||
|
|
||||||
return redirect($page->getUrl('/revisions'));
|
return redirect($page->getUrl('/revisions'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys existing drafts, belonging to the current user, for the given page.
|
||||||
|
*/
|
||||||
|
public function destroyUserDraft(string $pageId)
|
||||||
|
{
|
||||||
|
$page = $this->pageRepo->getById($pageId);
|
||||||
|
$this->revisionRepo->deleteDraftsForCurrentUser($page);
|
||||||
|
|
||||||
|
return response('', 200);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use BookStack\Http\Controller;
|
||||||
|
|
||||||
class RecycleBinController extends Controller
|
class RecycleBinController extends Controller
|
||||||
{
|
{
|
||||||
protected $recycleBinBaseUrl = '/settings/recycle-bin';
|
protected string $recycleBinBaseUrl = '/settings/recycle-bin';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On each request to a method of this controller check permissions
|
* On each request to a method of this controller check permissions
|
||||||
|
|
|
@ -52,9 +52,7 @@ class SettingController extends Controller
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$store->storeFromUpdateRequest($request, $category);
|
$store->storeFromUpdateRequest($request, $category);
|
||||||
|
|
||||||
$this->logActivity(ActivityType::SETTINGS_UPDATE, $category);
|
$this->logActivity(ActivityType::SETTINGS_UPDATE, $category);
|
||||||
$this->showSuccessNotification(trans('settings.settings_save_success'));
|
|
||||||
|
|
||||||
return redirect("/settings/{$category}");
|
return redirect("/settings/{$category}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,10 @@ use Illuminate\Validation\ValidationException;
|
||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
protected UserRepo $userRepo;
|
public function __construct(
|
||||||
protected ImageRepo $imageRepo;
|
protected UserRepo $userRepo,
|
||||||
|
protected ImageRepo $imageRepo
|
||||||
public function __construct(UserRepo $userRepo, ImageRepo $imageRepo)
|
) {
|
||||||
{
|
|
||||||
$this->userRepo = $userRepo;
|
|
||||||
$this->imageRepo = $imageRepo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,6 +15,7 @@ return [
|
||||||
'page_restore' => 'restored page',
|
'page_restore' => 'restored page',
|
||||||
'page_restore_notification' => 'Page successfully restored',
|
'page_restore_notification' => 'Page successfully restored',
|
||||||
'page_move' => 'moved page',
|
'page_move' => 'moved page',
|
||||||
|
'page_move_notification' => 'Page successfully moved',
|
||||||
|
|
||||||
// Chapters
|
// Chapters
|
||||||
'chapter_create' => 'created chapter',
|
'chapter_create' => 'created chapter',
|
||||||
|
@ -24,6 +25,7 @@ return [
|
||||||
'chapter_delete' => 'deleted chapter',
|
'chapter_delete' => 'deleted chapter',
|
||||||
'chapter_delete_notification' => 'Chapter successfully deleted',
|
'chapter_delete_notification' => 'Chapter successfully deleted',
|
||||||
'chapter_move' => 'moved chapter',
|
'chapter_move' => 'moved chapter',
|
||||||
|
'chapter_move_notification' => 'Chapter successfully moved',
|
||||||
|
|
||||||
// Books
|
// Books
|
||||||
'book_create' => 'created book',
|
'book_create' => 'created book',
|
||||||
|
@ -47,14 +49,30 @@ return [
|
||||||
'bookshelf_delete' => 'deleted shelf',
|
'bookshelf_delete' => 'deleted shelf',
|
||||||
'bookshelf_delete_notification' => 'Shelf successfully deleted',
|
'bookshelf_delete_notification' => 'Shelf successfully deleted',
|
||||||
|
|
||||||
|
// Revisions
|
||||||
|
'revision_restore' => 'restored revision',
|
||||||
|
'revision_delete' => 'deleted revision',
|
||||||
|
'revision_delete_notification' => 'Revision successfully deleted',
|
||||||
|
|
||||||
// Favourites
|
// Favourites
|
||||||
'favourite_add_notification' => '":name" has been added to your favourites',
|
'favourite_add_notification' => '":name" has been added to your favourites',
|
||||||
'favourite_remove_notification' => '":name" has been removed from your favourites',
|
'favourite_remove_notification' => '":name" has been removed from your favourites',
|
||||||
|
|
||||||
// MFA
|
// 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',
|
||||||
'mfa_setup_method_notification' => 'Multi-factor method successfully configured',
|
'mfa_setup_method_notification' => 'Multi-factor method successfully configured',
|
||||||
|
'mfa_remove_method' => 'removed MFA method',
|
||||||
'mfa_remove_method_notification' => 'Multi-factor method successfully removed',
|
'mfa_remove_method_notification' => 'Multi-factor method successfully removed',
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
'settings_update' => 'updated settings',
|
||||||
|
'settings_update_notification' => 'Settings successfully updated',
|
||||||
|
'maintenance_action_run' => 'ran maintenance action',
|
||||||
|
|
||||||
// Webhooks
|
// Webhooks
|
||||||
'webhook_create' => 'created webhook',
|
'webhook_create' => 'created webhook',
|
||||||
'webhook_create_notification' => 'Webhook successfully created',
|
'webhook_create_notification' => 'Webhook successfully created',
|
||||||
|
@ -64,14 +82,34 @@ return [
|
||||||
'webhook_delete_notification' => 'Webhook successfully deleted',
|
'webhook_delete_notification' => 'Webhook successfully deleted',
|
||||||
|
|
||||||
// Users
|
// Users
|
||||||
|
'user_create' => 'created user',
|
||||||
|
'user_create_notification' => 'User successfully created',
|
||||||
|
'user_update' => 'updated user',
|
||||||
'user_update_notification' => 'User successfully updated',
|
'user_update_notification' => 'User successfully updated',
|
||||||
|
'user_delete' => 'deleted user',
|
||||||
'user_delete_notification' => 'User successfully removed',
|
'user_delete_notification' => 'User successfully removed',
|
||||||
|
|
||||||
|
// 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',
|
||||||
|
|
||||||
// Roles
|
// Roles
|
||||||
|
'role_create' => 'created role',
|
||||||
'role_create_notification' => 'Role successfully created',
|
'role_create_notification' => 'Role successfully created',
|
||||||
|
'role_update' => 'updated role',
|
||||||
'role_update_notification' => 'Role successfully updated',
|
'role_update_notification' => 'Role successfully updated',
|
||||||
|
'role_delete' => 'deleted role',
|
||||||
'role_delete_notification' => 'Role successfully deleted',
|
'role_delete_notification' => 'Role successfully deleted',
|
||||||
|
|
||||||
|
// Recycle Bin
|
||||||
|
'recycle_bin_empty' => 'emptied recycle bin',
|
||||||
|
'recycle_bin_restore' => 'restored from recycle bin',
|
||||||
|
'recycle_bin_destroy' => 'removed from recycle bin',
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
'commented_on' => 'commented on',
|
'commented_on' => 'commented on',
|
||||||
'permissions_update' => 'updated permissions',
|
'permissions_update' => 'updated permissions',
|
||||||
|
|
|
@ -180,7 +180,6 @@ return [
|
||||||
'chapters_save' => 'Save Chapter',
|
'chapters_save' => 'Save Chapter',
|
||||||
'chapters_move' => 'Move Chapter',
|
'chapters_move' => 'Move Chapter',
|
||||||
'chapters_move_named' => 'Move Chapter :chapterName',
|
'chapters_move_named' => 'Move Chapter :chapterName',
|
||||||
'chapter_move_success' => 'Chapter moved to :bookName',
|
|
||||||
'chapters_copy' => 'Copy Chapter',
|
'chapters_copy' => 'Copy Chapter',
|
||||||
'chapters_copy_success' => 'Chapter successfully copied',
|
'chapters_copy_success' => 'Chapter successfully copied',
|
||||||
'chapters_permissions' => 'Chapter Permissions',
|
'chapters_permissions' => 'Chapter Permissions',
|
||||||
|
@ -214,6 +213,7 @@ return [
|
||||||
'pages_editing_page' => 'Editing Page',
|
'pages_editing_page' => 'Editing Page',
|
||||||
'pages_edit_draft_save_at' => 'Draft saved at ',
|
'pages_edit_draft_save_at' => 'Draft saved at ',
|
||||||
'pages_edit_delete_draft' => 'Delete Draft',
|
'pages_edit_delete_draft' => 'Delete Draft',
|
||||||
|
'pages_edit_delete_draft_confirm' => 'Are you sure you want to delete your draft page changes? All of your changes, since the last full save, will be lost and the editor will be updated with the latest page non-draft save state.',
|
||||||
'pages_edit_discard_draft' => 'Discard Draft',
|
'pages_edit_discard_draft' => 'Discard Draft',
|
||||||
'pages_edit_switch_to_markdown' => 'Switch to Markdown Editor',
|
'pages_edit_switch_to_markdown' => 'Switch to Markdown Editor',
|
||||||
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
|
'pages_edit_switch_to_markdown_clean' => '(Clean Content)',
|
||||||
|
@ -240,7 +240,6 @@ return [
|
||||||
'pages_md_sync_scroll' => 'Sync preview scroll',
|
'pages_md_sync_scroll' => 'Sync preview scroll',
|
||||||
'pages_not_in_chapter' => 'Page is not in a chapter',
|
'pages_not_in_chapter' => 'Page is not in a chapter',
|
||||||
'pages_move' => 'Move Page',
|
'pages_move' => 'Move Page',
|
||||||
'pages_move_success' => 'Page moved to ":parentName"',
|
|
||||||
'pages_copy' => 'Copy Page',
|
'pages_copy' => 'Copy Page',
|
||||||
'pages_copy_desination' => 'Copy Destination',
|
'pages_copy_desination' => 'Copy Destination',
|
||||||
'pages_copy_success' => 'Page successfully copied',
|
'pages_copy_success' => 'Page successfully copied',
|
||||||
|
@ -287,7 +286,8 @@ return [
|
||||||
'time_b' => 'in the last :minCount minutes',
|
'time_b' => 'in the last :minCount minutes',
|
||||||
'message' => ':start :time. Take care not to overwrite each other\'s updates!',
|
'message' => ':start :time. Take care not to overwrite each other\'s updates!',
|
||||||
],
|
],
|
||||||
'pages_draft_discarded' => 'Draft discarded, The editor has been updated with the current page content',
|
'pages_draft_discarded' => 'Draft discarded! The editor has been updated with the current page content',
|
||||||
|
'pages_draft_deleted' => 'Draft deleted! The editor has been updated with the current page content',
|
||||||
'pages_specific' => 'Specific Page',
|
'pages_specific' => 'Specific Page',
|
||||||
'pages_is_template' => 'Page Template',
|
'pages_is_template' => 'Page Template',
|
||||||
|
|
||||||
|
@ -375,7 +375,6 @@ return [
|
||||||
// Revision
|
// Revision
|
||||||
'revision_delete_confirm' => 'Are you sure you want to delete this revision?',
|
'revision_delete_confirm' => 'Are you sure you want to delete this revision?',
|
||||||
'revision_restore_confirm' => 'Are you sure you want to restore this revision? The current page contents will be replaced.',
|
'revision_restore_confirm' => 'Are you sure you want to restore this revision? The current page contents will be replaced.',
|
||||||
'revision_delete_success' => 'Revision deleted',
|
|
||||||
'revision_cannot_delete_latest' => 'Cannot delete the latest revision.',
|
'revision_cannot_delete_latest' => 'Cannot delete the latest revision.',
|
||||||
|
|
||||||
// Copy view
|
// Copy view
|
||||||
|
|
|
@ -58,6 +58,7 @@ return [
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
'page_draft_autosave_fail' => 'Failed to save draft. Ensure you have internet connection before saving this page',
|
'page_draft_autosave_fail' => 'Failed to save draft. Ensure you have internet connection before saving this page',
|
||||||
|
'page_draft_delete_fail' => 'Failed to delete page draft and fetch current page saved content',
|
||||||
'page_custom_home_deletion' => 'Cannot delete a page while it is set as a homepage',
|
'page_custom_home_deletion' => 'Cannot delete a page while it is set as a homepage',
|
||||||
|
|
||||||
// Entities
|
// Entities
|
||||||
|
|
|
@ -9,7 +9,6 @@ return [
|
||||||
// Common Messages
|
// Common Messages
|
||||||
'settings' => 'Settings',
|
'settings' => 'Settings',
|
||||||
'settings_save' => 'Save Settings',
|
'settings_save' => 'Save Settings',
|
||||||
'settings_save_success' => 'Settings saved',
|
|
||||||
'system_version' => 'System Version',
|
'system_version' => 'System Version',
|
||||||
'categories' => 'Categories',
|
'categories' => 'Categories',
|
||||||
|
|
||||||
|
@ -232,8 +231,6 @@ return [
|
||||||
'user_api_token_expiry' => 'Expiry Date',
|
'user_api_token_expiry' => 'Expiry Date',
|
||||||
'user_api_token_expiry_desc' => 'Set a date at which this token expires. After this date, requests made using this token will no longer work. Leaving this field blank will set an expiry 100 years into the future.',
|
'user_api_token_expiry_desc' => 'Set a date at which this token expires. After this date, requests made using this token will no longer work. Leaving this field blank will set an expiry 100 years into the future.',
|
||||||
'user_api_token_create_secret_message' => 'Immediately after creating this token a "Token ID" & "Token Secret" will be generated and displayed. The secret will only be shown a single time so be sure to copy the value to somewhere safe and secure before proceeding.',
|
'user_api_token_create_secret_message' => 'Immediately after creating this token a "Token ID" & "Token Secret" will be generated and displayed. The secret will only be shown a single time so be sure to copy the value to somewhere safe and secure before proceeding.',
|
||||||
'user_api_token_create_success' => 'API token successfully created',
|
|
||||||
'user_api_token_update_success' => 'API token successfully updated',
|
|
||||||
'user_api_token' => 'API Token',
|
'user_api_token' => 'API Token',
|
||||||
'user_api_token_id' => 'Token ID',
|
'user_api_token_id' => 'Token ID',
|
||||||
'user_api_token_id_desc' => 'This is a non-editable system generated identifier for this token which will need to be provided in API requests.',
|
'user_api_token_id_desc' => 'This is a non-editable system generated identifier for this token which will need to be provided in API requests.',
|
||||||
|
@ -244,7 +241,6 @@ return [
|
||||||
'user_api_token_delete' => 'Delete Token',
|
'user_api_token_delete' => 'Delete Token',
|
||||||
'user_api_token_delete_warning' => 'This will fully delete this API token with the name \':tokenName\' from the system.',
|
'user_api_token_delete_warning' => 'This will fully delete this API token with the name \':tokenName\' from the system.',
|
||||||
'user_api_token_delete_confirm' => 'Are you sure you want to delete this API token?',
|
'user_api_token_delete_confirm' => 'Are you sure you want to delete this API token?',
|
||||||
'user_api_token_delete_success' => 'API token successfully deleted',
|
|
||||||
|
|
||||||
// Webhooks
|
// Webhooks
|
||||||
'webhooks' => 'Webhooks',
|
'webhooks' => 'Webhooks',
|
||||||
|
|
|
@ -19,18 +19,23 @@ export class PageEditor extends Component {
|
||||||
this.saveDraftButton = this.$refs.saveDraft;
|
this.saveDraftButton = this.$refs.saveDraft;
|
||||||
this.discardDraftButton = this.$refs.discardDraft;
|
this.discardDraftButton = this.$refs.discardDraft;
|
||||||
this.discardDraftWrap = this.$refs.discardDraftWrap;
|
this.discardDraftWrap = this.$refs.discardDraftWrap;
|
||||||
|
this.deleteDraftButton = this.$refs.deleteDraft;
|
||||||
|
this.deleteDraftWrap = this.$refs.deleteDraftWrap;
|
||||||
this.draftDisplay = this.$refs.draftDisplay;
|
this.draftDisplay = this.$refs.draftDisplay;
|
||||||
this.draftDisplayIcon = this.$refs.draftDisplayIcon;
|
this.draftDisplayIcon = this.$refs.draftDisplayIcon;
|
||||||
this.changelogInput = this.$refs.changelogInput;
|
this.changelogInput = this.$refs.changelogInput;
|
||||||
this.changelogDisplay = this.$refs.changelogDisplay;
|
this.changelogDisplay = this.$refs.changelogDisplay;
|
||||||
this.changeEditorButtons = this.$manyRefs.changeEditor || [];
|
this.changeEditorButtons = this.$manyRefs.changeEditor || [];
|
||||||
this.switchDialogContainer = this.$refs.switchDialog;
|
this.switchDialogContainer = this.$refs.switchDialog;
|
||||||
|
this.deleteDraftDialogContainer = this.$refs.deleteDraftDialog;
|
||||||
|
|
||||||
// Translations
|
// Translations
|
||||||
this.draftText = this.$opts.draftText;
|
this.draftText = this.$opts.draftText;
|
||||||
this.autosaveFailText = this.$opts.autosaveFailText;
|
this.autosaveFailText = this.$opts.autosaveFailText;
|
||||||
this.editingPageText = this.$opts.editingPageText;
|
this.editingPageText = this.$opts.editingPageText;
|
||||||
this.draftDiscardedText = this.$opts.draftDiscardedText;
|
this.draftDiscardedText = this.$opts.draftDiscardedText;
|
||||||
|
this.draftDeleteText = this.$opts.draftDeleteText;
|
||||||
|
this.draftDeleteFailText = this.$opts.draftDeleteFailText;
|
||||||
this.setChangelogText = this.$opts.setChangelogText;
|
this.setChangelogText = this.$opts.setChangelogText;
|
||||||
|
|
||||||
// State data
|
// State data
|
||||||
|
@ -75,6 +80,7 @@ export class PageEditor extends Component {
|
||||||
// Draft Controls
|
// Draft Controls
|
||||||
onSelect(this.saveDraftButton, this.saveDraft.bind(this));
|
onSelect(this.saveDraftButton, this.saveDraft.bind(this));
|
||||||
onSelect(this.discardDraftButton, this.discardDraft.bind(this));
|
onSelect(this.discardDraftButton, this.discardDraft.bind(this));
|
||||||
|
onSelect(this.deleteDraftButton, this.deleteDraft.bind(this));
|
||||||
|
|
||||||
// Change editor controls
|
// Change editor controls
|
||||||
onSelect(this.changeEditorButtons, this.changeEditor.bind(this));
|
onSelect(this.changeEditorButtons, this.changeEditor.bind(this));
|
||||||
|
@ -119,7 +125,8 @@ export class PageEditor extends Component {
|
||||||
try {
|
try {
|
||||||
const resp = await window.$http.put(`/ajax/page/${this.pageId}/save-draft`, data);
|
const resp = await window.$http.put(`/ajax/page/${this.pageId}/save-draft`, data);
|
||||||
if (!this.isNewDraft) {
|
if (!this.isNewDraft) {
|
||||||
this.toggleDiscardDraftVisibility(true);
|
this.discardDraftWrap.toggleAttribute('hidden', false);
|
||||||
|
this.deleteDraftWrap.toggleAttribute('hidden', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.draftNotifyChange(`${resp.data.message} ${Dates.utcTimeStampToLocalTime(resp.data.timestamp)}`);
|
this.draftNotifyChange(`${resp.data.message} ${Dates.utcTimeStampToLocalTime(resp.data.timestamp)}`);
|
||||||
|
@ -154,7 +161,7 @@ export class PageEditor extends Component {
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
async discardDraft() {
|
async discardDraft(notify = true) {
|
||||||
let response;
|
let response;
|
||||||
try {
|
try {
|
||||||
response = await window.$http.get(`/ajax/page/${this.pageId}`);
|
response = await window.$http.get(`/ajax/page/${this.pageId}`);
|
||||||
|
@ -168,7 +175,7 @@ export class PageEditor extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.draftDisplay.innerText = this.editingPageText;
|
this.draftDisplay.innerText = this.editingPageText;
|
||||||
this.toggleDiscardDraftVisibility(false);
|
this.discardDraftWrap.toggleAttribute('hidden', true);
|
||||||
window.$events.emit('editor::replace', {
|
window.$events.emit('editor::replace', {
|
||||||
html: response.data.html,
|
html: response.data.html,
|
||||||
markdown: response.data.markdown,
|
markdown: response.data.markdown,
|
||||||
|
@ -178,7 +185,30 @@ export class PageEditor extends Component {
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
this.startAutoSave();
|
this.startAutoSave();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
window.$events.emit('success', this.draftDiscardedText);
|
|
||||||
|
if (notify) {
|
||||||
|
window.$events.success(this.draftDiscardedText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteDraft() {
|
||||||
|
/** @var {ConfirmDialog} * */
|
||||||
|
const dialog = window.$components.firstOnElement(this.deleteDraftDialogContainer, 'confirm-dialog');
|
||||||
|
const confirmed = await dialog.show();
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const discard = this.discardDraft(false);
|
||||||
|
const draftDelete = window.$http.delete(`/page-revisions/user-drafts/${this.pageId}`);
|
||||||
|
await Promise.all([discard, draftDelete]);
|
||||||
|
window.$events.success(this.draftDeleteText);
|
||||||
|
this.deleteDraftWrap.toggleAttribute('hidden', true);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
window.$events.error(this.draftDeleteFailText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateChangelogDisplay() {
|
updateChangelogDisplay() {
|
||||||
|
@ -191,10 +221,6 @@ export class PageEditor extends Component {
|
||||||
this.changelogDisplay.innerText = summary;
|
this.changelogDisplay.innerText = summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleDiscardDraftVisibility(show) {
|
|
||||||
this.discardDraftWrap.classList.toggle('hidden', !show);
|
|
||||||
}
|
|
||||||
|
|
||||||
async changeEditor(event) {
|
async changeEditor(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
|
|
@ -433,7 +433,9 @@ export class Actions {
|
||||||
*/
|
*/
|
||||||
#setText(text, selectionRange = null) {
|
#setText(text, selectionRange = null) {
|
||||||
selectionRange = selectionRange || this.#getSelectionRange();
|
selectionRange = selectionRange || this.#getSelectionRange();
|
||||||
this.#dispatchChange(0, this.editor.cm.state.doc.length, text, selectionRange.from);
|
const newDoc = this.editor.cm.state.toText(text);
|
||||||
|
const newSelectFrom = Math.min(selectionRange.from, newDoc.length);
|
||||||
|
this.#dispatchChange(0, this.editor.cm.state.doc.length, text, newSelectFrom);
|
||||||
this.focus();
|
this.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,63 +1,3 @@
|
||||||
|
|
||||||
/**
|
|
||||||
* Callouts
|
|
||||||
*/
|
|
||||||
.callout {
|
|
||||||
border-inline-start: 3px solid #BBB;
|
|
||||||
background-color: #EEE;
|
|
||||||
padding: $-s $-s $-s $-xl;
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
overflow: auto;
|
|
||||||
&:before {
|
|
||||||
background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9IiMwMTUzODAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+ICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4gICAgPHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bTEgMTVoLTJ2LTZoMnY2em0wLThoLTJWN2gydjJ6Ii8+PC9zdmc+');
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
content: '';
|
|
||||||
width: 1.2em;
|
|
||||||
height: 1.2em;
|
|
||||||
left: $-xs + 2px;
|
|
||||||
top: 50%;
|
|
||||||
margin-top: -9px;
|
|
||||||
display: inline-block;
|
|
||||||
position: absolute;
|
|
||||||
line-height: 1;
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
&.success {
|
|
||||||
border-left-color: $positive;
|
|
||||||
@include lightDark(background-color, lighten($positive, 68%), darken($positive, 22%));
|
|
||||||
@include lightDark(color, darken($positive, 16%), lighten($positive, 5%));
|
|
||||||
}
|
|
||||||
&.success:before {
|
|
||||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9IiMzNzZjMzkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+ICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4gICAgPHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bS0yIDE1bC01LTUgMS40MS0xLjQxTDEwIDE0LjE3bDcuNTktNy41OUwxOSA4bC05IDl6Ii8+PC9zdmc+");
|
|
||||||
}
|
|
||||||
&.danger {
|
|
||||||
border-left-color: $negative;
|
|
||||||
@include lightDark(background-color, lighten($negative, 56%), darken($negative, 30%));
|
|
||||||
@include lightDark(color, darken($negative, 20%), lighten($negative, 5%));
|
|
||||||
}
|
|
||||||
&.danger:before {
|
|
||||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9IiNiOTE4MTgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+ICAgIDxwYXRoIGQ9Ik0xNS43MyAzSDguMjdMMyA4LjI3djcuNDZMOC4yNyAyMWg3LjQ2TDIxIDE1LjczVjguMjdMMTUuNzMgM3pNMTIgMTcuM2MtLjcyIDAtMS4zLS41OC0xLjMtMS4zIDAtLjcyLjU4LTEuMyAxLjMtMS4zLjcyIDAgMS4zLjU4IDEuMyAxLjMgMCAuNzItLjU4IDEuMy0xLjMgMS4zem0xLTQuM2gtMlY3aDJ2NnoiLz4gICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==");
|
|
||||||
}
|
|
||||||
&.info {
|
|
||||||
border-left-color: $info;
|
|
||||||
@include lightDark(color, darken($info, 20%), lighten($info, 10%));
|
|
||||||
@include lightDark(background-color, lighten($info, 50%), darken($info, 35%));
|
|
||||||
}
|
|
||||||
&.warning {
|
|
||||||
border-left-color: $warning;
|
|
||||||
@include lightDark(background-color, lighten($warning, 50%), darken($warning, 36%));
|
|
||||||
@include lightDark(color, darken($warning, 20%), $warning);
|
|
||||||
}
|
|
||||||
&.warning:before {
|
|
||||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9IiNiNjUzMWMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+ICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4gICAgPHBhdGggZD0iTTEgMjFoMjJMMTIgMiAxIDIxem0xMi0zaC0ydi0yaDJ2MnptMC00aC0ydi00aDJ2NHoiLz48L3N2Zz4=");
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Card-style blocks
|
* Card-style blocks
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cm-editor .cm-line, .cm-editor .cm-gutter {
|
||||||
|
font-family: var(--font-code);
|
||||||
|
}
|
||||||
|
|
||||||
// Manual dark-mode definition so that it applies to code blocks within the shadow
|
// Manual dark-mode definition so that it applies to code blocks within the shadow
|
||||||
// dom which are used within the WYSIWYG editor, as the .dark-mode on the parent
|
// dom which are used within the WYSIWYG editor, as the .dark-mode on the parent
|
||||||
// <html> node are not applies so instead we have the class on the parent element.
|
// <html> node are not applies so instead we have the class on the parent element.
|
||||||
|
@ -50,7 +54,7 @@
|
||||||
fill: currentColor;
|
fill: currentColor;
|
||||||
}
|
}
|
||||||
&.success {
|
&.success {
|
||||||
background: $positive;
|
background: var(--color-positive);
|
||||||
color: #FFF;
|
color: #FFF;
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
|
|
|
@ -22,18 +22,18 @@
|
||||||
* Status text colors
|
* Status text colors
|
||||||
*/
|
*/
|
||||||
.text-pos, .text-pos:hover, .text-pos-hover:hover {
|
.text-pos, .text-pos:hover, .text-pos-hover:hover {
|
||||||
color: $positive !important;
|
color: var(--color-positive) !important;
|
||||||
fill: $positive !important;
|
fill: var(--color-positive) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-warn, .text-warn:hover, .text-warn-hover:hover {
|
.text-warn, .text-warn:hover, .text-warn-hover:hover {
|
||||||
color: $warning !important;
|
color: var(--color-warning) !important;
|
||||||
fill: $warning !important;
|
fill: var(--color-warning) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-neg, .text-neg:hover, .text-neg-hover:hover {
|
.text-neg, .text-neg:hover, .text-neg-hover:hover {
|
||||||
color: $negative !important;
|
color: var(--color-negative) !important;
|
||||||
fill: $negative !important;
|
fill: var(--color-negative) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -46,13 +46,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.pos {
|
&.pos {
|
||||||
color: $positive;
|
color: var(--color-positive);
|
||||||
}
|
}
|
||||||
&.neg {
|
&.neg {
|
||||||
color: $negative;
|
color: var(--color-negative);
|
||||||
}
|
}
|
||||||
&.warning {
|
&.warning {
|
||||||
color: $warning;
|
color: var(--color-warning);
|
||||||
}
|
}
|
||||||
&.showing {
|
&.showing {
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
|
@ -334,10 +334,10 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
.dropzone-file-item-status[data-status="success"] {
|
.dropzone-file-item-status[data-status="success"] {
|
||||||
color: $positive;
|
color: var(--color-positive);
|
||||||
}
|
}
|
||||||
.dropzone-file-item-status[data-status="error"] {
|
.dropzone-file-item-status[data-status="error"] {
|
||||||
color: $negative;
|
color: var(--color-negative);
|
||||||
}
|
}
|
||||||
.dropzone-file-item-status[data-status] + .dropzone-file-item-label {
|
.dropzone-file-item-status[data-status] + .dropzone-file-item-label {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -574,7 +574,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-family: $mono;
|
font-family: var(--font-code);
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
padding-left: 24px + $-xs;
|
padding-left: 24px + $-xs;
|
||||||
&:hover, &.active {
|
&:hover, &.active {
|
||||||
|
@ -921,10 +921,10 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.status-indicator-active {
|
.status-indicator-active {
|
||||||
background-color: $positive;
|
background-color: var(--color-positive);
|
||||||
}
|
}
|
||||||
.status-indicator-inactive {
|
.status-indicator-inactive {
|
||||||
background-color: $negative;
|
background-color: var(--color-negative);
|
||||||
}
|
}
|
||||||
|
|
||||||
.shortcut-container {
|
.shortcut-container {
|
||||||
|
|
175
resources/sass/_content.scss
Normal file
175
resources/sass/_content.scss
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
/**
|
||||||
|
* Page Content
|
||||||
|
* Styles specific to blocks used within page content.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.page-content {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 840px;
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
img.align-left, table.align-left {
|
||||||
|
float: left !important;
|
||||||
|
margin: $-xs $-m $-m 0;
|
||||||
|
}
|
||||||
|
.align-right {
|
||||||
|
text-align: right !important;
|
||||||
|
}
|
||||||
|
img.align-right, table.align-right {
|
||||||
|
float: right !important;
|
||||||
|
margin: $-xs 0 $-xs $-s;
|
||||||
|
}
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
img.align-center {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
img.align-center, table.align-center {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height:auto;
|
||||||
|
}
|
||||||
|
h1, h2, h3, h4, h5, h6, pre {
|
||||||
|
clear: left;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
clear: both;
|
||||||
|
margin: $-m 0;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
hyphens: auto;
|
||||||
|
table-layout: fixed;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// diffs
|
||||||
|
ins,
|
||||||
|
del {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
ins {
|
||||||
|
background: #dbffdb;
|
||||||
|
}
|
||||||
|
del {
|
||||||
|
background: #FFECEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
details {
|
||||||
|
border: 1px solid;
|
||||||
|
@include lightDark(border-color, #DDD, #555);
|
||||||
|
margin-bottom: 1em;
|
||||||
|
padding: $-s;
|
||||||
|
}
|
||||||
|
details > summary {
|
||||||
|
margin-top: -$-s;
|
||||||
|
margin-left: -$-s;
|
||||||
|
margin-right: -$-s;
|
||||||
|
margin-bottom: -$-s;
|
||||||
|
font-weight: bold;
|
||||||
|
@include lightDark(background-color, #EEE, #333);
|
||||||
|
padding: $-xs $-s;
|
||||||
|
}
|
||||||
|
details[open] > summary {
|
||||||
|
margin-bottom: $-s;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
@include lightDark(border-color, #DDD, #555);
|
||||||
|
}
|
||||||
|
details > summary + * {
|
||||||
|
margin-top: .2em;
|
||||||
|
}
|
||||||
|
details:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
li > input[type="checkbox"] {
|
||||||
|
vertical-align: top;
|
||||||
|
margin-top: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:empty {
|
||||||
|
min-height: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.page-revision {
|
||||||
|
pre code {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-editor {
|
||||||
|
margin-bottom: 1.375em;
|
||||||
|
}
|
||||||
|
|
||||||
|
video {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callouts
|
||||||
|
*/
|
||||||
|
.callout {
|
||||||
|
border-left: 3px solid #BBB;
|
||||||
|
background-color: #EEE;
|
||||||
|
padding: $-s $-s $-s $-xl;
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
overflow: auto;
|
||||||
|
&:before {
|
||||||
|
background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9IiMwMTUzODAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+ICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4gICAgPHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bTEgMTVoLTJ2LTZoMnY2em0wLThoLTJWN2gydjJ6Ii8+PC9zdmc+');
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
content: '';
|
||||||
|
width: 1.2em;
|
||||||
|
height: 1.2em;
|
||||||
|
left: $-xs + 2px;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -9px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
line-height: 1;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
&.success {
|
||||||
|
@include lightDark(border-left-color, $positive, $positive-dark);
|
||||||
|
@include lightDark(background-color, lighten($positive, 68%), darken($positive-dark, 36%));
|
||||||
|
@include lightDark(color, darken($positive, 16%), $positive-dark);
|
||||||
|
}
|
||||||
|
&.success:before {
|
||||||
|
background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9IiMzNzZjMzkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+ICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4gICAgPHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bS0yIDE1bC01LTUgMS40MS0xLjQxTDEwIDE0LjE3bDcuNTktNy41OUwxOSA4bC05IDl6Ii8+PC9zdmc+");
|
||||||
|
}
|
||||||
|
&.danger {
|
||||||
|
@include lightDark(border-left-color, $negative, $negative-dark);
|
||||||
|
@include lightDark(background-color, lighten($negative, 56%), darken($negative-dark, 55%));
|
||||||
|
@include lightDark(color, darken($negative, 20%), $negative-dark);
|
||||||
|
}
|
||||||
|
&.danger:before {
|
||||||
|
background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9IiNiOTE4MTgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+ICAgIDxwYXRoIGQ9Ik0xNS43MyAzSDguMjdMMyA4LjI3djcuNDZMOC4yNyAyMWg3LjQ2TDIxIDE1LjczVjguMjdMMTUuNzMgM3pNMTIgMTcuM2MtLjcyIDAtMS4zLS41OC0xLjMtMS4zIDAtLjcyLjU4LTEuMyAxLjMtMS4zLjcyIDAgMS4zLjU4IDEuMyAxLjMgMCAuNzItLjU4IDEuMy0xLjMgMS4zem0xLTQuM2gtMlY3aDJ2NnoiLz4gICAgPHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==");
|
||||||
|
}
|
||||||
|
&.info {
|
||||||
|
@include lightDark(border-left-color, $info, $info-dark);
|
||||||
|
@include lightDark(color, darken($info, 20%), $info-dark);
|
||||||
|
@include lightDark(background-color, lighten($info, 50%), darken($info-dark, 34%));
|
||||||
|
}
|
||||||
|
&.warning {
|
||||||
|
@include lightDark(border-left-color, $warning, $warning-dark);
|
||||||
|
@include lightDark(background-color, lighten($warning, 50%), darken($warning-dark, 50%));
|
||||||
|
@include lightDark(color, darken($warning, 20%), $warning-dark);
|
||||||
|
}
|
||||||
|
&.warning:before {
|
||||||
|
background-image: url("data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9IiNiNjUzMWMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+ICAgIDxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz4gICAgPHBhdGggZD0iTTEgMjFoMjJMMTIgMiAxIDIxem0xMi0zaC0ydi0yaDJ2MnptMC00aC0ydi00aDJ2NHoiLz48L3N2Zz4=");
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,10 +13,10 @@
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
&.neg, &.invalid {
|
&.neg, &.invalid {
|
||||||
border: 1px solid $negative;
|
border: 1px solid var(--color-negative);
|
||||||
}
|
}
|
||||||
&.pos, &.valid {
|
&.pos, &.valid {
|
||||||
border: 1px solid $positive;
|
border: 1px solid var(--color-positive);
|
||||||
}
|
}
|
||||||
&.disabled, &[disabled] {
|
&.disabled, &[disabled] {
|
||||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAMUlEQVQIW2NkwAGuXbv2nxGbHEhCS0uLEUMSJgHShCKJLIEiiS4Bl8QmAZbEJQGSBAC62BuJ+tt7zgAAAABJRU5ErkJggg==);
|
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAMUlEQVQIW2NkwAGuXbv2nxGbHEhCS0uLEUMSJgHShCKJLIEiiS4Bl8QmAZbEJQGSBAC62BuJ+tt7zgAAAABJRU5ErkJggg==);
|
||||||
|
|
|
@ -76,118 +76,6 @@ body.tox-fullscreen, body.markdown-fullscreen {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-content {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 840px;
|
|
||||||
margin: 0 auto;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
.align-left {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
img.align-left, table.align-left {
|
|
||||||
float: left !important;
|
|
||||||
margin: $-xs $-m $-m 0;
|
|
||||||
}
|
|
||||||
.align-right {
|
|
||||||
text-align: right !important;
|
|
||||||
}
|
|
||||||
img.align-right, table.align-right {
|
|
||||||
float: right !important;
|
|
||||||
margin: $-xs 0 $-xs $-s;
|
|
||||||
}
|
|
||||||
.align-center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
img.align-center {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
img.align-center, table.align-center {
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
max-width: 100%;
|
|
||||||
height:auto;
|
|
||||||
}
|
|
||||||
h1, h2, h3, h4, h5, h6, pre {
|
|
||||||
clear: left;
|
|
||||||
}
|
|
||||||
hr {
|
|
||||||
clear: both;
|
|
||||||
margin: $-m 0;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
hyphens: auto;
|
|
||||||
table-layout: fixed;
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// diffs
|
|
||||||
ins,
|
|
||||||
del {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
ins {
|
|
||||||
background: #dbffdb;
|
|
||||||
}
|
|
||||||
del {
|
|
||||||
background: #FFECEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
details {
|
|
||||||
border: 1px solid;
|
|
||||||
@include lightDark(border-color, #DDD, #555);
|
|
||||||
margin-bottom: 1em;
|
|
||||||
padding: $-s;
|
|
||||||
}
|
|
||||||
details > summary {
|
|
||||||
margin-top: -$-s;
|
|
||||||
margin-left: -$-s;
|
|
||||||
margin-right: -$-s;
|
|
||||||
margin-bottom: -$-s;
|
|
||||||
font-weight: bold;
|
|
||||||
@include lightDark(background-color, #EEE, #333);
|
|
||||||
padding: $-xs $-s;
|
|
||||||
}
|
|
||||||
details[open] > summary {
|
|
||||||
margin-bottom: $-s;
|
|
||||||
border-bottom: 1px solid;
|
|
||||||
@include lightDark(border-color, #DDD, #555);
|
|
||||||
}
|
|
||||||
details > summary + * {
|
|
||||||
margin-top: .2em;
|
|
||||||
}
|
|
||||||
details:after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
li > input[type="checkbox"] {
|
|
||||||
vertical-align: top;
|
|
||||||
margin-top: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
p:empty {
|
|
||||||
min-height: 1.6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.page-revision {
|
|
||||||
pre code {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cm-editor {
|
|
||||||
margin-bottom: 1.375em;
|
|
||||||
}
|
|
||||||
|
|
||||||
video {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page content pointers
|
// Page content pointers
|
||||||
.pointer-container {
|
.pointer-container {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
body, button, input, select, label, textarea {
|
body, button, input, select, label, textarea {
|
||||||
font-family: $text;
|
font-family: var(--font-body);
|
||||||
}
|
}
|
||||||
.Codemirror, pre, #markdown-editor-input, .text-mono, .code-base {
|
pre, #markdown-editor-input, .text-mono, .code-base {
|
||||||
font-family: $mono;
|
font-family: var(--font-code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -42,6 +42,7 @@ h1, h2, h3, h4, h5, h6 {
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
|
font-family: var(--font-heading);
|
||||||
@include lightDark(color, #222, #BBB);
|
@include lightDark(color, #222, #BBB);
|
||||||
.subheader {
|
.subheader {
|
||||||
font-size: 0.5em;
|
font-size: 0.5em;
|
||||||
|
@ -210,7 +211,8 @@ pre {
|
||||||
blockquote {
|
blockquote {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-left: 4px solid var(--color-primary);
|
border-left: 4px solid transparent;
|
||||||
|
border-left-color: var(--color-primary);
|
||||||
@include lightDark(background-color, #f8f8f8, #333);
|
@include lightDark(background-color, #f8f8f8, #333);
|
||||||
padding: $-s $-m $-s $-xl;
|
padding: $-s $-m $-s $-xl;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
@ -226,7 +228,7 @@ blockquote {
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-mono {
|
.text-mono {
|
||||||
font-family: $mono;
|
font-family: var(--font-code);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-uppercase {
|
.text-uppercase {
|
||||||
|
|
|
@ -110,7 +110,7 @@ body.page-content.mce-content-body {
|
||||||
border-left: 3px solid currentColor !important;
|
border-left: 3px solid currentColor !important;
|
||||||
}
|
}
|
||||||
.tox-menu .tox-collection__item[title^="<"] > div > div {
|
.tox-menu .tox-collection__item[title^="<"] > div > div {
|
||||||
font-family: $mono !important;
|
font-family: var(--font-code) !important;
|
||||||
border: 1px solid #DDD !important;
|
border: 1px solid #DDD !important;
|
||||||
background-color: #EEE !important;
|
background-color: #EEE !important;
|
||||||
padding: 4px 6px !important;
|
padding: 4px 6px !important;
|
||||||
|
|
|
@ -27,41 +27,23 @@ $-xxs: 3px;
|
||||||
$spacing: (('none', 0), ('xxs', $-xxs), ('xs', $-xs), ('s', $-s), ('m', $-m), ('l', $-l), ('xl', $-xl), ('xxl', $-xxl), ('auto', auto));
|
$spacing: (('none', 0), ('xxs', $-xxs), ('xs', $-xs), ('s', $-s), ('m', $-m), ('l', $-l), ('xl', $-xl), ('xxl', $-xxl), ('auto', auto));
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
$text: -apple-system, BlinkMacSystemFont,
|
$font-body: -apple-system, BlinkMacSystemFont,
|
||||||
"Segoe UI", "Oxygen", "Ubuntu", "Roboto", "Cantarell",
|
"Segoe UI", "Oxygen", "Ubuntu", "Roboto", "Cantarell",
|
||||||
"Fira Sans", "Droid Sans", "Helvetica Neue",
|
"Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||||
sans-serif;
|
sans-serif;
|
||||||
$mono: "Lucida Console", "DejaVu Sans Mono", "Ubuntu Mono", Monaco, monospace;
|
$font-mono: "Lucida Console", "DejaVu Sans Mono", "Ubuntu Mono", Monaco, monospace;
|
||||||
$fs-m: 14px;
|
$fs-m: 14px;
|
||||||
$fs-s: 12px;
|
$fs-s: 12px;
|
||||||
|
|
||||||
// Colours
|
// Colours
|
||||||
:root {
|
|
||||||
--color-primary: #206ea7;
|
|
||||||
--color-primary-light: rgba(32,110,167,0.15);
|
|
||||||
--color-link: #206ea7;
|
|
||||||
|
|
||||||
--color-page: #206ea7;
|
|
||||||
--color-page-draft: #7e50b1;
|
|
||||||
--color-chapter: #af4d0d;
|
|
||||||
--color-book: #077b70;
|
|
||||||
--color-bookshelf: #a94747;
|
|
||||||
|
|
||||||
--bg-disabled: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='100%25' width='100%25'%3E%3Cdefs%3E%3Cpattern id='doodad' width='19' height='19' viewBox='0 0 40 40' patternUnits='userSpaceOnUse' patternTransform='rotate(143)'%3E%3Crect width='100%25' height='100%25' fill='rgba(42, 67, 101,0)'/%3E%3Cpath d='M-10 30h60v20h-60zM-10-10h60v20h-60' fill='rgba(26, 32, 44,0)'/%3E%3Cpath d='M-10 10h60v20h-60zM-10-30h60v20h-60z' fill='rgba(0, 0, 0,0.05)'/%3E%3C/pattern%3E%3C/defs%3E%3Crect fill='url(%23doodad)' height='200%25' width='200%25'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
:root.dark-mode {
|
|
||||||
--bg-disabled: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='100%25' width='100%25'%3E%3Cdefs%3E%3Cpattern id='doodad' width='19' height='19' viewBox='0 0 40 40' patternUnits='userSpaceOnUse' patternTransform='rotate(143)'%3E%3Crect width='100%25' height='100%25' fill='rgba(42, 67, 101,0)'/%3E%3Cpath d='M-10 30h60v20h-60zM-10-10h60v20h-60' fill='rgba(26, 32, 44,0)'/%3E%3Cpath d='M-10 10h60v20h-60zM-10-30h60v20h-60z' fill='rgba(255, 255, 255,0.05)'/%3E%3C/pattern%3E%3C/defs%3E%3Crect fill='url(%23doodad)' height='200%25' width='200%25'/%3E%3C/svg%3E");
|
|
||||||
color-scheme: only dark;
|
|
||||||
}
|
|
||||||
:root:not(.dark-mode) {
|
|
||||||
color-scheme: only light;
|
|
||||||
}
|
|
||||||
|
|
||||||
$positive: #0f7d15;
|
$positive: #0f7d15;
|
||||||
$negative: #ab0f0e;
|
$negative: #ab0f0e;
|
||||||
$info: #0288D1;
|
$info: #0288D1;
|
||||||
$warning: #cf4d03;
|
$warning: #cf4d03;
|
||||||
|
$positive-dark: #4aa850;
|
||||||
|
$negative-dark: #e85c5b;
|
||||||
|
$info-dark: #0288D1;
|
||||||
|
$warning-dark: #de8a5a;
|
||||||
|
|
||||||
// Text colours
|
// Text colours
|
||||||
$text-dark: #444;
|
$text-dark: #444;
|
||||||
|
@ -74,3 +56,40 @@ $bs-large: 0 1px 6px 1px rgba(22, 22, 22, 0.2);
|
||||||
$bs-card: 0 1px 6px -1px rgba(0, 0, 0, 0.1);
|
$bs-card: 0 1px 6px -1px rgba(0, 0, 0, 0.1);
|
||||||
$bs-card-dark: 0 1px 6px -1px rgba(0, 0, 0, 0.5);
|
$bs-card-dark: 0 1px 6px -1px rgba(0, 0, 0, 0.5);
|
||||||
$bs-hover: 0 2px 2px 1px rgba(0,0,0,.13);
|
$bs-hover: 0 2px 2px 1px rgba(0,0,0,.13);
|
||||||
|
|
||||||
|
// CSS root variables
|
||||||
|
:root {
|
||||||
|
--font-body: #{$font-body};
|
||||||
|
--font-heading: #{$font-body};
|
||||||
|
--font-code: #{$font-mono};
|
||||||
|
|
||||||
|
|
||||||
|
--color-primary: #206ea7;
|
||||||
|
--color-primary-light: rgba(32,110,167,0.15);
|
||||||
|
--color-link: #206ea7;
|
||||||
|
|
||||||
|
--color-page: #206ea7;
|
||||||
|
--color-page-draft: #7e50b1;
|
||||||
|
--color-chapter: #af4d0d;
|
||||||
|
--color-book: #077b70;
|
||||||
|
--color-bookshelf: #a94747;
|
||||||
|
|
||||||
|
--color-positive: #{$positive};
|
||||||
|
--color-negative: #{$negative};
|
||||||
|
--color-info: #{$info};
|
||||||
|
--color-warning: #{$warning};
|
||||||
|
|
||||||
|
--bg-disabled: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='100%25' width='100%25'%3E%3Cdefs%3E%3Cpattern id='doodad' width='19' height='19' viewBox='0 0 40 40' patternUnits='userSpaceOnUse' patternTransform='rotate(143)'%3E%3Crect width='100%25' height='100%25' fill='rgba(42, 67, 101,0)'/%3E%3Cpath d='M-10 30h60v20h-60zM-10-10h60v20h-60' fill='rgba(26, 32, 44,0)'/%3E%3Cpath d='M-10 10h60v20h-60zM-10-30h60v20h-60z' fill='rgba(0, 0, 0,0.05)'/%3E%3C/pattern%3E%3C/defs%3E%3Crect fill='url(%23doodad)' height='200%25' width='200%25'/%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark-mode {
|
||||||
|
--bg-disabled: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' height='100%25' width='100%25'%3E%3Cdefs%3E%3Cpattern id='doodad' width='19' height='19' viewBox='0 0 40 40' patternUnits='userSpaceOnUse' patternTransform='rotate(143)'%3E%3Crect width='100%25' height='100%25' fill='rgba(42, 67, 101,0)'/%3E%3Cpath d='M-10 30h60v20h-60zM-10-10h60v20h-60' fill='rgba(26, 32, 44,0)'/%3E%3Cpath d='M-10 10h60v20h-60zM-10-30h60v20h-60z' fill='rgba(255, 255, 255,0.05)'/%3E%3C/pattern%3E%3C/defs%3E%3Crect fill='url(%23doodad)' height='200%25' width='200%25'/%3E%3C/svg%3E");
|
||||||
|
color-scheme: only dark;
|
||||||
|
|
||||||
|
--color-positive: #4aa850;
|
||||||
|
--color-negative: #e85c5b;
|
||||||
|
--color-warning: #de8a5a;
|
||||||
|
}
|
||||||
|
:root:not(.dark-mode) {
|
||||||
|
color-scheme: only light;
|
||||||
|
}
|
|
@ -3,11 +3,8 @@
|
||||||
@import "mixins";
|
@import "mixins";
|
||||||
@import "html";
|
@import "html";
|
||||||
@import "text";
|
@import "text";
|
||||||
@import "layout";
|
|
||||||
@import "blocks";
|
|
||||||
@import "tables";
|
@import "tables";
|
||||||
@import "lists";
|
@import "content";
|
||||||
@import "pages";
|
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
@import "footer";
|
@import "footer";
|
||||||
@import "lists";
|
@import "lists";
|
||||||
@import "pages";
|
@import "pages";
|
||||||
|
@import "content";
|
||||||
|
|
||||||
// Jquery Sortable Styles
|
// Jquery Sortable Styles
|
||||||
.dragged {
|
.dragged {
|
||||||
|
|
|
@ -27,13 +27,22 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@endif
|
@endif
|
||||||
<li refs="page-editor@discardDraftWrap" class="{{ $isDraftRevision ? '' : 'hidden' }}">
|
<li refs="page-editor@discard-draft-wrap" {{ $isDraftRevision ? '' : 'hidden' }}>
|
||||||
<button refs="page-editor@discardDraft" type="button" class="text-neg icon-item">
|
<button refs="page-editor@discard-draft" type="button" class="text-warn icon-item">
|
||||||
@icon('cancel')
|
@icon('cancel')
|
||||||
<div>{{ trans('entities.pages_edit_discard_draft') }}</div>
|
<div>{{ trans('entities.pages_edit_discard_draft') }}</div>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
<li refs="page-editor@delete-draft-wrap" {{ $isDraftRevision ? '' : 'hidden' }}>
|
||||||
|
<button refs="page-editor@delete-draft" type="button" class="text-neg icon-item">
|
||||||
|
@icon('delete')
|
||||||
|
<div>{{ trans('entities.pages_edit_delete_draft') }}</div>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
@if(userCan('editor-change'))
|
@if(userCan('editor-change'))
|
||||||
|
<li>
|
||||||
|
<hr>
|
||||||
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@if($editor === 'wysiwyg')
|
@if($editor === 'wysiwyg')
|
||||||
<a href="{{ $model->getUrl($isDraft ? '' : '/edit') }}?editor=markdown-clean" refs="page-editor@changeEditor" class="icon-item">
|
<a href="{{ $model->getUrl($isDraft ? '' : '/edit') }}?editor=markdown-clean" refs="page-editor@changeEditor" class="icon-item">
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
option:page-editor:autosave-fail-text="{{ trans('errors.page_draft_autosave_fail') }}"
|
option:page-editor:autosave-fail-text="{{ trans('errors.page_draft_autosave_fail') }}"
|
||||||
option:page-editor:editing-page-text="{{ trans('entities.pages_editing_page') }}"
|
option:page-editor:editing-page-text="{{ trans('entities.pages_editing_page') }}"
|
||||||
option:page-editor:draft-discarded-text="{{ trans('entities.pages_draft_discarded') }}"
|
option:page-editor:draft-discarded-text="{{ trans('entities.pages_draft_discarded') }}"
|
||||||
|
option:page-editor:draft-delete-text="{{ trans('entities.pages_draft_deleted') }}"
|
||||||
|
option:page-editor:draft-delete-fail-text="{{ trans('errors.page_draft_delete_fail') }}"
|
||||||
option:page-editor:set-changelog-text="{{ trans('entities.pages_edit_set_changelog') }}">
|
option:page-editor:set-changelog-text="{{ trans('entities.pages_edit_set_changelog') }}">
|
||||||
|
|
||||||
{{--Header Toolbar--}}
|
{{--Header Toolbar--}}
|
||||||
|
@ -47,7 +49,7 @@
|
||||||
class="text-link text-button hide-over-m page-save-mobile-button">@icon('save')</button>
|
class="text-link text-button hide-over-m page-save-mobile-button">@icon('save')</button>
|
||||||
|
|
||||||
{{--Editor Change Dialog--}}
|
{{--Editor Change Dialog--}}
|
||||||
@component('common.confirm-dialog', ['title' => trans('entities.pages_editor_switch_title'), 'ref' => 'page-editor@switchDialog'])
|
@component('common.confirm-dialog', ['title' => trans('entities.pages_editor_switch_title'), 'ref' => 'page-editor@switch-dialog'])
|
||||||
<p>
|
<p>
|
||||||
{{ trans('entities.pages_editor_switch_are_you_sure') }}
|
{{ trans('entities.pages_editor_switch_are_you_sure') }}
|
||||||
<br>
|
<br>
|
||||||
|
@ -60,4 +62,11 @@
|
||||||
<li>{{ trans('entities.pages_editor_switch_consideration_c') }}</li>
|
<li>{{ trans('entities.pages_editor_switch_consideration_c') }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
@endcomponent
|
@endcomponent
|
||||||
|
|
||||||
|
{{--Delete Draft Dialog--}}
|
||||||
|
@component('common.confirm-dialog', ['title' => trans('entities.pages_edit_delete_draft'), 'ref' => 'page-editor@delete-draft-dialog'])
|
||||||
|
<p>
|
||||||
|
{{ trans('entities.pages_edit_delete_draft_confirm') }}
|
||||||
|
</p>
|
||||||
|
@endcomponent
|
||||||
</div>
|
</div>
|
|
@ -106,6 +106,7 @@ Route::middleware('auth')->group(function () {
|
||||||
Route::get('/books/{bookSlug}/page/{pageSlug}/revisions/{revId}/changes', [EntityControllers\PageRevisionController::class, 'changes']);
|
Route::get('/books/{bookSlug}/page/{pageSlug}/revisions/{revId}/changes', [EntityControllers\PageRevisionController::class, 'changes']);
|
||||||
Route::put('/books/{bookSlug}/page/{pageSlug}/revisions/{revId}/restore', [EntityControllers\PageRevisionController::class, 'restore']);
|
Route::put('/books/{bookSlug}/page/{pageSlug}/revisions/{revId}/restore', [EntityControllers\PageRevisionController::class, 'restore']);
|
||||||
Route::delete('/books/{bookSlug}/page/{pageSlug}/revisions/{revId}/delete', [EntityControllers\PageRevisionController::class, 'destroy']);
|
Route::delete('/books/{bookSlug}/page/{pageSlug}/revisions/{revId}/delete', [EntityControllers\PageRevisionController::class, 'destroy']);
|
||||||
|
Route::delete('/page-revisions/user-drafts/{pageId}', [EntityControllers\PageRevisionController::class, 'destroyUserDraft']);
|
||||||
|
|
||||||
// Chapters
|
// Chapters
|
||||||
Route::get('/books/{bookSlug}/chapter/{chapterSlug}/create-page', [EntityControllers\PageController::class, 'create']);
|
Route::get('/books/{bookSlug}/chapter/{chapterSlug}/create-page', [EntityControllers\PageController::class, 'create']);
|
||||||
|
|
|
@ -166,6 +166,30 @@ class PageDraftTest extends TestCase
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_user_draft_removed_on_user_drafts_delete_call()
|
||||||
|
{
|
||||||
|
$editor = $this->users->editor();
|
||||||
|
$page = $this->entities->page();
|
||||||
|
|
||||||
|
$this->actingAs($editor)->put('/ajax/page/' . $page->id . '/save-draft', [
|
||||||
|
'name' => $page->name,
|
||||||
|
'html' => '<p>updated draft again</p>',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$revisionData = [
|
||||||
|
'type' => 'update_draft',
|
||||||
|
'created_by' => $editor->id,
|
||||||
|
'page_id' => $page->id,
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->assertDatabaseHas('page_revisions', $revisionData);
|
||||||
|
|
||||||
|
$resp = $this->delete("/page-revisions/user-drafts/{$page->id}");
|
||||||
|
|
||||||
|
$resp->assertOk();
|
||||||
|
$this->assertDatabaseMissing('page_revisions', $revisionData);
|
||||||
|
}
|
||||||
|
|
||||||
public function test_updating_page_draft_with_markdown_retains_markdown_content()
|
public function test_updating_page_draft_with_markdown_retains_markdown_content()
|
||||||
{
|
{
|
||||||
$book = $this->entities->book();
|
$book = $this->entities->book();
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Tests;
|
namespace Tests;
|
||||||
|
|
||||||
|
use BookStack\Activity\ActivityType;
|
||||||
|
|
||||||
class LanguageTest extends TestCase
|
class LanguageTest extends TestCase
|
||||||
{
|
{
|
||||||
protected array $langs;
|
protected array $langs;
|
||||||
|
@ -90,4 +92,12 @@ class LanguageTest extends TestCase
|
||||||
$loginReq->assertOk();
|
$loginReq->assertOk();
|
||||||
$loginReq->assertSee('Log In');
|
$loginReq->assertSee('Log In');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_all_activity_types_have_activity_text()
|
||||||
|
{
|
||||||
|
foreach (ActivityType::all() as $activityType) {
|
||||||
|
$langKey = 'activities.' . $activityType;
|
||||||
|
$this->assertNotEquals($langKey, trans($langKey, [], 'en'));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,7 +301,7 @@ class RolesTest extends TestCase
|
||||||
$resp = $this->post('/settings/features', []);
|
$resp = $this->post('/settings/features', []);
|
||||||
$resp->assertRedirect('/settings/features');
|
$resp->assertRedirect('/settings/features');
|
||||||
$resp = $this->get('/settings/features');
|
$resp = $this->get('/settings/features');
|
||||||
$resp->assertSee('Settings saved');
|
$resp->assertSee('Settings successfully updated');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_restrictions_manage_all_permission()
|
public function test_restrictions_manage_all_permission()
|
||||||
|
|
Loading…
Add table
Reference in a new issue