Dan Brown
Committed by GitHub

Merge pull request #234 from BookStackApp/translations

Setup for translations
Showing 137 changed files with 1841 additions and 1229 deletions
...@@ -77,7 +77,7 @@ class AttachmentController extends Controller ...@@ -77,7 +77,7 @@ class AttachmentController extends Controller
77 $this->checkOwnablePermission('attachment-create', $attachment); 77 $this->checkOwnablePermission('attachment-create', $attachment);
78 78
79 if (intval($pageId) !== intval($attachment->uploaded_to)) { 79 if (intval($pageId) !== intval($attachment->uploaded_to)) {
80 - return $this->jsonError('Page mismatch during attached file update'); 80 + return $this->jsonError(trans('errors.attachment_page_mismatch'));
81 } 81 }
82 82
83 $uploadedFile = $request->file('file'); 83 $uploadedFile = $request->file('file');
...@@ -113,11 +113,11 @@ class AttachmentController extends Controller ...@@ -113,11 +113,11 @@ class AttachmentController extends Controller
113 $this->checkOwnablePermission('attachment-create', $attachment); 113 $this->checkOwnablePermission('attachment-create', $attachment);
114 114
115 if (intval($pageId) !== intval($attachment->uploaded_to)) { 115 if (intval($pageId) !== intval($attachment->uploaded_to)) {
116 - return $this->jsonError('Page mismatch during attachment update'); 116 + return $this->jsonError(trans('errors.attachment_page_mismatch'));
117 } 117 }
118 118
119 $attachment = $this->attachmentService->updateFile($attachment, $request->all()); 119 $attachment = $this->attachmentService->updateFile($attachment, $request->all());
120 - return $attachment; 120 + return response()->json($attachment);
121 } 121 }
122 122
123 /** 123 /**
...@@ -175,7 +175,7 @@ class AttachmentController extends Controller ...@@ -175,7 +175,7 @@ class AttachmentController extends Controller
175 175
176 $attachments = $request->get('files'); 176 $attachments = $request->get('files');
177 $this->attachmentService->updateFileOrderWithinPage($attachments, $pageId); 177 $this->attachmentService->updateFileOrderWithinPage($attachments, $pageId);
178 - return response()->json(['message' => 'Attachment order updated']); 178 + return response()->json(['message' => trans('entities.attachments_order_updated')]);
179 } 179 }
180 180
181 /** 181 /**
...@@ -210,6 +210,6 @@ class AttachmentController extends Controller ...@@ -210,6 +210,6 @@ class AttachmentController extends Controller
210 $attachment = $this->attachment->findOrFail($attachmentId); 210 $attachment = $this->attachment->findOrFail($attachmentId);
211 $this->checkOwnablePermission('attachment-delete', $attachment); 211 $this->checkOwnablePermission('attachment-delete', $attachment);
212 $this->attachmentService->deleteFile($attachment); 212 $this->attachmentService->deleteFile($attachment);
213 - return response()->json(['message' => 'Attachment deleted']); 213 + return response()->json(['message' => trans('entities.attachments_deleted')]);
214 } 214 }
215 } 215 }
......
...@@ -52,7 +52,7 @@ class ForgotPasswordController extends Controller ...@@ -52,7 +52,7 @@ class ForgotPasswordController extends Controller
52 ); 52 );
53 53
54 if ($response === Password::RESET_LINK_SENT) { 54 if ($response === Password::RESET_LINK_SENT) {
55 - $message = 'A password reset link has been sent to ' . $request->get('email') . '.'; 55 + $message = trans('auth.reset_password_sent_success', ['email' => $request->get('email')]);
56 session()->flash('success', $message); 56 session()->flash('success', $message);
57 return back()->with('status', trans($response)); 57 return back()->with('status', trans($response));
58 } 58 }
......
...@@ -87,7 +87,7 @@ class LoginController extends Controller ...@@ -87,7 +87,7 @@ class LoginController extends Controller
87 // Check for users with same email already 87 // Check for users with same email already
88 $alreadyUser = $user->newQuery()->where('email', '=', $user->email)->count() > 0; 88 $alreadyUser = $user->newQuery()->where('email', '=', $user->email)->count() > 0;
89 if ($alreadyUser) { 89 if ($alreadyUser) {
90 - throw new AuthException('A user with the email ' . $user->email . ' already exists but with different credentials.'); 90 + throw new AuthException(trans('errors.error_user_exists_different_creds', ['email' => $user->email]));
91 } 91 }
92 92
93 $user->save(); 93 $user->save();
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
3 namespace BookStack\Http\Controllers\Auth; 3 namespace BookStack\Http\Controllers\Auth;
4 4
5 use BookStack\Exceptions\ConfirmationEmailException; 5 use BookStack\Exceptions\ConfirmationEmailException;
6 +use BookStack\Exceptions\SocialSignInException;
6 use BookStack\Exceptions\UserRegistrationException; 7 use BookStack\Exceptions\UserRegistrationException;
7 use BookStack\Repos\UserRepo; 8 use BookStack\Repos\UserRepo;
8 use BookStack\Services\EmailConfirmationService; 9 use BookStack\Services\EmailConfirmationService;
...@@ -82,7 +83,7 @@ class RegisterController extends Controller ...@@ -82,7 +83,7 @@ class RegisterController extends Controller
82 protected function checkRegistrationAllowed() 83 protected function checkRegistrationAllowed()
83 { 84 {
84 if (!setting('registration-enabled')) { 85 if (!setting('registration-enabled')) {
85 - throw new UserRegistrationException('Registrations are currently disabled.', '/login'); 86 + throw new UserRegistrationException(trans('auth.registrations_disabled'), '/login');
86 } 87 }
87 } 88 }
88 89
...@@ -147,7 +148,7 @@ class RegisterController extends Controller ...@@ -147,7 +148,7 @@ class RegisterController extends Controller
147 $restrictedEmailDomains = explode(',', str_replace(' ', '', setting('registration-restrict'))); 148 $restrictedEmailDomains = explode(',', str_replace(' ', '', setting('registration-restrict')));
148 $userEmailDomain = $domain = substr(strrchr($userData['email'], "@"), 1); 149 $userEmailDomain = $domain = substr(strrchr($userData['email'], "@"), 1);
149 if (!in_array($userEmailDomain, $restrictedEmailDomains)) { 150 if (!in_array($userEmailDomain, $restrictedEmailDomains)) {
150 - throw new UserRegistrationException('That email domain does not have access to this application', '/register'); 151 + throw new UserRegistrationException(trans('auth.registration_email_domain_invalid'), '/register');
151 } 152 }
152 } 153 }
153 154
...@@ -169,7 +170,7 @@ class RegisterController extends Controller ...@@ -169,7 +170,7 @@ class RegisterController extends Controller
169 } 170 }
170 171
171 auth()->login($newUser); 172 auth()->login($newUser);
172 - session()->flash('success', 'Thanks for signing up! You are now registered and signed in.'); 173 + session()->flash('success', trans('auth.register_success'));
173 return redirect($this->redirectPath()); 174 return redirect($this->redirectPath());
174 } 175 }
175 176
...@@ -262,7 +263,7 @@ class RegisterController extends Controller ...@@ -262,7 +263,7 @@ class RegisterController extends Controller
262 return $this->socialRegisterCallback($socialDriver); 263 return $this->socialRegisterCallback($socialDriver);
263 } 264 }
264 } else { 265 } else {
265 - throw new SocialSignInException('No action defined', '/login'); 266 + throw new SocialSignInException(trans('errors.social_no_action_defined'), '/login');
266 } 267 }
267 return redirect()->back(); 268 return redirect()->back();
268 } 269 }
......
...@@ -41,7 +41,7 @@ class ResetPasswordController extends Controller ...@@ -41,7 +41,7 @@ class ResetPasswordController extends Controller
41 */ 41 */
42 protected function sendResetResponse($response) 42 protected function sendResetResponse($response)
43 { 43 {
44 - $message = 'Your password has been successfully reset.'; 44 + $message = trans('auth.reset_password_success');
45 session()->flash('success', $message); 45 session()->flash('success', $message);
46 return redirect($this->redirectPath()) 46 return redirect($this->redirectPath())
47 ->with('status', trans($response)); 47 ->with('status', trans($response));
......
...@@ -7,6 +7,7 @@ use BookStack\Http\Requests; ...@@ -7,6 +7,7 @@ use BookStack\Http\Requests;
7 use BookStack\Repos\BookRepo; 7 use BookStack\Repos\BookRepo;
8 use BookStack\Repos\ChapterRepo; 8 use BookStack\Repos\ChapterRepo;
9 use BookStack\Repos\PageRepo; 9 use BookStack\Repos\PageRepo;
10 +use Illuminate\Http\Response;
10 use Views; 11 use Views;
11 12
12 class BookController extends Controller 13 class BookController extends Controller
...@@ -53,7 +54,7 @@ class BookController extends Controller ...@@ -53,7 +54,7 @@ class BookController extends Controller
53 public function create() 54 public function create()
54 { 55 {
55 $this->checkPermission('book-create-all'); 56 $this->checkPermission('book-create-all');
56 - $this->setPageTitle('Create New Book'); 57 + $this->setPageTitle(trans('entities.books_create'));
57 return view('books/create'); 58 return view('books/create');
58 } 59 }
59 60
...@@ -99,7 +100,7 @@ class BookController extends Controller ...@@ -99,7 +100,7 @@ class BookController extends Controller
99 { 100 {
100 $book = $this->bookRepo->getBySlug($slug); 101 $book = $this->bookRepo->getBySlug($slug);
101 $this->checkOwnablePermission('book-update', $book); 102 $this->checkOwnablePermission('book-update', $book);
102 - $this->setPageTitle('Edit Book ' . $book->getShortName()); 103 + $this->setPageTitle(trans('entities.books_edit_named',['bookName'=>$book->getShortName()]));
103 return view('books/edit', ['book' => $book, 'current' => $book]); 104 return view('books/edit', ['book' => $book, 'current' => $book]);
104 } 105 }
105 106
...@@ -131,7 +132,7 @@ class BookController extends Controller ...@@ -131,7 +132,7 @@ class BookController extends Controller
131 { 132 {
132 $book = $this->bookRepo->getBySlug($bookSlug); 133 $book = $this->bookRepo->getBySlug($bookSlug);
133 $this->checkOwnablePermission('book-delete', $book); 134 $this->checkOwnablePermission('book-delete', $book);
134 - $this->setPageTitle('Delete Book ' . $book->getShortName()); 135 + $this->setPageTitle(trans('entities.books_delete_named', ['bookName'=>$book->getShortName()]));
135 return view('books/delete', ['book' => $book, 'current' => $book]); 136 return view('books/delete', ['book' => $book, 'current' => $book]);
136 } 137 }
137 138
...@@ -146,7 +147,7 @@ class BookController extends Controller ...@@ -146,7 +147,7 @@ class BookController extends Controller
146 $this->checkOwnablePermission('book-update', $book); 147 $this->checkOwnablePermission('book-update', $book);
147 $bookChildren = $this->bookRepo->getChildren($book, true); 148 $bookChildren = $this->bookRepo->getChildren($book, true);
148 $books = $this->bookRepo->getAll(false); 149 $books = $this->bookRepo->getAll(false);
149 - $this->setPageTitle('Sort Book ' . $book->getShortName()); 150 + $this->setPageTitle(trans('entities.books_sort_named', ['bookName'=>$book->getShortName()]));
150 return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]); 151 return view('books/sort', ['book' => $book, 'current' => $book, 'books' => $books, 'bookChildren' => $bookChildren]);
151 } 152 }
152 153
...@@ -264,7 +265,7 @@ class BookController extends Controller ...@@ -264,7 +265,7 @@ class BookController extends Controller
264 $book = $this->bookRepo->getBySlug($bookSlug); 265 $book = $this->bookRepo->getBySlug($bookSlug);
265 $this->checkOwnablePermission('restrictions-manage', $book); 266 $this->checkOwnablePermission('restrictions-manage', $book);
266 $this->bookRepo->updateEntityPermissionsFromRequest($request, $book); 267 $this->bookRepo->updateEntityPermissionsFromRequest($request, $book);
267 - session()->flash('success', 'Book Restrictions Updated'); 268 + session()->flash('success', trans('entities.books_permissions_updated'));
268 return redirect($book->getUrl()); 269 return redirect($book->getUrl());
269 } 270 }
270 } 271 }
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
3 use Activity; 3 use Activity;
4 use BookStack\Repos\UserRepo; 4 use BookStack\Repos\UserRepo;
5 use Illuminate\Http\Request; 5 use Illuminate\Http\Request;
6 -use BookStack\Http\Requests;
7 use BookStack\Repos\BookRepo; 6 use BookStack\Repos\BookRepo;
8 use BookStack\Repos\ChapterRepo; 7 use BookStack\Repos\ChapterRepo;
8 +use Illuminate\Http\Response;
9 use Views; 9 use Views;
10 10
11 class ChapterController extends Controller 11 class ChapterController extends Controller
...@@ -38,7 +38,7 @@ class ChapterController extends Controller ...@@ -38,7 +38,7 @@ class ChapterController extends Controller
38 { 38 {
39 $book = $this->bookRepo->getBySlug($bookSlug); 39 $book = $this->bookRepo->getBySlug($bookSlug);
40 $this->checkOwnablePermission('chapter-create', $book); 40 $this->checkOwnablePermission('chapter-create', $book);
41 - $this->setPageTitle('Create New Chapter'); 41 + $this->setPageTitle(trans('entities.chapters_create'));
42 return view('chapters/create', ['book' => $book, 'current' => $book]); 42 return view('chapters/create', ['book' => $book, 'current' => $book]);
43 } 43 }
44 44
...@@ -99,7 +99,7 @@ class ChapterController extends Controller ...@@ -99,7 +99,7 @@ class ChapterController extends Controller
99 $book = $this->bookRepo->getBySlug($bookSlug); 99 $book = $this->bookRepo->getBySlug($bookSlug);
100 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); 100 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
101 $this->checkOwnablePermission('chapter-update', $chapter); 101 $this->checkOwnablePermission('chapter-update', $chapter);
102 - $this->setPageTitle('Edit Chapter' . $chapter->getShortName()); 102 + $this->setPageTitle(trans('entities.chapters_edit_named', ['chapterName' => $chapter->getShortName()]));
103 return view('chapters/edit', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]); 103 return view('chapters/edit', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]);
104 } 104 }
105 105
...@@ -136,7 +136,7 @@ class ChapterController extends Controller ...@@ -136,7 +136,7 @@ class ChapterController extends Controller
136 $book = $this->bookRepo->getBySlug($bookSlug); 136 $book = $this->bookRepo->getBySlug($bookSlug);
137 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); 137 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
138 $this->checkOwnablePermission('chapter-delete', $chapter); 138 $this->checkOwnablePermission('chapter-delete', $chapter);
139 - $this->setPageTitle('Delete Chapter' . $chapter->getShortName()); 139 + $this->setPageTitle(trans('entities.chapters_delete_named', ['chapterName' => $chapter->getShortName()]));
140 return view('chapters/delete', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]); 140 return view('chapters/delete', ['book' => $book, 'chapter' => $chapter, 'current' => $chapter]);
141 } 141 }
142 142
...@@ -166,6 +166,7 @@ class ChapterController extends Controller ...@@ -166,6 +166,7 @@ class ChapterController extends Controller
166 public function showMove($bookSlug, $chapterSlug) { 166 public function showMove($bookSlug, $chapterSlug) {
167 $book = $this->bookRepo->getBySlug($bookSlug); 167 $book = $this->bookRepo->getBySlug($bookSlug);
168 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); 168 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
169 + $this->setPageTitle(trans('entities.chapters_move_named', ['chapterName' => $chapter->getShortName()]));
169 $this->checkOwnablePermission('chapter-update', $chapter); 170 $this->checkOwnablePermission('chapter-update', $chapter);
170 return view('chapters/move', [ 171 return view('chapters/move', [
171 'chapter' => $chapter, 172 'chapter' => $chapter,
...@@ -202,13 +203,13 @@ class ChapterController extends Controller ...@@ -202,13 +203,13 @@ class ChapterController extends Controller
202 } 203 }
203 204
204 if ($parent === false || $parent === null) { 205 if ($parent === false || $parent === null) {
205 - session()->flash('The selected Book was not found'); 206 + session()->flash('error', trans('errors.selected_book_not_found'));
206 return redirect()->back(); 207 return redirect()->back();
207 } 208 }
208 209
209 $this->chapterRepo->changeBook($parent->id, $chapter, true); 210 $this->chapterRepo->changeBook($parent->id, $chapter, true);
210 Activity::add($chapter, 'chapter_move', $chapter->book->id); 211 Activity::add($chapter, 'chapter_move', $chapter->book->id);
211 - session()->flash('success', sprintf('Chapter moved to "%s"', $parent->name)); 212 + session()->flash('success', trans('entities.chapter_move_success', ['bookName' => $parent->name]));
212 213
213 return redirect($chapter->getUrl()); 214 return redirect($chapter->getUrl());
214 } 215 }
...@@ -244,7 +245,7 @@ class ChapterController extends Controller ...@@ -244,7 +245,7 @@ class ChapterController extends Controller
244 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id); 245 $chapter = $this->chapterRepo->getBySlug($chapterSlug, $book->id);
245 $this->checkOwnablePermission('restrictions-manage', $chapter); 246 $this->checkOwnablePermission('restrictions-manage', $chapter);
246 $this->chapterRepo->updateEntityPermissionsFromRequest($request, $chapter); 247 $this->chapterRepo->updateEntityPermissionsFromRequest($request, $chapter);
247 - session()->flash('success', 'Chapter Restrictions Updated'); 248 + session()->flash('success', trans('entities.chapters_permissions_success'));
248 return redirect($chapter->getUrl()); 249 return redirect($chapter->getUrl());
249 } 250 }
250 } 251 }
......
...@@ -43,4 +43,39 @@ class HomeController extends Controller ...@@ -43,4 +43,39 @@ class HomeController extends Controller
43 ]); 43 ]);
44 } 44 }
45 45
46 + /**
47 + * Get a js representation of the current translations
48 + * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
49 + */
50 + public function getTranslations() {
51 + $locale = trans()->getLocale();
52 + $cacheKey = 'GLOBAL_TRANSLATIONS_' . $locale;
53 + if (cache()->has($cacheKey) && config('app.env') !== 'development') {
54 + $resp = cache($cacheKey);
55 + } else {
56 + $translations = [
57 + // Get only translations which might be used in JS
58 + 'common' => trans('common'),
59 + 'components' => trans('components'),
60 + 'entities' => trans('entities'),
61 + 'errors' => trans('errors')
62 + ];
63 + if ($locale !== 'en') {
64 + $enTrans = [
65 + 'common' => trans('common', [], null, 'en'),
66 + 'components' => trans('components', [], null, 'en'),
67 + 'entities' => trans('entities', [], null, 'en'),
68 + 'errors' => trans('errors', [], null, 'en')
69 + ];
70 + $translations = array_replace_recursive($enTrans, $translations);
71 + }
72 + $resp = 'window.translations = ' . json_encode($translations);
73 + cache()->put($cacheKey, $resp, 120);
74 + }
75 +
76 + return response($resp, 200, [
77 + 'Content-Type' => 'application/javascript'
78 + ]);
79 + }
80 +
46 } 81 }
......
...@@ -73,6 +73,7 @@ class ImageController extends Controller ...@@ -73,6 +73,7 @@ class ImageController extends Controller
73 * @param $filter 73 * @param $filter
74 * @param int $page 74 * @param int $page
75 * @param Request $request 75 * @param Request $request
76 + * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Symfony\Component\HttpFoundation\Response
76 */ 77 */
77 public function getGalleryFiltered($filter, $page = 0, Request $request) 78 public function getGalleryFiltered($filter, $page = 0, Request $request)
78 { 79 {
...@@ -169,7 +170,7 @@ class ImageController extends Controller ...@@ -169,7 +170,7 @@ class ImageController extends Controller
169 } 170 }
170 171
171 $this->imageRepo->destroyImage($image); 172 $this->imageRepo->destroyImage($image);
172 - return response()->json('Image Deleted'); 173 + return response()->json(trans('components.images_deleted'));
173 } 174 }
174 175
175 176
......
...@@ -10,6 +10,7 @@ use BookStack\Http\Requests; ...@@ -10,6 +10,7 @@ use BookStack\Http\Requests;
10 use BookStack\Repos\BookRepo; 10 use BookStack\Repos\BookRepo;
11 use BookStack\Repos\ChapterRepo; 11 use BookStack\Repos\ChapterRepo;
12 use BookStack\Repos\PageRepo; 12 use BookStack\Repos\PageRepo;
13 +use Illuminate\Http\Response;
13 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 14 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
14 use Views; 15 use Views;
15 use GatherContent\Htmldiff\Htmldiff; 16 use GatherContent\Htmldiff\Htmldiff;
...@@ -62,7 +63,7 @@ class PageController extends Controller ...@@ -62,7 +63,7 @@ class PageController extends Controller
62 } 63 }
63 64
64 // Otherwise show edit view 65 // Otherwise show edit view
65 - $this->setPageTitle('Create New Page'); 66 + $this->setPageTitle(trans('entities.pages_new'));
66 return view('pages/guest-create', ['parent' => $parent]); 67 return view('pages/guest-create', ['parent' => $parent]);
67 } 68 }
68 69
...@@ -104,7 +105,7 @@ class PageController extends Controller ...@@ -104,7 +105,7 @@ class PageController extends Controller
104 $book = $this->bookRepo->getBySlug($bookSlug); 105 $book = $this->bookRepo->getBySlug($bookSlug);
105 $draft = $this->pageRepo->getById($pageId, true); 106 $draft = $this->pageRepo->getById($pageId, true);
106 $this->checkOwnablePermission('page-create', $book); 107 $this->checkOwnablePermission('page-create', $book);
107 - $this->setPageTitle('Edit Page Draft'); 108 + $this->setPageTitle(trans('entities.pages_edit_draft'));
108 109
109 $draftsEnabled = $this->signedIn; 110 $draftsEnabled = $this->signedIn;
110 return view('pages/edit', [ 111 return view('pages/edit', [
...@@ -119,6 +120,7 @@ class PageController extends Controller ...@@ -119,6 +120,7 @@ class PageController extends Controller
119 * Store a new page by changing a draft into a page. 120 * Store a new page by changing a draft into a page.
120 * @param Request $request 121 * @param Request $request
121 * @param string $bookSlug 122 * @param string $bookSlug
123 + * @param int $pageId
122 * @return Response 124 * @return Response
123 */ 125 */
124 public function store(Request $request, $bookSlug, $pageId) 126 public function store(Request $request, $bookSlug, $pageId)
...@@ -201,7 +203,7 @@ class PageController extends Controller ...@@ -201,7 +203,7 @@ class PageController extends Controller
201 $book = $this->bookRepo->getBySlug($bookSlug); 203 $book = $this->bookRepo->getBySlug($bookSlug);
202 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 204 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
203 $this->checkOwnablePermission('page-update', $page); 205 $this->checkOwnablePermission('page-update', $page);
204 - $this->setPageTitle('Editing Page ' . $page->getShortName()); 206 + $this->setPageTitle(trans('entities.pages_editing_named', ['pageName'=>$page->getShortName()]));
205 $page->isDraft = false; 207 $page->isDraft = false;
206 208
207 // Check for active editing 209 // Check for active editing
...@@ -265,7 +267,7 @@ class PageController extends Controller ...@@ -265,7 +267,7 @@ class PageController extends Controller
265 if (!$this->signedIn) { 267 if (!$this->signedIn) {
266 return response()->json([ 268 return response()->json([
267 'status' => 'error', 269 'status' => 'error',
268 - 'message' => 'Guests cannot save drafts', 270 + 'message' => trans('errors.guests_cannot_save_drafts'),
269 ], 500); 271 ], 500);
270 } 272 }
271 273
...@@ -279,7 +281,7 @@ class PageController extends Controller ...@@ -279,7 +281,7 @@ class PageController extends Controller
279 $utcUpdateTimestamp = $updateTime + Carbon::createFromTimestamp(0)->offset; 281 $utcUpdateTimestamp = $updateTime + Carbon::createFromTimestamp(0)->offset;
280 return response()->json([ 282 return response()->json([
281 'status' => 'success', 283 'status' => 'success',
282 - 'message' => 'Draft saved at ', 284 + 'message' => trans('entities.pages_edit_draft_save_at'),
283 'timestamp' => $utcUpdateTimestamp 285 'timestamp' => $utcUpdateTimestamp
284 ]); 286 ]);
285 } 287 }
...@@ -307,7 +309,7 @@ class PageController extends Controller ...@@ -307,7 +309,7 @@ class PageController extends Controller
307 $book = $this->bookRepo->getBySlug($bookSlug); 309 $book = $this->bookRepo->getBySlug($bookSlug);
308 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 310 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
309 $this->checkOwnablePermission('page-delete', $page); 311 $this->checkOwnablePermission('page-delete', $page);
310 - $this->setPageTitle('Delete Page ' . $page->getShortName()); 312 + $this->setPageTitle(trans('entities.pages_delete_named', ['pageName'=>$page->getShortName()]));
311 return view('pages/delete', ['book' => $book, 'page' => $page, 'current' => $page]); 313 return view('pages/delete', ['book' => $book, 'page' => $page, 'current' => $page]);
312 } 314 }
313 315
...@@ -324,7 +326,7 @@ class PageController extends Controller ...@@ -324,7 +326,7 @@ class PageController extends Controller
324 $book = $this->bookRepo->getBySlug($bookSlug); 326 $book = $this->bookRepo->getBySlug($bookSlug);
325 $page = $this->pageRepo->getById($pageId, true); 327 $page = $this->pageRepo->getById($pageId, true);
326 $this->checkOwnablePermission('page-update', $page); 328 $this->checkOwnablePermission('page-update', $page);
327 - $this->setPageTitle('Delete Draft Page ' . $page->getShortName()); 329 + $this->setPageTitle(trans('entities.pages_delete_draft_named', ['pageName'=>$page->getShortName()]));
328 return view('pages/delete', ['book' => $book, 'page' => $page, 'current' => $page]); 330 return view('pages/delete', ['book' => $book, 'page' => $page, 'current' => $page]);
329 } 331 }
330 332
...@@ -341,7 +343,7 @@ class PageController extends Controller ...@@ -341,7 +343,7 @@ class PageController extends Controller
341 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 343 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
342 $this->checkOwnablePermission('page-delete', $page); 344 $this->checkOwnablePermission('page-delete', $page);
343 Activity::addMessage('page_delete', $book->id, $page->name); 345 Activity::addMessage('page_delete', $book->id, $page->name);
344 - session()->flash('success', 'Page deleted'); 346 + session()->flash('success', trans('entities.pages_delete_success'));
345 $this->pageRepo->destroy($page); 347 $this->pageRepo->destroy($page);
346 return redirect($book->getUrl()); 348 return redirect($book->getUrl());
347 } 349 }
...@@ -358,7 +360,7 @@ class PageController extends Controller ...@@ -358,7 +360,7 @@ class PageController extends Controller
358 $book = $this->bookRepo->getBySlug($bookSlug); 360 $book = $this->bookRepo->getBySlug($bookSlug);
359 $page = $this->pageRepo->getById($pageId, true); 361 $page = $this->pageRepo->getById($pageId, true);
360 $this->checkOwnablePermission('page-update', $page); 362 $this->checkOwnablePermission('page-update', $page);
361 - session()->flash('success', 'Draft deleted'); 363 + session()->flash('success', trans('entities.pages_delete_draft_success'));
362 $this->pageRepo->destroy($page); 364 $this->pageRepo->destroy($page);
363 return redirect($book->getUrl()); 365 return redirect($book->getUrl());
364 } 366 }
...@@ -373,7 +375,7 @@ class PageController extends Controller ...@@ -373,7 +375,7 @@ class PageController extends Controller
373 { 375 {
374 $book = $this->bookRepo->getBySlug($bookSlug); 376 $book = $this->bookRepo->getBySlug($bookSlug);
375 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 377 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
376 - $this->setPageTitle('Revisions For ' . $page->getShortName()); 378 + $this->setPageTitle(trans('entities.pages_revisions_named', ['pageName'=>$page->getShortName()]));
377 return view('pages/revisions', ['page' => $page, 'book' => $book, 'current' => $page]); 379 return view('pages/revisions', ['page' => $page, 'book' => $book, 'current' => $page]);
378 } 380 }
379 381
...@@ -391,7 +393,7 @@ class PageController extends Controller ...@@ -391,7 +393,7 @@ class PageController extends Controller
391 $revision = $this->pageRepo->getRevisionById($revisionId); 393 $revision = $this->pageRepo->getRevisionById($revisionId);
392 394
393 $page->fill($revision->toArray()); 395 $page->fill($revision->toArray());
394 - $this->setPageTitle('Page Revision For ' . $page->getShortName()); 396 + $this->setPageTitle(trans('entities.pages_revision_named', ['pageName'=>$page->getShortName()]));
395 397
396 return view('pages/revision', [ 398 return view('pages/revision', [
397 'page' => $page, 399 'page' => $page,
...@@ -417,7 +419,7 @@ class PageController extends Controller ...@@ -417,7 +419,7 @@ class PageController extends Controller
417 $diff = (new Htmldiff)->diff($prevContent, $revision->html); 419 $diff = (new Htmldiff)->diff($prevContent, $revision->html);
418 420
419 $page->fill($revision->toArray()); 421 $page->fill($revision->toArray());
420 - $this->setPageTitle('Page Revision For ' . $page->getShortName()); 422 + $this->setPageTitle(trans('entities.pages_revision_named', ['pageName'=>$page->getShortName()]));
421 423
422 return view('pages/revision', [ 424 return view('pages/revision', [
423 'page' => $page, 425 'page' => $page,
...@@ -503,7 +505,7 @@ class PageController extends Controller ...@@ -503,7 +505,7 @@ class PageController extends Controller
503 { 505 {
504 $pages = $this->pageRepo->getRecentlyCreatedPaginated(20)->setPath(baseUrl('/pages/recently-created')); 506 $pages = $this->pageRepo->getRecentlyCreatedPaginated(20)->setPath(baseUrl('/pages/recently-created'));
505 return view('pages/detailed-listing', [ 507 return view('pages/detailed-listing', [
506 - 'title' => 'Recently Created Pages', 508 + 'title' => trans('entities.recently_created_pages'),
507 'pages' => $pages 509 'pages' => $pages
508 ]); 510 ]);
509 } 511 }
...@@ -516,7 +518,7 @@ class PageController extends Controller ...@@ -516,7 +518,7 @@ class PageController extends Controller
516 { 518 {
517 $pages = $this->pageRepo->getRecentlyUpdatedPaginated(20)->setPath(baseUrl('/pages/recently-updated')); 519 $pages = $this->pageRepo->getRecentlyUpdatedPaginated(20)->setPath(baseUrl('/pages/recently-updated'));
518 return view('pages/detailed-listing', [ 520 return view('pages/detailed-listing', [
519 - 'title' => 'Recently Updated Pages', 521 + 'title' => trans('entities.recently_updated_pages'),
520 'pages' => $pages 522 'pages' => $pages
521 ]); 523 ]);
522 } 524 }
...@@ -589,13 +591,13 @@ class PageController extends Controller ...@@ -589,13 +591,13 @@ class PageController extends Controller
589 } 591 }
590 592
591 if ($parent === false || $parent === null) { 593 if ($parent === false || $parent === null) {
592 - session()->flash('The selected Book or Chapter was not found'); 594 + session()->flash(trans('entities.selected_book_chapter_not_found'));
593 return redirect()->back(); 595 return redirect()->back();
594 } 596 }
595 597
596 $this->pageRepo->changePageParent($page, $parent); 598 $this->pageRepo->changePageParent($page, $parent);
597 Activity::add($page, 'page_move', $page->book->id); 599 Activity::add($page, 'page_move', $page->book->id);
598 - session()->flash('success', sprintf('Page moved to "%s"', $parent->name)); 600 + session()->flash('success', trans('entities.pages_move_success', ['parentName' => $parent->name]));
599 601
600 return redirect($page->getUrl()); 602 return redirect($page->getUrl());
601 } 603 }
...@@ -613,7 +615,7 @@ class PageController extends Controller ...@@ -613,7 +615,7 @@ class PageController extends Controller
613 $page = $this->pageRepo->getBySlug($pageSlug, $book->id); 615 $page = $this->pageRepo->getBySlug($pageSlug, $book->id);
614 $this->checkOwnablePermission('restrictions-manage', $page); 616 $this->checkOwnablePermission('restrictions-manage', $page);
615 $this->pageRepo->updateEntityPermissionsFromRequest($request, $page); 617 $this->pageRepo->updateEntityPermissionsFromRequest($request, $page);
616 - session()->flash('success', 'Page Permissions Updated'); 618 + session()->flash('success', trans('entities.pages_permissions_success'));
617 return redirect($page->getUrl()); 619 return redirect($page->getUrl());
618 } 620 }
619 621
......
...@@ -2,9 +2,7 @@ ...@@ -2,9 +2,7 @@
2 2
3 use BookStack\Exceptions\PermissionsException; 3 use BookStack\Exceptions\PermissionsException;
4 use BookStack\Repos\PermissionsRepo; 4 use BookStack\Repos\PermissionsRepo;
5 -use BookStack\Services\PermissionService;
6 use Illuminate\Http\Request; 5 use Illuminate\Http\Request;
7 -use BookStack\Http\Requests;
8 6
9 class PermissionController extends Controller 7 class PermissionController extends Controller
10 { 8 {
...@@ -55,7 +53,7 @@ class PermissionController extends Controller ...@@ -55,7 +53,7 @@ class PermissionController extends Controller
55 ]); 53 ]);
56 54
57 $this->permissionsRepo->saveNewRole($request->all()); 55 $this->permissionsRepo->saveNewRole($request->all());
58 - session()->flash('success', 'Role successfully created'); 56 + session()->flash('success', trans('settings.role_create_success'));
59 return redirect('/settings/roles'); 57 return redirect('/settings/roles');
60 } 58 }
61 59
...@@ -69,7 +67,7 @@ class PermissionController extends Controller ...@@ -69,7 +67,7 @@ class PermissionController extends Controller
69 { 67 {
70 $this->checkPermission('user-roles-manage'); 68 $this->checkPermission('user-roles-manage');
71 $role = $this->permissionsRepo->getRoleById($id); 69 $role = $this->permissionsRepo->getRoleById($id);
72 - if ($role->hidden) throw new PermissionsException('This role cannot be edited'); 70 + if ($role->hidden) throw new PermissionsException(trans('errors.role_cannot_be_edited'));
73 return view('settings/roles/edit', ['role' => $role]); 71 return view('settings/roles/edit', ['role' => $role]);
74 } 72 }
75 73
...@@ -88,7 +86,7 @@ class PermissionController extends Controller ...@@ -88,7 +86,7 @@ class PermissionController extends Controller
88 ]); 86 ]);
89 87
90 $this->permissionsRepo->updateRole($id, $request->all()); 88 $this->permissionsRepo->updateRole($id, $request->all());
91 - session()->flash('success', 'Role successfully updated'); 89 + session()->flash('success', trans('settings.role_update_success'));
92 return redirect('/settings/roles'); 90 return redirect('/settings/roles');
93 } 91 }
94 92
...@@ -103,7 +101,7 @@ class PermissionController extends Controller ...@@ -103,7 +101,7 @@ class PermissionController extends Controller
103 $this->checkPermission('user-roles-manage'); 101 $this->checkPermission('user-roles-manage');
104 $role = $this->permissionsRepo->getRoleById($id); 102 $role = $this->permissionsRepo->getRoleById($id);
105 $roles = $this->permissionsRepo->getAllRolesExcept($role); 103 $roles = $this->permissionsRepo->getAllRolesExcept($role);
106 - $blankRole = $role->newInstance(['display_name' => 'Don\'t migrate users']); 104 + $blankRole = $role->newInstance(['display_name' => trans('settings.role_delete_no_migration')]);
107 $roles->prepend($blankRole); 105 $roles->prepend($blankRole);
108 return view('settings/roles/delete', ['role' => $role, 'roles' => $roles]); 106 return view('settings/roles/delete', ['role' => $role, 'roles' => $roles]);
109 } 107 }
...@@ -126,7 +124,7 @@ class PermissionController extends Controller ...@@ -126,7 +124,7 @@ class PermissionController extends Controller
126 return redirect()->back(); 124 return redirect()->back();
127 } 125 }
128 126
129 - session()->flash('success', 'Role successfully deleted'); 127 + session()->flash('success', trans('settings.role_delete_success'));
130 return redirect('/settings/roles'); 128 return redirect('/settings/roles');
131 } 129 }
132 } 130 }
......
1 -<?php 1 +<?php namespace BookStack\Http\Controllers;
2 -
3 -namespace BookStack\Http\Controllers;
4 2
5 use BookStack\Services\ViewService; 3 use BookStack\Services\ViewService;
6 use Illuminate\Http\Request; 4 use Illuminate\Http\Request;
7 -
8 -use BookStack\Http\Requests;
9 use BookStack\Repos\BookRepo; 5 use BookStack\Repos\BookRepo;
10 use BookStack\Repos\ChapterRepo; 6 use BookStack\Repos\ChapterRepo;
11 use BookStack\Repos\PageRepo; 7 use BookStack\Repos\PageRepo;
...@@ -49,7 +45,7 @@ class SearchController extends Controller ...@@ -49,7 +45,7 @@ class SearchController extends Controller
49 $pages = $this->pageRepo->getBySearch($searchTerm, [], 20, $paginationAppends); 45 $pages = $this->pageRepo->getBySearch($searchTerm, [], 20, $paginationAppends);
50 $books = $this->bookRepo->getBySearch($searchTerm, 10, $paginationAppends); 46 $books = $this->bookRepo->getBySearch($searchTerm, 10, $paginationAppends);
51 $chapters = $this->chapterRepo->getBySearch($searchTerm, [], 10, $paginationAppends); 47 $chapters = $this->chapterRepo->getBySearch($searchTerm, [], 10, $paginationAppends);
52 - $this->setPageTitle('Search For ' . $searchTerm); 48 + $this->setPageTitle(trans('entities.search_for_term', ['term' => $searchTerm]));
53 return view('search/all', [ 49 return view('search/all', [
54 'pages' => $pages, 50 'pages' => $pages,
55 'books' => $books, 51 'books' => $books,
...@@ -70,10 +66,10 @@ class SearchController extends Controller ...@@ -70,10 +66,10 @@ class SearchController extends Controller
70 $searchTerm = $request->get('term'); 66 $searchTerm = $request->get('term');
71 $paginationAppends = $request->only('term'); 67 $paginationAppends = $request->only('term');
72 $pages = $this->pageRepo->getBySearch($searchTerm, [], 20, $paginationAppends); 68 $pages = $this->pageRepo->getBySearch($searchTerm, [], 20, $paginationAppends);
73 - $this->setPageTitle('Page Search For ' . $searchTerm); 69 + $this->setPageTitle(trans('entities.search_page_for_term', ['term' => $searchTerm]));
74 return view('search/entity-search-list', [ 70 return view('search/entity-search-list', [
75 'entities' => $pages, 71 'entities' => $pages,
76 - 'title' => 'Page Search Results', 72 + 'title' => trans('entities.search_results_page'),
77 'searchTerm' => $searchTerm 73 'searchTerm' => $searchTerm
78 ]); 74 ]);
79 } 75 }
...@@ -90,10 +86,10 @@ class SearchController extends Controller ...@@ -90,10 +86,10 @@ class SearchController extends Controller
90 $searchTerm = $request->get('term'); 86 $searchTerm = $request->get('term');
91 $paginationAppends = $request->only('term'); 87 $paginationAppends = $request->only('term');
92 $chapters = $this->chapterRepo->getBySearch($searchTerm, [], 20, $paginationAppends); 88 $chapters = $this->chapterRepo->getBySearch($searchTerm, [], 20, $paginationAppends);
93 - $this->setPageTitle('Chapter Search For ' . $searchTerm); 89 + $this->setPageTitle(trans('entities.search_chapter_for_term', ['term' => $searchTerm]));
94 return view('search/entity-search-list', [ 90 return view('search/entity-search-list', [
95 'entities' => $chapters, 91 'entities' => $chapters,
96 - 'title' => 'Chapter Search Results', 92 + 'title' => trans('entities.search_results_chapter'),
97 'searchTerm' => $searchTerm 93 'searchTerm' => $searchTerm
98 ]); 94 ]);
99 } 95 }
...@@ -110,10 +106,10 @@ class SearchController extends Controller ...@@ -110,10 +106,10 @@ class SearchController extends Controller
110 $searchTerm = $request->get('term'); 106 $searchTerm = $request->get('term');
111 $paginationAppends = $request->only('term'); 107 $paginationAppends = $request->only('term');
112 $books = $this->bookRepo->getBySearch($searchTerm, 20, $paginationAppends); 108 $books = $this->bookRepo->getBySearch($searchTerm, 20, $paginationAppends);
113 - $this->setPageTitle('Book Search For ' . $searchTerm); 109 + $this->setPageTitle(trans('entities.search_book_for_term', ['term' => $searchTerm]));
114 return view('search/entity-search-list', [ 110 return view('search/entity-search-list', [
115 'entities' => $books, 111 'entities' => $books,
116 - 'title' => 'Book Search Results', 112 + 'title' => trans('entities.search_results_book'),
117 'searchTerm' => $searchTerm 113 'searchTerm' => $searchTerm
118 ]); 114 ]);
119 } 115 }
......
1 <?php namespace BookStack\Http\Controllers; 1 <?php namespace BookStack\Http\Controllers;
2 2
3 use Illuminate\Http\Request; 3 use Illuminate\Http\Request;
4 - 4 +use Illuminate\Http\Response;
5 -use BookStack\Http\Requests;
6 use Setting; 5 use Setting;
7 6
8 class SettingController extends Controller 7 class SettingController extends Controller
...@@ -39,7 +38,7 @@ class SettingController extends Controller ...@@ -39,7 +38,7 @@ class SettingController extends Controller
39 Setting::put($key, $value); 38 Setting::put($key, $value);
40 } 39 }
41 40
42 - session()->flash('success', 'Settings Saved'); 41 + session()->flash('success', trans('settings.settings_save_success'));
43 return redirect('/settings'); 42 return redirect('/settings');
44 } 43 }
45 44
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
2 2
3 use BookStack\Repos\TagRepo; 3 use BookStack\Repos\TagRepo;
4 use Illuminate\Http\Request; 4 use Illuminate\Http\Request;
5 -use BookStack\Http\Requests;
6 5
7 class TagController extends Controller 6 class TagController extends Controller
8 { 7 {
...@@ -16,12 +15,14 @@ class TagController extends Controller ...@@ -16,12 +15,14 @@ class TagController extends Controller
16 public function __construct(TagRepo $tagRepo) 15 public function __construct(TagRepo $tagRepo)
17 { 16 {
18 $this->tagRepo = $tagRepo; 17 $this->tagRepo = $tagRepo;
18 + parent::__construct();
19 } 19 }
20 20
21 /** 21 /**
22 * Get all the Tags for a particular entity 22 * Get all the Tags for a particular entity
23 * @param $entityType 23 * @param $entityType
24 * @param $entityId 24 * @param $entityId
25 + * @return \Illuminate\Http\JsonResponse
25 */ 26 */
26 public function getForEntity($entityType, $entityId) 27 public function getForEntity($entityType, $entityId)
27 { 28 {
...@@ -30,28 +31,9 @@ class TagController extends Controller ...@@ -30,28 +31,9 @@ class TagController extends Controller
30 } 31 }
31 32
32 /** 33 /**
33 - * Update the tags for a particular entity.
34 - * @param $entityType
35 - * @param $entityId
36 - * @param Request $request
37 - * @return mixed
38 - */
39 - public function updateForEntity($entityType, $entityId, Request $request)
40 - {
41 - $entity = $this->tagRepo->getEntity($entityType, $entityId, 'update');
42 - if ($entity === null) return $this->jsonError("Entity not found", 404);
43 -
44 - $inputTags = $request->input('tags');
45 - $tags = $this->tagRepo->saveTagsToEntity($entity, $inputTags);
46 - return response()->json([
47 - 'tags' => $tags,
48 - 'message' => 'Tags successfully updated'
49 - ]);
50 - }
51 -
52 - /**
53 * Get tag name suggestions from a given search term. 34 * Get tag name suggestions from a given search term.
54 * @param Request $request 35 * @param Request $request
36 + * @return \Illuminate\Http\JsonResponse
55 */ 37 */
56 public function getNameSuggestions(Request $request) 38 public function getNameSuggestions(Request $request)
57 { 39 {
...@@ -63,6 +45,7 @@ class TagController extends Controller ...@@ -63,6 +45,7 @@ class TagController extends Controller
63 /** 45 /**
64 * Get tag value suggestions from a given search term. 46 * Get tag value suggestions from a given search term.
65 * @param Request $request 47 * @param Request $request
48 + * @return \Illuminate\Http\JsonResponse
66 */ 49 */
67 public function getValueSuggestions(Request $request) 50 public function getValueSuggestions(Request $request)
68 { 51 {
......
...@@ -44,7 +44,7 @@ class UserController extends Controller ...@@ -44,7 +44,7 @@ class UserController extends Controller
44 'sort' => $request->has('sort') ? $request->get('sort') : 'name', 44 'sort' => $request->has('sort') ? $request->get('sort') : 'name',
45 ]; 45 ];
46 $users = $this->userRepo->getAllUsersPaginatedAndSorted(20, $listDetails); 46 $users = $this->userRepo->getAllUsersPaginatedAndSorted(20, $listDetails);
47 - $this->setPageTitle('Users'); 47 + $this->setPageTitle(trans('settings.users'));
48 $users->appends($listDetails); 48 $users->appends($listDetails);
49 return view('users/index', ['users' => $users, 'listDetails' => $listDetails]); 49 return view('users/index', ['users' => $users, 'listDetails' => $listDetails]);
50 } 50 }
...@@ -83,7 +83,6 @@ class UserController extends Controller ...@@ -83,7 +83,6 @@ class UserController extends Controller
83 } 83 }
84 $this->validate($request, $validationRules); 84 $this->validate($request, $validationRules);
85 85
86 -
87 $user = $this->user->fill($request->all()); 86 $user = $this->user->fill($request->all());
88 87
89 if ($authMethod === 'standard') { 88 if ($authMethod === 'standard') {
...@@ -131,7 +130,7 @@ class UserController extends Controller ...@@ -131,7 +130,7 @@ class UserController extends Controller
131 $authMethod = ($user->system_name) ? 'system' : config('auth.method'); 130 $authMethod = ($user->system_name) ? 'system' : config('auth.method');
132 131
133 $activeSocialDrivers = $socialAuthService->getActiveDrivers(); 132 $activeSocialDrivers = $socialAuthService->getActiveDrivers();
134 - $this->setPageTitle('User Profile'); 133 + $this->setPageTitle(trans('settings.user_profile'));
135 $roles = $this->userRepo->getAllRoles(); 134 $roles = $this->userRepo->getAllRoles();
136 return view('users/edit', ['user' => $user, 'activeSocialDrivers' => $activeSocialDrivers, 'authMethod' => $authMethod, 'roles' => $roles]); 135 return view('users/edit', ['user' => $user, 'activeSocialDrivers' => $activeSocialDrivers, 'authMethod' => $authMethod, 'roles' => $roles]);
137 } 136 }
...@@ -154,8 +153,6 @@ class UserController extends Controller ...@@ -154,8 +153,6 @@ class UserController extends Controller
154 'email' => 'min:2|email|unique:users,email,' . $id, 153 'email' => 'min:2|email|unique:users,email,' . $id,
155 'password' => 'min:5|required_with:password_confirm', 154 'password' => 'min:5|required_with:password_confirm',
156 'password-confirm' => 'same:password|required_with:password' 155 'password-confirm' => 'same:password|required_with:password'
157 - ], [
158 - 'password-confirm.required_with' => 'Password confirmation required'
159 ]); 156 ]);
160 157
161 $user = $this->user->findOrFail($id); 158 $user = $this->user->findOrFail($id);
...@@ -179,7 +176,7 @@ class UserController extends Controller ...@@ -179,7 +176,7 @@ class UserController extends Controller
179 } 176 }
180 177
181 $user->save(); 178 $user->save();
182 - session()->flash('success', 'User successfully updated'); 179 + session()->flash('success', trans('settings.users_edit_success'));
183 180
184 $redirectUrl = userCan('users-manage') ? '/settings/users' : '/settings/users/' . $user->id; 181 $redirectUrl = userCan('users-manage') ? '/settings/users' : '/settings/users/' . $user->id;
185 return redirect($redirectUrl); 182 return redirect($redirectUrl);
...@@ -197,7 +194,7 @@ class UserController extends Controller ...@@ -197,7 +194,7 @@ class UserController extends Controller
197 }); 194 });
198 195
199 $user = $this->user->findOrFail($id); 196 $user = $this->user->findOrFail($id);
200 - $this->setPageTitle('Delete User ' . $user->name); 197 + $this->setPageTitle(trans('settings.users_delete_named', ['userName' => $user->name]));
201 return view('users/delete', ['user' => $user]); 198 return view('users/delete', ['user' => $user]);
202 } 199 }
203 200
...@@ -216,17 +213,17 @@ class UserController extends Controller ...@@ -216,17 +213,17 @@ class UserController extends Controller
216 $user = $this->userRepo->getById($id); 213 $user = $this->userRepo->getById($id);
217 214
218 if ($this->userRepo->isOnlyAdmin($user)) { 215 if ($this->userRepo->isOnlyAdmin($user)) {
219 - session()->flash('error', 'You cannot delete the only admin'); 216 + session()->flash('error', trans('errors.users_cannot_delete_only_admin'));
220 return redirect($user->getEditUrl()); 217 return redirect($user->getEditUrl());
221 } 218 }
222 219
223 if ($user->system_name === 'public') { 220 if ($user->system_name === 'public') {
224 - session()->flash('error', 'You cannot delete the guest user'); 221 + session()->flash('error', trans('errors.users_cannot_delete_guest'));
225 return redirect($user->getEditUrl()); 222 return redirect($user->getEditUrl());
226 } 223 }
227 224
228 $this->userRepo->destroy($user); 225 $this->userRepo->destroy($user);
229 - session()->flash('success', 'User successfully removed'); 226 + session()->flash('success', trans('settings.users_delete_success'));
230 227
231 return redirect('/settings/users'); 228 return redirect('/settings/users');
232 } 229 }
......
...@@ -43,8 +43,9 @@ class ResetPassword extends Notification ...@@ -43,8 +43,9 @@ class ResetPassword extends Notification
43 public function toMail() 43 public function toMail()
44 { 44 {
45 return (new MailMessage) 45 return (new MailMessage)
46 - ->line('You are receiving this email because we received a password reset request for your account.') 46 + ->subject(trans('auth.email_reset_subject', ['appName' => setting('app-name')]))
47 - ->action('Reset Password', baseUrl('password/reset/' . $this->token)) 47 + ->line(trans('auth.email_reset_text'))
48 - ->line('If you did not request a password reset, no further action is required.'); 48 + ->action(trans('auth.reset_password'), baseUrl('password/reset/' . $this->token))
49 + ->line(trans('auth.email_reset_not_requested'));
49 } 50 }
50 } 51 }
......
...@@ -109,7 +109,7 @@ class BookRepo extends EntityRepo ...@@ -109,7 +109,7 @@ class BookRepo extends EntityRepo
109 public function getBySlug($slug) 109 public function getBySlug($slug)
110 { 110 {
111 $book = $this->bookQuery()->where('slug', '=', $slug)->first(); 111 $book = $this->bookQuery()->where('slug', '=', $slug)->first();
112 - if ($book === null) throw new NotFoundException('Book not found'); 112 + if ($book === null) throw new NotFoundException(trans('errors.book_not_found'));
113 return $book; 113 return $book;
114 } 114 }
115 115
......
...@@ -69,7 +69,7 @@ class ChapterRepo extends EntityRepo ...@@ -69,7 +69,7 @@ class ChapterRepo extends EntityRepo
69 public function getBySlug($slug, $bookId) 69 public function getBySlug($slug, $bookId)
70 { 70 {
71 $chapter = $this->chapterQuery()->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first(); 71 $chapter = $this->chapterQuery()->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
72 - if ($chapter === null) throw new NotFoundException('Chapter not found'); 72 + if ($chapter === null) throw new NotFoundException(trans('errors.chapter_not_found'));
73 return $chapter; 73 return $chapter;
74 } 74 }
75 75
......
...@@ -66,7 +66,7 @@ class PageRepo extends EntityRepo ...@@ -66,7 +66,7 @@ class PageRepo extends EntityRepo
66 public function getBySlug($slug, $bookId) 66 public function getBySlug($slug, $bookId)
67 { 67 {
68 $page = $this->pageQuery()->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first(); 68 $page = $this->pageQuery()->where('slug', '=', $slug)->where('book_id', '=', $bookId)->first();
69 - if ($page === null) throw new NotFoundException('Page not found'); 69 + if ($page === null) throw new NotFoundException(trans('errors.page_not_found'));
70 return $page; 70 return $page;
71 } 71 }
72 72
...@@ -134,7 +134,7 @@ class PageRepo extends EntityRepo ...@@ -134,7 +134,7 @@ class PageRepo extends EntityRepo
134 $draftPage->draft = false; 134 $draftPage->draft = false;
135 135
136 $draftPage->save(); 136 $draftPage->save();
137 - $this->saveRevision($draftPage, 'Initial Publish'); 137 + $this->saveRevision($draftPage, trans('entities.pages_initial_revision'));
138 138
139 return $draftPage; 139 return $draftPage;
140 } 140 }
...@@ -143,12 +143,12 @@ class PageRepo extends EntityRepo ...@@ -143,12 +143,12 @@ class PageRepo extends EntityRepo
143 * Get a new draft page instance. 143 * Get a new draft page instance.
144 * @param Book $book 144 * @param Book $book
145 * @param Chapter|bool $chapter 145 * @param Chapter|bool $chapter
146 - * @return static 146 + * @return Page
147 */ 147 */
148 public function getDraftPage(Book $book, $chapter = false) 148 public function getDraftPage(Book $book, $chapter = false)
149 { 149 {
150 $page = $this->page->newInstance(); 150 $page = $this->page->newInstance();
151 - $page->name = 'New Page'; 151 + $page->name = trans('entities.pages_initial_name');
152 $page->created_by = user()->id; 152 $page->created_by = user()->id;
153 $page->updated_by = user()->id; 153 $page->updated_by = user()->id;
154 $page->draft = true; 154 $page->draft = true;
...@@ -487,11 +487,9 @@ class PageRepo extends EntityRepo ...@@ -487,11 +487,9 @@ class PageRepo extends EntityRepo
487 */ 487 */
488 public function getUserPageDraftMessage(PageRevision $draft) 488 public function getUserPageDraftMessage(PageRevision $draft)
489 { 489 {
490 - $message = 'You are currently editing a draft that was last saved ' . $draft->updated_at->diffForHumans() . '.'; 490 + $message = trans('entities.pages_editing_draft_notification', ['timeDiff' => $draft->updated_at->diffForHumans()]);
491 - if ($draft->page->updated_at->timestamp > $draft->updated_at->timestamp) { 491 + if ($draft->page->updated_at->timestamp <= $draft->updated_at->timestamp) return $message;
492 - $message .= "\n This page has been updated by since that time. It is recommended that you discard this draft."; 492 + return $message . "\n" . trans('entities.pages_draft_edited_notification');
493 - }
494 - return $message;
495 } 493 }
496 494
497 /** 495 /**
...@@ -519,10 +517,10 @@ class PageRepo extends EntityRepo ...@@ -519,10 +517,10 @@ class PageRepo extends EntityRepo
519 public function getPageEditingActiveMessage(Page $page, $minRange = null) 517 public function getPageEditingActiveMessage(Page $page, $minRange = null)
520 { 518 {
521 $pageDraftEdits = $this->activePageEditingQuery($page, $minRange)->get(); 519 $pageDraftEdits = $this->activePageEditingQuery($page, $minRange)->get();
522 - $userMessage = $pageDraftEdits->count() > 1 ? $pageDraftEdits->count() . ' users have' : $pageDraftEdits->first()->createdBy->name . ' has'; 520 +
523 - $timeMessage = $minRange === null ? 'since the page was last updated' : 'in the last ' . $minRange . ' minutes'; 521 + $userMessage = $pageDraftEdits->count() > 1 ? trans('entities.pages_draft_edit_active.start_a', ['count' => $pageDraftEdits->count()]): trans('entities.pages_draft_edit_active.start_b', ['userName' => $pageDraftEdits->first()->createdBy->name]);
524 - $message = '%s started editing this page %s. Take care not to overwrite each other\'s updates!'; 522 + $timeMessage = $minRange === null ? trans('entities.pages_draft_edit_active.time_a') : trans('entities.pages_draft_edit_active.time_b', ['minCount'=>$minRange]);
525 - return sprintf($message, $userMessage, $timeMessage); 523 + return trans('entities.pages_draft_edit_active.message', ['start' => $userMessage, 'time' => $timeMessage]);
526 } 524 }
527 525
528 /** 526 /**
......
...@@ -133,9 +133,9 @@ class PermissionsRepo ...@@ -133,9 +133,9 @@ class PermissionsRepo
133 133
134 // Prevent deleting admin role or default registration role. 134 // Prevent deleting admin role or default registration role.
135 if ($role->system_name && in_array($role->system_name, $this->systemRoles)) { 135 if ($role->system_name && in_array($role->system_name, $this->systemRoles)) {
136 - throw new PermissionsException('This role is a system role and cannot be deleted'); 136 + throw new PermissionsException(trans('errors.role_system_cannot_be_deleted'));
137 } else if ($role->id == setting('registration-role')) { 137 } else if ($role->id == setting('registration-role')) {
138 - throw new PermissionsException('This role cannot be deleted while set as the default registration role.'); 138 + throw new PermissionsException(trans('errors.role_registration_default_cannot_delete'));
139 } 139 }
140 140
141 if ($migrateRoleId) { 141 if ($migrateRoleId) {
......
...@@ -121,7 +121,7 @@ class TagRepo ...@@ -121,7 +121,7 @@ class TagRepo
121 /** 121 /**
122 * Create a new Tag instance from user input. 122 * Create a new Tag instance from user input.
123 * @param $input 123 * @param $input
124 - * @return static 124 + * @return Tag
125 */ 125 */
126 protected function newInstanceFromInput($input) 126 protected function newInstanceFromInput($input)
127 { 127 {
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
3 use BookStack\Role; 3 use BookStack\Role;
4 use BookStack\User; 4 use BookStack\User;
5 use Exception; 5 use Exception;
6 -use Setting;
7 6
8 class UserRepo 7 class UserRepo
9 { 8 {
......
...@@ -193,7 +193,7 @@ class AttachmentService extends UploadService ...@@ -193,7 +193,7 @@ class AttachmentService extends UploadService
193 try { 193 try {
194 $storage->put($attachmentStoragePath, $attachmentData); 194 $storage->put($attachmentStoragePath, $attachmentData);
195 } catch (Exception $e) { 195 } catch (Exception $e) {
196 - throw new FileUploadException('File path ' . $attachmentStoragePath . ' could not be uploaded to. Ensure it is writable to the server.'); 196 + throw new FileUploadException(trans('errors.path_not_writable', ['filePath' => $attachmentStoragePath]));
197 } 197 }
198 return $attachmentPath; 198 return $attachmentPath;
199 } 199 }
......
...@@ -33,7 +33,7 @@ class EmailConfirmationService ...@@ -33,7 +33,7 @@ class EmailConfirmationService
33 public function sendConfirmation(User $user) 33 public function sendConfirmation(User $user)
34 { 34 {
35 if ($user->email_confirmed) { 35 if ($user->email_confirmed) {
36 - throw new ConfirmationEmailException('Email has already been confirmed, Try logging in.', '/login'); 36 + throw new ConfirmationEmailException(trans('errors.email_already_confirmed'), '/login');
37 } 37 }
38 38
39 $this->deleteConfirmationsByUser($user); 39 $this->deleteConfirmationsByUser($user);
...@@ -63,7 +63,7 @@ class EmailConfirmationService ...@@ -63,7 +63,7 @@ class EmailConfirmationService
63 * Gets an email confirmation by looking up the token, 63 * Gets an email confirmation by looking up the token,
64 * Ensures the token has not expired. 64 * Ensures the token has not expired.
65 * @param string $token 65 * @param string $token
66 - * @return EmailConfirmation 66 + * @return array|null|\stdClass
67 * @throws UserRegistrationException 67 * @throws UserRegistrationException
68 */ 68 */
69 public function getEmailConfirmationFromToken($token) 69 public function getEmailConfirmationFromToken($token)
...@@ -72,14 +72,14 @@ class EmailConfirmationService ...@@ -72,14 +72,14 @@ class EmailConfirmationService
72 72
73 // If not found show error 73 // If not found show error
74 if ($emailConfirmation === null) { 74 if ($emailConfirmation === null) {
75 - throw new UserRegistrationException('This confirmation token is not valid or has already been used, Please try registering again.', '/register'); 75 + throw new UserRegistrationException(trans('errors.email_confirmation_invalid'), '/register');
76 } 76 }
77 77
78 // If more than a day old 78 // If more than a day old
79 if (Carbon::now()->subDay()->gt(new Carbon($emailConfirmation->created_at))) { 79 if (Carbon::now()->subDay()->gt(new Carbon($emailConfirmation->created_at))) {
80 $user = $this->users->getById($emailConfirmation->user_id); 80 $user = $this->users->getById($emailConfirmation->user_id);
81 $this->sendConfirmation($user); 81 $this->sendConfirmation($user);
82 - throw new UserRegistrationException('The confirmation token has expired, A new confirmation email has been sent.', '/register/confirm'); 82 + throw new UserRegistrationException(trans('errors.email_confirmation_expired'), '/register/confirm');
83 } 83 }
84 84
85 $emailConfirmation->user = $this->users->getById($emailConfirmation->user_id); 85 $emailConfirmation->user = $this->users->getById($emailConfirmation->user_id);
......
...@@ -59,7 +59,7 @@ class ImageService extends UploadService ...@@ -59,7 +59,7 @@ class ImageService extends UploadService
59 { 59 {
60 $imageName = $imageName ? $imageName : basename($url); 60 $imageName = $imageName ? $imageName : basename($url);
61 $imageData = file_get_contents($url); 61 $imageData = file_get_contents($url);
62 - if($imageData === false) throw new \Exception('Cannot get image from ' . $url); 62 + if($imageData === false) throw new \Exception(trans('errors.cannot_get_image_from_url', ['url' => $url]));
63 return $this->saveNew($imageName, $imageData, $type); 63 return $this->saveNew($imageName, $imageData, $type);
64 } 64 }
65 65
...@@ -93,7 +93,7 @@ class ImageService extends UploadService ...@@ -93,7 +93,7 @@ class ImageService extends UploadService
93 $storage->put($fullPath, $imageData); 93 $storage->put($fullPath, $imageData);
94 $storage->setVisibility($fullPath, 'public'); 94 $storage->setVisibility($fullPath, 'public');
95 } catch (Exception $e) { 95 } catch (Exception $e) {
96 - throw new ImageUploadException('Image Path ' . $fullPath . ' is not writable by the server.'); 96 + throw new ImageUploadException(trans('errors.path_not_writable', ['filePath' => $fullPath]));
97 } 97 }
98 98
99 if ($this->isLocal()) $fullPath = str_replace_first('/public', '', $fullPath); 99 if ($this->isLocal()) $fullPath = str_replace_first('/public', '', $fullPath);
...@@ -160,7 +160,7 @@ class ImageService extends UploadService ...@@ -160,7 +160,7 @@ class ImageService extends UploadService
160 $thumb = $this->imageTool->make($storage->get($imagePath)); 160 $thumb = $this->imageTool->make($storage->get($imagePath));
161 } catch (Exception $e) { 161 } catch (Exception $e) {
162 if ($e instanceof \ErrorException || $e instanceof NotSupportedException) { 162 if ($e instanceof \ErrorException || $e instanceof NotSupportedException) {
163 - throw new ImageUploadException('The server cannot create thumbnails. Please check you have the GD PHP extension installed.'); 163 + throw new ImageUploadException(trans('errors.cannot_create_thumbs'));
164 } else { 164 } else {
165 throw $e; 165 throw $e;
166 } 166 }
......
...@@ -94,7 +94,7 @@ class LdapService ...@@ -94,7 +94,7 @@ class LdapService
94 $ldapBind = $this->ldap->bind($connection, $ldapDn, $ldapPass); 94 $ldapBind = $this->ldap->bind($connection, $ldapDn, $ldapPass);
95 } 95 }
96 96
97 - if (!$ldapBind) throw new LdapException('LDAP access failed using ' . ($isAnonymous ? ' anonymous bind.' : ' given dn & pass details')); 97 + if (!$ldapBind) throw new LdapException(($isAnonymous ? trans('errors.ldap_fail_anonymous') : trans('errors.ldap_fail_authed')));
98 } 98 }
99 99
100 /** 100 /**
...@@ -109,7 +109,7 @@ class LdapService ...@@ -109,7 +109,7 @@ class LdapService
109 109
110 // Check LDAP extension in installed 110 // Check LDAP extension in installed
111 if (!function_exists('ldap_connect') && config('app.env') !== 'testing') { 111 if (!function_exists('ldap_connect') && config('app.env') !== 'testing') {
112 - throw new LdapException('LDAP PHP extension not installed'); 112 + throw new LdapException(trans('errors.ldap_extension_not_installed'));
113 } 113 }
114 114
115 // Get port from server string if specified. 115 // Get port from server string if specified.
...@@ -117,7 +117,7 @@ class LdapService ...@@ -117,7 +117,7 @@ class LdapService
117 $ldapConnection = $this->ldap->connect($ldapServer[0], count($ldapServer) > 1 ? $ldapServer[1] : 389); 117 $ldapConnection = $this->ldap->connect($ldapServer[0], count($ldapServer) > 1 ? $ldapServer[1] : 389);
118 118
119 if ($ldapConnection === false) { 119 if ($ldapConnection === false) {
120 - throw new LdapException('Cannot connect to ldap server, Initial connection failed'); 120 + throw new LdapException(trans('errors.ldap_cannot_connect'));
121 } 121 }
122 122
123 // Set any required options 123 // Set any required options
......
...@@ -70,12 +70,12 @@ class SocialAuthService ...@@ -70,12 +70,12 @@ class SocialAuthService
70 70
71 // Check social account has not already been used 71 // Check social account has not already been used
72 if ($this->socialAccount->where('driver_id', '=', $socialUser->getId())->exists()) { 72 if ($this->socialAccount->where('driver_id', '=', $socialUser->getId())->exists()) {
73 - throw new UserRegistrationException('This ' . $socialDriver . ' account is already in use, Try logging in via the ' . $socialDriver . ' option.', '/login'); 73 + throw new UserRegistrationException(trans('errors.social_account_in_use', ['socialAccount'=>$socialDriver]), '/login');
74 } 74 }
75 75
76 if ($this->userRepo->getByEmail($socialUser->getEmail())) { 76 if ($this->userRepo->getByEmail($socialUser->getEmail())) {
77 $email = $socialUser->getEmail(); 77 $email = $socialUser->getEmail();
78 - throw new UserRegistrationException('The email ' . $email . ' is already in use. If you already have an account you can connect your ' . $socialDriver . ' account from your profile settings.', '/login'); 78 + throw new UserRegistrationException(trans('errors.social_account_in_use', ['socialAccount'=>$socialDriver, 'email' => $email]), '/login');
79 } 79 }
80 80
81 return $socialUser; 81 return $socialUser;
...@@ -113,27 +113,26 @@ class SocialAuthService ...@@ -113,27 +113,26 @@ class SocialAuthService
113 if ($isLoggedIn && $socialAccount === null) { 113 if ($isLoggedIn && $socialAccount === null) {
114 $this->fillSocialAccount($socialDriver, $socialUser); 114 $this->fillSocialAccount($socialDriver, $socialUser);
115 $currentUser->socialAccounts()->save($this->socialAccount); 115 $currentUser->socialAccounts()->save($this->socialAccount);
116 - session()->flash('success', title_case($socialDriver) . ' account was successfully attached to your profile.'); 116 + session()->flash('success', trans('settings.users_social_connected', ['socialAccount' => title_case($socialDriver)]));
117 return redirect($currentUser->getEditUrl()); 117 return redirect($currentUser->getEditUrl());
118 } 118 }
119 119
120 // When a user is logged in and the social account exists and is already linked to the current user. 120 // When a user is logged in and the social account exists and is already linked to the current user.
121 if ($isLoggedIn && $socialAccount !== null && $socialAccount->user->id === $currentUser->id) { 121 if ($isLoggedIn && $socialAccount !== null && $socialAccount->user->id === $currentUser->id) {
122 - session()->flash('error', 'This ' . title_case($socialDriver) . ' account is already attached to your profile.'); 122 + session()->flash('error', trans('errors.social_account_existing', ['socialAccount' => title_case($socialDriver)]));
123 return redirect($currentUser->getEditUrl()); 123 return redirect($currentUser->getEditUrl());
124 } 124 }
125 125
126 // When a user is logged in, A social account exists but the users do not match. 126 // When a user is logged in, A social account exists but the users do not match.
127 - // Change the user that the social account is assigned to.
128 if ($isLoggedIn && $socialAccount !== null && $socialAccount->user->id != $currentUser->id) { 127 if ($isLoggedIn && $socialAccount !== null && $socialAccount->user->id != $currentUser->id) {
129 - session()->flash('success', 'This ' . title_case($socialDriver) . ' account is already used by another user.'); 128 + session()->flash('error', trans('errors.social_account_already_used_existing', ['socialAccount' => title_case($socialDriver)]));
130 return redirect($currentUser->getEditUrl()); 129 return redirect($currentUser->getEditUrl());
131 } 130 }
132 131
133 // Otherwise let the user know this social account is not used by anyone. 132 // Otherwise let the user know this social account is not used by anyone.
134 - $message = 'This ' . $socialDriver . ' account is not linked to any users. Please attach it in your profile settings'; 133 + $message = trans('errors.social_account_not_used', ['socialAccount' => title_case($socialDriver)]);
135 if (setting('registration-enabled')) { 134 if (setting('registration-enabled')) {
136 - $message .= ' or, If you do not yet have an account, You can register an account using the ' . $socialDriver . ' option'; 135 + $message .= trans('errors.social_account_register_instructions', ['socialAccount' => title_case($socialDriver)]);
137 } 136 }
138 137
139 throw new SocialSignInException($message . '.', '/login'); 138 throw new SocialSignInException($message . '.', '/login');
...@@ -157,8 +156,8 @@ class SocialAuthService ...@@ -157,8 +156,8 @@ class SocialAuthService
157 { 156 {
158 $driver = trim(strtolower($socialDriver)); 157 $driver = trim(strtolower($socialDriver));
159 158
160 - if (!in_array($driver, $this->validSocialDrivers)) abort(404, 'Social Driver Not Found'); 159 + if (!in_array($driver, $this->validSocialDrivers)) abort(404, trans('errors.social_driver_not_found'));
161 - if (!$this->checkDriverConfigured($driver)) throw new SocialDriverNotConfigured("Your {$driver} social settings are not configured correctly."); 160 + if (!$this->checkDriverConfigured($driver)) throw new SocialDriverNotConfigured(trans('errors.social_driver_not_configured', ['socialAccount' => title_case($socialDriver)]));
162 161
163 return $driver; 162 return $driver;
164 } 163 }
...@@ -215,7 +214,7 @@ class SocialAuthService ...@@ -215,7 +214,7 @@ class SocialAuthService
215 { 214 {
216 session(); 215 session();
217 user()->socialAccounts()->where('driver', '=', $socialDriver)->delete(); 216 user()->socialAccounts()->where('driver', '=', $socialDriver)->delete();
218 - session()->flash('success', title_case($socialDriver) . ' account successfully detached'); 217 + session()->flash('success', trans('settings.users_social_disconnected', ['socialAccount' => title_case($socialDriver)]));
219 return redirect(user()->getEditUrl()); 218 return redirect(user()->getEditUrl());
220 } 219 }
221 220
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
6 return [ 6 return [
7 7
8 'app-name' => 'BookStack', 8 'app-name' => 'BookStack',
9 + 'app-logo' => '',
9 'app-name-header' => true, 10 'app-name-header' => true,
10 'app-editor' => 'wysiwyg', 11 'app-editor' => 'wysiwyg',
11 'app-color' => '#0288D1', 12 'app-color' => '#0288D1',
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
22 <php> 22 <php>
23 <env name="APP_ENV" value="testing"/> 23 <env name="APP_ENV" value="testing"/>
24 <env name="APP_DEBUG" value="false"/> 24 <env name="APP_DEBUG" value="false"/>
25 + <env name="APP_LANG" value="en"/>
25 <env name="CACHE_DRIVER" value="array"/> 26 <env name="CACHE_DRIVER" value="array"/>
26 <env name="SESSION_DRIVER" value="array"/> 27 <env name="SESSION_DRIVER" value="array"/>
27 <env name="QUEUE_DRIVER" value="sync"/> 28 <env name="QUEUE_DRIVER" value="sync"/>
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
2 2
3 import moment from 'moment'; 3 import moment from 'moment';
4 import 'moment/locale/en-gb'; 4 import 'moment/locale/en-gb';
5 +import editorOptions from "./pages/page-form";
6 +
5 moment.locale('en-gb'); 7 moment.locale('en-gb');
6 8
7 export default function (ngApp, events) { 9 export default function (ngApp, events) {
...@@ -23,14 +25,14 @@ export default function (ngApp, events) { ...@@ -23,14 +25,14 @@ export default function (ngApp, events) {
23 $scope.searching = false; 25 $scope.searching = false;
24 $scope.searchTerm = ''; 26 $scope.searchTerm = '';
25 27
26 - var page = 0; 28 + let page = 0;
27 - var previousClickTime = 0; 29 + let previousClickTime = 0;
28 - var previousClickImage = 0; 30 + let previousClickImage = 0;
29 - var dataLoaded = false; 31 + let dataLoaded = false;
30 - var callback = false; 32 + let callback = false;
31 33
32 - var preSearchImages = []; 34 + let preSearchImages = [];
33 - var preSearchHasMore = false; 35 + let preSearchHasMore = false;
34 36
35 /** 37 /**
36 * Used by dropzone to get the endpoint to upload to. 38 * Used by dropzone to get the endpoint to upload to.
...@@ -62,7 +64,7 @@ export default function (ngApp, events) { ...@@ -62,7 +64,7 @@ export default function (ngApp, events) {
62 $scope.$apply(() => { 64 $scope.$apply(() => {
63 $scope.images.unshift(data); 65 $scope.images.unshift(data);
64 }); 66 });
65 - events.emit('success', 'Image uploaded'); 67 + events.emit('success', trans('components.image_upload_success'));
66 }; 68 };
67 69
68 /** 70 /**
...@@ -79,9 +81,9 @@ export default function (ngApp, events) { ...@@ -79,9 +81,9 @@ export default function (ngApp, events) {
79 * @param image 81 * @param image
80 */ 82 */
81 $scope.imageSelect = function (image) { 83 $scope.imageSelect = function (image) {
82 - var dblClickTime = 300; 84 + let dblClickTime = 300;
83 - var currentTime = Date.now(); 85 + let currentTime = Date.now();
84 - var timeDiff = currentTime - previousClickTime; 86 + let timeDiff = currentTime - previousClickTime;
85 87
86 if (timeDiff < dblClickTime && image.id === previousClickImage) { 88 if (timeDiff < dblClickTime && image.id === previousClickImage) {
87 // If double click 89 // If double click
...@@ -137,22 +139,21 @@ export default function (ngApp, events) { ...@@ -137,22 +139,21 @@ export default function (ngApp, events) {
137 $('#image-manager').find('.overlay').fadeOut(240); 139 $('#image-manager').find('.overlay').fadeOut(240);
138 }; 140 };
139 141
140 - var baseUrl = window.baseUrl('/images/' + $scope.imageType + '/all/'); 142 + let baseUrl = window.baseUrl('/images/' + $scope.imageType + '/all/');
141 143
142 /** 144 /**
143 * Fetch the list image data from the server. 145 * Fetch the list image data from the server.
144 */ 146 */
145 function fetchData() { 147 function fetchData() {
146 - var url = baseUrl + page + '?'; 148 + let url = baseUrl + page + '?';
147 - var components = {}; 149 + let components = {};
148 if ($scope.uploadedTo) components['page_id'] = $scope.uploadedTo; 150 if ($scope.uploadedTo) components['page_id'] = $scope.uploadedTo;
149 if ($scope.searching) components['term'] = $scope.searchTerm; 151 if ($scope.searching) components['term'] = $scope.searchTerm;
150 152
151 153
152 - var urlQueryString = Object.keys(components).map((key) => { 154 + url += Object.keys(components).map((key) => {
153 return key + '=' + encodeURIComponent(components[key]); 155 return key + '=' + encodeURIComponent(components[key]);
154 }).join('&'); 156 }).join('&');
155 - url += urlQueryString;
156 157
157 $http.get(url).then((response) => { 158 $http.get(url).then((response) => {
158 $scope.images = $scope.images.concat(response.data.images); 159 $scope.images = $scope.images.concat(response.data.images);
...@@ -205,13 +206,13 @@ export default function (ngApp, events) { ...@@ -205,13 +206,13 @@ export default function (ngApp, events) {
205 */ 206 */
206 $scope.saveImageDetails = function (event) { 207 $scope.saveImageDetails = function (event) {
207 event.preventDefault(); 208 event.preventDefault();
208 - var url = window.baseUrl('/images/update/' + $scope.selectedImage.id); 209 + let url = window.baseUrl('/images/update/' + $scope.selectedImage.id);
209 $http.put(url, this.selectedImage).then(response => { 210 $http.put(url, this.selectedImage).then(response => {
210 - events.emit('success', 'Image details updated'); 211 + events.emit('success', trans('components.image_update_success'));
211 }, (response) => { 212 }, (response) => {
212 if (response.status === 422) { 213 if (response.status === 422) {
213 - var errors = response.data; 214 + let errors = response.data;
214 - var message = ''; 215 + let message = '';
215 Object.keys(errors).forEach((key) => { 216 Object.keys(errors).forEach((key) => {
216 message += errors[key].join('\n'); 217 message += errors[key].join('\n');
217 }); 218 });
...@@ -230,13 +231,13 @@ export default function (ngApp, events) { ...@@ -230,13 +231,13 @@ export default function (ngApp, events) {
230 */ 231 */
231 $scope.deleteImage = function (event) { 232 $scope.deleteImage = function (event) {
232 event.preventDefault(); 233 event.preventDefault();
233 - var force = $scope.dependantPages !== false; 234 + let force = $scope.dependantPages !== false;
234 - var url = window.baseUrl('/images/' + $scope.selectedImage.id); 235 + let url = window.baseUrl('/images/' + $scope.selectedImage.id);
235 if (force) url += '?force=true'; 236 if (force) url += '?force=true';
236 $http.delete(url).then((response) => { 237 $http.delete(url).then((response) => {
237 $scope.images.splice($scope.images.indexOf($scope.selectedImage), 1); 238 $scope.images.splice($scope.images.indexOf($scope.selectedImage), 1);
238 $scope.selectedImage = false; 239 $scope.selectedImage = false;
239 - events.emit('success', 'Image successfully deleted'); 240 + events.emit('success', trans('components.image_delete_success'));
240 }, (response) => { 241 }, (response) => {
241 // Pages failure 242 // Pages failure
242 if (response.status === 400) { 243 if (response.status === 400) {
...@@ -266,11 +267,11 @@ export default function (ngApp, events) { ...@@ -266,11 +267,11 @@ export default function (ngApp, events) {
266 267
267 $scope.searchBook = function (e) { 268 $scope.searchBook = function (e) {
268 e.preventDefault(); 269 e.preventDefault();
269 - var term = $scope.searchTerm; 270 + let term = $scope.searchTerm;
270 if (term.length == 0) return; 271 if (term.length == 0) return;
271 $scope.searching = true; 272 $scope.searching = true;
272 $scope.searchResults = ''; 273 $scope.searchResults = '';
273 - var searchUrl = window.baseUrl('/search/book/' + $attrs.bookId); 274 + let searchUrl = window.baseUrl('/search/book/' + $attrs.bookId);
274 searchUrl += '?term=' + encodeURIComponent(term); 275 searchUrl += '?term=' + encodeURIComponent(term);
275 $http.get(searchUrl).then((response) => { 276 $http.get(searchUrl).then((response) => {
276 $scope.searchResults = $sce.trustAsHtml(response.data); 277 $scope.searchResults = $sce.trustAsHtml(response.data);
...@@ -294,27 +295,27 @@ export default function (ngApp, events) { ...@@ -294,27 +295,27 @@ export default function (ngApp, events) {
294 ngApp.controller('PageEditController', ['$scope', '$http', '$attrs', '$interval', '$timeout', '$sce', 295 ngApp.controller('PageEditController', ['$scope', '$http', '$attrs', '$interval', '$timeout', '$sce',
295 function ($scope, $http, $attrs, $interval, $timeout, $sce) { 296 function ($scope, $http, $attrs, $interval, $timeout, $sce) {
296 297
297 - $scope.editorOptions = require('./pages/page-form'); 298 + $scope.editorOptions = editorOptions();
298 $scope.editContent = ''; 299 $scope.editContent = '';
299 $scope.draftText = ''; 300 $scope.draftText = '';
300 - var pageId = Number($attrs.pageId); 301 + let pageId = Number($attrs.pageId);
301 - var isEdit = pageId !== 0; 302 + let isEdit = pageId !== 0;
302 - var autosaveFrequency = 30; // AutoSave interval in seconds. 303 + let autosaveFrequency = 30; // AutoSave interval in seconds.
303 - var isMarkdown = $attrs.editorType === 'markdown'; 304 + let isMarkdown = $attrs.editorType === 'markdown';
304 $scope.draftsEnabled = $attrs.draftsEnabled === 'true'; 305 $scope.draftsEnabled = $attrs.draftsEnabled === 'true';
305 $scope.isUpdateDraft = Number($attrs.pageUpdateDraft) === 1; 306 $scope.isUpdateDraft = Number($attrs.pageUpdateDraft) === 1;
306 $scope.isNewPageDraft = Number($attrs.pageNewDraft) === 1; 307 $scope.isNewPageDraft = Number($attrs.pageNewDraft) === 1;
307 308
308 // Set initial header draft text 309 // Set initial header draft text
309 if ($scope.isUpdateDraft || $scope.isNewPageDraft) { 310 if ($scope.isUpdateDraft || $scope.isNewPageDraft) {
310 - $scope.draftText = 'Editing Draft' 311 + $scope.draftText = trans('entities.pages_editing_draft');
311 } else { 312 } else {
312 - $scope.draftText = 'Editing Page' 313 + $scope.draftText = trans('entities.pages_editing_page');
313 } 314 }
314 315
315 - var autoSave = false; 316 + let autoSave = false;
316 317
317 - var currentContent = { 318 + let currentContent = {
318 title: false, 319 title: false,
319 html: false 320 html: false
320 }; 321 };
...@@ -351,8 +352,8 @@ export default function (ngApp, events) { ...@@ -351,8 +352,8 @@ export default function (ngApp, events) {
351 autoSave = $interval(() => { 352 autoSave = $interval(() => {
352 // Return if manually saved recently to prevent bombarding the server 353 // Return if manually saved recently to prevent bombarding the server
353 if (Date.now() - lastSave < (1000*autosaveFrequency)/2) return; 354 if (Date.now() - lastSave < (1000*autosaveFrequency)/2) return;
354 - var newTitle = $('#name').val(); 355 + let newTitle = $('#name').val();
355 - var newHtml = $scope.editContent; 356 + let newHtml = $scope.editContent;
356 357
357 if (newTitle !== currentContent.title || newHtml !== currentContent.html) { 358 if (newTitle !== currentContent.title || newHtml !== currentContent.html) {
358 currentContent.html = newHtml; 359 currentContent.html = newHtml;
...@@ -369,7 +370,7 @@ export default function (ngApp, events) { ...@@ -369,7 +370,7 @@ export default function (ngApp, events) {
369 */ 370 */
370 function saveDraft() { 371 function saveDraft() {
371 if (!$scope.draftsEnabled) return; 372 if (!$scope.draftsEnabled) return;
372 - var data = { 373 + let data = {
373 name: $('#name').val(), 374 name: $('#name').val(),
374 html: isMarkdown ? $sce.getTrustedHtml($scope.displayContent) : $scope.editContent 375 html: isMarkdown ? $sce.getTrustedHtml($scope.displayContent) : $scope.editContent
375 }; 376 };
...@@ -379,14 +380,14 @@ export default function (ngApp, events) { ...@@ -379,14 +380,14 @@ export default function (ngApp, events) {
379 let url = window.baseUrl('/ajax/page/' + pageId + '/save-draft'); 380 let url = window.baseUrl('/ajax/page/' + pageId + '/save-draft');
380 $http.put(url, data).then(responseData => { 381 $http.put(url, data).then(responseData => {
381 draftErroring = false; 382 draftErroring = false;
382 - var updateTime = moment.utc(moment.unix(responseData.data.timestamp)).toDate(); 383 + let updateTime = moment.utc(moment.unix(responseData.data.timestamp)).toDate();
383 $scope.draftText = responseData.data.message + moment(updateTime).format('HH:mm'); 384 $scope.draftText = responseData.data.message + moment(updateTime).format('HH:mm');
384 if (!$scope.isNewPageDraft) $scope.isUpdateDraft = true; 385 if (!$scope.isNewPageDraft) $scope.isUpdateDraft = true;
385 showDraftSaveNotification(); 386 showDraftSaveNotification();
386 lastSave = Date.now(); 387 lastSave = Date.now();
387 }, errorRes => { 388 }, errorRes => {
388 if (draftErroring) return; 389 if (draftErroring) return;
389 - events.emit('error', 'Failed to save draft. Ensure you have internet connection before saving this page.') 390 + events.emit('error', trans('errors.page_draft_autosave_fail'));
390 draftErroring = true; 391 draftErroring = true;
391 }); 392 });
392 } 393 }
...@@ -419,7 +420,7 @@ export default function (ngApp, events) { ...@@ -419,7 +420,7 @@ export default function (ngApp, events) {
419 let url = window.baseUrl('/ajax/page/' + pageId); 420 let url = window.baseUrl('/ajax/page/' + pageId);
420 $http.get(url).then((responseData) => { 421 $http.get(url).then((responseData) => {
421 if (autoSave) $interval.cancel(autoSave); 422 if (autoSave) $interval.cancel(autoSave);
422 - $scope.draftText = 'Editing Page'; 423 + $scope.draftText = trans('entities.pages_editing_page');
423 $scope.isUpdateDraft = false; 424 $scope.isUpdateDraft = false;
424 $scope.$broadcast('html-update', responseData.data.html); 425 $scope.$broadcast('html-update', responseData.data.html);
425 $scope.$broadcast('markdown-update', responseData.data.markdown || responseData.data.html); 426 $scope.$broadcast('markdown-update', responseData.data.markdown || responseData.data.html);
...@@ -427,7 +428,7 @@ export default function (ngApp, events) { ...@@ -427,7 +428,7 @@ export default function (ngApp, events) {
427 $timeout(() => { 428 $timeout(() => {
428 startAutoSave(); 429 startAutoSave();
429 }, 1000); 430 }, 1000);
430 - events.emit('success', 'Draft discarded, The editor has been updated with the current page content'); 431 + events.emit('success', trans('entities.pages_draft_discarded'));
431 }); 432 });
432 }; 433 };
433 434
...@@ -506,20 +507,6 @@ export default function (ngApp, events) { ...@@ -506,20 +507,6 @@ export default function (ngApp, events) {
506 }; 507 };
507 508
508 /** 509 /**
509 - * Save the tags to the current page.
510 - */
511 - $scope.saveTags = function() {
512 - setTagOrder();
513 - let postData = {tags: $scope.tags};
514 - let url = window.baseUrl('/ajax/tags/update/page/' + pageId);
515 - $http.post(url, postData).then((responseData) => {
516 - $scope.tags = responseData.data.tags;
517 - addEmptyTag();
518 - events.emit('success', responseData.data.message);
519 - })
520 - };
521 -
522 - /**
523 * Remove a tag from the current list. 510 * Remove a tag from the current list.
524 * @param tag 511 * @param tag
525 */ 512 */
...@@ -588,7 +575,7 @@ export default function (ngApp, events) { ...@@ -588,7 +575,7 @@ export default function (ngApp, events) {
588 * Get files for the current page from the server. 575 * Get files for the current page from the server.
589 */ 576 */
590 function getFiles() { 577 function getFiles() {
591 - let url = window.baseUrl(`/attachments/get/page/${pageId}`) 578 + let url = window.baseUrl(`/attachments/get/page/${pageId}`);
592 $http.get(url).then(resp => { 579 $http.get(url).then(resp => {
593 $scope.files = resp.data; 580 $scope.files = resp.data;
594 currentOrder = resp.data.map(file => {return file.id}).join(':'); 581 currentOrder = resp.data.map(file => {return file.id}).join(':');
...@@ -606,7 +593,7 @@ export default function (ngApp, events) { ...@@ -606,7 +593,7 @@ export default function (ngApp, events) {
606 $scope.$apply(() => { 593 $scope.$apply(() => {
607 $scope.files.push(data); 594 $scope.files.push(data);
608 }); 595 });
609 - events.emit('success', 'File uploaded'); 596 + events.emit('success', trans('entities.attachments_file_uploaded'));
610 }; 597 };
611 598
612 /** 599 /**
...@@ -624,7 +611,7 @@ export default function (ngApp, events) { ...@@ -624,7 +611,7 @@ export default function (ngApp, events) {
624 data.link = ''; 611 data.link = '';
625 } 612 }
626 }); 613 });
627 - events.emit('success', 'File updated'); 614 + events.emit('success', trans('entities.attachments_file_updated'));
628 }; 615 };
629 616
630 /** 617 /**
...@@ -650,7 +637,7 @@ export default function (ngApp, events) { ...@@ -650,7 +637,7 @@ export default function (ngApp, events) {
650 file.uploaded_to = pageId; 637 file.uploaded_to = pageId;
651 $http.post(window.baseUrl('/attachments/link'), file).then(resp => { 638 $http.post(window.baseUrl('/attachments/link'), file).then(resp => {
652 $scope.files.push(resp.data); 639 $scope.files.push(resp.data);
653 - events.emit('success', 'Link attached'); 640 + events.emit('success', trans('entities.attachments_link_attached'));
654 $scope.file = getCleanFile(); 641 $scope.file = getCleanFile();
655 }, checkError('link')); 642 }, checkError('link'));
656 }; 643 };
...@@ -684,7 +671,7 @@ export default function (ngApp, events) { ...@@ -684,7 +671,7 @@ export default function (ngApp, events) {
684 $scope.editFile.link = ''; 671 $scope.editFile.link = '';
685 } 672 }
686 $scope.editFile = false; 673 $scope.editFile = false;
687 - events.emit('success', 'Attachment details updated'); 674 + events.emit('success', trans('entities.attachments_updated_success'));
688 }, checkError('edit')); 675 }, checkError('edit'));
689 }; 676 };
690 677
......
1 "use strict"; 1 "use strict";
2 -const DropZone = require('dropzone'); 2 +import DropZone from "dropzone";
3 -const markdown = require('marked'); 3 +import markdown from "marked";
4 4
5 -module.exports = function (ngApp, events) { 5 +export default function (ngApp, events) {
6 -
7 - /**
8 - * Toggle Switches
9 - * Has basic on/off functionality.
10 - * Use string values of 'true' & 'false' to dictate the current state.
11 - */
12 - ngApp.directive('toggleSwitch', function () {
13 - return {
14 - restrict: 'A',
15 - template: `
16 - <div class="toggle-switch" ng-click="switch()" ng-class="{'active': isActive}">
17 - <input type="hidden" ng-attr-name="{{name}}" ng-attr-value="{{value}}"/>
18 - <div class="switch-handle"></div>
19 - </div>
20 - `,
21 - scope: true,
22 - link: function (scope, element, attrs) {
23 - scope.name = attrs.name;
24 - scope.value = attrs.value;
25 - scope.isActive = scope.value == true && scope.value != 'false';
26 - scope.value = (scope.value == true && scope.value != 'false') ? 'true' : 'false';
27 -
28 - scope.switch = function () {
29 - scope.isActive = !scope.isActive;
30 - scope.value = scope.isActive ? 'true' : 'false';
31 - }
32 -
33 - }
34 - };
35 - });
36 6
37 /** 7 /**
38 * Common tab controls using simple jQuery functions. 8 * Common tab controls using simple jQuery functions.
...@@ -65,7 +35,7 @@ module.exports = function (ngApp, events) { ...@@ -65,7 +35,7 @@ module.exports = function (ngApp, events) {
65 }); 35 });
66 36
67 /** 37 /**
68 - * Sub form component to allow inner-form sections to act like thier own forms. 38 + * Sub form component to allow inner-form sections to act like their own forms.
69 */ 39 */
70 ngApp.directive('subForm', function() { 40 ngApp.directive('subForm', function() {
71 return { 41 return {
...@@ -80,96 +50,13 @@ module.exports = function (ngApp, events) { ...@@ -80,96 +50,13 @@ module.exports = function (ngApp, events) {
80 element.find('button[type="submit"]').click(submitEvent); 50 element.find('button[type="submit"]').click(submitEvent);
81 51
82 function submitEvent(e) { 52 function submitEvent(e) {
83 - e.preventDefault() 53 + e.preventDefault();
84 if (attrs.subForm) scope.$eval(attrs.subForm); 54 if (attrs.subForm) scope.$eval(attrs.subForm);
85 } 55 }
86 } 56 }
87 }; 57 };
88 }); 58 });
89 59
90 -
91 - /**
92 - * Image Picker
93 - * Is a simple front-end interface that connects to an ImageManager if present.
94 - */
95 - ngApp.directive('imagePicker', ['$http', 'imageManagerService', function ($http, imageManagerService) {
96 - return {
97 - restrict: 'E',
98 - template: `
99 - <div class="image-picker">
100 - <div>
101 - <img ng-if="image && image !== 'none'" ng-src="{{image}}" ng-class="{{imageClass}}" alt="Image Preview">
102 - <img ng-if="image === '' && defaultImage" ng-src="{{defaultImage}}" ng-class="{{imageClass}}" alt="Image Preview">
103 - </div>
104 - <button class="button" type="button" ng-click="showImageManager()">Select Image</button>
105 - <br>
106 -
107 - <button class="text-button" ng-click="reset()" type="button">Reset</button>
108 - <span ng-show="showRemove" class="sep">|</span>
109 - <button ng-show="showRemove" class="text-button neg" ng-click="remove()" type="button">Remove</button>
110 -
111 - <input type="hidden" ng-attr-name="{{name}}" ng-attr-id="{{name}}" ng-attr-value="{{value}}">
112 - </div>
113 - `,
114 - scope: {
115 - name: '@',
116 - resizeHeight: '@',
117 - resizeWidth: '@',
118 - resizeCrop: '@',
119 - showRemove: '=',
120 - currentImage: '@',
121 - currentId: '@',
122 - defaultImage: '@',
123 - imageClass: '@'
124 - },
125 - link: function (scope, element, attrs) {
126 - let usingIds = typeof scope.currentId !== 'undefined' || scope.currentId === 'false';
127 - scope.image = scope.currentImage;
128 - scope.value = scope.currentImage || '';
129 - if (usingIds) scope.value = scope.currentId;
130 -
131 - function setImage(imageModel, imageUrl) {
132 - scope.image = imageUrl;
133 - scope.value = usingIds ? imageModel.id : imageUrl;
134 - }
135 -
136 - scope.reset = function () {
137 - setImage({id: 0}, scope.defaultImage);
138 - };
139 -
140 - scope.remove = function () {
141 - scope.image = 'none';
142 - scope.value = 'none';
143 - };
144 -
145 - scope.showImageManager = function () {
146 - imageManagerService.show((image) => {
147 - scope.updateImageFromModel(image);
148 - });
149 - };
150 -
151 - scope.updateImageFromModel = function (model) {
152 - let isResized = scope.resizeWidth && scope.resizeHeight;
153 -
154 - if (!isResized) {
155 - scope.$apply(() => {
156 - setImage(model, model.url);
157 - });
158 - return;
159 - }
160 -
161 - let cropped = scope.resizeCrop ? 'true' : 'false';
162 - let requestString = '/images/thumb/' + model.id + '/' + scope.resizeWidth + '/' + scope.resizeHeight + '/' + cropped;
163 - requestString = window.baseUrl(requestString);
164 - $http.get(requestString).then((response) => {
165 - setImage(model, response.data.url);
166 - });
167 - };
168 -
169 - }
170 - };
171 - }]);
172 -
173 /** 60 /**
174 * DropZone 61 * DropZone
175 * Used for uploading images 62 * Used for uploading images
...@@ -179,25 +66,26 @@ module.exports = function (ngApp, events) { ...@@ -179,25 +66,26 @@ module.exports = function (ngApp, events) {
179 restrict: 'E', 66 restrict: 'E',
180 template: ` 67 template: `
181 <div class="dropzone-container"> 68 <div class="dropzone-container">
182 - <div class="dz-message">Drop files or click here to upload</div> 69 + <div class="dz-message">{{message}}</div>
183 </div> 70 </div>
184 `, 71 `,
185 scope: { 72 scope: {
186 uploadUrl: '@', 73 uploadUrl: '@',
187 eventSuccess: '=', 74 eventSuccess: '=',
188 eventError: '=', 75 eventError: '=',
189 - uploadedTo: '@' 76 + uploadedTo: '@',
190 }, 77 },
191 link: function (scope, element, attrs) { 78 link: function (scope, element, attrs) {
79 + scope.message = attrs.message;
192 if (attrs.placeholder) element[0].querySelector('.dz-message').textContent = attrs.placeholder; 80 if (attrs.placeholder) element[0].querySelector('.dz-message').textContent = attrs.placeholder;
193 - var dropZone = new DropZone(element[0].querySelector('.dropzone-container'), { 81 + let dropZone = new DropZone(element[0].querySelector('.dropzone-container'), {
194 url: scope.uploadUrl, 82 url: scope.uploadUrl,
195 init: function () { 83 init: function () {
196 - var dz = this; 84 + let dz = this;
197 dz.on('sending', function (file, xhr, data) { 85 dz.on('sending', function (file, xhr, data) {
198 - var token = window.document.querySelector('meta[name=token]').getAttribute('content'); 86 + let token = window.document.querySelector('meta[name=token]').getAttribute('content');
199 data.append('_token', token); 87 data.append('_token', token);
200 - var uploadedTo = typeof scope.uploadedTo === 'undefined' ? 0 : scope.uploadedTo; 88 + let uploadedTo = typeof scope.uploadedTo === 'undefined' ? 0 : scope.uploadedTo;
201 data.append('uploaded_to', uploadedTo); 89 data.append('uploaded_to', uploadedTo);
202 }); 90 });
203 if (typeof scope.eventSuccess !== 'undefined') dz.on('success', scope.eventSuccess); 91 if (typeof scope.eventSuccess !== 'undefined') dz.on('success', scope.eventSuccess);
...@@ -214,7 +102,7 @@ module.exports = function (ngApp, events) { ...@@ -214,7 +102,7 @@ module.exports = function (ngApp, events) {
214 $(file.previewElement).find('[data-dz-errormessage]').text(message); 102 $(file.previewElement).find('[data-dz-errormessage]').text(message);
215 } 103 }
216 104
217 - if (xhr.status === 413) setMessage('The server does not allow uploads of this size. Please try a smaller file.'); 105 + if (xhr.status === 413) setMessage(trans('errors.server_upload_limit'));
218 if (errorMessage.file) setMessage(errorMessage.file[0]); 106 if (errorMessage.file) setMessage(errorMessage.file[0]);
219 107
220 }); 108 });
...@@ -273,7 +161,7 @@ module.exports = function (ngApp, events) { ...@@ -273,7 +161,7 @@ module.exports = function (ngApp, events) {
273 161
274 function tinyMceSetup(editor) { 162 function tinyMceSetup(editor) {
275 editor.on('ExecCommand change NodeChange ObjectResized', (e) => { 163 editor.on('ExecCommand change NodeChange ObjectResized', (e) => {
276 - var content = editor.getContent(); 164 + let content = editor.getContent();
277 $timeout(() => { 165 $timeout(() => {
278 scope.mceModel = content; 166 scope.mceModel = content;
279 }); 167 });
...@@ -301,9 +189,9 @@ module.exports = function (ngApp, events) { ...@@ -301,9 +189,9 @@ module.exports = function (ngApp, events) {
301 // Custom tinyMCE plugins 189 // Custom tinyMCE plugins
302 tinymce.PluginManager.add('customhr', function (editor) { 190 tinymce.PluginManager.add('customhr', function (editor) {
303 editor.addCommand('InsertHorizontalRule', function () { 191 editor.addCommand('InsertHorizontalRule', function () {
304 - var hrElem = document.createElement('hr'); 192 + let hrElem = document.createElement('hr');
305 - var cNode = editor.selection.getNode(); 193 + let cNode = editor.selection.getNode();
306 - var parentNode = cNode.parentNode; 194 + let parentNode = cNode.parentNode;
307 parentNode.insertBefore(hrElem, cNode); 195 parentNode.insertBefore(hrElem, cNode);
308 }); 196 });
309 197
...@@ -373,15 +261,21 @@ module.exports = function (ngApp, events) { ...@@ -373,15 +261,21 @@ module.exports = function (ngApp, events) {
373 link: function (scope, element, attrs) { 261 link: function (scope, element, attrs) {
374 262
375 // Elements 263 // Elements
376 - const input = element.find('[markdown-input] textarea').first(); 264 + const $input = element.find('[markdown-input] textarea').first();
377 - const display = element.find('.markdown-display').first(); 265 + const $display = element.find('.markdown-display').first();
378 - const insertImage = element.find('button[data-action="insertImage"]'); 266 + const $insertImage = element.find('button[data-action="insertImage"]');
379 - const insertEntityLink = element.find('button[data-action="insertEntityLink"]') 267 + const $insertEntityLink = element.find('button[data-action="insertEntityLink"]');
268 +
269 + // Prevent markdown display link click redirect
270 + $display.on('click', 'a', function(event) {
271 + event.preventDefault();
272 + window.open(this.getAttribute('href'));
273 + });
380 274
381 let currentCaretPos = 0; 275 let currentCaretPos = 0;
382 276
383 - input.blur(event => { 277 + $input.blur(event => {
384 - currentCaretPos = input[0].selectionStart; 278 + currentCaretPos = $input[0].selectionStart;
385 }); 279 });
386 280
387 // Scroll sync 281 // Scroll sync
...@@ -391,10 +285,10 @@ module.exports = function (ngApp, events) { ...@@ -391,10 +285,10 @@ module.exports = function (ngApp, events) {
391 displayHeight; 285 displayHeight;
392 286
393 function setScrollHeights() { 287 function setScrollHeights() {
394 - inputScrollHeight = input[0].scrollHeight; 288 + inputScrollHeight = $input[0].scrollHeight;
395 - inputHeight = input.height(); 289 + inputHeight = $input.height();
396 - displayScrollHeight = display[0].scrollHeight; 290 + displayScrollHeight = $display[0].scrollHeight;
397 - displayHeight = display.height(); 291 + displayHeight = $display.height();
398 } 292 }
399 293
400 setTimeout(() => { 294 setTimeout(() => {
...@@ -403,29 +297,29 @@ module.exports = function (ngApp, events) { ...@@ -403,29 +297,29 @@ module.exports = function (ngApp, events) {
403 window.addEventListener('resize', setScrollHeights); 297 window.addEventListener('resize', setScrollHeights);
404 let scrollDebounceTime = 800; 298 let scrollDebounceTime = 800;
405 let lastScroll = 0; 299 let lastScroll = 0;
406 - input.on('scroll', event => { 300 + $input.on('scroll', event => {
407 let now = Date.now(); 301 let now = Date.now();
408 if (now - lastScroll > scrollDebounceTime) { 302 if (now - lastScroll > scrollDebounceTime) {
409 setScrollHeights() 303 setScrollHeights()
410 } 304 }
411 - let scrollPercent = (input.scrollTop() / (inputScrollHeight - inputHeight)); 305 + let scrollPercent = ($input.scrollTop() / (inputScrollHeight - inputHeight));
412 let displayScrollY = (displayScrollHeight - displayHeight) * scrollPercent; 306 let displayScrollY = (displayScrollHeight - displayHeight) * scrollPercent;
413 - display.scrollTop(displayScrollY); 307 + $display.scrollTop(displayScrollY);
414 lastScroll = now; 308 lastScroll = now;
415 }); 309 });
416 310
417 // Editor key-presses 311 // Editor key-presses
418 - input.keydown(event => { 312 + $input.keydown(event => {
419 // Insert image shortcut 313 // Insert image shortcut
420 if (event.which === 73 && event.ctrlKey && event.shiftKey) { 314 if (event.which === 73 && event.ctrlKey && event.shiftKey) {
421 event.preventDefault(); 315 event.preventDefault();
422 - let caretPos = input[0].selectionStart; 316 + let caretPos = $input[0].selectionStart;
423 - let currentContent = input.val(); 317 + let currentContent = $input.val();
424 const mdImageText = "![](http://)"; 318 const mdImageText = "![](http://)";
425 - input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos)); 319 + $input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos));
426 - input.focus(); 320 + $input.focus();
427 - input[0].selectionStart = caretPos + ("![](".length); 321 + $input[0].selectionStart = caretPos + ("![](".length);
428 - input[0].selectionEnd = caretPos + ('![](http://'.length); 322 + $input[0].selectionEnd = caretPos + ('![](http://'.length);
429 return; 323 return;
430 } 324 }
431 325
...@@ -440,48 +334,48 @@ module.exports = function (ngApp, events) { ...@@ -440,48 +334,48 @@ module.exports = function (ngApp, events) {
440 }); 334 });
441 335
442 // Insert image from image manager 336 // Insert image from image manager
443 - insertImage.click(event => { 337 + $insertImage.click(event => {
444 window.ImageManager.showExternal(image => { 338 window.ImageManager.showExternal(image => {
445 let caretPos = currentCaretPos; 339 let caretPos = currentCaretPos;
446 - let currentContent = input.val(); 340 + let currentContent = $input.val();
447 let mdImageText = "![" + image.name + "](" + image.thumbs.display + ")"; 341 let mdImageText = "![" + image.name + "](" + image.thumbs.display + ")";
448 - input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos)); 342 + $input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos));
449 - input.change(); 343 + $input.change();
450 }); 344 });
451 }); 345 });
452 346
453 function showLinkSelector() { 347 function showLinkSelector() {
454 window.showEntityLinkSelector((entity) => { 348 window.showEntityLinkSelector((entity) => {
455 let selectionStart = currentCaretPos; 349 let selectionStart = currentCaretPos;
456 - let selectionEnd = input[0].selectionEnd; 350 + let selectionEnd = $input[0].selectionEnd;
457 let textSelected = (selectionEnd !== selectionStart); 351 let textSelected = (selectionEnd !== selectionStart);
458 - let currentContent = input.val(); 352 + let currentContent = $input.val();
459 353
460 if (textSelected) { 354 if (textSelected) {
461 let selectedText = currentContent.substring(selectionStart, selectionEnd); 355 let selectedText = currentContent.substring(selectionStart, selectionEnd);
462 let linkText = `[${selectedText}](${entity.link})`; 356 let linkText = `[${selectedText}](${entity.link})`;
463 - input.val(currentContent.substring(0, selectionStart) + linkText + currentContent.substring(selectionEnd)); 357 + $input.val(currentContent.substring(0, selectionStart) + linkText + currentContent.substring(selectionEnd));
464 } else { 358 } else {
465 let linkText = ` [${entity.name}](${entity.link}) `; 359 let linkText = ` [${entity.name}](${entity.link}) `;
466 - input.val(currentContent.substring(0, selectionStart) + linkText + currentContent.substring(selectionStart)) 360 + $input.val(currentContent.substring(0, selectionStart) + linkText + currentContent.substring(selectionStart))
467 } 361 }
468 - input.change(); 362 + $input.change();
469 }); 363 });
470 } 364 }
471 - insertEntityLink.click(showLinkSelector); 365 + $insertEntityLink.click(showLinkSelector);
472 366
473 // Upload and insert image on paste 367 // Upload and insert image on paste
474 function editorPaste(e) { 368 function editorPaste(e) {
475 e = e.originalEvent; 369 e = e.originalEvent;
476 if (!e.clipboardData) return 370 if (!e.clipboardData) return
477 - var items = e.clipboardData.items; 371 + let items = e.clipboardData.items;
478 if (!items) return; 372 if (!items) return;
479 - for (var i = 0; i < items.length; i++) { 373 + for (let i = 0; i < items.length; i++) {
480 uploadImage(items[i].getAsFile()); 374 uploadImage(items[i].getAsFile());
481 } 375 }
482 } 376 }
483 377
484 - input.on('paste', editorPaste); 378 + $input.on('paste', editorPaste);
485 379
486 // Handle image drop, Uploads images to BookStack. 380 // Handle image drop, Uploads images to BookStack.
487 function handleImageDrop(event) { 381 function handleImageDrop(event) {
...@@ -493,17 +387,17 @@ module.exports = function (ngApp, events) { ...@@ -493,17 +387,17 @@ module.exports = function (ngApp, events) {
493 } 387 }
494 } 388 }
495 389
496 - input.on('drop', handleImageDrop); 390 + $input.on('drop', handleImageDrop);
497 391
498 // Handle image upload and add image into markdown content 392 // Handle image upload and add image into markdown content
499 function uploadImage(file) { 393 function uploadImage(file) {
500 if (file.type.indexOf('image') !== 0) return; 394 if (file.type.indexOf('image') !== 0) return;
501 - var formData = new FormData(); 395 + let formData = new FormData();
502 - var ext = 'png'; 396 + let ext = 'png';
503 - var xhr = new XMLHttpRequest(); 397 + let xhr = new XMLHttpRequest();
504 398
505 if (file.name) { 399 if (file.name) {
506 - var fileNameMatches = file.name.match(/\.(.+)$/); 400 + let fileNameMatches = file.name.match(/\.(.+)$/);
507 if (fileNameMatches) { 401 if (fileNameMatches) {
508 ext = fileNameMatches[1]; 402 ext = fileNameMatches[1];
509 } 403 }
...@@ -511,17 +405,17 @@ module.exports = function (ngApp, events) { ...@@ -511,17 +405,17 @@ module.exports = function (ngApp, events) {
511 405
512 // Insert image into markdown 406 // Insert image into markdown
513 let id = "image-" + Math.random().toString(16).slice(2); 407 let id = "image-" + Math.random().toString(16).slice(2);
514 - let selectStart = input[0].selectionStart; 408 + let selectStart = $input[0].selectionStart;
515 - let selectEnd = input[0].selectionEnd; 409 + let selectEnd = $input[0].selectionEnd;
516 - let content = input[0].value; 410 + let content = $input[0].value;
517 let selectText = content.substring(selectStart, selectEnd); 411 let selectText = content.substring(selectStart, selectEnd);
518 let placeholderImage = window.baseUrl(`/loading.gif#upload${id}`); 412 let placeholderImage = window.baseUrl(`/loading.gif#upload${id}`);
519 let innerContent = ((selectEnd > selectStart) ? `![${selectText}]` : '![]') + `(${placeholderImage})`; 413 let innerContent = ((selectEnd > selectStart) ? `![${selectText}]` : '![]') + `(${placeholderImage})`;
520 - input[0].value = content.substring(0, selectStart) + innerContent + content.substring(selectEnd); 414 + $input[0].value = content.substring(0, selectStart) + innerContent + content.substring(selectEnd);
521 415
522 - input.focus(); 416 + $input.focus();
523 - input[0].selectionStart = selectStart; 417 + $input[0].selectionStart = selectStart;
524 - input[0].selectionEnd = selectStart; 418 + $input[0].selectionEnd = selectStart;
525 419
526 let remoteFilename = "image-" + Date.now() + "." + ext; 420 let remoteFilename = "image-" + Date.now() + "." + ext;
527 formData.append('file', file, remoteFilename); 421 formData.append('file', file, remoteFilename);
...@@ -529,20 +423,20 @@ module.exports = function (ngApp, events) { ...@@ -529,20 +423,20 @@ module.exports = function (ngApp, events) {
529 423
530 xhr.open('POST', window.baseUrl('/images/gallery/upload')); 424 xhr.open('POST', window.baseUrl('/images/gallery/upload'));
531 xhr.onload = function () { 425 xhr.onload = function () {
532 - let selectStart = input[0].selectionStart; 426 + let selectStart = $input[0].selectionStart;
533 if (xhr.status === 200 || xhr.status === 201) { 427 if (xhr.status === 200 || xhr.status === 201) {
534 - var result = JSON.parse(xhr.responseText); 428 + let result = JSON.parse(xhr.responseText);
535 - input[0].value = input[0].value.replace(placeholderImage, result.thumbs.display); 429 + $input[0].value = $input[0].value.replace(placeholderImage, result.thumbs.display);
536 - input.change(); 430 + $input.change();
537 } else { 431 } else {
538 - console.log('An error occurred uploading the image'); 432 + console.log(trans('errors.image_upload_error'));
539 console.log(xhr.responseText); 433 console.log(xhr.responseText);
540 - input[0].value = input[0].value.replace(innerContent, ''); 434 + $input[0].value = $input[0].value.replace(innerContent, '');
541 - input.change(); 435 + $input.change();
542 } 436 }
543 - input.focus(); 437 + $input.focus();
544 - input[0].selectionStart = selectStart; 438 + $input[0].selectionStart = selectStart;
545 - input[0].selectionEnd = selectStart; 439 + $input[0].selectionEnd = selectStart;
546 }; 440 };
547 xhr.send(formData); 441 xhr.send(formData);
548 } 442 }
...@@ -680,8 +574,7 @@ module.exports = function (ngApp, events) { ...@@ -680,8 +574,7 @@ module.exports = function (ngApp, events) {
680 } 574 }
681 // Enter or tab key 575 // Enter or tab key
682 else if ((event.keyCode === 13 || event.keyCode === 9) && !event.shiftKey) { 576 else if ((event.keyCode === 13 || event.keyCode === 9) && !event.shiftKey) {
683 - let text = suggestionElems[active].textContent; 577 + currentInput[0].value = suggestionElems[active].textContent;
684 - currentInput[0].value = text;
685 currentInput.focus(); 578 currentInput.focus();
686 $suggestionBox.hide(); 579 $suggestionBox.hide();
687 isShowing = false; 580 isShowing = false;
...@@ -732,14 +625,13 @@ module.exports = function (ngApp, events) { ...@@ -732,14 +625,13 @@ module.exports = function (ngApp, events) {
732 // Build suggestions 625 // Build suggestions
733 $suggestionBox[0].innerHTML = ''; 626 $suggestionBox[0].innerHTML = '';
734 for (let i = 0; i < suggestions.length; i++) { 627 for (let i = 0; i < suggestions.length; i++) {
735 - var suggestion = document.createElement('li'); 628 + let suggestion = document.createElement('li');
736 suggestion.textContent = suggestions[i]; 629 suggestion.textContent = suggestions[i];
737 suggestion.onclick = suggestionClick; 630 suggestion.onclick = suggestionClick;
738 if (i === 0) { 631 if (i === 0) {
739 - suggestion.className = 'active' 632 + suggestion.className = 'active';
740 active = 0; 633 active = 0;
741 } 634 }
742 - ;
743 $suggestionBox[0].appendChild(suggestion); 635 $suggestionBox[0].appendChild(suggestion);
744 } 636 }
745 637
...@@ -748,12 +640,11 @@ module.exports = function (ngApp, events) { ...@@ -748,12 +640,11 @@ module.exports = function (ngApp, events) {
748 640
749 // Suggestion click event 641 // Suggestion click event
750 function suggestionClick(event) { 642 function suggestionClick(event) {
751 - let text = this.textContent; 643 + currentInput[0].value = this.textContent;
752 - currentInput[0].value = text;
753 currentInput.focus(); 644 currentInput.focus();
754 $suggestionBox.hide(); 645 $suggestionBox.hide();
755 isShowing = false; 646 isShowing = false;
756 - }; 647 + }
757 648
758 // Get suggestions & cache 649 // Get suggestions & cache
759 function getSuggestions(input, url) { 650 function getSuggestions(input, url) {
...@@ -779,7 +670,7 @@ module.exports = function (ngApp, events) { ...@@ -779,7 +670,7 @@ module.exports = function (ngApp, events) {
779 670
780 ngApp.directive('entityLinkSelector', [function($http) { 671 ngApp.directive('entityLinkSelector', [function($http) {
781 return { 672 return {
782 - restict: 'A', 673 + restrict: 'A',
783 link: function(scope, element, attrs) { 674 link: function(scope, element, attrs) {
784 675
785 const selectButton = element.find('.entity-link-selector-confirm'); 676 const selectButton = element.find('.entity-link-selector-confirm');
...@@ -843,7 +734,7 @@ module.exports = function (ngApp, events) { ...@@ -843,7 +734,7 @@ module.exports = function (ngApp, events) {
843 const input = element.find('[entity-selector-input]').first(); 734 const input = element.find('[entity-selector-input]').first();
844 735
845 // Detect double click events 736 // Detect double click events
846 - var lastClick = 0; 737 + let lastClick = 0;
847 function isDoubleClick() { 738 function isDoubleClick() {
848 let now = Date.now(); 739 let now = Date.now();
849 let answer = now - lastClick < 300; 740 let answer = now - lastClick < 300;
......
1 "use strict"; 1 "use strict";
2 2
3 // AngularJS - Create application and load components 3 // AngularJS - Create application and load components
4 -var angular = require('angular'); 4 +import angular from "angular";
5 -var ngResource = require('angular-resource'); 5 +import "angular-resource";
6 -var ngAnimate = require('angular-animate'); 6 +import "angular-animate";
7 -var ngSanitize = require('angular-sanitize'); 7 +import "angular-sanitize";
8 -require('angular-ui-sortable'); 8 +import "angular-ui-sortable";
9 9
10 // Url retrieval function 10 // Url retrieval function
11 window.baseUrl = function(path) { 11 window.baseUrl = function(path) {
...@@ -15,7 +15,13 @@ window.baseUrl = function(path) { ...@@ -15,7 +15,13 @@ window.baseUrl = function(path) {
15 return basePath + '/' + path; 15 return basePath + '/' + path;
16 }; 16 };
17 17
18 -var ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']); 18 +let ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']);
19 +
20 +// Translation setup
21 +// Creates a global function with name 'trans' to be used in the same way as Laravel's translation system
22 +import Translations from "./translations"
23 +let translator = new Translations(window.translations);
24 +window.trans = translator.get.bind(translator);
19 25
20 // Global Event System 26 // Global Event System
21 class EventManager { 27 class EventManager {
...@@ -25,9 +31,9 @@ class EventManager { ...@@ -25,9 +31,9 @@ class EventManager {
25 31
26 emit(eventName, eventData) { 32 emit(eventName, eventData) {
27 if (typeof this.listeners[eventName] === 'undefined') return this; 33 if (typeof this.listeners[eventName] === 'undefined') return this;
28 - var eventsToStart = this.listeners[eventName]; 34 + let eventsToStart = this.listeners[eventName];
29 for (let i = 0; i < eventsToStart.length; i++) { 35 for (let i = 0; i < eventsToStart.length; i++) {
30 - var event = eventsToStart[i]; 36 + let event = eventsToStart[i];
31 event(eventData); 37 event(eventData);
32 } 38 }
33 return this; 39 return this;
...@@ -70,93 +76,83 @@ jQuery.expr[":"].contains = $.expr.createPseudo(function (arg) { ...@@ -70,93 +76,83 @@ jQuery.expr[":"].contains = $.expr.createPseudo(function (arg) {
70 }); 76 });
71 77
72 // Global jQuery Elements 78 // Global jQuery Elements
73 -$(function () { 79 +let notifications = $('.notification');
74 - 80 +let successNotification = notifications.filter('.pos');
75 - var notifications = $('.notification'); 81 +let errorNotification = notifications.filter('.neg');
76 - var successNotification = notifications.filter('.pos'); 82 +let warningNotification = notifications.filter('.warning');
77 - var errorNotification = notifications.filter('.neg'); 83 +// Notification Events
78 - var warningNotification = notifications.filter('.warning'); 84 +window.Events.listen('success', function (text) {
79 - // Notification Events 85 + successNotification.hide();
80 - window.Events.listen('success', function (text) { 86 + successNotification.find('span').text(text);
81 - successNotification.hide(); 87 + setTimeout(() => {
82 - successNotification.find('span').text(text); 88 + successNotification.show();
89 + }, 1);
90 +});
91 +window.Events.listen('warning', function (text) {
92 + warningNotification.find('span').text(text);
93 + warningNotification.show();
94 +});
95 +window.Events.listen('error', function (text) {
96 + errorNotification.find('span').text(text);
97 + errorNotification.show();
98 +});
99 +
100 +// Notification hiding
101 +notifications.click(function () {
102 + $(this).fadeOut(100);
103 +});
104 +
105 +// Chapter page list toggles
106 +$('.chapter-toggle').click(function (e) {
107 + e.preventDefault();
108 + $(this).toggleClass('open');
109 + $(this).closest('.chapter').find('.inset-list').slideToggle(180);
110 +});
111 +
112 +// Back to top button
113 +$('#back-to-top').click(function() {
114 + $('#header').smoothScrollTo();
115 +});
116 +let scrollTopShowing = false;
117 +let scrollTop = document.getElementById('back-to-top');
118 +let scrollTopBreakpoint = 1200;
119 +window.addEventListener('scroll', function() {
120 + let scrollTopPos = document.documentElement.scrollTop || document.body.scrollTop || 0;
121 + if (!scrollTopShowing && scrollTopPos > scrollTopBreakpoint) {
122 + scrollTop.style.display = 'block';
123 + scrollTopShowing = true;
83 setTimeout(() => { 124 setTimeout(() => {
84 - successNotification.show(); 125 + scrollTop.style.opacity = 0.4;
85 }, 1); 126 }, 1);
86 - }); 127 + } else if (scrollTopShowing && scrollTopPos < scrollTopBreakpoint) {
87 - window.Events.listen('warning', function (text) { 128 + scrollTop.style.opacity = 0;
88 - warningNotification.find('span').text(text); 129 + scrollTopShowing = false;
89 - warningNotification.show(); 130 + setTimeout(() => {
90 - }); 131 + scrollTop.style.display = 'none';
91 - window.Events.listen('error', function (text) { 132 + }, 500);
92 - errorNotification.find('span').text(text);
93 - errorNotification.show();
94 - });
95 -
96 - // Notification hiding
97 - notifications.click(function () {
98 - $(this).fadeOut(100);
99 - });
100 -
101 - // Chapter page list toggles
102 - $('.chapter-toggle').click(function (e) {
103 - e.preventDefault();
104 - $(this).toggleClass('open');
105 - $(this).closest('.chapter').find('.inset-list').slideToggle(180);
106 - });
107 -
108 - // Back to top button
109 - $('#back-to-top').click(function() {
110 - $('#header').smoothScrollTo();
111 - });
112 - var scrollTopShowing = false;
113 - var scrollTop = document.getElementById('back-to-top');
114 - var scrollTopBreakpoint = 1200;
115 - window.addEventListener('scroll', function() {
116 - let scrollTopPos = document.documentElement.scrollTop || document.body.scrollTop || 0;
117 - if (!scrollTopShowing && scrollTopPos > scrollTopBreakpoint) {
118 - scrollTop.style.display = 'block';
119 - scrollTopShowing = true;
120 - setTimeout(() => {
121 - scrollTop.style.opacity = 0.4;
122 - }, 1);
123 - } else if (scrollTopShowing && scrollTopPos < scrollTopBreakpoint) {
124 - scrollTop.style.opacity = 0;
125 - scrollTopShowing = false;
126 - setTimeout(() => {
127 - scrollTop.style.display = 'none';
128 - }, 500);
129 - }
130 - });
131 -
132 - // Common jQuery actions
133 - $('[data-action="expand-entity-list-details"]').click(function() {
134 - $('.entity-list.compact').find('p').not('.empty-text').slideToggle(240);
135 - });
136 -
137 - // Popup close
138 - $('.popup-close').click(function() {
139 - $(this).closest('.overlay').fadeOut(240);
140 - });
141 - $('.overlay').click(function(event) {
142 - if (!$(event.target).hasClass('overlay')) return;
143 - $(this).fadeOut(240);
144 - });
145 -
146 - // Prevent markdown display link click redirect
147 - $('.markdown-display').on('click', 'a', function(event) {
148 - event.preventDefault();
149 - window.open($(this).attr('href'));
150 - });
151 -
152 - // Detect IE for css
153 - if(navigator.userAgent.indexOf('MSIE')!==-1
154 - || navigator.appVersion.indexOf('Trident/') > 0
155 - || navigator.userAgent.indexOf('Safari') !== -1){
156 - $('body').addClass('flexbox-support');
157 } 133 }
134 +});
158 135
136 +// Common jQuery actions
137 +$('[data-action="expand-entity-list-details"]').click(function() {
138 + $('.entity-list.compact').find('p').not('.empty-text').slideToggle(240);
159 }); 139 });
160 140
141 +// Popup close
142 +$('.popup-close').click(function() {
143 + $(this).closest('.overlay').fadeOut(240);
144 +});
145 +$('.overlay').click(function(event) {
146 + if (!$(event.target).hasClass('overlay')) return;
147 + $(this).fadeOut(240);
148 +});
149 +
150 +// Detect IE for css
151 +if(navigator.userAgent.indexOf('MSIE')!==-1
152 + || navigator.appVersion.indexOf('Trident/') > 0
153 + || navigator.userAgent.indexOf('Safari') !== -1){
154 + $('body').addClass('flexbox-support');
155 +}
156 +
161 // Page specific items 157 // Page specific items
162 -require('./pages/page-show'); 158 +import "./pages/page-show";
......
...@@ -60,108 +60,108 @@ function registerEditorShortcuts(editor) { ...@@ -60,108 +60,108 @@ function registerEditorShortcuts(editor) {
60 editor.addShortcut('meta+shift+E', '', ['FormatBlock', false, 'code']); 60 editor.addShortcut('meta+shift+E', '', ['FormatBlock', false, 'code']);
61 } 61 }
62 62
63 -var mceOptions = module.exports = { 63 +export default function() {
64 - selector: '#html-editor', 64 + let settings = {
65 - content_css: [ 65 + selector: '#html-editor',
66 - window.baseUrl('/css/styles.css'), 66 + content_css: [
67 - window.baseUrl('/libs/material-design-iconic-font/css/material-design-iconic-font.min.css') 67 + window.baseUrl('/css/styles.css'),
68 - ], 68 + window.baseUrl('/libs/material-design-iconic-font/css/material-design-iconic-font.min.css')
69 - body_class: 'page-content', 69 + ],
70 - relative_urls: false, 70 + body_class: 'page-content',
71 - remove_script_host: false, 71 + relative_urls: false,
72 - document_base_url: window.baseUrl('/'), 72 + remove_script_host: false,
73 - statusbar: false, 73 + document_base_url: window.baseUrl('/'),
74 - menubar: false, 74 + statusbar: false,
75 - paste_data_images: false, 75 + menubar: false,
76 - extended_valid_elements: 'pre[*]', 76 + paste_data_images: false,
77 - automatic_uploads: false, 77 + extended_valid_elements: 'pre[*]',
78 - valid_children: "-div[p|pre|h1|h2|h3|h4|h5|h6|blockquote]", 78 + automatic_uploads: false,
79 - plugins: "image table textcolor paste link fullscreen imagetools code customhr autosave lists", 79 + valid_children: "-div[p|pre|h1|h2|h3|h4|h5|h6|blockquote]",
80 - imagetools_toolbar: 'imageoptions', 80 + plugins: "image table textcolor paste link fullscreen imagetools code customhr autosave lists",
81 - toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr | removeformat code fullscreen", 81 + imagetools_toolbar: 'imageoptions',
82 - content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}", 82 + toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr | removeformat code fullscreen",
83 - style_formats: [ 83 + content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}",
84 - {title: "Header Large", format: "h2"}, 84 + style_formats: [
85 - {title: "Header Medium", format: "h3"}, 85 + {title: "Header Large", format: "h2"},
86 - {title: "Header Small", format: "h4"}, 86 + {title: "Header Medium", format: "h3"},
87 - {title: "Header Tiny", format: "h5"}, 87 + {title: "Header Small", format: "h4"},
88 - {title: "Paragraph", format: "p", exact: true, classes: ''}, 88 + {title: "Header Tiny", format: "h5"},
89 - {title: "Blockquote", format: "blockquote"}, 89 + {title: "Paragraph", format: "p", exact: true, classes: ''},
90 - {title: "Code Block", icon: "code", format: "pre"}, 90 + {title: "Blockquote", format: "blockquote"},
91 - {title: "Inline Code", icon: "code", inline: "code"}, 91 + {title: "Code Block", icon: "code", format: "pre"},
92 - {title: "Callouts", items: [ 92 + {title: "Inline Code", icon: "code", inline: "code"},
93 - {title: "Success", block: 'p', exact: true, attributes : {'class' : 'callout success'}}, 93 + {title: "Callouts", items: [
94 - {title: "Info", block: 'p', exact: true, attributes : {'class' : 'callout info'}}, 94 + {title: "Success", block: 'p', exact: true, attributes : {'class' : 'callout success'}},
95 - {title: "Warning", block: 'p', exact: true, attributes : {'class' : 'callout warning'}}, 95 + {title: "Info", block: 'p', exact: true, attributes : {'class' : 'callout info'}},
96 - {title: "Danger", block: 'p', exact: true, attributes : {'class' : 'callout danger'}} 96 + {title: "Warning", block: 'p', exact: true, attributes : {'class' : 'callout warning'}},
97 - ]} 97 + {title: "Danger", block: 'p', exact: true, attributes : {'class' : 'callout danger'}}
98 - ], 98 + ]}
99 - style_formats_merge: false, 99 + ],
100 - formats: { 100 + style_formats_merge: false,
101 - alignleft: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-left'}, 101 + formats: {
102 - aligncenter: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-center'}, 102 + alignleft: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-left'},
103 - alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-right'}, 103 + aligncenter: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-center'},
104 - }, 104 + alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-right'},
105 - file_browser_callback: function (field_name, url, type, win) { 105 + },
106 - 106 + file_browser_callback: function (field_name, url, type, win) {
107 - if (type === 'file') { 107 +
108 - window.showEntityLinkSelector(function(entity) { 108 + if (type === 'file') {
109 - let originalField = win.document.getElementById(field_name); 109 + window.showEntityLinkSelector(function(entity) {
110 - originalField.value = entity.link; 110 + let originalField = win.document.getElementById(field_name);
111 - $(originalField).closest('.mce-form').find('input').eq(2).val(entity.name); 111 + originalField.value = entity.link;
112 - }); 112 + $(originalField).closest('.mce-form').find('input').eq(2).val(entity.name);
113 - } 113 + });
114 + }
114 115
115 - if (type === 'image') { 116 + if (type === 'image') {
116 - // Show image manager 117 + // Show image manager
117 - window.ImageManager.showExternal(function (image) { 118 + window.ImageManager.showExternal(function (image) {
118 -
119 - // Set popover link input to image url then fire change event
120 - // to ensure the new value sticks
121 - win.document.getElementById(field_name).value = image.url;
122 - if ("createEvent" in document) {
123 - let evt = document.createEvent("HTMLEvents");
124 - evt.initEvent("change", false, true);
125 - win.document.getElementById(field_name).dispatchEvent(evt);
126 - } else {
127 - win.document.getElementById(field_name).fireEvent("onchange");
128 - }
129 119
130 - // Replace the actively selected content with the linked image 120 + // Set popover link input to image url then fire change event
131 - let html = `<a href="${image.url}" target="_blank">`; 121 + // to ensure the new value sticks
132 - html += `<img src="${image.thumbs.display}" alt="${image.name}">`; 122 + win.document.getElementById(field_name).value = image.url;
133 - html += '</a>'; 123 + if ("createEvent" in document) {
134 - win.tinyMCE.activeEditor.execCommand('mceInsertContent', false, html); 124 + let evt = document.createEvent("HTMLEvents");
135 - }); 125 + evt.initEvent("change", false, true);
136 - } 126 + win.document.getElementById(field_name).dispatchEvent(evt);
127 + } else {
128 + win.document.getElementById(field_name).fireEvent("onchange");
129 + }
130 +
131 + // Replace the actively selected content with the linked image
132 + let html = `<a href="${image.url}" target="_blank">`;
133 + html += `<img src="${image.thumbs.display}" alt="${image.name}">`;
134 + html += '</a>';
135 + win.tinyMCE.activeEditor.execCommand('mceInsertContent', false, html);
136 + });
137 + }
137 138
138 - }, 139 + },
139 - paste_preprocess: function (plugin, args) { 140 + paste_preprocess: function (plugin, args) {
140 - let content = args.content; 141 + let content = args.content;
141 - if (content.indexOf('<img src="file://') !== -1) { 142 + if (content.indexOf('<img src="file://') !== -1) {
142 - args.content = ''; 143 + args.content = '';
143 - } 144 + }
144 - }, 145 + },
145 - extraSetups: [], 146 + extraSetups: [],
146 - setup: function (editor) { 147 + setup: function (editor) {
147 - 148 +
148 - // Run additional setup actions 149 + // Run additional setup actions
149 - // Used by the angular side of things 150 + // Used by the angular side of things
150 - for (let i = 0; i < mceOptions.extraSetups.length; i++) { 151 + for (let i = 0; i < settings.extraSetups.length; i++) {
151 - mceOptions.extraSetups[i](editor); 152 + settings.extraSetups[i](editor);
152 - } 153 + }
153 154
154 - registerEditorShortcuts(editor); 155 + registerEditorShortcuts(editor);
155 156
156 - (function () { 157 + let wrap;
157 - var wrap;
158 158
159 function hasTextContent(node) { 159 function hasTextContent(node) {
160 return node && !!( node.textContent || node.innerText ); 160 return node && !!( node.textContent || node.innerText );
161 } 161 }
162 162
163 editor.on('dragstart', function () { 163 editor.on('dragstart', function () {
164 - var node = editor.selection.getNode(); 164 + let node = editor.selection.getNode();
165 165
166 if (node.nodeName !== 'IMG') return; 166 if (node.nodeName !== 'IMG') return;
167 wrap = editor.dom.getParent(node, '.mceTemp'); 167 wrap = editor.dom.getParent(node, '.mceTemp');
...@@ -172,7 +172,7 @@ var mceOptions = module.exports = { ...@@ -172,7 +172,7 @@ var mceOptions = module.exports = {
172 }); 172 });
173 173
174 editor.on('drop', function (event) { 174 editor.on('drop', function (event) {
175 - var dom = editor.dom, 175 + let dom = editor.dom,
176 rng = tinymce.dom.RangeUtils.getCaretRangeFromPoint(event.clientX, event.clientY, editor.getDoc()); 176 rng = tinymce.dom.RangeUtils.getCaretRangeFromPoint(event.clientX, event.clientY, editor.getDoc());
177 177
178 // Don't allow anything to be dropped in a captioned image. 178 // Don't allow anything to be dropped in a captioned image.
...@@ -190,26 +190,27 @@ var mceOptions = module.exports = { ...@@ -190,26 +190,27 @@ var mceOptions = module.exports = {
190 190
191 wrap = null; 191 wrap = null;
192 }); 192 });
193 - })();
194 -
195 - // Custom Image picker button
196 - editor.addButton('image-insert', {
197 - title: 'My title',
198 - icon: 'image',
199 - tooltip: 'Insert an image',
200 - onclick: function () {
201 - window.ImageManager.showExternal(function (image) {
202 - let html = `<a href="${image.url}" target="_blank">`;
203 - html += `<img src="${image.thumbs.display}" alt="${image.name}">`;
204 - html += '</a>';
205 - editor.execCommand('mceInsertContent', false, html);
206 - });
207 - }
208 - });
209 193
210 - // Paste image-uploads
211 - editor.on('paste', function(event) {
212 - editorPaste(event, editor);
213 - });
214 - }
215 -};
...\ No newline at end of file ...\ No newline at end of file
194 + // Custom Image picker button
195 + editor.addButton('image-insert', {
196 + title: 'My title',
197 + icon: 'image',
198 + tooltip: 'Insert an image',
199 + onclick: function () {
200 + window.ImageManager.showExternal(function (image) {
201 + let html = `<a href="${image.url}" target="_blank">`;
202 + html += `<img src="${image.thumbs.display}" alt="${image.name}">`;
203 + html += '</a>';
204 + editor.execCommand('mceInsertContent', false, html);
205 + });
206 + }
207 + });
208 +
209 + // Paste image-uploads
210 + editor.on('paste', function(event) {
211 + editorPaste(event, editor);
212 + });
213 + }
214 + };
215 + return settings;
216 +}
...\ No newline at end of file ...\ No newline at end of file
......
1 "use strict"; 1 "use strict";
2 // Configure ZeroClipboard 2 // Configure ZeroClipboard
3 -var zeroClipBoard = require('zeroclipboard'); 3 +import zeroClipBoard from "zeroclipboard";
4 -zeroClipBoard.config({
5 - swfPath: window.baseUrl('/ZeroClipboard.swf')
6 -});
7 4
8 -window.setupPageShow = module.exports = function (pageId) { 5 +export default window.setupPageShow = function (pageId) {
9 6
10 // Set up pointer 7 // Set up pointer
11 - var $pointer = $('#pointer').detach(); 8 + let $pointer = $('#pointer').detach();
12 - var $pointerInner = $pointer.children('div.pointer').first(); 9 + let $pointerInner = $pointer.children('div.pointer').first();
13 - var isSelection = false; 10 + let isSelection = false;
14 11
15 // Select all contents on input click 12 // Select all contents on input click
16 $pointer.on('click', 'input', function (e) { 13 $pointer.on('click', 'input', function (e) {
...@@ -19,6 +16,9 @@ window.setupPageShow = module.exports = function (pageId) { ...@@ -19,6 +16,9 @@ window.setupPageShow = module.exports = function (pageId) {
19 }); 16 });
20 17
21 // Set up copy-to-clipboard 18 // Set up copy-to-clipboard
19 + zeroClipBoard.config({
20 + swfPath: window.baseUrl('/ZeroClipboard.swf')
21 + });
22 new zeroClipBoard($pointer.find('button').first()[0]); 22 new zeroClipBoard($pointer.find('button').first()[0]);
23 23
24 // Hide pointer when clicking away 24 // Hide pointer when clicking away
...@@ -31,11 +31,11 @@ window.setupPageShow = module.exports = function (pageId) { ...@@ -31,11 +31,11 @@ window.setupPageShow = module.exports = function (pageId) {
31 // Show pointer when selecting a single block of tagged content 31 // Show pointer when selecting a single block of tagged content
32 $('.page-content [id^="bkmrk"]').on('mouseup keyup', function (e) { 32 $('.page-content [id^="bkmrk"]').on('mouseup keyup', function (e) {
33 e.stopPropagation(); 33 e.stopPropagation();
34 - var selection = window.getSelection(); 34 + let selection = window.getSelection();
35 if (selection.toString().length === 0) return; 35 if (selection.toString().length === 0) return;
36 36
37 // Show pointer and set link 37 // Show pointer and set link
38 - var $elem = $(this); 38 + let $elem = $(this);
39 let link = window.baseUrl('/link/' + pageId + '#' + $elem.attr('id')); 39 let link = window.baseUrl('/link/' + pageId + '#' + $elem.attr('id'));
40 if (link.indexOf('http') !== 0) link = window.location.protocol + "//" + window.location.host + link; 40 if (link.indexOf('http') !== 0) link = window.location.protocol + "//" + window.location.host + link;
41 $pointer.find('input').val(link); 41 $pointer.find('input').val(link);
...@@ -44,9 +44,9 @@ window.setupPageShow = module.exports = function (pageId) { ...@@ -44,9 +44,9 @@ window.setupPageShow = module.exports = function (pageId) {
44 $pointer.show(); 44 $pointer.show();
45 45
46 // Set pointer to sit near mouse-up position 46 // Set pointer to sit near mouse-up position
47 - var pointerLeftOffset = (e.pageX - $elem.offset().left - ($pointerInner.width() / 2)); 47 + let pointerLeftOffset = (e.pageX - $elem.offset().left - ($pointerInner.width() / 2));
48 if (pointerLeftOffset < 0) pointerLeftOffset = 0; 48 if (pointerLeftOffset < 0) pointerLeftOffset = 0;
49 - var pointerLeftOffsetPercent = (pointerLeftOffset / $elem.width()) * 100; 49 + let pointerLeftOffsetPercent = (pointerLeftOffset / $elem.width()) * 100;
50 $pointerInner.css('left', pointerLeftOffsetPercent + '%'); 50 $pointerInner.css('left', pointerLeftOffsetPercent + '%');
51 51
52 isSelection = true; 52 isSelection = true;
...@@ -57,7 +57,7 @@ window.setupPageShow = module.exports = function (pageId) { ...@@ -57,7 +57,7 @@ window.setupPageShow = module.exports = function (pageId) {
57 57
58 // Go to, and highlight if necessary, the specified text. 58 // Go to, and highlight if necessary, the specified text.
59 function goToText(text) { 59 function goToText(text) {
60 - var idElem = $('.page-content #' + text).first(); 60 + let idElem = $('.page-content #' + text).first();
61 if (idElem.length !== 0) { 61 if (idElem.length !== 0) {
62 idElem.smoothScrollTo(); 62 idElem.smoothScrollTo();
63 idElem.css('background-color', 'rgba(244, 249, 54, 0.25)'); 63 idElem.css('background-color', 'rgba(244, 249, 54, 0.25)');
...@@ -68,19 +68,19 @@ window.setupPageShow = module.exports = function (pageId) { ...@@ -68,19 +68,19 @@ window.setupPageShow = module.exports = function (pageId) {
68 68
69 // Check the hash on load 69 // Check the hash on load
70 if (window.location.hash) { 70 if (window.location.hash) {
71 - var text = window.location.hash.replace(/\%20/g, ' ').substr(1); 71 + let text = window.location.hash.replace(/\%20/g, ' ').substr(1);
72 goToText(text); 72 goToText(text);
73 } 73 }
74 74
75 // Make the book-tree sidebar stick in view on scroll 75 // Make the book-tree sidebar stick in view on scroll
76 - var $window = $(window); 76 + let $window = $(window);
77 - var $bookTree = $(".book-tree"); 77 + let $bookTree = $(".book-tree");
78 - var $bookTreeParent = $bookTree.parent(); 78 + let $bookTreeParent = $bookTree.parent();
79 // Check the page is scrollable and the content is taller than the tree 79 // Check the page is scrollable and the content is taller than the tree
80 - var pageScrollable = ($(document).height() > $window.height()) && ($bookTree.height() < $('.page-content').height()); 80 + let pageScrollable = ($(document).height() > $window.height()) && ($bookTree.height() < $('.page-content').height());
81 // Get current tree's width and header height 81 // Get current tree's width and header height
82 - var headerHeight = $("#header").height() + $(".toolbar").height(); 82 + let headerHeight = $("#header").height() + $(".toolbar").height();
83 - var isFixed = $window.scrollTop() > headerHeight; 83 + let isFixed = $window.scrollTop() > headerHeight;
84 // Function to fix the tree as a sidebar 84 // Function to fix the tree as a sidebar
85 function stickTree() { 85 function stickTree() {
86 $bookTree.width($bookTreeParent.width() + 15); 86 $bookTree.width($bookTreeParent.width() + 15);
...@@ -95,7 +95,7 @@ window.setupPageShow = module.exports = function (pageId) { ...@@ -95,7 +95,7 @@ window.setupPageShow = module.exports = function (pageId) {
95 } 95 }
96 // Checks if the tree stickiness state should change 96 // Checks if the tree stickiness state should change
97 function checkTreeStickiness(skipCheck) { 97 function checkTreeStickiness(skipCheck) {
98 - var shouldBeFixed = $window.scrollTop() > headerHeight; 98 + let shouldBeFixed = $window.scrollTop() > headerHeight;
99 if (shouldBeFixed && (!isFixed || skipCheck)) { 99 if (shouldBeFixed && (!isFixed || skipCheck)) {
100 stickTree(); 100 stickTree();
101 } else if (!shouldBeFixed && (isFixed || skipCheck)) { 101 } else if (!shouldBeFixed && (isFixed || skipCheck)) {
......
1 +/**
2 + * Translation Manager
3 + * Handles the JavaScript side of translating strings
4 + * in a way which fits with Laravel.
5 + */
6 +class Translator {
7 +
8 + /**
9 + * Create an instance, Passing in the required translations
10 + * @param translations
11 + */
12 + constructor(translations) {
13 + this.store = translations;
14 + }
15 +
16 + /**
17 + * Get a translation, Same format as laravel's 'trans' helper
18 + * @param key
19 + * @param replacements
20 + * @returns {*}
21 + */
22 + get(key, replacements) {
23 + let splitKey = key.split('.');
24 + let value = splitKey.reduce((a, b) => {
25 + return a != undefined ? a[b] : a;
26 + }, this.store);
27 +
28 + if (value === undefined) {
29 + console.log(`Translation with key "${key}" does not exist`);
30 + value = key;
31 + }
32 +
33 + if (replacements === undefined) return value;
34 +
35 + let replaceMatches = value.match(/:([\S]+)/g);
36 + if (replaceMatches === null) return value;
37 + replaceMatches.forEach(match => {
38 + let key = match.substring(1);
39 + if (typeof replacements[key] === 'undefined') return;
40 + value = value.replace(match, replacements[key]);
41 + });
42 + return value;
43 + }
44 +
45 +}
46 +
47 +export default Translator
...@@ -465,4 +465,8 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group { ...@@ -465,4 +465,8 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
465 border-bottom-width: 3px; 465 border-bottom-width: 3px;
466 } 466 }
467 } 467 }
468 +}
469 +
470 +.image-picker .none {
471 + display: none;
468 } 472 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -267,9 +267,4 @@ input.outline { ...@@ -267,9 +267,4 @@ input.outline {
267 267
268 .image-picker img { 268 .image-picker img {
269 background-color: #BBB; 269 background-color: #BBB;
270 -}
271 -
272 -div[toggle-switch] {
273 - height: 18px;
274 - width: 150px;
275 } 270 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -322,6 +322,9 @@ ul.pagination { ...@@ -322,6 +322,9 @@ ul.pagination {
322 font-size: 0.75em; 322 font-size: 0.75em;
323 margin-top: $-xs; 323 margin-top: $-xs;
324 } 324 }
325 + .text-muted p.text-muted {
326 + margin-top: 0;
327 + }
325 .page.draft .text-page { 328 .page.draft .text-page {
326 color: $color-page-draft; 329 color: $color-page-draft;
327 } 330 }
......
...@@ -35,6 +35,12 @@ table.table { ...@@ -35,6 +35,12 @@ table.table {
35 tr:hover { 35 tr:hover {
36 background-color: #EEE; 36 background-color: #EEE;
37 } 37 }
38 + .text-right {
39 + text-align: right;
40 + }
41 + .text-center {
42 + text-align: center;
43 + }
38 } 44 }
39 45
40 table.no-style { 46 table.no-style {
......
...@@ -109,6 +109,9 @@ em, i, .italic { ...@@ -109,6 +109,9 @@ em, i, .italic {
109 small, p.small, span.small, .text-small { 109 small, p.small, span.small, .text-small {
110 font-size: 0.8em; 110 font-size: 0.8em;
111 color: lighten($text-dark, 20%); 111 color: lighten($text-dark, 20%);
112 + small, p.small, span.small, .text-small {
113 + font-size: 1em;
114 + }
112 } 115 }
113 116
114 sup, .superscript { 117 sup, .superscript {
......
...@@ -16,7 +16,7 @@ return [ ...@@ -16,7 +16,7 @@ return [
16 'app_name_desc' => 'Dieser Name wird im Header und E-Mails angezeigt.', 16 'app_name_desc' => 'Dieser Name wird im Header und E-Mails angezeigt.',
17 'app_name_header' => 'Anwendungsname im Header anzeigen?', 17 'app_name_header' => 'Anwendungsname im Header anzeigen?',
18 'app_public_viewing' => '&Ouml;ffentliche Ansicht erlauben?', 18 'app_public_viewing' => '&Ouml;ffentliche Ansicht erlauben?',
19 - 'app_secure_images' => 'Erh&oml;hte Sicherheit f&uuml;r Bilduploads aktivieren?', 19 + 'app_secure_images' => 'Erh&ouml;hte Sicherheit f&uuml;r Bilduploads aktivieren?',
20 'app_secure_images_desc' => 'Aus Leistungsgr&uuml;nden sind alle Bilder &ouml;ffentlich sichtbar. Diese Option f&uuml;gt zuf&auml;llige, schwer zu eratene, Zeichenketten vor die Bild-URLs hinzu. Stellen sie sicher, dass Verzeichnindexes deaktiviert sind, um einen einfachen Zugrif zu verhindern.', 20 'app_secure_images_desc' => 'Aus Leistungsgr&uuml;nden sind alle Bilder &ouml;ffentlich sichtbar. Diese Option f&uuml;gt zuf&auml;llige, schwer zu eratene, Zeichenketten vor die Bild-URLs hinzu. Stellen sie sicher, dass Verzeichnindexes deaktiviert sind, um einen einfachen Zugrif zu verhindern.',
21 'app_editor' => 'Seiteneditor', 21 'app_editor' => 'Seiteneditor',
22 'app_editor_desc' => 'W&auml;hlen sie den Editor aus, der von allen Benutzern genutzt werden soll, um Seiten zu editieren.', 22 'app_editor_desc' => 'W&auml;hlen sie den Editor aus, der von allen Benutzern genutzt werden soll, um Seiten zu editieren.',
......
...@@ -14,7 +14,49 @@ return [ ...@@ -14,7 +14,49 @@ return [
14 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 14 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
15 15
16 /** 16 /**
17 - * Email Confirmation Text 17 + * Login & Register
18 + */
19 + 'sign_up' => 'Sign up',
20 + 'log_in' => 'Log in',
21 + 'logout' => 'Logout',
22 +
23 + 'name' => 'Name',
24 + 'username' => 'Username',
25 + 'email' => 'Email',
26 + 'password' => 'Password',
27 + 'password_confirm' => 'Confirm Password',
28 + 'password_hint' => 'Must be over 5 characters',
29 + 'forgot_password' => 'Forgot Password?',
30 + 'remember_me' => 'Remember Me',
31 + 'ldap_email_hint' => 'Please enter an email to use for this account.',
32 + 'create_account' => 'Create Account',
33 + 'social_login' => 'Social Login',
34 + 'social_registration' => 'Social Registration',
35 + 'social_registration_text' => 'Register and sign in using another service.',
36 +
37 + 'register_thanks' => 'Thanks for registering!',
38 + 'register_confirm' => 'Please check your email and click the confirmation button to access :appName.',
39 + 'registrations_disabled' => 'Registrations are currently disabled',
40 + 'registration_email_domain_invalid' => 'That email domain does not have access to this application',
41 + 'register_success' => 'Thanks for signing up! You are now registered and signed in.',
42 +
43 +
44 + /**
45 + * Password Reset
46 + */
47 + 'reset_password' => 'Reset Password',
48 + 'reset_password_send_instructions' => 'Enter your email below and you will be sent an email with a password reset link.',
49 + 'reset_password_send_button' => 'Send Reset Link',
50 + 'reset_password_sent_success' => 'A password reset link has been sent to :email.',
51 + 'reset_password_success' => 'Your password has been successfully reset.',
52 +
53 + 'email_reset_subject' => 'Reset your :appName password',
54 + 'email_reset_text' => 'You are receiving this email because we received a password reset request for your account.',
55 + 'email_reset_not_requested' => 'If you did not request a password reset, no further action is required.',
56 +
57 +
58 + /**
59 + * Email Confirmation
18 */ 60 */
19 'email_confirm_subject' => 'Confirm your email on :appName', 61 'email_confirm_subject' => 'Confirm your email on :appName',
20 'email_confirm_greeting' => 'Thanks for joining :appName!', 62 'email_confirm_greeting' => 'Thanks for joining :appName!',
...@@ -23,4 +65,10 @@ return [ ...@@ -23,4 +65,10 @@ return [
23 'email_confirm_send_error' => 'Email confirmation required but the system could not send the email. Contact the admin to ensure email is set up correctly.', 65 'email_confirm_send_error' => 'Email confirmation required but the system could not send the email. Contact the admin to ensure email is set up correctly.',
24 'email_confirm_success' => 'Your email has been confirmed!', 66 'email_confirm_success' => 'Your email has been confirmed!',
25 'email_confirm_resent' => 'Confirmation email resent, Please check your inbox.', 67 'email_confirm_resent' => 'Confirmation email resent, Please check your inbox.',
68 +
69 + 'email_not_confirmed' => 'Email Address Not Confirmed',
70 + 'email_not_confirmed_text' => 'Your email address has not yet been confirmed.',
71 + 'email_not_confirmed_click_link' => 'Please click the link in the email that was sent shortly after you registered.',
72 + 'email_not_confirmed_resend' => 'If you cannot find the email you can re-send the confirmation email by submitting the form below.',
73 + 'email_not_confirmed_resend_button' => 'Resend Confirmation Email',
26 ]; 74 ];
...\ No newline at end of file ...\ No newline at end of file
......
1 +<?php
2 +return [
3 +
4 + /**
5 + * Buttons
6 + */
7 + 'cancel' => 'Cancel',
8 + 'confirm' => 'Confirm',
9 + 'back' => 'Back',
10 + 'save' => 'Save',
11 + 'continue' => 'Continue',
12 + 'select' => 'Select',
13 +
14 + /**
15 + * Form Labels
16 + */
17 + 'name' => 'Name',
18 + 'description' => 'Description',
19 + 'role' => 'Role',
20 +
21 + /**
22 + * Actions
23 + */
24 + 'actions' => 'Actions',
25 + 'view' => 'View',
26 + 'create' => 'Create',
27 + 'update' => 'Update',
28 + 'edit' => 'Edit',
29 + 'sort' => 'Sort',
30 + 'move' => 'Move',
31 + 'delete' => 'Delete',
32 + 'search' => 'Search',
33 + 'search_clear' => 'Clear Search',
34 + 'reset' => 'Reset',
35 + 'remove' => 'Remove',
36 +
37 +
38 + /**
39 + * Misc
40 + */
41 + 'deleted_user' => 'Deleted User',
42 + 'no_activity' => 'No activity to show',
43 + 'no_items' => 'No items available',
44 + 'back_to_top' => 'Back to top',
45 + 'toggle_details' => 'Toggle Details',
46 +
47 + /**
48 + * Header
49 + */
50 + 'view_profile' => 'View Profile',
51 + 'edit_profile' => 'Edit Profile',
52 +
53 + /**
54 + * Email Content
55 + */
56 + 'email_action_help' => 'If you’re having trouble clicking the ":actionText" button, copy and paste the URL below into your web browser:',
57 + 'email_rights' => 'All rights reserved',
58 +];
...\ No newline at end of file ...\ No newline at end of file
1 +<?php
2 +return [
3 +
4 + /**
5 + * Image Manager
6 + */
7 + 'image_select' => 'Image Select',
8 + 'image_all' => 'All',
9 + 'image_all_title' => 'View all images',
10 + 'image_book_title' => 'View images uploaded to this book',
11 + 'image_page_title' => 'View images uploaded to this page',
12 + 'image_search_hint' => 'Search by image name',
13 + 'image_uploaded' => 'Uploaded :uploadedDate',
14 + 'image_load_more' => 'Load More',
15 + 'image_image_name' => 'Image Name',
16 + 'image_delete_confirm' => 'This image is used in the pages below, Click delete again to confirm you want to delete this image.',
17 + 'image_select_image' => 'Select Image',
18 + 'image_dropzone' => 'Drop images or click here to upload',
19 + 'images_deleted' => 'Images Deleted',
20 + 'image_preview' => 'Image Preview',
21 + 'image_upload_success' => 'Image uploaded successfully',
22 + 'image_update_success' => 'Image details successfully updated',
23 + 'image_delete_success' => 'Image successfully deleted'
24 +];
...\ No newline at end of file ...\ No newline at end of file
1 +<?php
2 +return [
3 +
4 + /**
5 + * Shared
6 + */
7 + 'recently_created' => 'Recently Created',
8 + 'recently_created_pages' => 'Recently Created Pages',
9 + 'recently_updated_pages' => 'Recently Updated Pages',
10 + 'recently_created_chapters' => 'Recently Created Chapters',
11 + 'recently_created_books' => 'Recently Created Books',
12 + 'recently_update' => 'Recently Updated',
13 + 'recently_viewed' => 'Recently Viewed',
14 + 'recent_activity' => 'Recent Activity',
15 + 'create_now' => 'Create one now',
16 + 'revisions' => 'Revisions',
17 + 'meta_created' => 'Created :timeLength',
18 + 'meta_created_name' => 'Created :timeLength by :user',
19 + 'meta_updated' => 'Updated :timeLength',
20 + 'meta_updated_name' => 'Updated :timeLength by :user',
21 + 'x_pages' => ':count Pages',
22 + 'entity_select' => 'Entity Select',
23 + 'images' => 'Images',
24 + 'my_recent_drafts' => 'My Recent Drafts',
25 + 'my_recently_viewed' => 'My Recently Viewed',
26 + 'no_pages_viewed' => 'You have not viewed any pages',
27 + 'no_pages_recently_created' => 'No pages have been recently created',
28 + 'no_pages_recently_updated' => 'No pages have been recently updated',
29 +
30 + /**
31 + * Permissions and restrictions
32 + */
33 + 'permissions' => 'Permissions',
34 + 'permissions_intro' => 'Once enabled, These permissions will take priority over any set role permissions.',
35 + 'permissions_enable' => 'Enable Custom Permissions',
36 + 'permissions_save' => 'Save Permissions',
37 +
38 + /**
39 + * Search
40 + */
41 + 'search_results' => 'Search Results',
42 + 'search_results_page' => 'Page Search Results',
43 + 'search_results_chapter' => 'Chapter Search Results',
44 + 'search_results_book' => 'Book Search Results',
45 + 'search_clear' => 'Clear Search',
46 + 'search_view_pages' => 'View all matches pages',
47 + 'search_view_chapters' => 'View all matches chapters',
48 + 'search_view_books' => 'View all matches books',
49 + 'search_no_pages' => 'No pages matched this search',
50 + 'search_for_term' => 'Search for :term',
51 + 'search_page_for_term' => 'Page search for :term',
52 + 'search_chapter_for_term' => 'Chapter search for :term',
53 + 'search_book_for_term' => 'Books search for :term',
54 +
55 + /**
56 + * Books
57 + */
58 + 'book' => 'Book',
59 + 'books' => 'Books',
60 + 'books_empty' => 'No books have been created',
61 + 'books_popular' => 'Popular Books',
62 + 'books_recent' => 'Recent Books',
63 + 'books_popular_empty' => 'The most popular books will appear here.',
64 + 'books_create' => 'Create New Book',
65 + 'books_delete' => 'Delete Book',
66 + 'books_delete_named' => 'Delete Book :bookName',
67 + 'books_delete_explain' => 'This will delete the book with the name \':bookName\', All pages and chapters will be removed.',
68 + 'books_delete_confirmation' => 'Are you sure you want to delete this book?',
69 + 'books_edit' => 'Edit Book',
70 + 'books_edit_named' => 'Edit Book :bookName',
71 + 'books_form_book_name' => 'Book Name',
72 + 'books_save' => 'Save Book',
73 + 'books_permissions' => 'Book Permissions',
74 + 'books_permissions_updated' => 'Book Permissions Updated',
75 + 'books_empty_contents' => 'No pages or chapters have been created for this book.',
76 + 'books_empty_create_page' => 'Create a new page',
77 + 'books_empty_or' => 'or',
78 + 'books_empty_sort_current_book' => 'Sort the current book',
79 + 'books_empty_add_chapter' => 'Add a chapter',
80 + 'books_permissions_active' => 'Book Permissions Active',
81 + 'books_search_this' => 'Search this book',
82 + 'books_navigation' => 'Book Navigation',
83 + 'books_sort' => 'Sort Book Contents',
84 + 'books_sort_named' => 'Sort Book :bookName',
85 + 'books_sort_show_other' => 'Show Other Books',
86 + 'books_sort_save' => 'Save New Order',
87 +
88 + /**
89 + * Chapters
90 + */
91 + 'chapter' => 'Chapter',
92 + 'chapters_popular' => 'Popular Chapters',
93 + 'chapters_new' => 'New Chapter',
94 + 'chapters_create' => 'Create New Chapter',
95 + 'chapters_delete' => 'Delete Chapter',
96 + 'chapters_delete_named' => 'Delete Chapter :chapterName',
97 + 'chapters_delete_explain' => 'This will delete the chapter with the name \':chapterName\', All pages will be removed
98 + and added directly to the parent book.',
99 + 'chapters_delete_confirm' => 'Are you sure you want to delete this chapter?',
100 + 'chapters_edit' => 'Edit Chapter',
101 + 'chapters_edit_named' => 'Edit Chapter :chapterName',
102 + 'chapters_save' => 'Save Chapter',
103 + 'chapters_move' => 'Move Chapter',
104 + 'chapters_move_named' => 'Move Chapter :chapterName',
105 + 'chapter_move_success' => 'Chapter moved to :bookName',
106 + 'chapters_permissions' => 'Chapter Permissions',
107 + 'chapters_empty' => 'No pages are currently in this chapter.',
108 + 'chapters_permissions_active' => 'Chapter Permissions Active',
109 + 'chapters_permissions_success' => 'Chapter Permissions Updated',
110 +
111 + /**
112 + * Pages
113 + */
114 + 'page' => 'Page',
115 + 'pages' => 'Pages',
116 + 'pages_popular' => 'Popular Pages',
117 + 'pages_new' => 'New Page',
118 + 'pages_attachments' => 'Attachments',
119 + 'pages_navigation' => 'Page Navigation',
120 + 'pages_delete' => 'Delete Page',
121 + 'pages_delete_named' => 'Delete Page :pageName',
122 + 'pages_delete_draft_named' => 'Delete Draft Page :pageName',
123 + 'pages_delete_draft' => 'Delete Draft Page',
124 + 'pages_delete_success' => 'Page deleted',
125 + 'pages_delete_draft_success' => 'Draft page deleted',
126 + 'pages_delete_confirm' => 'Are you sure you want to delete this page?',
127 + 'pages_delete_draft_confirm' => 'Are you sure you want to delete this draft page?',
128 + 'pages_editing_named' => 'Editing Page :pageName',
129 + 'pages_edit_toggle_header' => 'Toggle header',
130 + 'pages_edit_save_draft' => 'Save Draft',
131 + 'pages_edit_draft' => 'Edit Page Draft',
132 + 'pages_editing_draft' => 'Editing Draft',
133 + 'pages_editing_page' => 'Editing Page',
134 + 'pages_edit_draft_save_at' => 'Draft saved at ',
135 + 'pages_edit_delete_draft' => 'Delete Draft',
136 + 'pages_edit_discard_draft' => 'Discard Draft',
137 + 'pages_edit_set_changelog' => 'Set Changelog',
138 + 'pages_edit_enter_changelog_desc' => 'Enter a brief description of the changes you\'ve made',
139 + 'pages_edit_enter_changelog' => 'Enter Changelog',
140 + 'pages_save' => 'Save Page',
141 + 'pages_title' => 'Page Title',
142 + 'pages_name' => 'Page Name',
143 + 'pages_md_editor' => 'Editor',
144 + 'pages_md_preview' => 'Preview',
145 + 'pages_md_insert_image' => 'Insert Image',
146 + 'pages_md_insert_link' => 'Insert Entity Link',
147 + 'pages_not_in_chapter' => 'Page is not in a chapter',
148 + 'pages_move' => 'Move Page',
149 + 'pages_move_success' => 'Page moved to ":parentName"',
150 + 'pages_permissions' => 'Page Permissions',
151 + 'pages_permissions_success' => 'Page permissions updated',
152 + 'pages_revisions' => 'Page Revisions',
153 + 'pages_revisions_named' => 'Page Revisions for :pageName',
154 + 'pages_revision_named' => 'Page Revision for :pageName',
155 + 'pages_revisions_created_by' => 'Created By',
156 + 'pages_revisions_date' => 'Revision Date',
157 + 'pages_revisions_changelog' => 'Changelog',
158 + 'pages_revisions_changes' => 'Changes',
159 + 'pages_revisions_current' => 'Current Version',
160 + 'pages_revisions_preview' => 'Preview',
161 + 'pages_revisions_restore' => 'Restore',
162 + 'pages_revisions_none' => 'This page has no revisions',
163 + 'pages_export' => 'Export',
164 + 'pages_export_html' => 'Contained Web File',
165 + 'pages_export_pdf' => 'PDF File',
166 + 'pages_export_text' => 'Plain Text File',
167 + 'pages_copy_link' => 'Copy Link',
168 + 'pages_permissions_active' => 'Page Permissions Active',
169 + 'pages_initial_revision' => 'Initial publish',
170 + 'pages_initial_name' => 'New Page',
171 + 'pages_editing_draft_notification' => 'You are currently editing a draft that was last saved :timeDiff.',
172 + 'pages_draft_edited_notification' => 'This page has been updated by since that time. It is recommended that you discard this draft.',
173 + 'pages_draft_edit_active' => [
174 + 'start_a' => ':count users have started editing this page',
175 + 'start_b' => ':userName has started editing this page',
176 + 'time_a' => 'since the pages was last updated',
177 + 'time_b' => 'in the last :minCount minutes',
178 + 'message' => ':start :time. Take care not to overwrite each other\'s updates!',
179 + ],
180 + 'pages_draft_discarded' => 'Draft discarded, The editor has been updated with the current page content',
181 +
182 + /**
183 + * Editor sidebar
184 + */
185 + 'page_tags' => 'Page Tags',
186 + 'tag' => 'Tag',
187 + 'tags' => '',
188 + 'tag_value' => 'Tag Value (Optional)',
189 + 'tags_explain' => "Add some tags to better categorise your content. \n You can assign a value to a tag for more in-depth organisation.",
190 + 'tags_add' => 'Add another tag',
191 + 'attachments' => 'Attachments',
192 + 'attachments_explain' => 'Upload some files or attach some link to display on your page. These are visible in the page sidebar.',
193 + 'attachments_explain_instant_save' => 'Changes here are saved instantly.',
194 + 'attachments_items' => 'Attached Items',
195 + 'attachments_upload' => 'Upload File',
196 + 'attachments_link' => 'Attach Link',
197 + 'attachments_set_link' => 'Set Link',
198 + 'attachments_delete_confirm' => 'Click delete again to confirm you want to delete this attachment.',
199 + 'attachments_dropzone' => 'Drop files or click here to attach a file',
200 + 'attachments_no_files' => 'No files have been uploaded',
201 + 'attachments_explain_link' => 'You can attach a link if you\'d prefer not to upload a file. This can be a link to another page or a link to a file in the cloud.',
202 + 'attachments_link_name' => 'Link Name',
203 + 'attachment_link' => 'Attachment link',
204 + 'attachments_link_url' => 'Link to file',
205 + 'attachments_link_url_hint' => 'Url of site or file',
206 + 'attach' => 'Attach',
207 + 'attachments_edit_file' => 'Edit File',
208 + 'attachments_edit_file_name' => 'File Name',
209 + 'attachments_edit_drop_upload' => 'Drop files or click here to upload and overwrite',
210 + 'attachments_order_updated' => 'Attachment order updated',
211 + 'attachments_updated_success' => 'Attachment details updated',
212 + 'attachments_deleted' => 'Attachment deleted',
213 + 'attachments_file_uploaded' => 'File successfully uploaded',
214 + 'attachments_file_updated' => 'File successfully updated',
215 + 'attachments_link_attached' => 'Link successfully attached to page',
216 +
217 + /**
218 + * Profile View
219 + */
220 + 'profile_user_for_x' => 'User for :time',
221 + 'profile_created_content' => 'Created Content',
222 + 'profile_not_created_pages' => ':userName has not created any pages',
223 + 'profile_not_created_chapters' => ':userName has not created any chapters',
224 + 'profile_not_created_books' => ':userName has not created any books',
225 +];
...\ No newline at end of file ...\ No newline at end of file
...@@ -6,7 +6,65 @@ return [ ...@@ -6,7 +6,65 @@ return [
6 * Error text strings. 6 * Error text strings.
7 */ 7 */
8 8
9 - // Pages 9 + // Permissions
10 'permission' => 'You do not have permission to access the requested page.', 10 'permission' => 'You do not have permission to access the requested page.',
11 - 'permissionJson' => 'You do not have permission to perform the requested action.' 11 + 'permissionJson' => 'You do not have permission to perform the requested action.',
12 +
13 + // Auth
14 + 'error_user_exists_different_creds' => 'A user with the email :email already exists but with different credentials.',
15 + 'email_already_confirmed' => 'Email has already been confirmed, Try logging in.',
16 + 'email_confirmation_invalid' => 'This confirmation token is not valid or has already been used, Please try registering again.',
17 + 'email_confirmation_expired' => 'The confirmation token has expired, A new confirmation email has been sent.',
18 + 'ldap_fail_anonymous' => 'LDAP access failed using anonymous bind',
19 + 'ldap_fail_authed' => 'LDAP access failed using given dn & password details',
20 + 'ldap_extension_not_installed' => 'LDAP PHP extension not installed',
21 + 'ldap_cannot_connect' => 'Cannot connect to ldap server, Initial connection failed',
22 + 'social_no_action_defined' => 'No action defined',
23 + 'social_account_in_use' => 'This :socialAccount account is already in use, Try logging in via the :socialAccount option.',
24 + 'social_account_email_in_use' => 'The email :email is already in use. If you already have an account you can connect your :socialAccount account from your profile settings.',
25 + 'social_account_existing' => 'This :socialAccount is already attached to your profile.',
26 + 'social_account_already_used_existing' => 'This :socialAccount account is already used by another user.',
27 + 'social_account_not_used' => 'This :socialAccount account is not linked to any users. Please attach it in your profile settings. ',
28 + 'social_account_register_instructions' => 'If you do not yet have an account, You can register an account using the :socialAccount option.',
29 + 'social_driver_not_found' => 'Social driver not found',
30 + 'social_driver_not_configured' => 'Your :socialAccount social settings are not configured correctly.',
31 +
32 + // System
33 + 'path_not_writable' => 'File path :filePath could not be uploaded to. Ensure it is writable to the server.',
34 + 'cannot_get_image_from_url' => 'Cannot get image from :url',
35 + 'cannot_create_thumbs' => 'The server cannot create thumbnails. Please check you have the GD PHP extension installed.',
36 + 'server_upload_limit' => 'The server does not allow uploads of this size. Please try a smaller file size.',
37 + 'image_upload_error' => 'An error occurred uploading the image',
38 +
39 + // Attachments
40 + 'attachment_page_mismatch' => 'Page mismatch during attachment update',
41 +
42 + // Pages
43 + 'page_draft_autosave_fail' => 'Failed to save draft. Ensure you have internet connection before saving this page',
44 +
45 + // Entities
46 + 'entity_not_found' => 'Entity not found',
47 + 'book_not_found' => 'Book not found',
48 + 'page_not_found' => 'Page not found',
49 + 'chapter_not_found' => 'Chapter not found',
50 + 'selected_book_not_found' => 'The selected book was not found',
51 + 'selected_book_chapter_not_found' => 'The selected Book or Chapter was not found',
52 + 'guests_cannot_save_drafts' => 'Guests cannot save drafts',
53 +
54 + // Users
55 + 'users_cannot_delete_only_admin' => 'You cannot delete the only admin',
56 + 'users_cannot_delete_guest' => 'You cannot delete the guest user',
57 +
58 + // Roles
59 + 'role_cannot_be_edited' => 'This role cannot be edited',
60 + 'role_system_cannot_be_deleted' => 'This role is a system role and cannot be deleted',
61 + 'role_registration_default_cannot_delete' => 'This role cannot be deleted while set as the default registration role',
62 +
63 + // Error pages
64 + '404_page_not_found' => 'Page Not Found',
65 + 'sorry_page_not_found' => 'Sorry, The page you were looking for could not be found.',
66 + 'return_home' => 'Return to home',
67 + 'error_occurred' => 'An Error Occurred',
68 + 'app_down' => ':appName is down right now',
69 + 'back_soon' => 'It will be back up soon.',
12 ]; 70 ];
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -10,7 +10,12 @@ return [ ...@@ -10,7 +10,12 @@ return [
10 10
11 'settings' => 'Settings', 11 'settings' => 'Settings',
12 'settings_save' => 'Save Settings', 12 'settings_save' => 'Save Settings',
13 - 13 + 'settings_save_success' => 'Settings saved',
14 +
15 + /**
16 + * App settings
17 + */
18 +
14 'app_settings' => 'App Settings', 19 'app_settings' => 'App Settings',
15 'app_name' => 'Application name', 20 'app_name' => 'Application name',
16 'app_name_desc' => 'This name is shown in the header and any emails.', 21 'app_name_desc' => 'This name is shown in the header and any emails.',
...@@ -27,6 +32,10 @@ return [ ...@@ -27,6 +32,10 @@ return [
27 'app_primary_color' => 'Application primary color', 32 'app_primary_color' => 'Application primary color',
28 'app_primary_color_desc' => 'This should be a hex value. <br>Leave empty to reset to the default color.', 33 'app_primary_color_desc' => 'This should be a hex value. <br>Leave empty to reset to the default color.',
29 34
35 + /**
36 + * Registration settings
37 + */
38 +
30 'reg_settings' => 'Registration Settings', 39 'reg_settings' => 'Registration Settings',
31 'reg_allow' => 'Allow registration?', 40 'reg_allow' => 'Allow registration?',
32 'reg_default_role' => 'Default user role after registration', 41 'reg_default_role' => 'Default user role after registration',
...@@ -36,4 +45,96 @@ return [ ...@@ -36,4 +45,96 @@ return [
36 'reg_confirm_restrict_domain_desc' => 'Enter a comma separated list of email domains you would like to restrict registration to. Users will be sent an email to confirm their address before being allowed to interact with the application. <br> Note that users will be able to change their email addresses after successful registration.', 45 'reg_confirm_restrict_domain_desc' => 'Enter a comma separated list of email domains you would like to restrict registration to. Users will be sent an email to confirm their address before being allowed to interact with the application. <br> Note that users will be able to change their email addresses after successful registration.',
37 'reg_confirm_restrict_domain_placeholder' => 'No restriction set', 46 'reg_confirm_restrict_domain_placeholder' => 'No restriction set',
38 47
39 -];
...\ No newline at end of file ...\ No newline at end of file
48 + /**
49 + * Role settings
50 + */
51 +
52 + 'roles' => 'Roles',
53 + 'role_user_roles' => 'User Roles',
54 + 'role_create' => 'Create New Role',
55 + 'role_create_success' => 'Role successfully created',
56 + 'role_delete' => 'Delete Role',
57 + 'role_delete_confirm' => 'This will delete the role with the name \':roleName\'.',
58 + 'role_delete_users_assigned' => 'This role has :userCount users assigned to it. If you would like to migrate the users from this role select a new role below.',
59 + 'role_delete_no_migration' => "Don't migrate users",
60 + 'role_delete_sure' => 'Are you sure you want to delete this role?',
61 + 'role_delete_success' => 'Role successfully deleted',
62 + 'role_edit' => 'Edit Role',
63 + 'role_details' => 'Role Details',
64 + 'role_name' => 'Role Name',
65 + 'role_desc' => 'Short Description of Role',
66 + 'role_system' => 'System Permissions',
67 + 'role_manage_users' => 'Manage users',
68 + 'role_manage_roles' => 'Manage roles & role permissions',
69 + 'role_manage_entity_permissions' => 'Manage all book, chapter & page permissions',
70 + 'role_manage_own_entity_permissions' => 'Manage permissions on own book, chapter & pages',
71 + 'role_manage_settings' => 'Manage app settings',
72 + 'role_asset' => 'Asset Permissions',
73 + 'role_asset_desc' => 'These permissions control default access to the assets within the system. Permissions on Books, Chapters and Pages will override these permissions.',
74 + 'role_all' => 'All',
75 + 'role_own' => 'Own',
76 + 'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to',
77 + 'role_save' => 'Save Role',
78 + 'role_update_success' => 'Role successfully updated',
79 + 'role_users' => 'Users in this role',
80 + 'role_users_none' => 'No users are currently assigned to this role',
81 +
82 + /**
83 + * Users
84 + */
85 +
86 + 'users' => 'Users',
87 + 'user_profile' => 'User Profile',
88 + 'users_add_new' => 'Add New User',
89 + 'users_search' => 'Search Users',
90 + 'users_role' => 'User Roles',
91 + 'users_external_auth_id' => 'External Authentication ID',
92 + 'users_password_warning' => 'Only fill the below if you would like to change your password:',
93 + 'users_system_public' => 'This user represents any guest users that visit your instance. It cannot be used to log in but is assigned automatically.',
94 + 'users_delete' => 'Delete User',
95 + 'users_delete_named' => 'Delete ser :userName',
96 + 'users_delete_warning' => 'This will fully delete this user with the name \':userName\' from the system.',
97 + 'users_delete_confirm' => 'Are you sure you want to delete this user?',
98 + 'users_delete_success' => 'Users successfully removed',
99 + 'users_edit' => 'Edit User',
100 + 'users_edit_profile' => 'Edit Profile',
101 + 'users_edit_success' => 'User successfully updated',
102 + 'users_avatar' => 'User Avatar',
103 + 'users_avatar_desc' => 'This image should be approx 256px square.',
104 + 'users_social_accounts' => 'Social Accounts',
105 + 'users_social_accounts_info' => 'Here you can connect your other accounts for quicker and easier login. Disconnecting an account here does not previously authorized access. Revoke access from your profile settings on the connected social account.',
106 + 'users_social_connect' => 'Connect Account',
107 + 'users_social_disconnect' => 'Disconnect Account',
108 + 'users_social_connected' => ':socialAccount account was successfully attached to your profile.',
109 + 'users_social_disconnected' => ':socialAccount account was successfully disconnected from your profile.',
110 +];
111 +
112 +
113 +
114 +
115 +
116 +
117 +
118 +
119 +
120 +
121 +
122 +
123 +
124 +
125 +
126 +
127 +
128 +
129 +
130 +
131 +
132 +
133 +
134 +
135 +
136 +
137 +
138 +
139 +
140 +
......
...@@ -87,8 +87,8 @@ return [ ...@@ -87,8 +87,8 @@ return [
87 */ 87 */
88 88
89 'custom' => [ 89 'custom' => [
90 - 'attribute-name' => [ 90 + 'password-confirm' => [
91 - 'rule-name' => 'custom-message', 91 + 'required_with' => 'Password confirmation required',
92 ], 92 ],
93 ], 93 ],
94 94
......
1 <div class="form-group"> 1 <div class="form-group">
2 - <label for="username">Username</label> 2 + <label for="username">{{ trans('auth.username') }}</label>
3 @include('form/text', ['name' => 'username', 'tabindex' => 1]) 3 @include('form/text', ['name' => 'username', 'tabindex' => 1])
4 </div> 4 </div>
5 5
6 @if(session('request-email', false) === true) 6 @if(session('request-email', false) === true)
7 <div class="form-group"> 7 <div class="form-group">
8 - <label for="email">Email</label> 8 + <label for="email">{{ trans('auth.email') }}</label>
9 @include('form/text', ['name' => 'email', 'tabindex' => 1]) 9 @include('form/text', ['name' => 'email', 'tabindex' => 1])
10 <span class="text-neg"> 10 <span class="text-neg">
11 - Please enter an email to use for this account. 11 + {{ trans('auth.ldap_email_hint') }}
12 </span> 12 </span>
13 </div> 13 </div>
14 @endif 14 @endif
15 15
16 <div class="form-group"> 16 <div class="form-group">
17 - <label for="password">Password</label> 17 + <label for="password">{{ trans('auth.password') }}</label>
18 @include('form/password', ['name' => 'password', 'tabindex' => 2]) 18 @include('form/password', ['name' => 'password', 'tabindex' => 2])
19 </div> 19 </div>
...\ No newline at end of file ...\ No newline at end of file
......
1 <div class="form-group"> 1 <div class="form-group">
2 - <label for="email">Email</label> 2 + <label for="email">{{ trans('auth.email') }}</label>
3 @include('form/text', ['name' => 'email', 'tabindex' => 1]) 3 @include('form/text', ['name' => 'email', 'tabindex' => 1])
4 </div> 4 </div>
5 5
6 <div class="form-group"> 6 <div class="form-group">
7 - <label for="password">Password</label> 7 + <label for="password">{{ trans('auth.password') }}</label>
8 @include('form/password', ['name' => 'password', 'tabindex' => 2]) 8 @include('form/password', ['name' => 'password', 'tabindex' => 2])
9 - <span class="block small"><a href="{{ baseUrl('/password/email') }}">Forgot Password?</a></span> 9 + <span class="block small"><a href="{{ baseUrl('/password/email') }}">{{ trans('auth.forgot_password') }}</a></span>
10 </div> 10 </div>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
2 2
3 @section('header-buttons') 3 @section('header-buttons')
4 @if(setting('registration-enabled', false)) 4 @if(setting('registration-enabled', false))
5 - <a href="{{ baseUrl("/register") }}"><i class="zmdi zmdi-account-add"></i>Sign up</a> 5 + <a href="{{ baseUrl("/register") }}"><i class="zmdi zmdi-account-add"></i>{{ trans('auth.sign_up') }}</a>
6 @endif 6 @endif
7 @stop 7 @stop
8 8
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
10 10
11 <div class="text-center"> 11 <div class="text-center">
12 <div class="center-box"> 12 <div class="center-box">
13 - <h1>Log In</h1> 13 + <h1>{{ title_case(trans('auth.log_in')) }}</h1>
14 14
15 <form action="{{ baseUrl("/login") }}" method="POST" id="login-form"> 15 <form action="{{ baseUrl("/login") }}" method="POST" id="login-form">
16 {!! csrf_field() !!} 16 {!! csrf_field() !!}
...@@ -19,20 +19,20 @@ ...@@ -19,20 +19,20 @@
19 @include('auth/forms/login/' . $authMethod) 19 @include('auth/forms/login/' . $authMethod)
20 20
21 <div class="form-group"> 21 <div class="form-group">
22 - <label for="remember" class="inline">Remember Me</label> 22 + <label for="remember" class="inline">{{ trans('auth.remember_me') }}</label>
23 <input type="checkbox" id="remember" name="remember" class="toggle-switch-checkbox"> 23 <input type="checkbox" id="remember" name="remember" class="toggle-switch-checkbox">
24 <label for="remember" class="toggle-switch"></label> 24 <label for="remember" class="toggle-switch"></label>
25 </div> 25 </div>
26 26
27 27
28 <div class="from-group"> 28 <div class="from-group">
29 - <button class="button block pos" tabindex="3"><i class="zmdi zmdi-sign-in"></i> Sign In</button> 29 + <button class="button block pos" tabindex="3"><i class="zmdi zmdi-sign-in"></i> {{ title_case(trans('auth.log_in')) }}</button>
30 </div> 30 </div>
31 </form> 31 </form>
32 32
33 @if(count($socialDrivers) > 0) 33 @if(count($socialDrivers) > 0)
34 <hr class="margin-top"> 34 <hr class="margin-top">
35 - <h3 class="text-muted">Social Login</h3> 35 + <h3 class="text-muted">{{ trans('auth.social_login') }}</h3>
36 @if(isset($socialDrivers['google'])) 36 @if(isset($socialDrivers['google']))
37 <a href="{{ baseUrl("/login/service/google") }}" style="color: #DC4E41;"><i class="zmdi zmdi-google-plus-box zmdi-hc-4x"></i></a> 37 <a href="{{ baseUrl("/login/service/google") }}" style="color: #DC4E41;"><i class="zmdi zmdi-google-plus-box zmdi-hc-4x"></i></a>
38 @endif 38 @endif
......
1 @extends('public') 1 @extends('public')
2 2
3 @section('header-buttons') 3 @section('header-buttons')
4 - <a href="{{ baseUrl("/login") }}"><i class="zmdi zmdi-sign-in"></i>Sign in</a> 4 + <a href="{{ baseUrl("/login") }}"><i class="zmdi zmdi-sign-in"></i>{{ trans('auth.log_in') }}</a>
5 @if(setting('registration-enabled')) 5 @if(setting('registration-enabled'))
6 - <a href="{{ baseUrl("/register") }}"><i class="zmdi zmdi-account-add"></i>Sign up</a> 6 + <a href="{{ baseUrl("/register") }}"><i class="zmdi zmdi-account-add"></i>{{ trans('auth.sign_up') }}</a>
7 @endif 7 @endif
8 @stop 8 @stop
9 9
...@@ -12,20 +12,20 @@ ...@@ -12,20 +12,20 @@
12 12
13 <div class="text-center"> 13 <div class="text-center">
14 <div class="center-box text-left"> 14 <div class="center-box text-left">
15 - <h1>Reset Password</h1> 15 + <h1>{{ trans('auth.reset_password') }}</h1>
16 16
17 - <p class="muted small">Enter your email below and you will be sent an email with a password reset link.</p> 17 + <p class="muted small">{{ trans('auth.reset_password_send_instructions') }}</p>
18 18
19 <form action="{{ baseUrl("/password/email") }}" method="POST"> 19 <form action="{{ baseUrl("/password/email") }}" method="POST">
20 {!! csrf_field() !!} 20 {!! csrf_field() !!}
21 21
22 <div class="form-group"> 22 <div class="form-group">
23 - <label for="email">Email</label> 23 + <label for="email">{{ trans('auth.email') }}</label>
24 @include('form/text', ['name' => 'email']) 24 @include('form/text', ['name' => 'email'])
25 </div> 25 </div>
26 26
27 <div class="from-group"> 27 <div class="from-group">
28 - <button class="button block pos">Send Reset Link</button> 28 + <button class="button block pos">{{ trans('auth.reset_password_send_button') }}</button>
29 </div> 29 </div>
30 </form> 30 </form>
31 </div> 31 </div>
......
1 @extends('public') 1 @extends('public')
2 2
3 @section('header-buttons') 3 @section('header-buttons')
4 - <a href="{{ baseUrl("/login") }}"><i class="zmdi zmdi-sign-in"></i>Sign in</a> 4 + <a href="{{ baseUrl("/login") }}"><i class="zmdi zmdi-sign-in"></i>{{ trans('auth.log_in') }}</a>
5 @if(setting('registration-enabled')) 5 @if(setting('registration-enabled'))
6 - <a href="{{ baseUrl("/register") }}"><i class="zmdi zmdi-account-add"></i>Sign up</a> 6 + <a href="{{ baseUrl("/register") }}"><i class="zmdi zmdi-account-add"></i>{{ trans('auth.sign_up') }}</a>
7 @endif 7 @endif
8 @stop 8 @stop
9 9
...@@ -14,29 +14,29 @@ ...@@ -14,29 +14,29 @@
14 14
15 <div class="text-center"> 15 <div class="text-center">
16 <div class="center-box text-left"> 16 <div class="center-box text-left">
17 - <h1>Reset Password</h1> 17 + <h1>{{ trans('auth.reset_password') }}</h1>
18 18
19 <form action="{{ baseUrl("/password/reset") }}" method="POST"> 19 <form action="{{ baseUrl("/password/reset") }}" method="POST">
20 {!! csrf_field() !!} 20 {!! csrf_field() !!}
21 <input type="hidden" name="token" value="{{ $token }}"> 21 <input type="hidden" name="token" value="{{ $token }}">
22 22
23 <div class="form-group"> 23 <div class="form-group">
24 - <label for="email">Email</label> 24 + <label for="email">{{ trans('auth.email') }}</label>
25 @include('form/text', ['name' => 'email']) 25 @include('form/text', ['name' => 'email'])
26 </div> 26 </div>
27 27
28 <div class="form-group"> 28 <div class="form-group">
29 - <label for="password">Password</label> 29 + <label for="password">{{ trans('auth.password') }}</label>
30 @include('form/password', ['name' => 'password']) 30 @include('form/password', ['name' => 'password'])
31 </div> 31 </div>
32 32
33 <div class="form-group"> 33 <div class="form-group">
34 - <label for="password_confirmation">Confirm Password</label> 34 + <label for="password_confirmation">{{ trans('auth.password_confirm') }}</label>
35 @include('form/password', ['name' => 'password_confirmation']) 35 @include('form/password', ['name' => 'password_confirmation'])
36 </div> 36 </div>
37 37
38 <div class="from-group"> 38 <div class="from-group">
39 - <button class="button block pos">Reset Password</button> 39 + <button class="button block pos">{{ trans('auth.reset_password') }}</button>
40 </div> 40 </div>
41 </form> 41 </form>
42 </div> 42 </div>
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
2 2
3 @section('header-buttons') 3 @section('header-buttons')
4 @if(!$signedIn) 4 @if(!$signedIn)
5 - <a href="{{ baseUrl("/login") }}"><i class="zmdi zmdi-sign-in"></i>Sign in</a> 5 + <a href="{{ baseUrl("/login") }}"><i class="zmdi zmdi-sign-in"></i>{{ trans('auth.log_in') }}</a>
6 @endif 6 @endif
7 @stop 7 @stop
8 8
...@@ -10,10 +10,9 @@ ...@@ -10,10 +10,9 @@
10 10
11 <div class="text-center"> 11 <div class="text-center">
12 <div class="center-box"> 12 <div class="center-box">
13 - <h2>Thanks for registering!</h2> 13 + <h2>{{ trans('auth.register_thanks') }}</h2>
14 - <p>Please check your email and click the confirmation button to access {{ setting('app-name', 'BookStack') }}.</p> 14 + <p>{{ trans('auth.register_confirm', ['appName' => setting('app-name')]) }}</p>
15 </div> 15 </div>
16 </div> 16 </div>
17 17
18 -
19 @stop 18 @stop
......
1 @extends('public') 1 @extends('public')
2 2
3 @section('header-buttons') 3 @section('header-buttons')
4 - <a href="{{ baseUrl("/login") }}"><i class="zmdi zmdi-sign-in"></i>Sign in</a> 4 + <a href="{{ baseUrl("/login") }}"><i class="zmdi zmdi-sign-in"></i>{{ trans('auth.log_in') }}</a>
5 @stop 5 @stop
6 6
7 @section('content') 7 @section('content')
8 8
9 <div class="text-center"> 9 <div class="text-center">
10 <div class="center-box"> 10 <div class="center-box">
11 - <h1>Sign Up</h1> 11 + <h1>{{ title_case(trans('auth.sign_up')) }}</h1>
12 12
13 <form action="{{ baseUrl("/register") }}" method="POST"> 13 <form action="{{ baseUrl("/register") }}" method="POST">
14 {!! csrf_field() !!} 14 {!! csrf_field() !!}
15 15
16 <div class="form-group"> 16 <div class="form-group">
17 - <label for="email">Name</label> 17 + <label for="email">{{ trans('auth.name') }}</label>
18 @include('form/text', ['name' => 'name']) 18 @include('form/text', ['name' => 'name'])
19 </div> 19 </div>
20 20
21 <div class="form-group"> 21 <div class="form-group">
22 - <label for="email">Email</label> 22 + <label for="email">{{ trans('auth.email') }}</label>
23 @include('form/text', ['name' => 'email']) 23 @include('form/text', ['name' => 'email'])
24 </div> 24 </div>
25 25
26 <div class="form-group"> 26 <div class="form-group">
27 - <label for="password">Password</label> 27 + <label for="password">{{ trans('auth.password') }}</label>
28 - @include('form/password', ['name' => 'password', 'placeholder' => 'Must be over 5 characters']) 28 + @include('form/password', ['name' => 'password', 'placeholder' => trans('auth.password_hint')])
29 </div> 29 </div>
30 30
31 <div class="from-group"> 31 <div class="from-group">
32 - <button class="button block pos">Create Account</button> 32 + <button class="button block pos">{{ trans('auth.create_account') }}</button>
33 </div> 33 </div>
34 </form> 34 </form>
35 35
36 @if(count($socialDrivers) > 0) 36 @if(count($socialDrivers) > 0)
37 <hr class="margin-top"> 37 <hr class="margin-top">
38 - <h3 class="text-muted">Social Registration</h3> 38 + <h3 class="text-muted">{{ trans('auth.social_registration') }}</h3>
39 - <p class="text-small">Register and sign in using another service.</p> 39 + <p class="text-small">{{ trans('auth.social_registration_text') }}</p>
40 @if(isset($socialDrivers['google'])) 40 @if(isset($socialDrivers['google']))
41 <a href="{{ baseUrl("/register/service/google") }}" style="color: #DC4E41;"><i class="zmdi zmdi-google-plus-box zmdi-hc-4x"></i></a> 41 <a href="{{ baseUrl("/register/service/google") }}" style="color: #DC4E41;"><i class="zmdi zmdi-google-plus-box zmdi-hc-4x"></i></a>
42 @endif 42 @endif
......
...@@ -4,16 +4,16 @@ ...@@ -4,16 +4,16 @@
4 4
5 <div class="row"> 5 <div class="row">
6 <div class="col-md-6 col-md-offset-3"> 6 <div class="col-md-6 col-md-offset-3">
7 - <h2>Email Address not confirmed</h2> 7 + <h2>{{ trans('auth.email_not_confirmed') }}</h2>
8 - <p class="text-muted">Your email address has not yet been confirmed. <br> 8 + <p class="text-muted">{{ trans('auth.email_not_confirmed_text') }}<br>
9 - Please click the link in the email that was sent shortly after you registered. <br> 9 + {{ trans('auth.email_not_confirmed_click_link') }} <br>
10 - If you cannot find the email you can re-send the confirmation email by submitting the form below. 10 + {{ trans('auth.email_not_confirmed_resend') }}
11 </p> 11 </p>
12 <hr> 12 <hr>
13 <form action="{{ baseUrl("/register/confirm/resend") }}" method="POST"> 13 <form action="{{ baseUrl("/register/confirm/resend") }}" method="POST">
14 {!! csrf_field() !!} 14 {!! csrf_field() !!}
15 <div class="form-group"> 15 <div class="form-group">
16 - <label for="email">Email Address</label> 16 + <label for="email">{{ trans('auth.email') }}</label>
17 @if(auth()->check()) 17 @if(auth()->check())
18 @include('form/text', ['name' => 'email', 'model' => auth()->user()]) 18 @include('form/text', ['name' => 'email', 'model' => auth()->user()])
19 @else 19 @else
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
21 @endif 21 @endif
22 </div> 22 </div>
23 <div class="form-group"> 23 <div class="form-group">
24 - <button type="submit" class="button pos">Resend Confirmation Email</button> 24 + <button type="submit" class="button pos">{{ trans('auth.email_not_confirmed_resend_button') }}</button>
25 </div> 25 </div>
26 </form> 26 </form>
27 </div> 27 </div>
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
17 <!-- Scripts --> 17 <!-- Scripts -->
18 <script src="{{ baseUrl('/libs/jquery/jquery.min.js?version=2.1.4') }}"></script> 18 <script src="{{ baseUrl('/libs/jquery/jquery.min.js?version=2.1.4') }}"></script>
19 <script src="{{ baseUrl('/libs/jquery/jquery-ui.min.js?version=1.11.4') }}"></script> 19 <script src="{{ baseUrl('/libs/jquery/jquery-ui.min.js?version=1.11.4') }}"></script>
20 + <script src="{{ baseUrl('/translations.js') }}"></script>
20 21
21 @yield('head') 22 @yield('head')
22 23
...@@ -53,32 +54,16 @@ ...@@ -53,32 +54,16 @@
53 <div class="col-lg-4 col-sm-5"> 54 <div class="col-lg-4 col-sm-5">
54 <div class="float right"> 55 <div class="float right">
55 <div class="links text-center"> 56 <div class="links text-center">
56 - <a href="{{ baseUrl('/books') }}"><i class="zmdi zmdi-book"></i>Books</a> 57 + <a href="{{ baseUrl('/books') }}"><i class="zmdi zmdi-book"></i>{{ trans('entities.books') }}</a>
57 @if(isset($currentUser) && userCan('settings-manage')) 58 @if(isset($currentUser) && userCan('settings-manage'))
58 - <a href="{{ baseUrl('/settings') }}"><i class="zmdi zmdi-settings"></i>Settings</a> 59 + <a href="{{ baseUrl('/settings') }}"><i class="zmdi zmdi-settings"></i>{{ trans('settings.settings') }}</a>
59 @endif 60 @endif
60 @if(!isset($signedIn) || !$signedIn) 61 @if(!isset($signedIn) || !$signedIn)
61 - <a href="{{ baseUrl('/login') }}"><i class="zmdi zmdi-sign-in"></i>Sign In</a> 62 + <a href="{{ baseUrl('/login') }}"><i class="zmdi zmdi-sign-in"></i>{{ trans('auth.log_in') }}</a>
62 @endif 63 @endif
63 </div> 64 </div>
64 @if(isset($signedIn) && $signedIn) 65 @if(isset($signedIn) && $signedIn)
65 - <div class="dropdown-container" dropdown> 66 + @include('partials._header-dropdown', ['currentUser' => $currentUser])
66 - <span class="user-name" dropdown-toggle>
67 - <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}">
68 - <span class="name" ng-non-bindable>{{ $currentUser->getShortName(9) }}</span> <i class="zmdi zmdi-caret-down"></i>
69 - </span>
70 - <ul>
71 - <li>
72 - <a href="{{ baseUrl("/user/{$currentUser->id}") }}" class="text-primary"><i class="zmdi zmdi-account zmdi-hc-fw zmdi-hc-lg"></i>View Profile</a>
73 - </li>
74 - <li>
75 - <a href="{{ baseUrl("/settings/users/{$currentUser->id}") }}" class="text-primary"><i class="zmdi zmdi-edit zmdi-hc-fw zmdi-hc-lg"></i>Edit Profile</a>
76 - </li>
77 - <li>
78 - <a href="{{ baseUrl('/logout') }}" class="text-neg"><i class="zmdi zmdi-run zmdi-hc-fw zmdi-hc-lg"></i>Logout</a>
79 - </li>
80 - </ul>
81 - </div>
82 @endif 67 @endif
83 68
84 </div> 69 </div>
...@@ -93,7 +78,7 @@ ...@@ -93,7 +78,7 @@
93 78
94 <div id="back-to-top"> 79 <div id="back-to-top">
95 <div class="inner"> 80 <div class="inner">
96 - <i class="zmdi zmdi-chevron-up"></i> <span>Back to top</span> 81 + <i class="zmdi zmdi-chevron-up"></i> <span>{{ trans('common.back_to_top') }}</span>
97 </div> 82 </div>
98 </div> 83 </div>
99 @yield('bottom') 84 @yield('bottom')
......
1 +<div class="breadcrumbs">
2 + <a href="{{$book->getUrl()}}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $book->getShortName() }}</a>
3 +</div>
...\ No newline at end of file ...\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 @section('content') 3 @section('content')
4 4
5 <div class="container small" ng-non-bindable> 5 <div class="container small" ng-non-bindable>
6 - <h1>Create New Book</h1> 6 + <h1>{{ trans('entities.books_create') }}</h1>
7 <form action="{{ baseUrl("/books") }}" method="POST"> 7 <form action="{{ baseUrl("/books") }}" method="POST">
8 @include('books/form') 8 @include('books/form')
9 </form> 9 </form>
......
...@@ -2,16 +2,26 @@ ...@@ -2,16 +2,26 @@
2 2
3 @section('content') 3 @section('content')
4 4
5 + <div class="faded-small toolbar">
6 + <div class="container">
7 + <div class="row">
8 + <div class="col-sm-12 faded">
9 + @include('books._breadcrumbs', ['book' => $book])
10 + </div>
11 + </div>
12 + </div>
13 + </div>
14 +
5 <div class="container small" ng-non-bindable> 15 <div class="container small" ng-non-bindable>
6 - <h1>Delete Book</h1> 16 + <h1>{{ trans('entities.books_delete') }}</h1>
7 - <p>This will delete the book with the name '{{$book->name}}', All pages and chapters will be removed.</p> 17 + <p>{{ trans('entities.books_delete_explain', ['bookName' => $book->name]) }}</p>
8 - <p class="text-neg">Are you sure you want to delete this book?</p> 18 + <p class="text-neg">{{ trans('entities.books_delete_confirmation') }}</p>
9 19
10 <form action="{{$book->getUrl()}}" method="POST"> 20 <form action="{{$book->getUrl()}}" method="POST">
11 {!! csrf_field() !!} 21 {!! csrf_field() !!}
12 <input type="hidden" name="_method" value="DELETE"> 22 <input type="hidden" name="_method" value="DELETE">
13 - <a href="{{$book->getUrl()}}" class="button">Cancel</a> 23 + <a href="{{$book->getUrl()}}" class="button">{{ trans('common.cancel') }}</a>
14 - <button type="submit" class="button neg">Confirm</button> 24 + <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
15 </form> 25 </form>
16 </div> 26 </div>
17 27
......
...@@ -2,8 +2,18 @@ ...@@ -2,8 +2,18 @@
2 2
3 @section('content') 3 @section('content')
4 4
5 + <div class="faded-small toolbar">
6 + <div class="container">
7 + <div class="row">
8 + <div class="col-sm-12 faded">
9 + @include('books._breadcrumbs', ['book' => $book])
10 + </div>
11 + </div>
12 + </div>
13 + </div>
14 +
5 <div class="container small" ng-non-bindable> 15 <div class="container small" ng-non-bindable>
6 - <h1>Edit Book</h1> 16 + <h1>{{ trans('entities.books_edit') }}</h1>
7 <form action="{{ $book->getUrl() }}" method="POST"> 17 <form action="{{ $book->getUrl() }}" method="POST">
8 <input type="hidden" name="_method" value="PUT"> 18 <input type="hidden" name="_method" value="PUT">
9 @include('books/form', ['model' => $book]) 19 @include('books/form', ['model' => $book])
......
1 1
2 {{ csrf_field() }} 2 {{ csrf_field() }}
3 <div class="form-group title-input"> 3 <div class="form-group title-input">
4 - <label for="name">Book Name</label> 4 + <label for="name">{{ trans('common.name') }}</label>
5 @include('form/text', ['name' => 'name']) 5 @include('form/text', ['name' => 'name'])
6 </div> 6 </div>
7 7
8 <div class="form-group description-input"> 8 <div class="form-group description-input">
9 - <label for="description">Description</label> 9 + <label for="description">{{ trans('common.description') }}</label>
10 @include('form/textarea', ['name' => 'description']) 10 @include('form/textarea', ['name' => 'description'])
11 </div> 11 </div>
12 12
13 <div class="form-group"> 13 <div class="form-group">
14 - <a href="{{ back()->getTargetUrl() }}" class="button muted">Cancel</a> 14 + <a href="{{ back()->getTargetUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
15 - <button type="submit" class="button pos">Save Book</button> 15 + <button type="submit" class="button pos">{{ trans('entities.books_save') }}</button>
16 </div> 16 </div>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
9 <div class="col-xs-11 faded"> 9 <div class="col-xs-11 faded">
10 <div class="action-buttons"> 10 <div class="action-buttons">
11 @if($currentUser->can('book-create-all')) 11 @if($currentUser->can('book-create-all'))
12 - <a href="{{ baseUrl("/books/create") }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>Add new book</a> 12 + <a href="{{ baseUrl("/books/create") }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.books_create') }}</a>
13 @endif 13 @endif
14 </div> 14 </div>
15 </div> 15 </div>
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
21 <div class="container" ng-non-bindable> 21 <div class="container" ng-non-bindable>
22 <div class="row"> 22 <div class="row">
23 <div class="col-sm-7"> 23 <div class="col-sm-7">
24 - <h1>Books</h1> 24 + <h1>{{ trans('entities.books') }}</h1>
25 @if(count($books) > 0) 25 @if(count($books) > 0)
26 @foreach($books as $book) 26 @foreach($books as $book)
27 @include('books/list-item', ['book' => $book]) 27 @include('books/list-item', ['book' => $book])
...@@ -29,27 +29,27 @@ ...@@ -29,27 +29,27 @@
29 @endforeach 29 @endforeach
30 {!! $books->render() !!} 30 {!! $books->render() !!}
31 @else 31 @else
32 - <p class="text-muted">No books have been created.</p> 32 + <p class="text-muted">{{ trans('entities.books_empty') }}</p>
33 @if(userCan('books-create-all')) 33 @if(userCan('books-create-all'))
34 - <a href="{{ baseUrl("/books/create") }}" class="text-pos"><i class="zmdi zmdi-edit"></i>Create one now</a> 34 + <a href="{{ baseUrl("/books/create") }}" class="text-pos"><i class="zmdi zmdi-edit"></i>{{ trans('entities.create_one_now') }}</a>
35 @endif 35 @endif
36 @endif 36 @endif
37 </div> 37 </div>
38 <div class="col-sm-4 col-sm-offset-1"> 38 <div class="col-sm-4 col-sm-offset-1">
39 <div id="recents"> 39 <div id="recents">
40 @if($recents) 40 @if($recents)
41 - <div class="margin-top large">&nbsp;</div> 41 + <div class="margin-top">&nbsp;</div>
42 - <h3>Recently Viewed</h3> 42 + <h3>{{ trans('entities.recently_viewed') }}</h3>
43 @include('partials/entity-list', ['entities' => $recents]) 43 @include('partials/entity-list', ['entities' => $recents])
44 @endif 44 @endif
45 </div> 45 </div>
46 <div class="margin-top large">&nbsp;</div> 46 <div class="margin-top large">&nbsp;</div>
47 <div id="popular"> 47 <div id="popular">
48 - <h3>Popular Books</h3> 48 + <h3>{{ trans('entities.books_popular') }}</h3>
49 @if(count($popular) > 0) 49 @if(count($popular) > 0)
50 @include('partials/entity-list', ['entities' => $popular]) 50 @include('partials/entity-list', ['entities' => $popular])
51 @else 51 @else
52 - <p class="text-muted">The most popular books will appear here.</p> 52 + <p class="text-muted">{{ trans('entities.books_popular_empty') }}</p>
53 @endif 53 @endif
54 </div> 54 </div>
55 </div> 55 </div>
......
...@@ -6,9 +6,7 @@ ...@@ -6,9 +6,7 @@
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 <div class="col-sm-12 faded"> 8 <div class="col-sm-12 faded">
9 - <div class="breadcrumbs"> 9 + @include('books._breadcrumbs', ['book' => $book])
10 - <a href="{{$book->getUrl()}}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $book->getShortName() }}</a>
11 - </div>
12 </div> 10 </div>
13 </div> 11 </div>
14 </div> 12 </div>
...@@ -16,7 +14,7 @@ ...@@ -16,7 +14,7 @@
16 14
17 15
18 <div class="container" ng-non-bindable> 16 <div class="container" ng-non-bindable>
19 - <h1>Book Permissions</h1> 17 + <h1>{{ trans('entities.books_permissions') }}</h1>
20 @include('form/restriction-form', ['model' => $book]) 18 @include('form/restriction-form', ['model' => $book])
21 </div> 19 </div>
22 20
......
...@@ -5,29 +5,32 @@ ...@@ -5,29 +5,32 @@
5 <div class="faded-small toolbar"> 5 <div class="faded-small toolbar">
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 - <div class="col-md-12"> 8 + <div class="col-md-6 faded">
9 + @include('books._breadcrumbs', ['book' => $book])
10 + </div>
11 + <div class="col-md-6">
9 <div class="action-buttons faded"> 12 <div class="action-buttons faded">
10 @if(userCan('page-create', $book)) 13 @if(userCan('page-create', $book))
11 - <a href="{{ $book->getUrl('/page/create') }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i> New Page</a> 14 + <a href="{{ $book->getUrl('/page/create') }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.pages_new') }}</a>
12 @endif 15 @endif
13 @if(userCan('chapter-create', $book)) 16 @if(userCan('chapter-create', $book))
14 - <a href="{{ $book->getUrl('/chapter/create') }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i> New Chapter</a> 17 + <a href="{{ $book->getUrl('/chapter/create') }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.chapters_new') }}</a>
15 @endif 18 @endif
16 @if(userCan('book-update', $book)) 19 @if(userCan('book-update', $book))
17 - <a href="{{$book->getEditUrl()}}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>Edit</a> 20 + <a href="{{$book->getEditUrl()}}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>{{ trans('common.edit') }}</a>
18 @endif 21 @endif
19 @if(userCan('book-update', $book) || userCan('restrictions-manage', $book) || userCan('book-delete', $book)) 22 @if(userCan('book-update', $book) || userCan('restrictions-manage', $book) || userCan('book-delete', $book))
20 <div dropdown class="dropdown-container"> 23 <div dropdown class="dropdown-container">
21 <a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i></a> 24 <a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i></a>
22 <ul> 25 <ul>
23 @if(userCan('book-update', $book)) 26 @if(userCan('book-update', $book))
24 - <li><a href="{{ $book->getUrl('/sort') }}" class="text-primary"><i class="zmdi zmdi-sort"></i>Sort</a></li> 27 + <li><a href="{{ $book->getUrl('/sort') }}" class="text-primary"><i class="zmdi zmdi-sort"></i>{{ trans('common.sort') }}</a></li>
25 @endif 28 @endif
26 @if(userCan('restrictions-manage', $book)) 29 @if(userCan('restrictions-manage', $book))
27 - <li><a href="{{ $book->getUrl('/permissions') }}" class="text-primary"><i class="zmdi zmdi-lock-outline"></i>Permissions</a></li> 30 + <li><a href="{{ $book->getUrl('/permissions') }}" class="text-primary"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.permissions') }}</a></li>
28 @endif 31 @endif
29 @if(userCan('book-delete', $book)) 32 @if(userCan('book-delete', $book))
30 - <li><a href="{{ $book->getUrl('/delete') }}" class="text-neg"><i class="zmdi zmdi-delete"></i>Delete</a></li> 33 + <li><a href="{{ $book->getUrl('/delete') }}" class="text-neg"><i class="zmdi zmdi-delete"></i>{{ trans('common.delete') }}</a></li>
31 @endif 34 @endif
32 </ul> 35 </ul>
33 </div> 36 </div>
...@@ -59,23 +62,19 @@ ...@@ -59,23 +62,19 @@
59 <hr> 62 <hr>
60 @endforeach 63 @endforeach
61 @else 64 @else
62 - <p class="text-muted">No pages or chapters have been created for this book.</p> 65 + <p class="text-muted">{{ trans('entities.books_empty_contents') }}</p>
63 <p> 66 <p>
64 - <a href="{{ $book->getUrl('/page/create') }}" class="text-page"><i class="zmdi zmdi-file-text"></i>Create a new page</a> 67 + <a href="{{ $book->getUrl('/page/create') }}" class="text-page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.books_empty_create_page') }}</a>
65 - &nbsp;&nbsp;<em class="text-muted">-or-</em>&nbsp;&nbsp;&nbsp; 68 + &nbsp;&nbsp;<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>&nbsp;&nbsp;&nbsp;
66 - <a href="{{ $book->getUrl('/chapter/create') }}" class="text-chapter"><i class="zmdi zmdi-collection-bookmark"></i>Add a chapter</a> 69 + <a href="{{ $book->getUrl('/chapter/create') }}" class="text-chapter"><i class="zmdi zmdi-collection-bookmark"></i>{{ trans('entities.books_empty_add_chapter') }}</a>
67 </p> 70 </p>
68 <hr> 71 <hr>
69 @endif 72 @endif
70 - <p class="text-muted small"> 73 + @include('partials.entity-meta', ['entity' => $book])
71 - Created {{$book->created_at->diffForHumans()}} @if($book->createdBy) by <a href="{{ $book->createdBy->getProfileUrl() }}">{{$book->createdBy->name}}</a> @endif
72 - <br>
73 - Last Updated {{$book->updated_at->diffForHumans()}} @if($book->updatedBy) by <a href="{{ $book->updatedBy->getProfileUrl() }}">{{$book->updatedBy->name}}</a> @endif
74 - </p>
75 </div> 74 </div>
76 </div> 75 </div>
77 <div class="search-results" ng-cloak ng-show="searching"> 76 <div class="search-results" ng-cloak ng-show="searching">
78 - <h3 class="text-muted">Search Results <a ng-if="searching" ng-click="clearSearch()" class="text-small"><i class="zmdi zmdi-close"></i>Clear Search</a></h3> 77 + <h3 class="text-muted">{{ trans('entities.search_results') }} <a ng-if="searching" ng-click="clearSearch()" class="text-small"><i class="zmdi zmdi-close"></i>{{ trans('entities.search_clear') }}</a></h3>
79 <div ng-if="!searchResults"> 78 <div ng-if="!searchResults">
80 @include('partials/loading-icon') 79 @include('partials/loading-icon')
81 </div> 80 </div>
...@@ -90,21 +89,21 @@ ...@@ -90,21 +89,21 @@
90 @if($book->restricted) 89 @if($book->restricted)
91 <p class="text-muted"> 90 <p class="text-muted">
92 @if(userCan('restrictions-manage', $book)) 91 @if(userCan('restrictions-manage', $book))
93 - <a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>Book Permissions Active</a> 92 + <a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}</a>
94 @else 93 @else
95 - <i class="zmdi zmdi-lock-outline"></i>Book Permissions Active 94 + <i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}
96 @endif 95 @endif
97 </p> 96 </p>
98 @endif 97 @endif
99 <div class="search-box"> 98 <div class="search-box">
100 <form ng-submit="searchBook($event)"> 99 <form ng-submit="searchBook($event)">
101 - <input ng-model="searchTerm" ng-change="checkSearchForm()" type="text" name="term" placeholder="Search This Book"> 100 + <input ng-model="searchTerm" ng-change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.books_search_this') }}">
102 <button type="submit"><i class="zmdi zmdi-search"></i></button> 101 <button type="submit"><i class="zmdi zmdi-search"></i></button>
103 <button ng-if="searching" ng-click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button> 102 <button ng-if="searching" ng-click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>
104 </form> 103 </form>
105 </div> 104 </div>
106 <div class="activity anim fadeIn"> 105 <div class="activity anim fadeIn">
107 - <h3>Recent Activity</h3> 106 + <h3>{{ trans('entities.recent_activity') }}</h3>
108 @include('partials/activity-list', ['activity' => Activity::entityActivity($book, 20, 0)]) 107 @include('partials/activity-list', ['activity' => Activity::entityActivity($book, 20, 0)])
109 </div> 108 </div>
110 </div> 109 </div>
......
...@@ -6,8 +6,18 @@ ...@@ -6,8 +6,18 @@
6 6
7 @section('content') 7 @section('content')
8 8
9 + <div class="faded-small toolbar">
10 + <div class="container">
11 + <div class="row">
12 + <div class="col-sm-12 faded">
13 + @include('books._breadcrumbs', ['book' => $book])
14 + </div>
15 + </div>
16 + </div>
17 + </div>
18 +
9 <div class="container" ng-non-bindable> 19 <div class="container" ng-non-bindable>
10 - <h1>Sorting Pages & Chapters<span class="subheader">For {{ $book->name }}</span></h1> 20 + <h1>{{ trans('entities.books_sort') }}</h1>
11 <div class="row"> 21 <div class="row">
12 <div class="col-md-8" id="sort-boxes"> 22 <div class="col-md-8" id="sort-boxes">
13 23
...@@ -17,7 +27,7 @@ ...@@ -17,7 +27,7 @@
17 27
18 @if(count($books) > 1) 28 @if(count($books) > 1)
19 <div class="col-md-4"> 29 <div class="col-md-4">
20 - <h3>Show Other Books</h3> 30 + <h3>{{ trans('entities.books_sort_show_other') }}</h3>
21 <div id="additional-books"> 31 <div id="additional-books">
22 @foreach($books as $otherBook) 32 @foreach($books as $otherBook)
23 @if($otherBook->id !== $book->id) 33 @if($otherBook->id !== $book->id)
...@@ -37,8 +47,8 @@ ...@@ -37,8 +47,8 @@
37 <input type="hidden" name="_method" value="PUT"> 47 <input type="hidden" name="_method" value="PUT">
38 <input type="hidden" id="sort-tree-input" name="sort-tree"> 48 <input type="hidden" id="sort-tree-input" name="sort-tree">
39 <div class="list"> 49 <div class="list">
40 - <a href="{{ $book->getUrl() }}" class="button muted">Cancel</a> 50 + <a href="{{ $book->getUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
41 - <button class="button pos" type="submit">Save Order</button> 51 + <button class="button pos" type="submit">{{ trans('entities.books_sort_save') }}</button>
42 </div> 52 </div>
43 </form> 53 </form>
44 54
......
1 +<div class="breadcrumbs">
2 + <a href="{{ $chapter->book->getUrl() }}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $chapter->book->getShortName() }}</a>
3 + <span class="sep">&raquo;</span>
4 + <a href="{{ $chapter->getUrl() }}" class="text-chapter text-button"><i class="zmdi zmdi-collection-bookmark"></i>{{$chapter->getShortName()}}</a>
5 +</div>
...\ No newline at end of file ...\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 @section('content') 3 @section('content')
4 4
5 <div class="container small" ng-non-bindable> 5 <div class="container small" ng-non-bindable>
6 - <h1>Create New Chapter</h1> 6 + <h1>{{ trans('entities.chapters_create') }}</h1>
7 <form action="{{ $book->getUrl('/chapter/create') }}" method="POST"> 7 <form action="{{ $book->getUrl('/chapter/create') }}" method="POST">
8 @include('chapters/form') 8 @include('chapters/form')
9 </form> 9 </form>
......
...@@ -2,17 +2,26 @@ ...@@ -2,17 +2,26 @@
2 2
3 @section('content') 3 @section('content')
4 4
5 + <div class="faded-small toolbar">
6 + <div class="container">
7 + <div class="row">
8 + <div class="col-sm-12 faded">
9 + @include('chapters._breadcrumbs', ['chapter' => $chapter])
10 + </div>
11 + </div>
12 + </div>
13 + </div>
14 +
5 <div class="container small" ng-non-bindable> 15 <div class="container small" ng-non-bindable>
6 - <h1>Delete Chapter</h1> 16 + <h1>{{ trans('entities.chapters_delete') }}</h1>
7 - <p>This will delete the chapter with the name '{{$chapter->name}}', All pages will be removed 17 + <p>{{ trans('entities.chapters_delete_explain', ['chapterName' => $chapter->name]) }}</p>
8 - and added directly to the book.</p> 18 + <p class="text-neg">{{ trans('entities.chapters_delete_confirm') }}</p>
9 - <p class="text-neg">Are you sure you want to delete this chapter?</p>
10 19
11 <form action="{{ $chapter->getUrl() }}" method="POST"> 20 <form action="{{ $chapter->getUrl() }}" method="POST">
12 {!! csrf_field() !!} 21 {!! csrf_field() !!}
13 <input type="hidden" name="_method" value="DELETE"> 22 <input type="hidden" name="_method" value="DELETE">
14 - <a href="{{ $chapter->getUrl() }}" class="button primary">Cancel</a> 23 + <a href="{{ $chapter->getUrl() }}" class="button primary">{{ trans('common.cancel') }}</a>
15 - <button type="submit" class="button neg">Confirm</button> 24 + <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
16 </form> 25 </form>
17 </div> 26 </div>
18 27
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 @section('content') 3 @section('content')
4 4
5 <div class="container small" ng-non-bindable> 5 <div class="container small" ng-non-bindable>
6 - <h1>Edit Chapter</h1> 6 + <h1>{{ trans('entities.chapters_edit') }}</h1>
7 <form action="{{ $chapter->getUrl() }}" method="POST"> 7 <form action="{{ $chapter->getUrl() }}" method="POST">
8 <input type="hidden" name="_method" value="PUT"> 8 <input type="hidden" name="_method" value="PUT">
9 @include('chapters/form', ['model' => $chapter]) 9 @include('chapters/form', ['model' => $chapter])
......
...@@ -2,16 +2,16 @@ ...@@ -2,16 +2,16 @@
2 {!! csrf_field() !!} 2 {!! csrf_field() !!}
3 3
4 <div class="form-group title-input"> 4 <div class="form-group title-input">
5 - <label for="name">Chapter Name</label> 5 + <label for="name">{{ trans('common.name') }}</label>
6 @include('form/text', ['name' => 'name']) 6 @include('form/text', ['name' => 'name'])
7 </div> 7 </div>
8 8
9 <div class="form-group description-input"> 9 <div class="form-group description-input">
10 - <label for="description">Description</label> 10 + <label for="description">{{ trans('common.description') }}</label>
11 @include('form/textarea', ['name' => 'description']) 11 @include('form/textarea', ['name' => 'description'])
12 </div> 12 </div>
13 13
14 <div class="form-group"> 14 <div class="form-group">
15 - <a href="{{ back()->getTargetUrl() }}" class="button muted">Cancel</a> 15 + <a href="{{ back()->getTargetUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
16 - <button type="submit" class="button pos">Save Chapter</button> 16 + <button type="submit" class="button pos">{{ trans('entities.chapters_save') }}</button>
17 </div> 17 </div>
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 @endif 17 @endif
18 18
19 @if(!isset($hidePages) && count($chapter->pages) > 0) 19 @if(!isset($hidePages) && count($chapter->pages) > 0)
20 - <p class="text-muted chapter-toggle"><i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ count($chapter->pages) }} Pages</span></p> 20 + <p class="text-muted chapter-toggle"><i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ trans('entities.x_pages', ['count' => $chapter->pages->count()]) }}</span></p>
21 <div class="inset-list"> 21 <div class="inset-list">
22 @foreach($chapter->pages as $page) 22 @foreach($chapter->pages as $page)
23 <h5 class="@if($page->draft) draft @endif"><a href="{{ $page->getUrl() }}" class="text-page @if($page->draft) draft @endif"><i class="zmdi zmdi-file-text"></i>{{$page->name}}</a></h5> 23 <h5 class="@if($page->draft) draft @endif"><a href="{{ $page->getUrl() }}" class="text-page @if($page->draft) draft @endif"><i class="zmdi zmdi-file-text"></i>{{$page->name}}</a></h5>
......
...@@ -6,27 +6,23 @@ ...@@ -6,27 +6,23 @@
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 <div class="col-sm-12 faded"> 8 <div class="col-sm-12 faded">
9 - <div class="breadcrumbs"> 9 + @include('chapters._breadcrumbs', ['chapter' => $chapter])
10 - <a href="{{ $book->getUrl() }}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $book->getShortName() }}</a>
11 - <span class="sep">&raquo;</span>
12 - <a href="{{ $chapter->getUrl() }}" class="text-chapter text-button"><i class="zmdi zmdi-collection-bookmark"></i>{{ $chapter->getShortName() }}</a>
13 - </div>
14 </div> 10 </div>
15 </div> 11 </div>
16 </div> 12 </div>
17 </div> 13 </div>
18 14
19 <div class="container"> 15 <div class="container">
20 - <h1>Move Chapter <small class="subheader">{{$chapter->name}}</small></h1> 16 + <h1>{{ trans('entities.chapters_move') }}</h1>
21 17
22 <form action="{{ $chapter->getUrl('/move') }}" method="POST"> 18 <form action="{{ $chapter->getUrl('/move') }}" method="POST">
23 {!! csrf_field() !!} 19 {!! csrf_field() !!}
24 <input type="hidden" name="_method" value="PUT"> 20 <input type="hidden" name="_method" value="PUT">
25 21
26 - @include('partials/entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book']) 22 + @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book'])
27 23
28 - <a href="{{ $chapter->getUrl() }}" class="button muted">Cancel</a> 24 + <a href="{{ $chapter->getUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
29 - <button type="submit" class="button pos">Move Chapter</button> 25 + <button type="submit" class="button pos">{{ trans('entities.chapters_move') }}</button>
30 </form> 26 </form>
31 </div> 27 </div>
32 28
......
...@@ -6,18 +6,14 @@ ...@@ -6,18 +6,14 @@
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 <div class="col-sm-12 faded"> 8 <div class="col-sm-12 faded">
9 - <div class="breadcrumbs"> 9 + @include('chapters._breadcrumbs', ['chapter' => $chapter])
10 - <a href="{{ $chapter->book->getUrl() }}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $chapter->book->getShortName() }}</a>
11 - <span class="sep">&raquo;</span>
12 - <a href="{{ $chapter->getUrl() }}" class="text-chapter text-button"><i class="zmdi zmdi-collection-bookmark"></i>{{$chapter->getShortName()}}</a>
13 - </div>
14 </div> 10 </div>
15 </div> 11 </div>
16 </div> 12 </div>
17 </div> 13 </div>
18 14
19 <div class="container" ng-non-bindable> 15 <div class="container" ng-non-bindable>
20 - <h1>Chapter Permissions</h1> 16 + <h1>{{ trans('entities.chapters_permissions') }}</h1>
21 @include('form/restriction-form', ['model' => $chapter]) 17 @include('form/restriction-form', ['model' => $chapter])
22 </div> 18 </div>
23 19
......
...@@ -6,30 +6,28 @@ ...@@ -6,30 +6,28 @@
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 <div class="col-sm-8 faded" ng-non-bindable> 8 <div class="col-sm-8 faded" ng-non-bindable>
9 - <div class="breadcrumbs"> 9 + @include('chapters._breadcrumbs', ['chapter' => $chapter])
10 - <a href="{{ $book->getUrl() }}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $book->getShortName() }}</a>
11 - </div>
12 </div> 10 </div>
13 <div class="col-sm-4 faded"> 11 <div class="col-sm-4 faded">
14 <div class="action-buttons"> 12 <div class="action-buttons">
15 @if(userCan('page-create', $chapter)) 13 @if(userCan('page-create', $chapter))
16 - <a href="{{ $chapter->getUrl('/create-page') }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>New Page</a> 14 + <a href="{{ $chapter->getUrl('/create-page') }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.pages_new') }}</a>
17 @endif 15 @endif
18 @if(userCan('chapter-update', $chapter)) 16 @if(userCan('chapter-update', $chapter))
19 - <a href="{{ $chapter->getUrl('/edit') }}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>Edit</a> 17 + <a href="{{ $chapter->getUrl('/edit') }}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>{{ trans('common.edit') }}</a>
20 @endif 18 @endif
21 @if(userCan('chapter-update', $chapter) || userCan('restrictions-manage', $chapter) || userCan('chapter-delete', $chapter)) 19 @if(userCan('chapter-update', $chapter) || userCan('restrictions-manage', $chapter) || userCan('chapter-delete', $chapter))
22 <div dropdown class="dropdown-container"> 20 <div dropdown class="dropdown-container">
23 <a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i></a> 21 <a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i></a>
24 <ul> 22 <ul>
25 @if(userCan('chapter-update', $chapter)) 23 @if(userCan('chapter-update', $chapter))
26 - <li><a href="{{ $chapter->getUrl('/move') }}" class="text-primary"><i class="zmdi zmdi-folder"></i>Move</a></li> 24 + <li><a href="{{ $chapter->getUrl('/move') }}" class="text-primary"><i class="zmdi zmdi-folder"></i>{{ trans('common.move') }}</a></li>
27 @endif 25 @endif
28 @if(userCan('restrictions-manage', $chapter)) 26 @if(userCan('restrictions-manage', $chapter))
29 - <li><a href="{{ $chapter->getUrl('/permissions') }}" class="text-primary"><i class="zmdi zmdi-lock-outline"></i>Permissions</a></li> 27 + <li><a href="{{ $chapter->getUrl('/permissions') }}" class="text-primary"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.permissions') }}</a></li>
30 @endif 28 @endif
31 @if(userCan('chapter-delete', $chapter)) 29 @if(userCan('chapter-delete', $chapter))
32 - <li><a href="{{ $chapter->getUrl('/delete') }}" class="text-neg"><i class="zmdi zmdi-delete"></i>Delete</a></li> 30 + <li><a href="{{ $chapter->getUrl('/delete') }}" class="text-neg"><i class="zmdi zmdi-delete"></i>{{ trans('common.delete') }}</a></li>
33 @endif 31 @endif
34 </ul> 32 </ul>
35 </div> 33 </div>
...@@ -57,26 +55,22 @@ ...@@ -57,26 +55,22 @@
57 </div> 55 </div>
58 @else 56 @else
59 <hr> 57 <hr>
60 - <p class="text-muted">No pages are currently in this chapter.</p> 58 + <p class="text-muted">{{ trans('entities.chapters_empty') }}</p>
61 <p> 59 <p>
62 @if(userCan('page-create', $chapter)) 60 @if(userCan('page-create', $chapter))
63 - <a href="{{ $chapter->getUrl('/create-page') }}" class="text-page"><i class="zmdi zmdi-file-text"></i>Create a new page</a> 61 + <a href="{{ $chapter->getUrl('/create-page') }}" class="text-page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.books_empty_create_page') }}</a>
64 @endif 62 @endif
65 @if(userCan('page-create', $chapter) && userCan('book-update', $book)) 63 @if(userCan('page-create', $chapter) && userCan('book-update', $book))
66 - &nbsp;&nbsp;<em class="text-muted">-or-</em>&nbsp;&nbsp;&nbsp; 64 + &nbsp;&nbsp;<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>&nbsp;&nbsp;&nbsp;
67 @endif 65 @endif
68 @if(userCan('book-update', $book)) 66 @if(userCan('book-update', $book))
69 - <a href="{{ $book->getUrl('/sort') }}" class="text-book"><i class="zmdi zmdi-book"></i>Sort the current book</a> 67 + <a href="{{ $book->getUrl('/sort') }}" class="text-book"><i class="zmdi zmdi-book"></i>{{ trans('entities.books_empty_sort_current_book') }}</a>
70 @endif 68 @endif
71 </p> 69 </p>
72 <hr> 70 <hr>
73 @endif 71 @endif
74 72
75 - <p class="text-muted small"> 73 + @include('partials.entity-meta', ['entity' => $chapter])
76 - Created {{ $chapter->created_at->diffForHumans() }} @if($chapter->createdBy) by <a href="{{ $chapter->createdBy->getProfileUrl() }}">{{ $chapter->createdBy->name}}</a> @endif
77 - <br>
78 - Last Updated {{ $chapter->updated_at->diffForHumans() }} @if($chapter->updatedBy) by <a href="{{ $chapter->updatedBy->getProfileUrl() }}">{{ $chapter->updatedBy->name}}</a> @endif
79 - </p>
80 </div> 74 </div>
81 <div class="col-md-3 col-md-offset-1"> 75 <div class="col-md-3 col-md-offset-1">
82 <div class="margin-top large"></div> 76 <div class="margin-top large"></div>
...@@ -84,19 +78,20 @@ ...@@ -84,19 +78,20 @@
84 <div class="text-muted"> 78 <div class="text-muted">
85 79
86 @if($book->restricted) 80 @if($book->restricted)
87 - @if(userCan('restrictions-manage', $book)) 81 + <p class="text-muted">
88 - <a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>Book Permissions Active</a> 82 + @if(userCan('restrictions-manage', $book))
89 - @else 83 + <a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}</a>
90 - <i class="zmdi zmdi-lock-outline"></i>Book Permissions Active 84 + @else
91 - @endif 85 + <i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}
92 - <br> 86 + @endif
87 + </p>
93 @endif 88 @endif
94 89
95 @if($chapter->restricted) 90 @if($chapter->restricted)
96 @if(userCan('restrictions-manage', $chapter)) 91 @if(userCan('restrictions-manage', $chapter))
97 - <a href="{{ $chapter->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>Chapter Permissions Active</a> 92 + <a href="{{ $chapter->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.chapters_permissions_active') }}</a>
98 @else 93 @else
99 - <i class="zmdi zmdi-lock-outline"></i>Chapter Permissions Active 94 + <i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.chapters_permissions_active') }}
100 @endif 95 @endif
101 @endif 96 @endif
102 </div> 97 </div>
......
...@@ -2,12 +2,12 @@ ...@@ -2,12 +2,12 @@
2 <div class="overlay" entity-link-selector> 2 <div class="overlay" entity-link-selector>
3 <div class="popup-body small flex-child"> 3 <div class="popup-body small flex-child">
4 <div class="popup-header primary-background"> 4 <div class="popup-header primary-background">
5 - <div class="popup-title">Entity Select</div> 5 + <div class="popup-title">{{ trans('entities.entity_select') }}</div>
6 <button type="button" class="corner-button neg button popup-close">x</button> 6 <button type="button" class="corner-button neg button popup-close">x</button>
7 </div> 7 </div>
8 - @include('partials/entity-selector', ['name' => 'entity-selector']) 8 + @include('components.entity-selector', ['name' => 'entity-selector'])
9 <div class="popup-footer"> 9 <div class="popup-footer">
10 - <button type="button" disabled="true" class="button entity-link-selector-confirm pos corner-button">Select</button> 10 + <button type="button" disabled="true" class="button entity-link-selector-confirm pos corner-button">{{ trans('common.select') }}</button>
11 </div> 11 </div>
12 </div> 12 </div>
13 </div> 13 </div>
......
1 <div class="form-group"> 1 <div class="form-group">
2 <div entity-selector class="entity-selector {{$selectorSize or ''}}" entity-types="{{ $entityTypes or 'book,chapter,page' }}"> 2 <div entity-selector class="entity-selector {{$selectorSize or ''}}" entity-types="{{ $entityTypes or 'book,chapter,page' }}">
3 <input type="hidden" entity-selector-input name="{{$name}}" value=""> 3 <input type="hidden" entity-selector-input name="{{$name}}" value="">
4 - <input type="text" placeholder="Search" ng-model="search" ng-model-options="{debounce: 200}" ng-change="searchEntities()"> 4 + <input type="text" placeholder="{{ trans('common.search') }}" ng-model="search" ng-model-options="{debounce: 200}" ng-change="searchEntities()">
5 - <div class="text-center loading" ng-show="loading">@include('partials/loading-icon')</div> 5 + <div class="text-center loading" ng-show="loading">@include('partials.loading-icon')</div>
6 <div ng-show="!loading" ng-bind-html="entityResults"></div> 6 <div ng-show="!loading" ng-bind-html="entityResults"></div>
7 </div> 7 </div>
8 </div> 8 </div>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 <div class="popup-body" ng-click="$event.stopPropagation()"> 3 <div class="popup-body" ng-click="$event.stopPropagation()">
4 4
5 <div class="popup-header primary-background"> 5 <div class="popup-header primary-background">
6 - <div class="popup-title">Image Select</div> 6 + <div class="popup-title">{{ trans('components.image_select') }}</div>
7 <button class="popup-close neg corner-button button">x</button> 7 <button class="popup-close neg corner-button button">x</button>
8 </div> 8 </div>
9 9
...@@ -12,16 +12,16 @@ ...@@ -12,16 +12,16 @@
12 <div class="image-manager-content"> 12 <div class="image-manager-content">
13 <div ng-if="imageType === 'gallery'" class="container"> 13 <div ng-if="imageType === 'gallery'" class="container">
14 <div class="image-manager-header row faded-small nav-tabs"> 14 <div class="image-manager-header row faded-small nav-tabs">
15 - <div class="col-xs-4 tab-item" title="View all images" ng-class="{selected: (view=='all')}" ng-click="setView('all')"><i class="zmdi zmdi-collection-image"></i> All</div> 15 + <div class="col-xs-4 tab-item" title="{{ trans('components.image_all_title') }}" ng-class="{selected: (view=='all')}" ng-click="setView('all')"><i class="zmdi zmdi-collection-image"></i> {{ trans('components.image_all') }}</div>
16 - <div class="col-xs-4 tab-item" title="View images uploaded to this book" ng-class="{selected: (view=='book')}" ng-click="setView('book')"><i class="zmdi zmdi-book text-book"></i> Book</div> 16 + <div class="col-xs-4 tab-item" title="{{ trans('components.image_book_title') }}" ng-class="{selected: (view=='book')}" ng-click="setView('book')"><i class="zmdi zmdi-book text-book"></i> {{ trans('entities.book') }}</div>
17 - <div class="col-xs-4 tab-item" title="View images uploaded to this page" ng-class="{selected: (view=='page')}" ng-click="setView('page')"><i class="zmdi zmdi-file-text text-page"></i> Page</div> 17 + <div class="col-xs-4 tab-item" title="{{ trans('components.image_page_title') }}" ng-class="{selected: (view=='page')}" ng-click="setView('page')"><i class="zmdi zmdi-file-text text-page"></i> {{ trans('entities.page') }}</div>
18 </div> 18 </div>
19 </div> 19 </div>
20 <div ng-show="view === 'all'" > 20 <div ng-show="view === 'all'" >
21 <form ng-submit="searchImages()" class="contained-search-box"> 21 <form ng-submit="searchImages()" class="contained-search-box">
22 - <input type="text" placeholder="Search by image name" ng-model="searchTerm"> 22 + <input type="text" placeholder="{{ trans('components.image_search_hint') }}" ng-model="searchTerm">
23 - <button ng-class="{active: searching}" title="Clear Search" type="button" ng-click="cancelSearch()" class="text-button cancel"><i class="zmdi zmdi-close-circle-o"></i></button> 23 + <button ng-class="{active: searching}" title="{{ trans('common.search_clear') }}" type="button" ng-click="cancelSearch()" class="text-button cancel"><i class="zmdi zmdi-close-circle-o"></i></button>
24 - <button title="Search" class="text-button" type="submit"><i class="zmdi zmdi-search"></i></button> 24 + <button title="{{ trans('common.search') }}" class="text-button" type="submit"><i class="zmdi zmdi-search"></i></button>
25 </form> 25 </form>
26 </div> 26 </div>
27 <div class="image-manager-list"> 27 <div class="image-manager-list">
...@@ -31,11 +31,11 @@ ...@@ -31,11 +31,11 @@
31 <img ng-src="@{{image.thumbs.gallery}}" ng-attr-alt="@{{image.title}}" ng-attr-title="@{{image.name}}"> 31 <img ng-src="@{{image.thumbs.gallery}}" ng-attr-alt="@{{image.title}}" ng-attr-title="@{{image.name}}">
32 <div class="image-meta"> 32 <div class="image-meta">
33 <span class="name" ng-bind="image.name"></span> 33 <span class="name" ng-bind="image.name"></span>
34 - <span class="date">Uploaded @{{ getDate(image.created_at) }}</span> 34 + <span class="date">{{ trans('components.image_uploaded', ['uploadedDate' => "{{ getDate(image.created_at) }" . "}"]) }}</span>
35 </div> 35 </div>
36 </div> 36 </div>
37 </div> 37 </div>
38 - <div class="load-more" ng-show="hasMore" ng-click="fetchData()">Load More</div> 38 + <div class="load-more" ng-show="hasMore" ng-click="fetchData()">{{ trans('components.image_load_more') }}</div>
39 </div> 39 </div>
40 </div> 40 </div>
41 41
...@@ -51,15 +51,14 @@ ...@@ -51,15 +51,14 @@
51 </a> 51 </a>
52 </div> 52 </div>
53 <div class="form-group"> 53 <div class="form-group">
54 - <label for="name">Image Name</label> 54 + <label for="name">{{ trans('components.image_image_name') }}</label>
55 <input type="text" id="name" name="name" ng-model="selectedImage.name"> 55 <input type="text" id="name" name="name" ng-model="selectedImage.name">
56 </div> 56 </div>
57 </form> 57 </form>
58 58
59 <div ng-show="dependantPages"> 59 <div ng-show="dependantPages">
60 <p class="text-neg text-small"> 60 <p class="text-neg text-small">
61 - This image is used in the pages below, Click delete again to confirm you want to delete 61 + {{ trans('components.image_delete_confirm') }}
62 - this image.
63 </p> 62 </p>
64 <ul class="text-neg"> 63 <ul class="text-neg">
65 <li ng-repeat="page in dependantPages"> 64 <li ng-repeat="page in dependantPages">
...@@ -73,13 +72,13 @@ ...@@ -73,13 +72,13 @@
73 <button class="button icon neg"><i class="zmdi zmdi-delete"></i></button> 72 <button class="button icon neg"><i class="zmdi zmdi-delete"></i></button>
74 </form> 73 </form>
75 <button class="button pos anim fadeIn float right" ng-show="selectedImage" ng-click="selectButtonClick()"> 74 <button class="button pos anim fadeIn float right" ng-show="selectedImage" ng-click="selectButtonClick()">
76 - <i class="zmdi zmdi-square-right"></i>Select Image 75 + <i class="zmdi zmdi-square-right"></i>{{ trans('components.image_select_image') }}
77 </button> 76 </button>
78 </div> 77 </div>
79 78
80 </div> 79 </div>
81 80
82 - <drop-zone upload-url="@{{getUploadUrl()}}" uploaded-to="@{{uploadedTo}}" event-success="uploadSuccess"></drop-zone> 81 + <drop-zone message="{{ trans('components.image_dropzone') }}" upload-url="@{{getUploadUrl()}}" uploaded-to="@{{uploadedTo}}" event-success="uploadSuccess"></drop-zone>
83 82
84 83
85 </div> 84 </div>
......
1 +<div class="image-picker" image-picker="{{$name}}" data-default-image="{{ $defaultImage }}" data-resize-height="{{ $resizeHeight }}" data-resize-width="{{ $resizeWidth }}" data-current-id="{{ $currentId or '' }}" data-resize-crop="{{ $resizeCrop or '' }}">
2 +
3 + <div>
4 + <img @if($currentImage && $currentImage !== 'none') src="{{$currentImage}}" @else src="{{$defaultImage}}" @endif class="{{$imageClass}} @if($currentImage=== 'none') none @endif" alt="{{ trans('components.image_preview') }}">
5 + </div>
6 +
7 + <button class="button" type="button" data-action="show-image-manager">{{ trans('components.image_select_image') }}</button>
8 + <br>
9 + <button class="text-button" data-action="reset-image" type="button">{{ trans('common.reset') }}</button>
10 +
11 + @if ($showRemove)
12 + <span class="sep">|</span>
13 + <button class="text-button neg" data-action="remove-image" type="button">{{ trans('common.remove') }}</button>
14 + @endif
15 +
16 + <input type="hidden" name="{{$name}}" id="{{$name}}" value="{{ isset($currentId) && ($currentId !== '' && $currentId !== false) ? $currentId : $currentImage}}">
17 +</div>
18 +
19 +<script>
20 + (function(){
21 +
22 + var picker = document.querySelector('[image-picker="{{$name}}"]');
23 + picker.addEventListener('click', function(event) {
24 + if (event.target.nodeName.toLowerCase() !== 'button') return;
25 + var button = event.target;
26 + var action = button.getAttribute('data-action');
27 + var resize = picker.getAttribute('data-resize-height') && picker.getAttribute('data-resize-width');
28 + var usingIds = picker.getAttribute('data-current-id') !== '';
29 + var resizeCrop = picker.getAttribute('data-resize-crop') !== '';
30 + var imageElem = picker.querySelector('img');
31 + var input = picker.querySelector('input');
32 +
33 + function setImage(image) {
34 + if (image === 'none') {
35 + imageElem.src = picker.getAttribute('data-default-image');
36 + imageElem.classList.add('none');
37 + input.value = 'none';
38 + return;
39 + }
40 + imageElem.src = image.url;
41 + input.value = usingIds ? image.id : image.url;
42 + imageElem.classList.remove('none');
43 + }
44 +
45 + if (action === 'show-image-manager') {
46 + window.ImageManager.showExternal((image) => {
47 + if (!resize) {
48 + setImage(image);
49 + return;
50 + }
51 + var requestString = '/images/thumb/' + image.id + '/' + picker.getAttribute('data-resize-width') + '/' + picker.getAttribute('data-resize-height') + '/' + (resizeCrop ? 'true' : 'false');
52 + $.get(window.baseUrl(requestString), resp => {
53 + image.url = resp.url;
54 + setImage(image);
55 + });
56 + });
57 + } else if (action === 'reset-image') {
58 + setImage({id: 0, url: picker.getAttribute('data-default-image')});
59 + } else if (action === 'remove-image') {
60 + setImage('none');
61 + }
62 +
63 + });
64 +
65 + })();
66 +</script>
...\ No newline at end of file ...\ No newline at end of file
1 +<div toggle-switch="{{$name}}" class="toggle-switch @if($value) active @endif">
2 + <input type="hidden" name="{{$name}}" value="{{$value?'true':'false'}}"/>
3 + <div class="switch-handle"></div>
4 +</div>
5 +<script>
6 + (function() {
7 + var toggle = document.querySelector('[toggle-switch="{{$name}}"]');
8 + var toggleInput = toggle.querySelector('input');
9 + toggle.onclick = function(event) {
10 + var checked = toggleInput.value !== 'true';
11 + toggleInput.value = checked ? 'true' : 'false';
12 + checked ? toggle.classList.add('active') : toggle.classList.remove('active');
13 + };
14 + })()
15 +</script>
...\ No newline at end of file ...\ No newline at end of file
...@@ -4,9 +4,28 @@ ...@@ -4,9 +4,28 @@
4 4
5 5
6 <div class="container"> 6 <div class="container">
7 - <h1 class="text-muted">{{ $message or 'Page Not Found' }}</h1> 7 +
8 - <p>Sorry, The page you were looking for could not be found.</p> 8 +
9 - <a href="{{ baseUrl('/') }}" class="button">Return To Home</a> 9 + <h1>{{ $message or trans('errors.404_page_not_found') }}</h1>
10 + <p>{{ trans('errors.sorry_page_not_found') }}</p>
11 + <p><a href="{{ baseUrl('/') }}" class="button">{{ trans('errors.return_home') }}</a></p>
12 +
13 + <hr>
14 +
15 + <div class="row">
16 + <div class="col-md-4">
17 + <h3 class="text-muted">{{ trans('entities.pages_popular') }}</h3>
18 + @include('partials.entity-list', ['entities' => Views::getPopular(10, 0, [\BookStack\Page::class]), 'style' => 'compact'])
19 + </div>
20 + <div class="col-md-4">
21 + <h3 class="text-muted">{{ trans('entities.books_popular') }}</h3>
22 + @include('partials.entity-list', ['entities' => Views::getPopular(10, 0, [\BookStack\Book::class]), 'style' => 'compact'])
23 + </div>
24 + <div class="col-md-4">
25 + <h3 class="text-muted">{{ trans('entities.chapters_popular') }}</h3>
26 + @include('partials.entity-list', ['entities' => Views::getPopular(10, 0, [\BookStack\Chapter::class]), 'style' => 'compact'])
27 + </div>
28 + </div>
10 </div> 29 </div>
11 30
12 @stop 31 @stop
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 @section('content') 3 @section('content')
4 4
5 <div class="container"> 5 <div class="container">
6 - <h1 class="text-muted">An Error Occurred</h1> 6 + <h1 class="text-muted">{{ trans('errors.error_occurred') }}</h1>
7 <p>{{ $message }}</p> 7 <p>{{ $message }}</p>
8 </div> 8 </div>
9 9
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
3 @section('content') 3 @section('content')
4 4
5 <div class="container"> 5 <div class="container">
6 - <h1 class="text-muted">{{ setting('app-name') }} is down right now</h1> 6 + <h1 class="text-muted">{{ trans('errors.app_down', ['appName' => setting('app-name')]) }}</h1>
7 - <p>It will be back up soon.</p> 7 + <p>{{ trans('errors.back_soon') }}</p>
8 </div> 8 </div>
9 9
10 @stop 10 @stop
...\ No newline at end of file ...\ No newline at end of file
......
1 <form action="{{$url}}" method="POST" class="inline"> 1 <form action="{{$url}}" method="POST" class="inline">
2 {{ csrf_field() }} 2 {{ csrf_field() }}
3 <input type="hidden" name="_method" value="DELETE"> 3 <input type="hidden" name="_method" value="DELETE">
4 - <button type="submit" class="button neg">{{ isset($text) ? $text : 'Delete' }}</button> 4 + <button type="submit" class="button neg">{{ isset($text) ? $text : trans('common.delete') }}</button>
5 </form> 5 </form>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,31 +2,31 @@ ...@@ -2,31 +2,31 @@
2 {!! csrf_field() !!} 2 {!! csrf_field() !!}
3 <input type="hidden" name="_method" value="PUT"> 3 <input type="hidden" name="_method" value="PUT">
4 4
5 - <p>Once enabled, These permissions will take priority over any set role permissions.</p> 5 + <p>{{ trans('entities.permissions_intro') }}</p>
6 6
7 <div class="form-group"> 7 <div class="form-group">
8 - @include('form/checkbox', ['name' => 'restricted', 'label' => 'Enable custom permissions']) 8 + @include('form/checkbox', ['name' => 'restricted', 'label' => trans('entities.permissions_enable')])
9 </div> 9 </div>
10 10
11 11
12 <table class="table"> 12 <table class="table">
13 <tr> 13 <tr>
14 - <th>Role</th> 14 + <th>{{ trans('common.role') }}</th>
15 - <th @if($model->isA('page')) colspan="3" @else colspan="4" @endif>Actions</th> 15 + <th @if($model->isA('page')) colspan="3" @else colspan="4" @endif>{{ trans('common.actions') }}</th>
16 </tr> 16 </tr>
17 @foreach($roles as $role) 17 @foreach($roles as $role)
18 <tr> 18 <tr>
19 <td>{{ $role->display_name }}</td> 19 <td>{{ $role->display_name }}</td>
20 - <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => 'View', 'action' => 'view'])</td> 20 + <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.view'), 'action' => 'view'])</td>
21 @if(!$model->isA('page')) 21 @if(!$model->isA('page'))
22 - <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => 'Create', 'action' => 'create'])</td> 22 + <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.create'), 'action' => 'create'])</td>
23 @endif 23 @endif
24 - <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => 'Update', 'action' => 'update'])</td> 24 + <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.update'), 'action' => 'update'])</td>
25 - <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => 'Delete', 'action' => 'delete'])</td> 25 + <td>@include('form/restriction-checkbox', ['name'=>'restrictions', 'label' => trans('common.delete'), 'action' => 'delete'])</td>
26 </tr> 26 </tr>
27 @endforeach 27 @endforeach
28 </table> 28 </table>
29 29
30 - <a href="{{ $model->getUrl() }}" class="button muted">Cancel</a> 30 + <a href="{{ $model->getUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
31 - <button type="submit" class="button pos">Save Permissions</button> 31 + <button type="submit" class="button pos">{{ trans('entities.permissions_save') }}</button>
32 </form> 32 </form>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -5,14 +5,9 @@ ...@@ -5,14 +5,9 @@
5 <div class="faded-small toolbar"> 5 <div class="faded-small toolbar">
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 - <div class="col-sm-4 faded"> 8 + <div class="col-sm-6 faded">
9 <div class="action-buttons text-left"> 9 <div class="action-buttons text-left">
10 - <a data-action="expand-entity-list-details" class="text-primary text-button"><i class="zmdi zmdi-wrap-text"></i>Toggle Details</a> 10 + <a data-action="expand-entity-list-details" class="text-primary text-button"><i class="zmdi zmdi-wrap-text"></i>{{ trans('common.toggle_details') }}</a>
11 - </div>
12 - </div>
13 - <div class="col-sm-8 faded">
14 - <div class="action-buttons">
15 -
16 </div> 11 </div>
17 </div> 12 </div>
18 </div> 13 </div>
...@@ -25,44 +20,44 @@ ...@@ -25,44 +20,44 @@
25 <div class="col-sm-4"> 20 <div class="col-sm-4">
26 <div id="recent-drafts"> 21 <div id="recent-drafts">
27 @if(count($draftPages) > 0) 22 @if(count($draftPages) > 0)
28 - <h4>My Recent Drafts</h4> 23 + <h4>{{ trans('entities.my_recent_drafts') }}</h4>
29 @include('partials/entity-list', ['entities' => $draftPages, 'style' => 'compact']) 24 @include('partials/entity-list', ['entities' => $draftPages, 'style' => 'compact'])
30 @endif 25 @endif
31 </div> 26 </div>
32 @if($signedIn) 27 @if($signedIn)
33 - <h4>My Recently Viewed</h4> 28 + <h4>{{ trans('entities.my_recently_viewed') }}</h4>
34 @else 29 @else
35 - <h4>Recent Books</h4> 30 + <h4>{{ trans('entities.books_recent') }}</h4>
36 @endif 31 @endif
37 @include('partials/entity-list', [ 32 @include('partials/entity-list', [
38 'entities' => $recents, 33 'entities' => $recents,
39 'style' => 'compact', 34 'style' => 'compact',
40 - 'emptyText' => $signedIn ? 'You have not viewed any pages' : 'No books have been created' 35 + 'emptyText' => $signedIn ? trans('entities.no_pages_viewed') : trans('entities.books_empty')
41 ]) 36 ])
42 </div> 37 </div>
43 38
44 <div class="col-sm-4"> 39 <div class="col-sm-4">
45 - <h4><a class="no-color" href="{{ baseUrl("/pages/recently-created") }}">Recently Created Pages</a></h4> 40 + <h4><a class="no-color" href="{{ baseUrl("/pages/recently-created") }}">{{ trans('entities.recently_created_pages') }}</a></h4>
46 <div id="recently-created-pages"> 41 <div id="recently-created-pages">
47 @include('partials/entity-list', [ 42 @include('partials/entity-list', [
48 'entities' => $recentlyCreatedPages, 43 'entities' => $recentlyCreatedPages,
49 'style' => 'compact', 44 'style' => 'compact',
50 - 'emptyText' => 'No pages have been recently created' 45 + 'emptyText' => trans('entities.no_pages_recently_created')
51 ]) 46 ])
52 </div> 47 </div>
53 48
54 - <h4><a class="no-color" href="{{ baseUrl("/pages/recently-updated") }}">Recently Updated Pages</a></h4> 49 + <h4><a class="no-color" href="{{ baseUrl("/pages/recently-updated") }}">{{ trans('entities.recently_updated_pages') }}</a></h4>
55 <div id="recently-updated-pages"> 50 <div id="recently-updated-pages">
56 @include('partials/entity-list', [ 51 @include('partials/entity-list', [
57 'entities' => $recentlyUpdatedPages, 52 'entities' => $recentlyUpdatedPages,
58 'style' => 'compact', 53 'style' => 'compact',
59 - 'emptyText' => 'No pages have been recently updated' 54 + 'emptyText' => trans('entites.no_pages_recently_updated')
60 ]) 55 ])
61 </div> 56 </div>
62 </div> 57 </div>
63 58
64 <div class="col-sm-4" id="recent-activity"> 59 <div class="col-sm-4" id="recent-activity">
65 - <h4>Recent Activity</h4> 60 + <h4>{{ trans('entities.recent_activity') }}</h4>
66 @include('partials/activity-list', ['activity' => $activity]) 61 @include('partials/activity-list', ['activity' => $activity])
67 </div> 62 </div>
68 63
......
1 +<div class="breadcrumbs">
2 + <a href="{{ $page->book->getUrl() }}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $page->book->getShortName() }}</a>
3 + @if($page->hasChapter())
4 + <span class="sep">&raquo;</span>
5 + <a href="{{ $page->chapter->getUrl() }}" class="text-chapter text-button">
6 + <i class="zmdi zmdi-collection-bookmark"></i>
7 + {{ $page->chapter->getShortName() }}
8 + </a>
9 + @endif
10 + <span class="sep">&raquo;</span>
11 + <a href="{{ $page->getUrl() }}" class="text-page text-button"><i class="zmdi zmdi-file"></i>{{ $page->getShortName() }}</a>
12 +</div>
...\ No newline at end of file ...\ No newline at end of file
...@@ -2,15 +2,25 @@ ...@@ -2,15 +2,25 @@
2 2
3 @section('content') 3 @section('content')
4 4
5 + <div class="faded-small toolbar">
6 + <div class="container">
7 + <div class="row">
8 + <div class="col-sm-12 faded">
9 + @include('pages._breadcrumbs', ['page' => $page])
10 + </div>
11 + </div>
12 + </div>
13 + </div>
14 +
5 <div class="container small" ng-non-bindable> 15 <div class="container small" ng-non-bindable>
6 - <h1>Delete {{ $page->draft ? 'Draft' : '' }} Page</h1> 16 + <h1>{{ $page->draft ? trans('entities.pages_delete_draft') : trans('entities.pages_delete') }}</h1>
7 - <p class="text-neg">Are you sure you want to delete this {{ $page->draft ? 'draft' : '' }} page?</p> 17 + <p class="text-neg">{{ $page->draft ? trans('entities.pages_delete_draft_confirm'): trans('entities.pages_delete_confirm') }}</p>
8 18
9 <form action="{{ $page->getUrl() }}" method="POST"> 19 <form action="{{ $page->getUrl() }}" method="POST">
10 {!! csrf_field() !!} 20 {!! csrf_field() !!}
11 <input type="hidden" name="_method" value="DELETE"> 21 <input type="hidden" name="_method" value="DELETE">
12 - <a href="{{ $page->getUrl() }}" class="button primary">Cancel</a> 22 + <a href="{{ $page->getUrl() }}" class="button primary">{{ trans('common.cancel') }}</a>
13 - <button type="submit" class="button neg">Confirm</button> 23 + <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
14 </form> 24 </form>
15 </div> 25 </div>
16 26
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
20 20
21 </div> 21 </div>
22 22
23 - @include('partials/image-manager', ['imageType' => 'gallery', 'uploaded_to' => $page->id]) 23 + @include('components.image-manager', ['imageType' => 'gallery', 'uploaded_to' => $page->id])
24 - @include('partials/entity-selector-popup') 24 + @include('components.entity-selector-popup')
25 25
26 @stop 26 @stop
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -15,15 +15,11 @@ ...@@ -15,15 +15,11 @@
15 <div class="col-md-8 col-md-offset-2"> 15 <div class="col-md-8 col-md-offset-2">
16 <div class="page-content"> 16 <div class="page-content">
17 17
18 - @include('pages/page-display') 18 + @include('pages.page-display')
19 19
20 <hr> 20 <hr>
21 21
22 - <p class="text-muted small"> 22 + @include('partials.entity-meta', ['entity' => $page])
23 - Created {{$page->created_at->toDayDateTimeString()}} @if($page->createdBy) by {{$page->createdBy->name}} @endif
24 - <br>
25 - Last Updated {{$page->updated_at->toDayDateTimeString()}} @if($page->updatedBy) by {{$page->updatedBy->name}} @endif
26 - </p>
27 23
28 </div> 24 </div>
29 </div> 25 </div>
......
...@@ -3,22 +3,22 @@ ...@@ -3,22 +3,22 @@
3 3
4 <div class="tabs primary-background-light"> 4 <div class="tabs primary-background-light">
5 <span toolbox-toggle><i class="zmdi zmdi-caret-left-circle"></i></span> 5 <span toolbox-toggle><i class="zmdi zmdi-caret-left-circle"></i></span>
6 - <span toolbox-tab-button="tags" title="Page Tags" class="active"><i class="zmdi zmdi-tag"></i></span> 6 + <span toolbox-tab-button="tags" title="{{ trans('entities.page_tags') }}" class="active"><i class="zmdi zmdi-tag"></i></span>
7 @if(userCan('attachment-create-all')) 7 @if(userCan('attachment-create-all'))
8 - <span toolbox-tab-button="files" title="Attachments"><i class="zmdi zmdi-attachment"></i></span> 8 + <span toolbox-tab-button="files" title="{{ trans('entities.attachments') }}"><i class="zmdi zmdi-attachment"></i></span>
9 @endif 9 @endif
10 </div> 10 </div>
11 11
12 <div toolbox-tab-content="tags" ng-controller="PageTagController" page-id="{{ $page->id or 0 }}"> 12 <div toolbox-tab-content="tags" ng-controller="PageTagController" page-id="{{ $page->id or 0 }}">
13 - <h4>Page Tags</h4> 13 + <h4>{{ trans('entities.page_tags') }}</h4>
14 <div class="padded tags"> 14 <div class="padded tags">
15 - <p class="muted small">Add some tags to better categorise your content. <br> You can assign a value to a tag for more in-depth organisation.</p> 15 + <p class="muted small">{!! nl2br(e(trans('entities.tags_explain'))) !!}</p>
16 <table class="no-style" tag-autosuggestions style="width: 100%;"> 16 <table class="no-style" tag-autosuggestions style="width: 100%;">
17 <tbody ui-sortable="sortOptions" ng-model="tags" > 17 <tbody ui-sortable="sortOptions" ng-model="tags" >
18 <tr ng-repeat="tag in tags track by $index"> 18 <tr ng-repeat="tag in tags track by $index">
19 <td width="20" ><i class="handle zmdi zmdi-menu"></i></td> 19 <td width="20" ><i class="handle zmdi zmdi-menu"></i></td>
20 - <td><input autosuggest="{{ baseUrl('/ajax/tags/suggest/names') }}" autosuggest-type="name" class="outline" ng-attr-name="tags[@{{$index}}][name]" type="text" ng-model="tag.name" ng-change="tagChange(tag)" ng-blur="tagBlur(tag)" placeholder="Tag"></td> 20 + <td><input autosuggest="{{ baseUrl('/ajax/tags/suggest/names') }}" autosuggest-type="name" class="outline" ng-attr-name="tags[@{{$index}}][name]" type="text" ng-model="tag.name" ng-change="tagChange(tag)" ng-blur="tagBlur(tag)" placeholder="{{ trans('entities.tag') }}"></td>
21 - <td><input autosuggest="{{ baseUrl('/ajax/tags/suggest/values') }}" autosuggest-type="value" class="outline" ng-attr-name="tags[@{{$index}}][value]" type="text" ng-model="tag.value" ng-change="tagChange(tag)" ng-blur="tagBlur(tag)" placeholder="Tag Value (Optional)"></td> 21 + <td><input autosuggest="{{ baseUrl('/ajax/tags/suggest/values') }}" autosuggest-type="value" class="outline" ng-attr-name="tags[@{{$index}}][value]" type="text" ng-model="tag.value" ng-change="tagChange(tag)" ng-blur="tagBlur(tag)" placeholder="{{ trans('entities.tag_value') }}"></td>
22 <td width="10" ng-show="tags.length != 1" class="text-center text-neg" style="padding: 0;" ng-click="removeTag(tag)"><i class="zmdi zmdi-close"></i></td> 22 <td width="10" ng-show="tags.length != 1" class="text-center text-neg" style="padding: 0;" ng-click="removeTag(tag)"><i class="zmdi zmdi-close"></i></td>
23 </tr> 23 </tr>
24 </tbody> 24 </tbody>
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
28 <tr class="unsortable"> 28 <tr class="unsortable">
29 <td width="34"></td> 29 <td width="34"></td>
30 <td ng-click="addEmptyTag()"> 30 <td ng-click="addEmptyTag()">
31 - <button type="button" class="text-button">Add another tag</button> 31 + <button type="button" class="text-button">{{ trans('entities.tags_add') }}</button>
32 </td> 32 </td>
33 <td></td> 33 <td></td>
34 </tr> 34 </tr>
...@@ -39,17 +39,17 @@ ...@@ -39,17 +39,17 @@
39 39
40 @if(userCan('attachment-create-all')) 40 @if(userCan('attachment-create-all'))
41 <div toolbox-tab-content="files" ng-controller="PageAttachmentController" page-id="{{ $page->id or 0 }}"> 41 <div toolbox-tab-content="files" ng-controller="PageAttachmentController" page-id="{{ $page->id or 0 }}">
42 - <h4>Attachments</h4> 42 + <h4>{{ trans('entities.attachments') }}</h4>
43 <div class="padded files"> 43 <div class="padded files">
44 44
45 <div id="file-list" ng-show="!editFile"> 45 <div id="file-list" ng-show="!editFile">
46 - <p class="muted small">Upload some files or attach some link to display on your page. These are visible in the page sidebar. <span class="secondary">Changes here are saved instantly.</span></p> 46 + <p class="muted small">{{ trans('entities.attachments_explain') }} <span class="secondary">{{ trans('entities.attachments_explain_instant_save') }}</span></p>
47 47
48 <div tab-container> 48 <div tab-container>
49 <div class="nav-tabs"> 49 <div class="nav-tabs">
50 - <div tab-button="list" class="tab-item">Attached Items</div> 50 + <div tab-button="list" class="tab-item">{{ trans('entities.attachments_items') }}</div>
51 - <div tab-button="file" class="tab-item">Upload File</div> 51 + <div tab-button="file" class="tab-item">{{ trans('entities.attachments_upload') }}</div>
52 - <div tab-button="link" class="tab-item">Attach Link</div> 52 + <div tab-button="link" class="tab-item">{{ trans('entities.attachments_link') }}</div>
53 </div> 53 </div>
54 <div tab-content="list"> 54 <div tab-content="list">
55 <table class="file-table" style="width: 100%;"> 55 <table class="file-table" style="width: 100%;">
...@@ -59,9 +59,9 @@ ...@@ -59,9 +59,9 @@
59 <td> 59 <td>
60 <a ng-href="@{{getFileUrl(file)}}" target="_blank" ng-bind="file.name"></a> 60 <a ng-href="@{{getFileUrl(file)}}" target="_blank" ng-bind="file.name"></a>
61 <div ng-if="file.deleting"> 61 <div ng-if="file.deleting">
62 - <span class="neg small">Click delete again to confirm you want to delete this attachment.</span> 62 + <span class="neg small">{{ trans('entities.attachments_delete_confirm') }}</span>
63 <br> 63 <br>
64 - <span class="text-primary small" ng-click="file.deleting=false;">Cancel</span> 64 + <span class="text-primary small" ng-click="file.deleting=false;">{{ trans('common.cancel') }}</span>
65 </div> 65 </div>
66 </td> 66 </td>
67 <td width="10" ng-click="startEdit(file)" class="text-center text-primary" style="padding: 0;"><i class="zmdi zmdi-edit"></i></td> 67 <td width="10" ng-click="startEdit(file)" class="text-center text-primary" style="padding: 0;"><i class="zmdi zmdi-edit"></i></td>
...@@ -71,25 +71,25 @@ ...@@ -71,25 +71,25 @@
71 </tbody> 71 </tbody>
72 </table> 72 </table>
73 <p class="small muted" ng-if="files.length == 0"> 73 <p class="small muted" ng-if="files.length == 0">
74 - No files have been uploaded. 74 + {{ trans('entities.attachments_no_files') }}
75 </p> 75 </p>
76 </div> 76 </div>
77 <div tab-content="file"> 77 <div tab-content="file">
78 - <drop-zone upload-url="@{{getUploadUrl()}}" uploaded-to="@{{uploadedTo}}" event-success="uploadSuccess"></drop-zone> 78 + <drop-zone message="{{ trans('entities.attachments_dropzone') }}" upload-url="@{{getUploadUrl()}}" uploaded-to="@{{uploadedTo}}" event-success="uploadSuccess"></drop-zone>
79 </div> 79 </div>
80 <div tab-content="link" sub-form="attachLinkSubmit(file)"> 80 <div tab-content="link" sub-form="attachLinkSubmit(file)">
81 - <p class="muted small">You can attach a link if you'd prefer not to upload a file. This can be a link to another page or a link to a file in the cloud.</p> 81 + <p class="muted small">{{ trans('entities.attachments_explain_link') }}</p>
82 <div class="form-group"> 82 <div class="form-group">
83 - <label for="attachment-via-link">Link Name</label> 83 + <label for="attachment-via-link">{{ trans('entities.attachments_link_name') }}</label>
84 - <input type="text" placeholder="Link name" ng-model="file.name"> 84 + <input type="text" placeholder="{{ trans('entities.attachments_link_name') }}" ng-model="file.name">
85 <p class="small neg" ng-repeat="error in errors.link.name" ng-bind="error"></p> 85 <p class="small neg" ng-repeat="error in errors.link.name" ng-bind="error"></p>
86 </div> 86 </div>
87 <div class="form-group"> 87 <div class="form-group">
88 - <label for="attachment-via-link">Link to file</label> 88 + <label for="attachment-via-link">{{ trans('entities.attachments_link_url') }}</label>
89 - <input type="text" placeholder="Url of site or file" ng-model="file.link"> 89 + <input type="text" placeholder="{{ trans('entities.attachments_link_url_hint') }}" ng-model="file.link">
90 <p class="small neg" ng-repeat="error in errors.link.link" ng-bind="error"></p> 90 <p class="small neg" ng-repeat="error in errors.link.link" ng-bind="error"></p>
91 </div> 91 </div>
92 - <button type="submit" class="button pos">Attach</button> 92 + <button type="submit" class="button pos">{{ trans('entities.attach') }}</button>
93 93
94 </div> 94 </div>
95 </div> 95 </div>
...@@ -97,34 +97,34 @@ ...@@ -97,34 +97,34 @@
97 </div> 97 </div>
98 98
99 <div id="file-edit" ng-if="editFile" sub-form="updateFile(editFile)"> 99 <div id="file-edit" ng-if="editFile" sub-form="updateFile(editFile)">
100 - <h5>Edit File</h5> 100 + <h5>{{ trans('entities.attachments_edit_file') }}</h5>
101 101
102 <div class="form-group"> 102 <div class="form-group">
103 - <label for="attachment-name-edit">File Name</label> 103 + <label for="attachment-name-edit">{{ trans('entities.attachments_edit_file_name') }}</label>
104 - <input type="text" id="attachment-name-edit" placeholder="File name" ng-model="editFile.name"> 104 + <input type="text" id="attachment-name-edit" placeholder="{{ trans('entities.attachments_edit_file_name') }}" ng-model="editFile.name">
105 <p class="small neg" ng-repeat="error in errors.edit.name" ng-bind="error"></p> 105 <p class="small neg" ng-repeat="error in errors.edit.name" ng-bind="error"></p>
106 </div> 106 </div>
107 107
108 <div tab-container="@{{ editFile.external ? 'link' : 'file' }}"> 108 <div tab-container="@{{ editFile.external ? 'link' : 'file' }}">
109 <div class="nav-tabs"> 109 <div class="nav-tabs">
110 - <div tab-button="file" class="tab-item">Upload File</div> 110 + <div tab-button="file" class="tab-item">{{ trans('entities.attachments_upload') }}</div>
111 - <div tab-button="link" class="tab-item">Set Link</div> 111 + <div tab-button="link" class="tab-item">{{ trans('entities.attachments_set_link') }}</div>
112 </div> 112 </div>
113 <div tab-content="file"> 113 <div tab-content="file">
114 - <drop-zone upload-url="@{{getUploadUrl(editFile)}}" uploaded-to="@{{uploadedTo}}" placeholder="Drop files or click here to upload and overwrite" event-success="uploadSuccessUpdate"></drop-zone> 114 + <drop-zone upload-url="@{{getUploadUrl(editFile)}}" uploaded-to="@{{uploadedTo}}" placeholder="{{ trans('entities.attachments_edit_drop_upload') }}" event-success="uploadSuccessUpdate"></drop-zone>
115 <br> 115 <br>
116 </div> 116 </div>
117 <div tab-content="link"> 117 <div tab-content="link">
118 <div class="form-group"> 118 <div class="form-group">
119 - <label for="attachment-link-edit">Link to file</label> 119 + <label for="attachment-link-edit">{{ trans('entities.attachments_link_url') }}</label>
120 - <input type="text" id="attachment-link-edit" placeholder="Attachment link" ng-model="editFile.link"> 120 + <input type="text" id="attachment-link-edit" placeholder="{{ trans('entities.attachment_link') }}" ng-model="editFile.link">
121 <p class="small neg" ng-repeat="error in errors.edit.link" ng-bind="error"></p> 121 <p class="small neg" ng-repeat="error in errors.edit.link" ng-bind="error"></p>
122 </div> 122 </div>
123 </div> 123 </div>
124 </div> 124 </div>
125 125
126 - <button type="button" class="button" ng-click="cancelEdit()">Back</button> 126 + <button type="button" class="button" ng-click="cancelEdit()">{{ trans('common.back') }}</button>
127 - <button type="submit" class="button pos">Save</button> 127 + <button type="submit" class="button pos">{{ trans('common.save') }}</button>
128 </div> 128 </div>
129 129
130 </div> 130 </div>
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
9 <div class="row"> 9 <div class="row">
10 <div class="col-sm-4 faded"> 10 <div class="col-sm-4 faded">
11 <div class="action-buttons text-left"> 11 <div class="action-buttons text-left">
12 - <a href="{{ back()->getTargetUrl() }}" class="text-button text-primary"><i class="zmdi zmdi-arrow-left"></i>Back</a> 12 + <a href="{{ back()->getTargetUrl() }}" class="text-button text-primary"><i class="zmdi zmdi-arrow-left"></i>{{ trans('common.back') }}</a>
13 - <a onclick="$('body>header').slideToggle();" class="text-button text-primary"><i class="zmdi zmdi-swap-vertical"></i>Toggle Header</a> 13 + <a onclick="$('body>header').slideToggle();" class="text-button text-primary"><i class="zmdi zmdi-swap-vertical"></i>{{ trans('entities.pages_edit_toggle_header') }}</a>
14 </div> 14 </div>
15 </div> 15 </div>
16 <div class="col-sm-4 faded text-center"> 16 <div class="col-sm-4 faded text-center">
...@@ -20,13 +20,13 @@ ...@@ -20,13 +20,13 @@
20 <i class="zmdi zmdi-check-circle text-pos draft-notification" ng-class="{visible: draftUpdated}"></i> 20 <i class="zmdi zmdi-check-circle text-pos draft-notification" ng-class="{visible: draftUpdated}"></i>
21 <ul> 21 <ul>
22 <li> 22 <li>
23 - <a ng-click="forceDraftSave()" class="text-pos"><i class="zmdi zmdi-save"></i>Save Draft</a> 23 + <a ng-click="forceDraftSave()" class="text-pos"><i class="zmdi zmdi-save"></i>{{ trans('entities.pages_edit_save_draft') }}</a>
24 </li> 24 </li>
25 <li ng-if="isNewPageDraft"> 25 <li ng-if="isNewPageDraft">
26 - <a href="{{ $model->getUrl('/delete') }}" class="text-neg"><i class="zmdi zmdi-delete"></i>Delete Draft</a> 26 + <a href="{{ $model->getUrl('/delete') }}" class="text-neg"><i class="zmdi zmdi-delete"></i>{{ trans('entities.pages_edit_delete_draft') }}</a>
27 </li> 27 </li>
28 <li> 28 <li>
29 - <a type="button" ng-if="isUpdateDraft" ng-click="discardDraft()" class="text-neg"><i class="zmdi zmdi-close-circle"></i>Discard Draft</a> 29 + <a type="button" ng-if="isUpdateDraft" ng-click="discardDraft()" class="text-neg"><i class="zmdi zmdi-close-circle"></i>{{ trans('entities.pages_edit_discard_draft') }}</a>
30 </li> 30 </li>
31 </ul> 31 </ul>
32 </div> 32 </div>
...@@ -34,16 +34,16 @@ ...@@ -34,16 +34,16 @@
34 <div class="col-sm-4 faded"> 34 <div class="col-sm-4 faded">
35 <div class="action-buttons" ng-cloak> 35 <div class="action-buttons" ng-cloak>
36 <div dropdown class="dropdown-container"> 36 <div dropdown class="dropdown-container">
37 - <a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-edit"></i> @{{(changeSummary | limitTo:16) + (changeSummary.length>16?'...':'') || 'Set Changelog'}}</a> 37 + <a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-edit"></i> <span ng-bind="(changeSummary | limitTo:16) + (changeSummary.length>16?'...':'') || '{{ trans('entities.pages_edit_set_changelog') }}'"></span></a>
38 <ul class="wide"> 38 <ul class="wide">
39 <li class="padded"> 39 <li class="padded">
40 - <p class="text-muted">Enter a brief description of the changes you've made</p> 40 + <p class="text-muted">{{ trans('entities.pages_edit_enter_changelog_desc') }}</p>
41 - <input name="summary" id="summary-input" type="text" placeholder="Enter Changelog" ng-model="changeSummary" /> 41 + <input name="summary" id="summary-input" type="text" placeholder="{{ trans('entities.pages_edit_enter_changelog') }}" ng-model="changeSummary" />
42 </li> 42 </li>
43 </ul> 43 </ul>
44 </div> 44 </div>
45 45
46 - <button type="submit" id="save-button" class="text-button text-pos"><i class="zmdi zmdi-floppy"></i>Save Page</button> 46 + <button type="submit" id="save-button" class="text-button text-pos"><i class="zmdi zmdi-floppy"></i>{{ trans('entities.pages_save') }}</button>
47 </div> 47 </div>
48 </div> 48 </div>
49 </div> 49 </div>
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
53 {{--Title input--}} 53 {{--Title input--}}
54 <div class="title-input page-title clearfix" ng-non-bindable> 54 <div class="title-input page-title clearfix" ng-non-bindable>
55 <div class="input"> 55 <div class="input">
56 - @include('form/text', ['name' => 'name', 'placeholder' => 'Page Title']) 56 + @include('form/text', ['name' => 'name', 'placeholder' => trans('entities.pages_title')])
57 </div> 57 </div>
58 </div> 58 </div>
59 59
...@@ -78,24 +78,24 @@ ...@@ -78,24 +78,24 @@
78 78
79 <div class="markdown-editor-wrap"> 79 <div class="markdown-editor-wrap">
80 <div class="editor-toolbar"> 80 <div class="editor-toolbar">
81 - <span class="float left">Editor</span> 81 + <span class="float left">{{ trans('entities.pages_md_editor') }}</span>
82 <div class="float right buttons"> 82 <div class="float right buttons">
83 - <button class="text-button" type="button" data-action="insertImage"><i class="zmdi zmdi-image"></i>Insert Image</button> 83 + <button class="text-button" type="button" data-action="insertImage"><i class="zmdi zmdi-image"></i>{{ trans('entities.pages_md_insert_image') }}</button>
84 &nbsp;|&nbsp; 84 &nbsp;|&nbsp;
85 - <button class="text-button" type="button" data-action="insertEntityLink"><i class="zmdi zmdi-link"></i>Insert Entity Link</button> 85 + <button class="text-button" type="button" data-action="insertEntityLink"><i class="zmdi zmdi-link"></i>{{ trans('entities.pages_md_insert_link') }}</button>
86 </div> 86 </div>
87 </div> 87 </div>
88 88
89 <div markdown-input md-change="editorChange" md-model="editContent" class="flex flex-fill"> 89 <div markdown-input md-change="editorChange" md-model="editContent" class="flex flex-fill">
90 <textarea ng-non-bindable id="markdown-editor-input" name="markdown" rows="5" 90 <textarea ng-non-bindable id="markdown-editor-input" name="markdown" rows="5"
91 - @if($errors->has('markdown')) class="neg" @endif>@if(isset($model) || old('markdown')){{htmlspecialchars( old('markdown') ? old('markdown') : ($model->markdown === '' ? $model->html : $model->markdown))}}@endif</textarea> 91 + @if($errors->has('markdown')) class="neg" @endif>@if(isset($model) || old('markdown')){{htmlspecialchars( old('markdown') ? old('markdown') : ($model->markdown === '' ? $model->html : $model->markdown))}}@endif</textarea>
92 </div> 92 </div>
93 93
94 </div> 94 </div>
95 95
96 <div class="markdown-editor-wrap"> 96 <div class="markdown-editor-wrap">
97 <div class="editor-toolbar"> 97 <div class="editor-toolbar">
98 - <div class="">Preview</div> 98 + <div class="">{{ trans('entities.pages_md_preview') }}</div>
99 </div> 99 </div>
100 <div class="markdown-display"> 100 <div class="markdown-display">
101 <div class="page-content" ng-bind-html="displayContent"></div> 101 <div class="page-content" ng-bind-html="displayContent"></div>
......
...@@ -3,19 +3,19 @@ ...@@ -3,19 +3,19 @@
3 @section('content') 3 @section('content')
4 4
5 <div class="container small" ng-non-bindable> 5 <div class="container small" ng-non-bindable>
6 - <h1>Create Page</h1> 6 + <h1>{{ trans('entities.pages_new') }}</h1>
7 <form action="{{ $parent->getUrl('/page/create/guest') }}" method="POST"> 7 <form action="{{ $parent->getUrl('/page/create/guest') }}" method="POST">
8 8
9 {!! csrf_field() !!} 9 {!! csrf_field() !!}
10 10
11 <div class="form-group title-input"> 11 <div class="form-group title-input">
12 - <label for="name">Page Name</label> 12 + <label for="name">{{ trans('entities.pages_name') }}</label>
13 @include('form/text', ['name' => 'name']) 13 @include('form/text', ['name' => 'name'])
14 </div> 14 </div>
15 15
16 <div class="form-group"> 16 <div class="form-group">
17 - <a href="{{ $parent->getUrl() }}" class="button muted">Cancel</a> 17 + <a href="{{ $parent->getUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
18 - <button type="submit" class="button pos">Continue</button> 18 + <button type="submit" class="button pos">{{ trans('common.continue') }}</button>
19 </div> 19 </div>
20 20
21 </form> 21 </form>
......
...@@ -12,8 +12,7 @@ ...@@ -12,8 +12,7 @@
12 @if(isset($style) && $style === 'detailed') 12 @if(isset($style) && $style === 'detailed')
13 <div class="row meta text-muted text-small"> 13 <div class="row meta text-muted text-small">
14 <div class="col-md-6"> 14 <div class="col-md-6">
15 - Created {{$page->created_at->diffForHumans()}} @if($page->createdBy)by {{$page->createdBy->name}}@endif <br> 15 + @include('partials.entity-meta', ['entity' => $page])
16 - Last updated {{ $page->updated_at->diffForHumans() }} @if($page->updatedBy)by {{$page->updatedBy->name}} @endif
17 </div> 16 </div>
18 <div class="col-md-6"> 17 <div class="col-md-6">
19 <a class="text-book" href="{{ $page->book->getUrl() }}"><i class="zmdi zmdi-book"></i>{{ $page->book->getShortName(30) }}</a> 18 <a class="text-book" href="{{ $page->book->getUrl() }}"><i class="zmdi zmdi-book"></i>{{ $page->book->getShortName(30) }}</a>
...@@ -21,7 +20,7 @@ ...@@ -21,7 +20,7 @@
21 @if($page->chapter) 20 @if($page->chapter)
22 <a class="text-chapter" href="{{ $page->chapter->getUrl() }}"><i class="zmdi zmdi-collection-bookmark"></i>{{ $page->chapter->getShortName(30) }}</a> 21 <a class="text-chapter" href="{{ $page->chapter->getUrl() }}"><i class="zmdi zmdi-collection-bookmark"></i>{{ $page->chapter->getShortName(30) }}</a>
23 @else 22 @else
24 - <i class="zmdi zmdi-collection-bookmark"></i> Page is not in a chapter 23 + <i class="zmdi zmdi-collection-bookmark"></i> {{ trans('entities.pages_not_in_chapter') }}
25 @endif 24 @endif
26 </div> 25 </div>
27 </div> 26 </div>
......
...@@ -6,34 +6,23 @@ ...@@ -6,34 +6,23 @@
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 <div class="col-sm-12 faded"> 8 <div class="col-sm-12 faded">
9 - <div class="breadcrumbs"> 9 + @include('pages._breadcrumbs', ['page' => $page])
10 - <a href="{{ $book->getUrl() }}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $book->getShortName() }}</a>
11 - @if($page->hasChapter())
12 - <span class="sep">&raquo;</span>
13 - <a href="{{ $page->chapter->getUrl() }}" class="text-chapter text-button">
14 - <i class="zmdi zmdi-collection-bookmark"></i>
15 - {{ $page->chapter->getShortName() }}
16 - </a>
17 - @endif
18 - <span class="sep">&raquo;</span>
19 - <a href="{{ $page->getUrl() }}" class="text-page text-button"><i class="zmdi zmdi-file-text"></i>{{ $page->getShortName() }}</a>
20 - </div>
21 </div> 10 </div>
22 </div> 11 </div>
23 </div> 12 </div>
24 </div> 13 </div>
25 14
26 <div class="container"> 15 <div class="container">
27 - <h1>Move Page <small class="subheader">{{$page->name}}</small></h1> 16 + <h1>{{ trans('entities.pages_move') }}</h1>
28 17
29 <form action="{{ $page->getUrl('/move') }}" method="POST"> 18 <form action="{{ $page->getUrl('/move') }}" method="POST">
30 {!! csrf_field() !!} 19 {!! csrf_field() !!}
31 <input type="hidden" name="_method" value="PUT"> 20 <input type="hidden" name="_method" value="PUT">
32 21
33 - @include('partials/entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter']) 22 + @include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter'])
34 23
35 - <a href="{{ $page->getUrl() }}" class="button muted">Cancel</a> 24 + <a href="{{ $page->getUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
36 - <button type="submit" class="button pos">Move Page</button> 25 + <button type="submit" class="button pos">{{ trans('entities.pages_move') }}</button>
37 </form> 26 </form>
38 </div> 27 </div>
39 28
......
...@@ -36,6 +36,5 @@ ...@@ -36,6 +36,5 @@
36 max-width: none; 36 max-width: none;
37 display: none; 37 display: none;
38 } 38 }
39 -
40 </style> 39 </style>
41 @stop 40 @stop
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -6,26 +6,15 @@ ...@@ -6,26 +6,15 @@
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 <div class="col-sm-12 faded"> 8 <div class="col-sm-12 faded">
9 - <div class="breadcrumbs"> 9 + @include('pages._breadcrumbs', ['page' => $page])
10 - <a href="{{ $page->book->getUrl() }}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $page->book->getShortName() }}</a>
11 - @if($page->hasChapter())
12 - <span class="sep">&raquo;</span>
13 - <a href="{{ $page->chapter->getUrl() }}" class="text-chapter text-button">
14 - <i class="zmdi zmdi-collection-bookmark"></i>
15 - {{ $page->chapter->getShortName() }}
16 - </a>
17 - @endif
18 - <span class="sep">&raquo;</span>
19 - <a href="{{ $page->getUrl() }}" class="text-page text-button"><i class="zmdi zmdi-file"></i>{{ $page->getShortName() }}</a>
20 - </div>
21 </div> 10 </div>
22 </div> 11 </div>
23 </div> 12 </div>
24 </div> 13 </div>
25 14
26 <div class="container" ng-non-bindable> 15 <div class="container" ng-non-bindable>
27 - <h1>Page Permissions</h1> 16 + <h1>{{ trans('entities.pages_permissions') }}</h1>
28 - @include('form/restriction-form', ['model' => $page]) 17 + @include('form.restriction-form', ['model' => $page])
29 </div> 18 </div>
30 19
31 @stop 20 @stop
......
...@@ -7,14 +7,12 @@ ...@@ -7,14 +7,12 @@
7 <div class="row"> 7 <div class="row">
8 <div class="col-md-9"> 8 <div class="col-md-9">
9 <div class="page-content anim fadeIn"> 9 <div class="page-content anim fadeIn">
10 - @include('pages/page-display') 10 + @include('pages.page-display')
11 </div> 11 </div>
12 </div> 12 </div>
13 </div> 13 </div>
14 </div> 14 </div>
15 15
16 16
17 - 17 + @include('partials.highlight')
18 - @include('partials/highlight')
19 -
20 @stop 18 @stop
......
...@@ -6,37 +6,24 @@ ...@@ -6,37 +6,24 @@
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 <div class="col-sm-12 faded"> 8 <div class="col-sm-12 faded">
9 - <div class="breadcrumbs"> 9 + @include('pages._breadcrumbs', ['page' => $page])
10 - <a href="{{ $page->book->getUrl() }}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $page->book->getShortName() }}</a>
11 - @if($page->hasChapter())
12 - <span class="sep">&raquo;</span>
13 - <a href="{{ $page->chapter->getUrl() }}" class="text-chapter text-button">
14 - <i class="zmdi zmdi-collection-bookmark"></i>
15 - {{ $page->chapter->getShortName() }}
16 - </a>
17 - @endif
18 - <span class="sep">&raquo;</span>
19 - <a href="{{ $page->getUrl() }}" class="text-page text-button"><i class="zmdi zmdi-file"></i>{{ $page->getShortName() }}</a>
20 - </div>
21 </div> 10 </div>
22 </div> 11 </div>
23 </div> 12 </div>
24 </div> 13 </div>
25 14
26 -
27 -
28 <div class="container" ng-non-bindable> 15 <div class="container" ng-non-bindable>
29 - <h1>Page Revisions <span class="subheader">For "{{ $page->name }}"</span></h1> 16 + <h1>{{ trans('entities.pages_revisions') }}</h1>
30 17
31 @if(count($page->revisions) > 0) 18 @if(count($page->revisions) > 0)
32 19
33 <table class="table"> 20 <table class="table">
34 <tr> 21 <tr>
35 - <th width="23%">Name</th> 22 + <th width="23%">{{ trans('entities.pages_name') }}</th>
36 - <th colspan="2" width="8%">Created By</th> 23 + <th colspan="2" width="8%">{{ trans('entities.pages_revisions_created_by') }}</th>
37 - <th width="15%">Revision Date</th> 24 + <th width="15%">{{ trans('entities.pages_revisions_date') }}</th>
38 - <th width="25%">Changelog</th> 25 + <th width="25%">{{ trans('entities.pages_revisions_changelog') }}</th>
39 - <th width="20%">Actions</th> 26 + <th width="20%">{{ trans('common.actions') }}</th>
40 </tr> 27 </tr>
41 @foreach($page->revisions as $index => $revision) 28 @foreach($page->revisions as $index => $revision)
42 <tr> 29 <tr>
...@@ -46,19 +33,19 @@ ...@@ -46,19 +33,19 @@
46 <img class="avatar" src="{{ $revision->createdBy->getAvatar(30) }}" alt="{{ $revision->createdBy->name }}"> 33 <img class="avatar" src="{{ $revision->createdBy->getAvatar(30) }}" alt="{{ $revision->createdBy->name }}">
47 @endif 34 @endif
48 </td> 35 </td>
49 - <td> @if($revision->createdBy) {{ $revision->createdBy->name }} @else Deleted User @endif</td> 36 + <td> @if($revision->createdBy) {{ $revision->createdBy->name }} @else {{ trans('common.deleted_user') }} @endif</td>
50 <td><small>{{ $revision->created_at->format('jS F, Y H:i:s') }} <br> ({{ $revision->created_at->diffForHumans() }})</small></td> 37 <td><small>{{ $revision->created_at->format('jS F, Y H:i:s') }} <br> ({{ $revision->created_at->diffForHumans() }})</small></td>
51 <td>{{ $revision->summary }}</td> 38 <td>{{ $revision->summary }}</td>
52 <td> 39 <td>
53 - <a href="{{ $revision->getUrl('changes') }}" target="_blank">Changes</a> 40 + <a href="{{ $revision->getUrl('changes') }}" target="_blank">{{ trans('entities.pages_revisions_changes') }}</a>
54 <span class="text-muted">&nbsp;|&nbsp;</span> 41 <span class="text-muted">&nbsp;|&nbsp;</span>
55 42
56 @if ($index === 0) 43 @if ($index === 0)
57 - <a target="_blank" href="{{ $page->getUrl() }}"><i>Current Version</i></a> 44 + <a target="_blank" href="{{ $page->getUrl() }}"><i>{{ trans('entities.pages_revisions_current') }}</i></a>
58 @else 45 @else
59 - <a href="{{ $revision->getUrl() }}" target="_blank">Preview</a> 46 + <a href="{{ $revision->getUrl() }}" target="_blank">{{ trans('entities.pages_revisions_preview') }}</a>
60 <span class="text-muted">&nbsp;|&nbsp;</span> 47 <span class="text-muted">&nbsp;|&nbsp;</span>
61 - <a href="{{ $revision->getUrl('restore') }}" target="_blank">Restore</a> 48 + <a href="{{ $revision->getUrl('restore') }}" target="_blank">{{ trans('entities.pages_revisions_restore') }}</a>
62 @endif 49 @endif
63 </td> 50 </td>
64 </tr> 51 </tr>
...@@ -66,7 +53,7 @@ ...@@ -66,7 +53,7 @@
66 </table> 53 </table>
67 54
68 @else 55 @else
69 - <p>This page has no revisions.</p> 56 + <p>{{ trans('entities.pages_revisions_none') }}</p>
70 @endif 57 @endif
71 58
72 </div> 59 </div>
......
...@@ -6,43 +6,34 @@ ...@@ -6,43 +6,34 @@
6 <div class="container"> 6 <div class="container">
7 <div class="row"> 7 <div class="row">
8 <div class="col-sm-6 faded"> 8 <div class="col-sm-6 faded">
9 - <div class="breadcrumbs"> 9 + @include('pages._breadcrumbs', ['page' => $page])
10 - <a href="{{ $book->getUrl() }}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $book->getShortName() }}</a>
11 - @if($page->hasChapter())
12 - <span class="sep">&raquo;</span>
13 - <a href="{{ $page->chapter->getUrl() }}" class="text-chapter text-button">
14 - <i class="zmdi zmdi-collection-bookmark"></i>
15 - {{ $page->chapter->getShortName() }}
16 - </a>
17 - @endif
18 - </div>
19 </div> 10 </div>
20 <div class="col-sm-6 faded"> 11 <div class="col-sm-6 faded">
21 <div class="action-buttons"> 12 <div class="action-buttons">
22 <span dropdown class="dropdown-container"> 13 <span dropdown class="dropdown-container">
23 - <div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>Export</div> 14 + <div dropdown-toggle class="text-button text-primary"><i class="zmdi zmdi-open-in-new"></i>{{ trans('entities.pages_export') }}</div>
24 <ul class="wide"> 15 <ul class="wide">
25 - <li><a href="{{ $page->getUrl('/export/html') }}" target="_blank">Contained Web File <span class="text-muted float right">.html</span></a></li> 16 + <li><a href="{{ $page->getUrl('/export/html') }}" target="_blank">{{ trans('entities.pages_export_html') }} <span class="text-muted float right">.html</span></a></li>
26 - <li><a href="{{ $page->getUrl('/export/pdf') }}" target="_blank">PDF File <span class="text-muted float right">.pdf</span></a></li> 17 + <li><a href="{{ $page->getUrl('/export/pdf') }}" target="_blank">{{ trans('entities.pages_export_pdf') }} <span class="text-muted float right">.pdf</span></a></li>
27 - <li><a href="{{ $page->getUrl('/export/plaintext') }}" target="_blank">Plain Text File <span class="text-muted float right">.txt</span></a></li> 18 + <li><a href="{{ $page->getUrl('/export/plaintext') }}" target="_blank">{{ trans('entities.pages_export_text') }} <span class="text-muted float right">.txt</span></a></li>
28 </ul> 19 </ul>
29 </span> 20 </span>
30 @if(userCan('page-update', $page)) 21 @if(userCan('page-update', $page))
31 - <a href="{{ $page->getUrl('/edit') }}" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>Edit</a> 22 + <a href="{{ $page->getUrl('/edit') }}" class="text-primary text-button" ><i class="zmdi zmdi-edit"></i>{{ trans('common.edit') }}</a>
32 @endif 23 @endif
33 @if(userCan('page-update', $page) || userCan('restrictions-manage', $page) || userCan('page-delete', $page)) 24 @if(userCan('page-update', $page) || userCan('restrictions-manage', $page) || userCan('page-delete', $page))
34 <div dropdown class="dropdown-container"> 25 <div dropdown class="dropdown-container">
35 <a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i></a> 26 <a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i></a>
36 <ul> 27 <ul>
37 @if(userCan('page-update', $page)) 28 @if(userCan('page-update', $page))
38 - <li><a href="{{ $page->getUrl('/move') }}" class="text-primary" ><i class="zmdi zmdi-folder"></i>Move</a></li> 29 + <li><a href="{{ $page->getUrl('/move') }}" class="text-primary" ><i class="zmdi zmdi-folder"></i>{{ trans('common.move') }}</a></li>
39 - <li><a href="{{ $page->getUrl('/revisions') }}" class="text-primary"><i class="zmdi zmdi-replay"></i>Revisions</a></li> 30 + <li><a href="{{ $page->getUrl('/revisions') }}" class="text-primary"><i class="zmdi zmdi-replay"></i>{{ trans('entities.revisions') }}</a></li>
40 @endif 31 @endif
41 @if(userCan('restrictions-manage', $page)) 32 @if(userCan('restrictions-manage', $page))
42 - <li><a href="{{ $page->getUrl('/permissions') }}" class="text-primary"><i class="zmdi zmdi-lock-outline"></i>Permissions</a></li> 33 + <li><a href="{{ $page->getUrl('/permissions') }}" class="text-primary"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.permissions') }}</a></li>
43 @endif 34 @endif
44 @if(userCan('page-delete', $page)) 35 @if(userCan('page-delete', $page))
45 - <li><a href="{{ $page->getUrl('/delete') }}" class="text-neg"><i class="zmdi zmdi-delete"></i>Delete</a></li> 36 + <li><a href="{{ $page->getUrl('/delete') }}" class="text-neg"><i class="zmdi zmdi-delete"></i>{{ trans('common.delete') }}</a></li>
46 @endif 37 @endif
47 </ul> 38 </ul>
48 </div> 39 </div>
...@@ -64,7 +55,7 @@ ...@@ -64,7 +55,7 @@
64 <div class="pointer anim"> 55 <div class="pointer anim">
65 <i class="zmdi zmdi-link"></i> 56 <i class="zmdi zmdi-link"></i>
66 <input readonly="readonly" type="text" placeholder="url"> 57 <input readonly="readonly" type="text" placeholder="url">
67 - <button class="button icon" title="Copy Link" data-clipboard-text=""><i class="zmdi zmdi-copy"></i></button> 58 + <button class="button icon" title="{{ trans('entities.pages_copy_link') }}" data-clipboard-text=""><i class="zmdi zmdi-copy"></i></button>
68 </div> 59 </div>
69 </div> 60 </div>
70 61
...@@ -72,11 +63,7 @@ ...@@ -72,11 +63,7 @@
72 63
73 <hr> 64 <hr>
74 65
75 - <p class="text-muted small"> 66 + @include('partials.entity-meta', ['entity' => $page])
76 - Created {{ $page->created_at->diffForHumans() }} @if($page->createdBy) by <a href="{{ $page->createdBy->getProfileUrl() }}">{{$page->createdBy->name}}</a> @endif
77 - <br>
78 - Last Updated {{ $page->updated_at->diffForHumans() }} @if($page->updatedBy) by <a href="{{ $page->updatedBy->getProfileUrl() }}">{{$page->updatedBy->name}}</a> @endif
79 - </p>
80 67
81 </div> 68 </div>
82 </div> 69 </div>
...@@ -88,27 +75,27 @@ ...@@ -88,27 +75,27 @@
88 75
89 @if($book->restricted) 76 @if($book->restricted)
90 @if(userCan('restrictions-manage', $book)) 77 @if(userCan('restrictions-manage', $book))
91 - <a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>Book Permissions Active</a> 78 + <a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}</a>
92 @else 79 @else
93 - <i class="zmdi zmdi-lock-outline"></i>Book Permissions Active 80 + <i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}
94 @endif 81 @endif
95 <br> 82 <br>
96 @endif 83 @endif
97 84
98 @if($page->chapter && $page->chapter->restricted) 85 @if($page->chapter && $page->chapter->restricted)
99 @if(userCan('restrictions-manage', $page->chapter)) 86 @if(userCan('restrictions-manage', $page->chapter))
100 - <a href="{{ $page->chapter->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>Chapter Permissions Active</a> 87 + <a href="{{ $page->chapter->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.chapters_permissions_active') }}</a>
101 @else 88 @else
102 - <i class="zmdi zmdi-lock-outline"></i>Chapter Permissions Active 89 + <i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.chapters_permissions_active') }}
103 @endif 90 @endif
104 <br> 91 <br>
105 @endif 92 @endif
106 93
107 @if($page->restricted) 94 @if($page->restricted)
108 @if(userCan('restrictions-manage', $page)) 95 @if(userCan('restrictions-manage', $page))
109 - <a href="{{ $page->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>Page Permissions Active</a> 96 + <a href="{{ $page->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.pages_permissions_active') }}</a>
110 @else 97 @else
111 - <i class="zmdi zmdi-lock-outline"></i>Page Permissions Active 98 + <i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.pages_permissions_active') }}
112 @endif 99 @endif
113 <br> 100 <br>
114 @endif 101 @endif
......
...@@ -18,16 +18,16 @@ ...@@ -18,16 +18,16 @@
18 @endif 18 @endif
19 19
20 @if (isset($page) && $page->attachments->count() > 0) 20 @if (isset($page) && $page->attachments->count() > 0)
21 - <h6 class="text-muted">Attachments</h6> 21 + <h6 class="text-muted">{{ trans('entities.pages_attachments') }}</h6>
22 @foreach($page->attachments as $attachment) 22 @foreach($page->attachments as $attachment)
23 <div class="attachment"> 23 <div class="attachment">
24 - <a href="{{ $attachment->getUrl() }}" @if($attachment->external) target="_blank" @endif><i class="zmdi zmdi-{{ $attachment->external ? 'open-in-new' : 'file' }}"></i> {{ $attachment->name }}</a> 24 + <a href="{{ $attachment->getUrl() }}" @if($attachment->external) target="_blank" @endif><i class="zmdi zmdi-{{ $attachment->external ? 'open-in-new' : 'file' }}"></i>{{ $attachment->name }}</a>
25 </div> 25 </div>
26 @endforeach 26 @endforeach
27 @endif 27 @endif
28 28
29 @if (isset($pageNav) && $pageNav) 29 @if (isset($pageNav) && $pageNav)
30 - <h6 class="text-muted">Page Navigation</h6> 30 + <h6 class="text-muted">{{ trans('entities.pages_navigation') }}</h6>
31 <div class="sidebar-page-nav menu"> 31 <div class="sidebar-page-nav menu">
32 @foreach($pageNav as $navItem) 32 @foreach($pageNav as $navItem)
33 <li class="page-nav-item {{ $navItem['nodeName'] }}"> 33 <li class="page-nav-item {{ $navItem['nodeName'] }}">
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
37 </div> 37 </div>
38 @endif 38 @endif
39 39
40 - <h6 class="text-muted">Book Navigation</h6> 40 + <h6 class="text-muted">{{ trans('entities.books_navigation') }}</h6>
41 <ul class="sidebar-page-list menu"> 41 <ul class="sidebar-page-list menu">
42 <li class="book-header"><a href="{{ $book->getUrl() }}" class="book {{ $current->matches($book)? 'selected' : '' }}"><i class="zmdi zmdi-book"></i>{{$book->name}}</a></li> 42 <li class="book-header"><a href="{{ $book->getUrl() }}" class="book {{ $current->matches($book)? 'selected' : '' }}"><i class="zmdi zmdi-book"></i>{{$book->name}}</a></li>
43 43
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
50 50
51 @if($bookChild->isA('chapter') && count($bookChild->pages) > 0) 51 @if($bookChild->isA('chapter') && count($bookChild->pages) > 0)
52 <p class="text-muted chapter-toggle @if($bookChild->matchesOrContains($current)) open @endif"> 52 <p class="text-muted chapter-toggle @if($bookChild->matchesOrContains($current)) open @endif">
53 - <i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ count($bookChild->pages) }} Pages</span> 53 + <i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ trans('entities.x_pages', ['count' => $bookChild->pages->count()]) }}</span>
54 </p> 54 </p>
55 <ul class="menu sub-menu inset-list @if($bookChild->matchesOrContains($current)) open @endif"> 55 <ul class="menu sub-menu inset-list @if($bookChild->matchesOrContains($current)) open @endif">
56 @foreach($bookChild->pages as $childPage) 56 @foreach($bookChild->pages as $childPage)
......
1 +<div class="dropdown-container" dropdown>
2 + <span class="user-name" dropdown-toggle>
3 + <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}">
4 + <span class="name" ng-non-bindable>{{ $currentUser->getShortName(9) }}</span> <i class="zmdi zmdi-caret-down"></i>
5 + </span>
6 + <ul>
7 + <li>
8 + <a href="{{ baseUrl("/user/{$currentUser->id}") }}" class="text-primary"><i class="zmdi zmdi-account zmdi-hc-fw zmdi-hc-lg"></i>{{ trans('common.view_profile') }}</a>
9 + </li>
10 + <li>
11 + <a href="{{ baseUrl("/settings/users/{$currentUser->id}") }}" class="text-primary"><i class="zmdi zmdi-edit zmdi-hc-fw zmdi-hc-lg"></i>{{ trans('common.edit_profile') }}</a>
12 + </li>
13 + <li>
14 + <a href="{{ baseUrl('/logout') }}" class="text-neg"><i class="zmdi zmdi-run zmdi-hc-fw zmdi-hc-lg"></i>{{ trans('auth.logout') }}</a>
15 + </li>
16 + </ul>
17 +</div>
...\ No newline at end of file ...\ No newline at end of file
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
11 @if($activity->user) 11 @if($activity->user)
12 <a href="{{ $activity->user->getProfileUrl() }}">{{ $activity->user->name }}</a> 12 <a href="{{ $activity->user->getProfileUrl() }}">{{ $activity->user->name }}</a>
13 @else 13 @else
14 - A deleted user 14 + {{ trans('common.deleted_user') }}
15 @endif 15 @endif
16 16
17 {{ $activity->getText() }} 17 {{ $activity->getText() }}
......
...@@ -8,5 +8,5 @@ ...@@ -8,5 +8,5 @@
8 @endforeach 8 @endforeach
9 </div> 9 </div>
10 @else 10 @else
11 - <p class="text-muted">No activity to show</p> 11 + <p class="text-muted">{{ trans('common.no_activity') }}</p>
12 @endif 12 @endif
...\ No newline at end of file ...\ No newline at end of file
......
1 -<style> 1 +<style id="custom-styles" data-color="{{ setting('app-color') }}" data-color-light="{{ setting('app-color-light') }}">
2 header, #back-to-top, .primary-background { 2 header, #back-to-top, .primary-background {
3 background-color: {{ setting('app-color') }} !important; 3 background-color: {{ setting('app-color') }} !important;
4 } 4 }
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
17 @endforeach 17 @endforeach
18 @else 18 @else
19 <p class="text-muted empty-text"> 19 <p class="text-muted empty-text">
20 - {{ $emptyText or 'No items available' }} 20 + {{ $emptyText or trans('common.no_items') }}
21 </p> 21 </p>
22 @endif 22 @endif
23 </div> 23 </div>
...\ No newline at end of file ...\ No newline at end of file
......
1 +<p class="text-muted small">
2 + @if ($entity->createdBy)
3 + {!! trans('entities.meta_created_name', ['timeLength' => $entity->created_at->diffForHumans(), 'user' => "<a href='{$entity->createdBy->getProfileUrl()}'>".htmlentities($entity->createdBy->name). "</a>"]) !!}
4 + @else
5 + {{ trans('entities.meta_created', ['timeLength' => $entity->created_at->diffForHumans()]) }}
6 + @endif
7 + <br>
8 + @if ($entity->updatedBy)
9 + {!! trans('entities.meta_updated_name', ['timeLength' => $entity->updated_at->diffForHumans(), 'user' => "<a href='{$entity->updatedBy->getProfileUrl()}'>".htmlentities($entity->updatedBy->name). "</a>"]) !!}
10 + @else
11 + {{ trans('entities.meta_updated', ['timeLength' => $entity->updated_at->diffForHumans()]) }}
12 + @endif
13 +</p>
...\ No newline at end of file ...\ No newline at end of file
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
25 </head> 25 </head>
26 <body class="@yield('body-class')" ng-app="bookStack"> 26 <body class="@yield('body-class')" ng-app="bookStack">
27 27
28 -@include('partials/notifications') 28 +@include('partials.notifications')
29 29
30 <header id="header"> 30 <header id="header">
31 <div class="container"> 31 <div class="container">
...@@ -47,23 +47,7 @@ ...@@ -47,23 +47,7 @@
47 @yield('header-buttons') 47 @yield('header-buttons')
48 </div> 48 </div>
49 @if(isset($signedIn) && $signedIn) 49 @if(isset($signedIn) && $signedIn)
50 - <div class="dropdown-container" dropdown> 50 + @include('partials._header-dropdown', ['currentUser' => $currentUser])
51 - <span class="user-name" dropdown-toggle>
52 - <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}">
53 - <span class="name" ng-non-bindable>{{ $currentUser->getShortName(9) }}</span> <i class="zmdi zmdi-caret-down"></i>
54 - </span>
55 - <ul>
56 - <li>
57 - <a href="{{ baseUrl("/user/{$currentUser->id}") }}" class="text-primary"><i class="zmdi zmdi-account zmdi-hc-fw zmdi-hc-lg"></i>View Profile</a>
58 - </li>
59 - <li>
60 - <a href="{{ baseUrl("/settings/users/{$currentUser->id}") }}" class="text-primary"><i class="zmdi zmdi-edit zmdi-hc-fw zmdi-hc-lg"></i>Edit Profile</a>
61 - </li>
62 - <li>
63 - <a href="{{ baseUrl('/logout') }}" class="text-neg"><i class="zmdi zmdi-run zmdi-hc-fw zmdi-hc-lg"></i>Logout</a>
64 - </li>
65 - </ul>
66 - </div>
67 @endif 51 @endif
68 </div> 52 </div>
69 </div> 53 </div>
......
...@@ -2,49 +2,55 @@ ...@@ -2,49 +2,55 @@
2 2
3 @section('content') 3 @section('content')
4 4
5 - <div class="container anim fadeIn" ng-non-bindable> 5 + <div class="faded-small toolbar">
6 + <div class="container">
7 + <div class="row">
8 + <div class="col-sm-12 faded">
9 + <div class="breadcrumbs">
10 + <a href="{{ baseUrl("/search/all?term={$searchTerm}") }}" class="text-button"><i class="zmdi zmdi-search"></i>{{ $searchTerm }}</a>
11 + </div>
12 + </div>
13 + </div>
14 + </div>
15 + </div>
6 16
7 - <h1>Search Results&nbsp;&nbsp;&nbsp; <span class="text-muted">{{ $searchTerm }}</span></h1>
8 17
9 - <p> 18 + <div class="container" ng-non-bindable>
10 19
20 + <h1>{{ trans('entities.search_results') }}</h1>
21 +
22 + <p>
11 @if(count($pages) > 0) 23 @if(count($pages) > 0)
12 - <a href="{{ baseUrl("/search/pages?term={$searchTerm}") }}" class="text-page"><i class="zmdi zmdi-file-text"></i>View all matched pages</a> 24 + <a href="{{ baseUrl("/search/pages?term={$searchTerm}") }}" class="text-page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.search_view_pages') }}</a>
13 @endif 25 @endif
14 26
15 -
16 @if(count($chapters) > 0) 27 @if(count($chapters) > 0)
17 &nbsp; &nbsp;&nbsp; 28 &nbsp; &nbsp;&nbsp;
18 - <a href="{{ baseUrl("/search/chapters?term={$searchTerm}") }}" class="text-chapter"><i class="zmdi zmdi-collection-bookmark"></i>View all matched chapters</a> 29 + <a href="{{ baseUrl("/search/chapters?term={$searchTerm}") }}" class="text-chapter"><i class="zmdi zmdi-collection-bookmark"></i>{{ trans('entities.search_view_chapters') }}</a>
19 @endif 30 @endif
20 31
21 @if(count($books) > 0) 32 @if(count($books) > 0)
22 &nbsp; &nbsp;&nbsp; 33 &nbsp; &nbsp;&nbsp;
23 - <a href="{{ baseUrl("/search/books?term={$searchTerm}") }}" class="text-book"><i class="zmdi zmdi-book"></i>View all matched books</a> 34 + <a href="{{ baseUrl("/search/books?term={$searchTerm}") }}" class="text-book"><i class="zmdi zmdi-book"></i>{{ trans('entities.search_view_books') }}</a>
24 @endif 35 @endif
25 </p> 36 </p>
26 - <div class="row">
27 37
38 + <div class="row">
28 <div class="col-md-6"> 39 <div class="col-md-6">
29 - <h3><a href="{{ baseUrl("/search/pages?term={$searchTerm}") }}" class="no-color">Matching Pages</a></h3> 40 + <h3><a href="{{ baseUrl("/search/pages?term={$searchTerm}") }}" class="no-color">{{ trans('entities.pages') }}</a></h3>
30 @include('partials/entity-list', ['entities' => $pages, 'style' => 'detailed']) 41 @include('partials/entity-list', ['entities' => $pages, 'style' => 'detailed'])
31 </div> 42 </div>
32 -
33 <div class="col-md-5 col-md-offset-1"> 43 <div class="col-md-5 col-md-offset-1">
34 -
35 @if(count($books) > 0) 44 @if(count($books) > 0)
36 - <h3><a href="{{ baseUrl("/search/books?term={$searchTerm}") }}" class="no-color">Matching Books</a></h3> 45 + <h3><a href="{{ baseUrl("/search/books?term={$searchTerm}") }}" class="no-color">{{ trans('entities.books') }}</a></h3>
37 @include('partials/entity-list', ['entities' => $books]) 46 @include('partials/entity-list', ['entities' => $books])
38 @endif 47 @endif
39 48
40 @if(count($chapters) > 0) 49 @if(count($chapters) > 0)
41 - <h3><a href="{{ baseUrl("/search/chapters?term={$searchTerm}") }}" class="no-color">Matching Chapters</a></h3> 50 + <h3><a href="{{ baseUrl("/search/chapters?term={$searchTerm}") }}" class="no-color">{{ trans('entities.chapters') }}</a></h3>
42 @include('partials/entity-list', ['entities' => $chapters]) 51 @include('partials/entity-list', ['entities' => $chapters])
43 @endif 52 @endif
44 -
45 </div> 53 </div>
46 -
47 -
48 </div> 54 </div>
49 55
50 56
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
7 </div> 7 </div>
8 @endforeach 8 @endforeach
9 @else 9 @else
10 - <p class="text-muted">No pages matched this search</p> 10 + <p class="text-muted">{{ trans('entities.search_no_pages') }}</p>
11 @endif 11 @endif
12 </div> 12 </div>
13 13
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
16 @endforeach 16 @endforeach
17 @else 17 @else
18 <p class="text-muted"> 18 <p class="text-muted">
19 - No items available 19 + {{ trans('common.no_items') }}
20 </p> 20 </p>
21 @endif 21 @endif
22 </div> 22 </div>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -2,17 +2,27 @@ ...@@ -2,17 +2,27 @@
2 2
3 @section('content') 3 @section('content')
4 4
5 + <div class="faded-small toolbar">
6 + <div class="container">
7 + <div class="row">
8 + <div class="col-sm-12 faded">
9 + <div class="breadcrumbs">
10 + <a href="{{ baseUrl("/search/all?term={$searchTerm}") }}" class="text-button"><i class="zmdi zmdi-search"></i>{{ $searchTerm }}</a>
11 + </div>
12 + </div>
13 + </div>
14 + </div>
15 + </div>
16 +
5 <div class="container"> 17 <div class="container">
6 <div class="row"> 18 <div class="row">
7 19
8 <div class="col-sm-7"> 20 <div class="col-sm-7">
9 - <h1>{{ $title }} <small>{{ $searchTerm }}</small></h1> 21 + <h1>{{ $title }}</h1>
10 @include('partials.entity-list', ['entities' => $entities, 'style' => 'detailed']) 22 @include('partials.entity-list', ['entities' => $entities, 'style' => 'detailed'])
11 {!! $entities->links() !!} 23 {!! $entities->links() !!}
12 </div> 24 </div>
13 25
14 - <div class="col-sm-4 col-sm-offset-1"></div>
15 -
16 </div> 26 </div>
17 </div> 27 </div>
18 @stop 28 @stop
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -8,10 +8,10 @@ ...@@ -8,10 +8,10 @@
8 8
9 <h1>{{ trans('settings.settings') }}</h1> 9 <h1>{{ trans('settings.settings') }}</h1>
10 10
11 - <form action="{{ baseUrl("/settings") }}" method="POST" ng-cloak> 11 + <form action="{{ baseUrl("/settings") }}" method="POST">
12 {!! csrf_field() !!} 12 {!! csrf_field() !!}
13 13
14 - <h3>App Settings</h3> 14 + <h3>{{ trans('settings.app_settings') }}</h3>
15 15
16 <div class="row"> 16 <div class="row">
17 17
...@@ -23,16 +23,16 @@ ...@@ -23,16 +23,16 @@
23 </div> 23 </div>
24 <div class="form-group"> 24 <div class="form-group">
25 <label>{{ trans('settings.app_name_header') }}</label> 25 <label>{{ trans('settings.app_name_header') }}</label>
26 - <div toggle-switch name="setting-app-name-header" value="{{ setting('app-name-header') }}"></div> 26 + @include('components.toggle-switch', ['name' => 'setting-app-name-header', 'value' => setting('app-name-header')])
27 </div> 27 </div>
28 <div class="form-group"> 28 <div class="form-group">
29 <label for="setting-app-public">{{ trans('settings.app_public_viewing') }}</label> 29 <label for="setting-app-public">{{ trans('settings.app_public_viewing') }}</label>
30 - <div toggle-switch name="setting-app-public" value="{{ setting('app-public') }}"></div> 30 + @include('components.toggle-switch', ['name' => 'setting-app-public', 'value' => setting('app-public')])
31 </div> 31 </div>
32 <div class="form-group"> 32 <div class="form-group">
33 <label>{{ trans('settings.app_secure_images') }}</label> 33 <label>{{ trans('settings.app_secure_images') }}</label>
34 <p class="small">{{ trans('settings.app_secure_images_desc') }}</p> 34 <p class="small">{{ trans('settings.app_secure_images_desc') }}</p>
35 - <div toggle-switch name="setting-app-secure-images" value="{{ setting('app-secure-images') }}"></div> 35 + @include('components.toggle-switch', ['name' => 'setting-app-secure-images', 'value' => setting('app-secure-images')])
36 </div> 36 </div>
37 <div class="form-group"> 37 <div class="form-group">
38 <label for="setting-app-editor">{{ trans('settings.app_editor') }}</label> 38 <label for="setting-app-editor">{{ trans('settings.app_editor') }}</label>
...@@ -48,7 +48,18 @@ ...@@ -48,7 +48,18 @@
48 <div class="form-group" id="logo-control"> 48 <div class="form-group" id="logo-control">
49 <label for="setting-app-logo">{{ trans('settings.app_logo') }}</label> 49 <label for="setting-app-logo">{{ trans('settings.app_logo') }}</label>
50 <p class="small">{!! trans('settings.app_logo_desc') !!}</p> 50 <p class="small">{!! trans('settings.app_logo_desc') !!}</p>
51 - <image-picker resize-height="43" show-remove="true" resize-width="200" current-image="{{ setting('app-logo', '') }}" default-image="{{ baseUrl('/logo.png') }}" name="setting-app-logo" image-class="logo-image"></image-picker> 51 +
52 + @include('components.image-picker', [
53 + 'resizeHeight' => '43',
54 + 'resizeWidth' => '200',
55 + 'showRemove' => true,
56 + 'defaultImage' => baseUrl('/logo.png'),
57 + 'currentImage' => setting('app-logo'),
58 + 'name' => 'setting-app-logo',
59 + 'imageClass' => 'logo-image',
60 + 'currentId' => false
61 + ])
62 +
52 </div> 63 </div>
53 <div class="form-group" id="color-control"> 64 <div class="form-group" id="color-control">
54 <label for="setting-app-color">{{ trans('settings.app_primary_color') }}</label> 65 <label for="setting-app-color">{{ trans('settings.app_primary_color') }}</label>
...@@ -74,7 +85,7 @@ ...@@ -74,7 +85,7 @@
74 <div class="col-md-6"> 85 <div class="col-md-6">
75 <div class="form-group"> 86 <div class="form-group">
76 <label for="setting-registration-enabled">{{ trans('settings.reg_allow') }}</label> 87 <label for="setting-registration-enabled">{{ trans('settings.reg_allow') }}</label>
77 - <div toggle-switch name="setting-registration-enabled" value="{{ setting('registration-enabled') }}"></div> 88 + @include('components.toggle-switch', ['name' => 'setting-registration-enabled', 'value' => setting('registration-enabled')])
78 </div> 89 </div>
79 <div class="form-group"> 90 <div class="form-group">
80 <label for="setting-registration-role">{{ trans('settings.reg_default_role') }}</label> 91 <label for="setting-registration-role">{{ trans('settings.reg_default_role') }}</label>
...@@ -91,7 +102,7 @@ ...@@ -91,7 +102,7 @@
91 <div class="form-group"> 102 <div class="form-group">
92 <label for="setting-registration-confirmation">{{ trans('settings.reg_confirm_email') }}</label> 103 <label for="setting-registration-confirmation">{{ trans('settings.reg_confirm_email') }}</label>
93 <p class="small">{{ trans('settings.reg_confirm_email_desc') }}</p> 104 <p class="small">{{ trans('settings.reg_confirm_email_desc') }}</p>
94 - <div toggle-switch name="setting-registration-confirmation" value="{{ setting('registration-confirmation') }}"></div> 105 + @include('components.toggle-switch', ['name' => 'setting-registration-confirmation', 'value' => setting('registration-confirmation')])
95 </div> 106 </div>
96 </div> 107 </div>
97 <div class="col-md-6"> 108 <div class="col-md-6">
...@@ -115,7 +126,7 @@ ...@@ -115,7 +126,7 @@
115 126
116 </div> 127 </div>
117 128
118 -@include('partials/image-manager', ['imageType' => 'system']) 129 +@include('components.image-manager', ['imageType' => 'system'])
119 130
120 @stop 131 @stop
121 132
...@@ -132,10 +143,16 @@ ...@@ -132,10 +143,16 @@
132 var isEmpty = $.trim($elm.val()).length === 0; 143 var isEmpty = $.trim($elm.val()).length === 0;
133 if (!isEmpty) $elm.val(hexVal); 144 if (!isEmpty) $elm.val(hexVal);
134 $('#setting-app-color-light').val(isEmpty ? '' : rgbLightVal); 145 $('#setting-app-color-light').val(isEmpty ? '' : rgbLightVal);
135 - // Set page elements to provide preview 146 +
136 - $('#header, .image-picker .button').attr('style', 'background-color:'+ hexVal+'!important;'); 147 + var customStyles = document.getElementById('custom-styles');
137 - $('.faded-small').css('background-color', rgbLightVal); 148 + var oldColor = customStyles.getAttribute('data-color');
138 - $('.setting-nav a.selected').css('border-bottom-color', hexVal + '!important'); 149 + var oldColorLight = customStyles.getAttribute('data-color-light');
150 +
151 + customStyles.innerHTML = customStyles.innerHTML.split(oldColor).join(hexVal);
152 + customStyles.innerHTML = customStyles.innerHTML.split(oldColorLight).join(rgbLightVal);
153 +
154 + customStyles.setAttribute('data-color', hexVal);
155 + customStyles.setAttribute('data-color-light', rgbLightVal);
139 } 156 }
140 }); 157 });
141 </script> 158 </script>
......
...@@ -4,13 +4,13 @@ ...@@ -4,13 +4,13 @@
4 <div class="row"> 4 <div class="row">
5 <div class="col-md-12 setting-nav nav-tabs"> 5 <div class="col-md-12 setting-nav nav-tabs">
6 @if($currentUser->can('settings-manage')) 6 @if($currentUser->can('settings-manage'))
7 - <a href="{{ baseUrl('/settings') }}" @if($selected == 'settings') class="selected text-button" @endif><i class="zmdi zmdi-settings"></i>Settings</a> 7 + <a href="{{ baseUrl('/settings') }}" @if($selected == 'settings') class="selected text-button" @endif><i class="zmdi zmdi-settings"></i>{{ trans('settings.settings') }}</a>
8 @endif 8 @endif
9 @if($currentUser->can('users-manage')) 9 @if($currentUser->can('users-manage'))
10 - <a href="{{ baseUrl('/settings/users') }}" @if($selected == 'users') class="selected text-button" @endif><i class="zmdi zmdi-accounts"></i>Users</a> 10 + <a href="{{ baseUrl('/settings/users') }}" @if($selected == 'users') class="selected text-button" @endif><i class="zmdi zmdi-accounts"></i>{{ trans('settings.users') }}</a>
11 @endif 11 @endif
12 @if($currentUser->can('user-roles-manage')) 12 @if($currentUser->can('user-roles-manage'))
13 - <a href="{{ baseUrl('/settings/roles') }}" @if($selected == 'roles') class="selected text-button" @endif><i class="zmdi zmdi-lock-open"></i>Roles</a> 13 + <a href="{{ baseUrl('/settings/roles') }}" @if($selected == 'roles') class="selected text-button" @endif><i class="zmdi zmdi-lock-open"></i>{{ trans('settings.roles') }}</a>
14 @endif 14 @endif
15 </div> 15 </div>
16 </div> 16 </div>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
5 @include('settings/navbar', ['selected' => 'roles']) 5 @include('settings/navbar', ['selected' => 'roles'])
6 6
7 <div class="container"> 7 <div class="container">
8 - <h1>Create New Role</h1> 8 + <h1>{{ trans('settings.role_create') }}</h1>
9 9
10 <form action="{{ baseUrl("/settings/roles/new") }}" method="POST"> 10 <form action="{{ baseUrl("/settings/roles/new") }}" method="POST">
11 @include('settings/roles/form') 11 @include('settings/roles/form')
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
5 @include('settings/navbar', ['selected' => 'roles']) 5 @include('settings/navbar', ['selected' => 'roles'])
6 6
7 <div class="container small" ng-non-bindable> 7 <div class="container small" ng-non-bindable>
8 - <h1>Delete Role</h1> 8 + <h1>{{ trans('settings.role_delete') }}</h1>
9 - <p>This will delete the role with the name '{{ $role->display_name }}'.</p> 9 + <p>{{ trans('settings.role_delete_confirm', ['roleName' => $role->display_name]) }}</p>
10 10
11 <form action="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" method="POST"> 11 <form action="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" method="POST">
12 {!! csrf_field() !!} 12 {!! csrf_field() !!}
...@@ -14,14 +14,14 @@ ...@@ -14,14 +14,14 @@
14 14
15 @if($role->users->count() > 0) 15 @if($role->users->count() > 0)
16 <div class="form-group"> 16 <div class="form-group">
17 - <p>This role has {{$role->users->count()}} users assigned to it. If you would like to migrate the users from this role select a new role below.</p> 17 + <p>{{ trans('settings.role_delete_users_assigned', ['userCount' => $role->users->count()]) }}</p>
18 @include('form/role-select', ['options' => $roles, 'name' => 'migration_role_id']) 18 @include('form/role-select', ['options' => $roles, 'name' => 'migration_role_id'])
19 </div> 19 </div>
20 @endif 20 @endif
21 21
22 - <p class="text-neg">Are you sure you want to delete this role?</p> 22 + <p class="text-neg">{{ trans('settings.role_delete_sure') }}</p>
23 - <a href="{{ baseUrl("/settings/roles/{$role->id}") }}" class="button">Cancel</a> 23 + <a href="{{ baseUrl("/settings/roles/{$role->id}") }}" class="button muted">{{ trans('common.cancel') }}</a>
24 - <button type="submit" class="button neg">Confirm</button> 24 + <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
25 </form> 25 </form>
26 </div> 26 </div>
27 27
......
...@@ -7,11 +7,11 @@ ...@@ -7,11 +7,11 @@
7 <div class="container"> 7 <div class="container">
8 <div class="row"> 8 <div class="row">
9 <div class="col-sm-6"> 9 <div class="col-sm-6">
10 - <h1>Edit Role <small> {{ $role->display_name }}</small></h1> 10 + <h1>{{ trans('settings.role_edit') }}</h1>
11 </div> 11 </div>
12 <div class="col-sm-6"> 12 <div class="col-sm-6">
13 <p></p> 13 <p></p>
14 - <a href="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" class="button neg float right">Delete Role</a> 14 + <a href="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" class="button neg float right">{{ trans('settings.role_delete') }}</a>
15 </div> 15 </div>
16 </div> 16 </div>
17 17
......
...@@ -5,128 +5,126 @@ ...@@ -5,128 +5,126 @@
5 <div class="col-md-9"> 5 <div class="col-md-9">
6 <div class="row"> 6 <div class="row">
7 <div class="col-md-5"> 7 <div class="col-md-5">
8 - <h3>Role Details</h3> 8 + <h3>{{ trans('settings.role_details') }}</h3>
9 <div class="form-group"> 9 <div class="form-group">
10 - <label for="name">Role Name</label> 10 + <label for="name">{{ trans('settings.role_name') }}</label>
11 @include('form/text', ['name' => 'display_name']) 11 @include('form/text', ['name' => 'display_name'])
12 </div> 12 </div>
13 <div class="form-group"> 13 <div class="form-group">
14 - <label for="name">Short Role Description</label> 14 + <label for="name">{{ trans('settings.role_desc') }}</label>
15 @include('form/text', ['name' => 'description']) 15 @include('form/text', ['name' => 'description'])
16 </div> 16 </div>
17 - <h3>System Permissions</h3> 17 + <h3>{{ trans('settings.role_system') }}</h3>
18 - <label>@include('settings/roles/checkbox', ['permission' => 'users-manage']) Manage users</label> 18 + <label>@include('settings/roles/checkbox', ['permission' => 'users-manage']) {{ trans('settings.role_manage_users') }}</label>
19 - <label>@include('settings/roles/checkbox', ['permission' => 'user-roles-manage']) Manage roles & role permissions</label> 19 + <label>@include('settings/roles/checkbox', ['permission' => 'user-roles-manage']) {{ trans('settings.role_manage_roles') }}</label>
20 - <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-all']) Manage all Book, Chapter & Page permissions</label> 20 + <label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-all']) {{ trans('settings.role_manage_entity_permissions') }}</label>
21 - <label>@include('settings/roles/checkbox', ['permission' => 'permissions']) Manage permissions on own Book, Chapter & Pages</label> 21 + <label>@include('settings/roles/checkbox', ['permission' => 'permissions']) {{ trans('settings.role_manage_own_entity_permissions') }}</label>
22 - <label>@include('settings/roles/checkbox', ['permission' => 'settings-manage']) Manage app settings</label> 22 + <label>@include('settings/roles/checkbox', ['permission' => 'settings-manage']) {{ trans('settings.role_manage_settings') }}</label>
23 </div> 23 </div>
24 24
25 <div class="col-md-6"> 25 <div class="col-md-6">
26 26
27 - <h3>Asset Permissions</h3> 27 + <h3>{{ trans('settings.role_asset') }}</h3>
28 - <p> 28 + <p>{{ trans('settings.role_asset_desc') }}</p>
29 - These permissions control default access to the assets within the system. 29 +
30 - Permissions on Books, Chapters and Pages will override these permissions.
31 - </p>
32 <table class="table"> 30 <table class="table">
33 <tr> 31 <tr>
34 <th width="20%"></th> 32 <th width="20%"></th>
35 - <th width="20%">Create</th> 33 + <th width="20%">{{ trans('common.create') }}</th>
36 - <th width="20%">View</th> 34 + <th width="20%">{{ trans('common.view') }}</th>
37 - <th width="20%">Edit</th> 35 + <th width="20%">{{ trans('common.edit') }}</th>
38 - <th width="20%">Delete</th> 36 + <th width="20%">{{ trans('common.delete') }}</th>
39 </tr> 37 </tr>
40 <tr> 38 <tr>
41 - <td>Books</td> 39 + <td>{{ trans('entities.books') }}</td>
42 <td> 40 <td>
43 - <label>@include('settings/roles/checkbox', ['permission' => 'book-create-all']) All</label> 41 + <label>@include('settings/roles/checkbox', ['permission' => 'book-create-all']) {{ trans('settings.role_all') }}</label>
44 </td> 42 </td>
45 <td> 43 <td>
46 - <label>@include('settings/roles/checkbox', ['permission' => 'book-view-own']) Own</label> 44 + <label>@include('settings/roles/checkbox', ['permission' => 'book-view-own']) {{ trans('settings.role_own') }}</label>
47 - <label>@include('settings/roles/checkbox', ['permission' => 'book-view-all']) All</label> 45 + <label>@include('settings/roles/checkbox', ['permission' => 'book-view-all']) {{ trans('settings.role_all') }}</label>
48 </td> 46 </td>
49 <td> 47 <td>
50 - <label>@include('settings/roles/checkbox', ['permission' => 'book-update-own']) Own</label> 48 + <label>@include('settings/roles/checkbox', ['permission' => 'book-update-own']) {{ trans('settings.role_own') }}</label>
51 - <label>@include('settings/roles/checkbox', ['permission' => 'book-update-all']) All</label> 49 + <label>@include('settings/roles/checkbox', ['permission' => 'book-update-all']) {{ trans('settings.role_all') }}</label>
52 </td> 50 </td>
53 <td> 51 <td>
54 - <label>@include('settings/roles/checkbox', ['permission' => 'book-delete-own']) Own</label> 52 + <label>@include('settings/roles/checkbox', ['permission' => 'book-delete-own']) {{ trans('settings.role_own') }}</label>
55 - <label>@include('settings/roles/checkbox', ['permission' => 'book-delete-all']) All</label> 53 + <label>@include('settings/roles/checkbox', ['permission' => 'book-delete-all']) {{ trans('settings.role_all') }}</label>
56 </td> 54 </td>
57 </tr> 55 </tr>
58 <tr> 56 <tr>
59 - <td>Chapters</td> 57 + <td>{{ trans('entities.chapters') }}</td>
60 <td> 58 <td>
61 - <label>@include('settings/roles/checkbox', ['permission' => 'chapter-create-own']) Own</label> 59 + <label>@include('settings/roles/checkbox', ['permission' => 'chapter-create-own']) {{ trans('settings.role_own') }}</label>
62 - <label>@include('settings/roles/checkbox', ['permission' => 'chapter-create-all']) All</label> 60 + <label>@include('settings/roles/checkbox', ['permission' => 'chapter-create-all']) {{ trans('settings.role_all') }}</label>
63 </td> 61 </td>
64 <td> 62 <td>
65 - <label>@include('settings/roles/checkbox', ['permission' => 'chapter-view-own']) Own</label> 63 + <label>@include('settings/roles/checkbox', ['permission' => 'chapter-view-own']) {{ trans('settings.role_own') }}</label>
66 - <label>@include('settings/roles/checkbox', ['permission' => 'chapter-view-all']) All</label> 64 + <label>@include('settings/roles/checkbox', ['permission' => 'chapter-view-all']) {{ trans('settings.role_all') }}</label>
67 </td> 65 </td>
68 <td> 66 <td>
69 - <label>@include('settings/roles/checkbox', ['permission' => 'chapter-update-own']) Own</label> 67 + <label>@include('settings/roles/checkbox', ['permission' => 'chapter-update-own']) {{ trans('settings.role_own') }}</label>
70 - <label>@include('settings/roles/checkbox', ['permission' => 'chapter-update-all']) All</label> 68 + <label>@include('settings/roles/checkbox', ['permission' => 'chapter-update-all']) {{ trans('settings.role_all') }}</label>
71 </td> 69 </td>
72 <td> 70 <td>
73 - <label>@include('settings/roles/checkbox', ['permission' => 'chapter-delete-own']) Own</label> 71 + <label>@include('settings/roles/checkbox', ['permission' => 'chapter-delete-own']) {{ trans('settings.role_own') }}</label>
74 - <label>@include('settings/roles/checkbox', ['permission' => 'chapter-delete-all']) All</label> 72 + <label>@include('settings/roles/checkbox', ['permission' => 'chapter-delete-all']) {{ trans('settings.role_all') }}</label>
75 </td> 73 </td>
76 </tr> 74 </tr>
77 <tr> 75 <tr>
78 - <td>Pages</td> 76 + <td>{{ trans('entities.pages') }}</td>
79 <td> 77 <td>
80 - <label>@include('settings/roles/checkbox', ['permission' => 'page-create-own']) Own</label> 78 + <label>@include('settings/roles/checkbox', ['permission' => 'page-create-own']) {{ trans('settings.role_own') }}</label>
81 - <label>@include('settings/roles/checkbox', ['permission' => 'page-create-all']) All</label> 79 + <label>@include('settings/roles/checkbox', ['permission' => 'page-create-all']) {{ trans('settings.role_all') }}</label>
82 </td> 80 </td>
83 <td> 81 <td>
84 - <label>@include('settings/roles/checkbox', ['permission' => 'page-view-own']) Own</label> 82 + <label>@include('settings/roles/checkbox', ['permission' => 'page-view-own']) {{ trans('settings.role_own') }}</label>
85 - <label>@include('settings/roles/checkbox', ['permission' => 'page-view-all']) All</label> 83 + <label>@include('settings/roles/checkbox', ['permission' => 'page-view-all']) {{ trans('settings.role_all') }}</label>
86 </td> 84 </td>
87 <td> 85 <td>
88 - <label>@include('settings/roles/checkbox', ['permission' => 'page-update-own']) Own</label> 86 + <label>@include('settings/roles/checkbox', ['permission' => 'page-update-own']) {{ trans('settings.role_own') }}</label>
89 - <label>@include('settings/roles/checkbox', ['permission' => 'page-update-all']) All</label> 87 + <label>@include('settings/roles/checkbox', ['permission' => 'page-update-all']) {{ trans('settings.role_all') }}</label>
90 </td> 88 </td>
91 <td> 89 <td>
92 - <label>@include('settings/roles/checkbox', ['permission' => 'page-delete-own']) Own</label> 90 + <label>@include('settings/roles/checkbox', ['permission' => 'page-delete-own']) {{ trans('settings.role_own') }}</label>
93 - <label>@include('settings/roles/checkbox', ['permission' => 'page-delete-all']) All</label> 91 + <label>@include('settings/roles/checkbox', ['permission' => 'page-delete-all']) {{ trans('settings.role_all') }}</label>
94 </td> 92 </td>
95 </tr> 93 </tr>
96 <tr> 94 <tr>
97 - <td>Images</td> 95 + <td>{{ trans('entities.images') }}</td>
98 <td>@include('settings/roles/checkbox', ['permission' => 'image-create-all'])</td> 96 <td>@include('settings/roles/checkbox', ['permission' => 'image-create-all'])</td>
99 - <td style="line-height:1.2;"><small class="faded">Controlled by the asset they are uploaded to</small></td> 97 + <td style="line-height:1.2;"><small class="faded">{{ trans('settings.role_controlled_by_asset') }}</small></td>
100 <td> 98 <td>
101 - <label>@include('settings/roles/checkbox', ['permission' => 'image-update-own']) Own</label> 99 + <label>@include('settings/roles/checkbox', ['permission' => 'image-update-own']) {{ trans('settings.role_own') }}</label>
102 - <label>@include('settings/roles/checkbox', ['permission' => 'image-update-all']) All</label> 100 + <label>@include('settings/roles/checkbox', ['permission' => 'image-update-all']) {{ trans('settings.role_all') }}</label>
103 </td> 101 </td>
104 <td> 102 <td>
105 - <label>@include('settings/roles/checkbox', ['permission' => 'image-delete-own']) Own</label> 103 + <label>@include('settings/roles/checkbox', ['permission' => 'image-delete-own']) {{ trans('settings.role_own') }}</label>
106 - <label>@include('settings/roles/checkbox', ['permission' => 'image-delete-all']) All</label> 104 + <label>@include('settings/roles/checkbox', ['permission' => 'image-delete-all']) {{ trans('settings.role_all') }}</label>
107 </td> 105 </td>
108 </tr> 106 </tr>
109 <tr> 107 <tr>
110 - <td>Attachments</td> 108 + <td>{{ trans('entities.attachments') }}</td>
111 <td>@include('settings/roles/checkbox', ['permission' => 'attachment-create-all'])</td> 109 <td>@include('settings/roles/checkbox', ['permission' => 'attachment-create-all'])</td>
112 - <td style="line-height:1.2;"><small class="faded">Controlled by the asset they are uploaded to</small></td> 110 + <td style="line-height:1.2;"><small class="faded">{{ trans('settings.role_controlled_by_asset') }}</small></td>
113 <td> 111 <td>
114 - <label>@include('settings/roles/checkbox', ['permission' => 'attachment-update-own']) Own</label> 112 + <label>@include('settings/roles/checkbox', ['permission' => 'attachment-update-own']) {{ trans('settings.role_own') }}</label>
115 - <label>@include('settings/roles/checkbox', ['permission' => 'attachment-update-all']) All</label> 113 + <label>@include('settings/roles/checkbox', ['permission' => 'attachment-update-all']) {{ trans('settings.role_all') }}</label>
116 </td> 114 </td>
117 <td> 115 <td>
118 - <label>@include('settings/roles/checkbox', ['permission' => 'attachment-delete-own']) Own</label> 116 + <label>@include('settings/roles/checkbox', ['permission' => 'attachment-delete-own']) {{ trans('settings.role_own') }}</label>
119 - <label>@include('settings/roles/checkbox', ['permission' => 'attachment-delete-all']) All</label> 117 + <label>@include('settings/roles/checkbox', ['permission' => 'attachment-delete-all']) {{ trans('settings.role_all') }}</label>
120 </td> 118 </td>
121 </tr> 119 </tr>
122 </table> 120 </table>
123 </div> 121 </div>
124 </div> 122 </div>
125 - <a href="{{ baseUrl("/settings/roles") }}" class="button muted">Cancel</a> 123 + <a href="{{ baseUrl("/settings/roles") }}" class="button muted">{{ trans('common.cancel') }}</a>
126 - <button type="submit" class="button pos">Save Role</button> 124 + <button type="submit" class="button pos">{{ trans('settings.role_save') }}</button>
127 </div> 125 </div>
128 <div class="col-md-3"> 126 <div class="col-md-3">
129 - <h3>Users in this role</h3> 127 + <h3>{{ trans('settings.role_users') }}</h3>
130 128
131 @if(isset($role) && count($role->users) > 0) 129 @if(isset($role) && count($role->users) > 0)
132 <table class="list-table"> 130 <table class="list-table">
...@@ -147,7 +145,7 @@ ...@@ -147,7 +145,7 @@
147 </table> 145 </table>
148 @else 146 @else
149 <p class="text-muted"> 147 <p class="text-muted">
150 - No users currently in this role. 148 + {{ trans('settings.role_users_none') }}
151 </p> 149 </p>
152 @endif 150 @endif
153 151
......
...@@ -8,25 +8,25 @@ ...@@ -8,25 +8,25 @@
8 8
9 <div class="row action-header"> 9 <div class="row action-header">
10 <div class="col-sm-8"> 10 <div class="col-sm-8">
11 - <h1>User Roles</h1> 11 + <h1>{{ trans('settings.role_user_roles') }}</h1>
12 </div> 12 </div>
13 <div class="col-sm-4"> 13 <div class="col-sm-4">
14 <p></p> 14 <p></p>
15 - <a href="{{ baseUrl("/settings/roles/new") }}" class="button float right pos"><i class="zmdi zmdi-lock-open"></i>Add new role</a> 15 + <a href="{{ baseUrl("/settings/roles/new") }}" class="button float right pos"><i class="zmdi zmdi-lock-open"></i>{{ trans('settings.role_create') }}</a>
16 </div> 16 </div>
17 </div> 17 </div>
18 18
19 <table class="table"> 19 <table class="table">
20 <tr> 20 <tr>
21 - <th>Role Name</th> 21 + <th>{{ trans('settings.role_name') }}</th>
22 <th></th> 22 <th></th>
23 - <th class="text-right">Users</th> 23 + <th class="text-center">{{ trans('settings.users') }}</th>
24 </tr> 24 </tr>
25 @foreach($roles as $role) 25 @foreach($roles as $role)
26 <tr> 26 <tr>
27 <td><a href="{{ baseUrl("/settings/roles/{$role->id}") }}">{{ $role->display_name }}</a></td> 27 <td><a href="{{ baseUrl("/settings/roles/{$role->id}") }}">{{ $role->display_name }}</a></td>
28 <td>{{ $role->description }}</td> 28 <td>{{ $role->description }}</td>
29 - <td class="text-right">{{ $role->users->count() }}</td> 29 + <td class="text-center">{{ $role->users->count() }}</td>
30 </tr> 30 </tr>
31 @endforeach 31 @endforeach
32 </table> 32 </table>
......
...@@ -3,6 +3,18 @@ ...@@ -3,6 +3,18 @@
3 3
4 @section('content') 4 @section('content')
5 5
6 + <div class="faded-small toolbar">
7 + <div class="container">
8 + <div class="row">
9 + <div class="col-sm-12 faded">
10 + <div class="breadcrumbs">
11 + <a href="{{ baseUrl('/settings/users') }}" class="text-button"><i class="zmdi zmdi-accounts"></i>Users</a>
12 + </div>
13 + </div>
14 + </div>
15 + </div>
16 + </div>
17 +
6 <div class="container small" ng-non-bindable> 18 <div class="container small" ng-non-bindable>
7 <h1>Create User</h1> 19 <h1>Create User</h1>
8 20
......
...@@ -2,16 +2,30 @@ ...@@ -2,16 +2,30 @@
2 2
3 @section('content') 3 @section('content')
4 4
5 + <div class="faded-small toolbar">
6 + <div class="container">
7 + <div class="row">
8 + <div class="col-sm-12 faded">
9 + <div class="breadcrumbs">
10 + <a href="{{ baseUrl("/settings/users") }}" class="text-button"><i class="zmdi zmdi-accounts"></i>Users</a>
11 + <span class="sep">&raquo;</span>
12 + <a href="{{ baseUrl("/settings/users/{$user->id}") }}" class="text-button"><i class="zmdi zmdi-account"></i>{{ $user->name }}</a>
13 + </div>
14 + </div>
15 + </div>
16 + </div>
17 + </div>
18 +
5 <div class="container small" ng-non-bindable> 19 <div class="container small" ng-non-bindable>
6 - <h1>Delete User</h1> 20 + <h1>{{ trans('settings.users_delete') }}</h1>
7 - <p>This will fully delete this user with the name '<span class="text-neg">{{ $user->name }}</span>' from the system.</p> 21 + <p>{{ trans('settings.users_delete_warning', ['userName' => $user->name]) }}</p>
8 - <p class="text-neg">Are you sure you want to delete this user?</p> 22 + <p class="text-neg">{{ trans('settings.users_delete_confirm') }}</p>
9 23
10 <form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="POST"> 24 <form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="POST">
11 {!! csrf_field() !!} 25 {!! csrf_field() !!}
12 <input type="hidden" name="_method" value="DELETE"> 26 <input type="hidden" name="_method" value="DELETE">
13 - <a href="{{ baseUrl("/settings/users/{$user->id}") }}" class="button muted">Cancel</a> 27 + <a href="{{ baseUrl("/settings/users/{$user->id}") }}" class="button muted">{{ trans('common.cancel') }}</a>
14 - <button type="submit" class="button neg">Confirm</button> 28 + <button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
15 </form> 29 </form>
16 </div> 30 </div>
17 31
......
...@@ -11,12 +11,12 @@ ...@@ -11,12 +11,12 @@
11 <form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="post"> 11 <form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="post">
12 <div class="row"> 12 <div class="row">
13 <div class="col-sm-8"> 13 <div class="col-sm-8">
14 - <h1>Edit {{ $user->id === $currentUser->id ? 'Profile' : 'User' }}</h1> 14 + <h1>{{ $user->id === $currentUser->id ? trans('settings.users_edit_profile') : trans('settings.users_edit') }}</h1>
15 </div> 15 </div>
16 <div class="col-sm-4"> 16 <div class="col-sm-4">
17 <p></p> 17 <p></p>
18 @if($authMethod !== 'system') 18 @if($authMethod !== 'system')
19 - <a href="{{ baseUrl("/settings/users/{$user->id}/delete") }}" class="neg button float right">Delete User</a> 19 + <a href="{{ baseUrl("/settings/users/{$user->id}/delete") }}" class="neg button float right">{{ trans('settings.users_delete') }}</a>
20 @endif 20 @endif
21 </div> 21 </div>
22 </div> 22 </div>
...@@ -29,9 +29,20 @@ ...@@ -29,9 +29,20 @@
29 </div> 29 </div>
30 <div class="col-md-6"> 30 <div class="col-md-6">
31 <div class="form-group" id="logo-control"> 31 <div class="form-group" id="logo-control">
32 - <label for="user-avatar">User Avatar</label> 32 + <label for="user-avatar">{{ trans('settings.users_avatar') }}</label>
33 - <p class="small">This image should be approx 256px square.</p> 33 + <p class="small">{{ trans('settings.users_avatar_desc') }}</p>
34 - <image-picker resize-height="512" resize-width="512" current-image="{{ $user->getAvatar(80) }}" current-id="{{ $user->image_id }}" default-image="{{ baseUrl("/user_avatar.png") }}" name="image_id" show-remove="false" image-class="['avatar' ,'large']"></image-picker> 34 +
35 + @include('components.image-picker', [
36 + 'resizeHeight' => '512',
37 + 'resizeWidth' => '512',
38 + 'showRemove' => false,
39 + 'defaultImage' => baseUrl('/user_avatar.png'),
40 + 'currentImage' => $user->getAvatar(80),
41 + 'currentId' => $user->image_id,
42 + 'name' => 'image_id',
43 + 'imageClass' => 'avatar large'
44 + ])
45 +
35 </div> 46 </div>
36 </div> 47 </div>
37 </div> 48 </div>
...@@ -40,20 +51,17 @@ ...@@ -40,20 +51,17 @@
40 <hr class="margin-top large"> 51 <hr class="margin-top large">
41 52
42 @if($currentUser->id === $user->id && count($activeSocialDrivers) > 0) 53 @if($currentUser->id === $user->id && count($activeSocialDrivers) > 0)
43 - <h3>Social Accounts</h3> 54 + <h3>{{ trans('settings.users_social_accounts') }}</h3>
44 - <p class="text-muted"> 55 + <p class="text-muted">{{ trans('settings.users_social_accounts_info') }}</p>
45 - Here you can connect your other accounts for quicker and easier login. <br>
46 - Disconnecting an account here does not previously authorized access. Revoke access from your profile settings on the connected social account.
47 - </p>
48 <div class="row"> 56 <div class="row">
49 @if(isset($activeSocialDrivers['google'])) 57 @if(isset($activeSocialDrivers['google']))
50 <div class="col-md-3 text-center"> 58 <div class="col-md-3 text-center">
51 <div><i class="zmdi zmdi-google-plus-box zmdi-hc-4x" style="color: #DC4E41;"></i></div> 59 <div><i class="zmdi zmdi-google-plus-box zmdi-hc-4x" style="color: #DC4E41;"></i></div>
52 <div> 60 <div>
53 @if($user->hasSocialAccount('google')) 61 @if($user->hasSocialAccount('google'))
54 - <a href="{{ baseUrl("/login/service/google/detach") }}" class="button neg">Disconnect Account</a> 62 + <a href="{{ baseUrl("/login/service/google/detach") }}" class="button neg">{{ trans('settings.users_social_disconnect') }}</a>
55 @else 63 @else
56 - <a href="{{ baseUrl("/login/service/google") }}" class="button pos">Attach Account</a> 64 + <a href="{{ baseUrl("/login/service/google") }}" class="button pos">{{ trans('settings.users_social_connect') }}</a>
57 @endif 65 @endif
58 </div> 66 </div>
59 </div> 67 </div>
...@@ -63,9 +71,9 @@ ...@@ -63,9 +71,9 @@
63 <div><i class="zmdi zmdi-github zmdi-hc-4x" style="color: #444;"></i></div> 71 <div><i class="zmdi zmdi-github zmdi-hc-4x" style="color: #444;"></i></div>
64 <div> 72 <div>
65 @if($user->hasSocialAccount('github')) 73 @if($user->hasSocialAccount('github'))
66 - <a href="{{ baseUrl("/login/service/github/detach") }}" class="button neg">Disconnect Account</a> 74 + <a href="{{ baseUrl("/login/service/github/detach") }}" class="button neg">{{ trans('settings.users_social_disconnect') }}</a>
67 @else 75 @else
68 - <a href="{{ baseUrl("/login/service/github") }}" class="button pos">Attach Account</a> 76 + <a href="{{ baseUrl("/login/service/github") }}" class="button pos">{{ trans('settings.users_social_connect') }}</a>
69 @endif 77 @endif
70 </div> 78 </div>
71 </div> 79 </div>
...@@ -77,5 +85,5 @@ ...@@ -77,5 +85,5 @@
77 </div> 85 </div>
78 86
79 <p class="margin-top large"><br></p> 87 <p class="margin-top large"><br></p>
80 - @include('partials/image-manager', ['imageType' => 'user']) 88 + @include('components.image-manager', ['imageType' => 'user'])
81 @stop 89 @stop
......
1 <div class="form-group"> 1 <div class="form-group">
2 - <label for="name">Name</label> 2 + <label for="name">{{ trans('auth.name') }}</label>
3 @include('form.text', ['name' => 'name']) 3 @include('form.text', ['name' => 'name'])
4 </div> 4 </div>
5 5
6 @if(userCan('users-manage')) 6 @if(userCan('users-manage'))
7 <div class="form-group"> 7 <div class="form-group">
8 - <label for="email">Email</label> 8 + <label for="email">{{ trans('auth.email') }}</label>
9 @include('form.text', ['name' => 'email']) 9 @include('form.text', ['name' => 'email'])
10 </div> 10 </div>
11 @endif 11 @endif
12 12
13 @if(userCan('users-manage')) 13 @if(userCan('users-manage'))
14 <div class="form-group"> 14 <div class="form-group">
15 - <label for="role">User Role</label> 15 + <label for="role">{{ trans('settings.users_role') }}</label>
16 @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles]) 16 @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles])
17 </div> 17 </div>
18 @endif 18 @endif
19 19
20 @if(userCan('users-manage')) 20 @if(userCan('users-manage'))
21 <div class="form-group"> 21 <div class="form-group">
22 - <label for="external_auth_id">External Authentication ID</label> 22 + <label for="external_auth_id">{{ trans('settings.users_external_auth_id') }}</label>
23 @include('form.text', ['name' => 'external_auth_id']) 23 @include('form.text', ['name' => 'external_auth_id'])
24 </div> 24 </div>
25 @endif 25 @endif
26 26
27 <div class="form-group"> 27 <div class="form-group">
28 - <a href="{{ baseUrl("/settings/users") }}" class="button muted">Cancel</a> 28 + <a href="{{ baseUrl("/settings/users") }}" class="button muted">{{ trans('common.cancel') }}</a>
29 - <button class="button pos" type="submit">Save</button> 29 + <button class="button pos" type="submit">{{ trans('common.save') }}</button>
30 </div> 30 </div>
...\ No newline at end of file ...\ No newline at end of file
......
1 <div class="form-group"> 1 <div class="form-group">
2 - <label for="name">Name</label> 2 + <label for="name">{{ trans('auth.name') }}</label>
3 @include('form.text', ['name' => 'name']) 3 @include('form.text', ['name' => 'name'])
4 </div> 4 </div>
5 5
6 <div class="form-group"> 6 <div class="form-group">
7 - <label for="email">Email</label> 7 + <label for="email">{{ trans('auth.email') }}</label>
8 @include('form.text', ['name' => 'email']) 8 @include('form.text', ['name' => 'email'])
9 </div> 9 </div>
10 10
11 @if(userCan('users-manage')) 11 @if(userCan('users-manage'))
12 <div class="form-group"> 12 <div class="form-group">
13 - <label for="role">User Role</label> 13 + <label for="role">{{ trans('settings.users_role') }}</label>
14 @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles]) 14 @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles])
15 </div> 15 </div>
16 @endif 16 @endif
...@@ -18,23 +18,23 @@ ...@@ -18,23 +18,23 @@
18 @if(isset($model)) 18 @if(isset($model))
19 <div class="form-group"> 19 <div class="form-group">
20 <span class="text-muted"> 20 <span class="text-muted">
21 - Only fill the below if you would like <br>to change your password: 21 + {{ trans('settings.users_password_warning') }}
22 </span> 22 </span>
23 </div> 23 </div>
24 @endif 24 @endif
25 25
26 <div class="form-group"> 26 <div class="form-group">
27 - <label for="password">Password</label> 27 + <label for="password">{{ trans('auth.password') }}</label>
28 @include('form.password', ['name' => 'password']) 28 @include('form.password', ['name' => 'password'])
29 </div> 29 </div>
30 30
31 <div class="form-group"> 31 <div class="form-group">
32 - <label for="password-confirm">Confirm Password</label> 32 + <label for="password-confirm">{{ trans('auth.password_confirm') }}</label>
33 @include('form.password', ['name' => 'password-confirm']) 33 @include('form.password', ['name' => 'password-confirm'])
34 </div> 34 </div>
35 35
36 <div class="form-group"> 36 <div class="form-group">
37 - <a href="{{ baseUrl("/settings/users") }}" class="button muted">Cancel</a> 37 + <a href="{{ baseUrl("/settings/users") }}" class="button muted">{{ trans('common.cancel') }}</a>
38 - <button class="button pos" type="submit">Save</button> 38 + <button class="button pos" type="submit">{{ trans('common.save') }}</button>
39 </div> 39 </div>
40 40
......
1 @if($user->system_name == 'public') 1 @if($user->system_name == 'public')
2 - <p>This user represents any guest users that visit your instance. It cannot be used for logins but is assigned&nbsp;automatically.</p> 2 + <p>{{ trans('settings.users_system_public') }}</p>
3 @endif 3 @endif
4 4
5 <div class="form-group"> 5 <div class="form-group">
6 - <label for="name">Name</label> 6 + <label for="name">{{ trans('auth.name') }}</label>
7 @include('form.text', ['name' => 'name']) 7 @include('form.text', ['name' => 'name'])
8 </div> 8 </div>
9 9
10 <div class="form-group"> 10 <div class="form-group">
11 - <label for="email">Email</label> 11 + <label for="email">{{ trans('auth.email') }}</label>
12 @include('form.text', ['name' => 'email']) 12 @include('form.text', ['name' => 'email'])
13 </div> 13 </div>
14 14
15 @if(userCan('users-manage')) 15 @if(userCan('users-manage'))
16 <div class="form-group"> 16 <div class="form-group">
17 - <label for="role">User Role</label> 17 + <label for="role">{{ trans('settings.users_role') }}</label>
18 @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles]) 18 @include('form/role-checkboxes', ['name' => 'roles', 'roles' => $roles])
19 </div> 19 </div>
20 @endif 20 @endif
21 21
22 <div class="form-group"> 22 <div class="form-group">
23 - <a href="{{ baseUrl("/settings/users") }}" class="button muted">Cancel</a> 23 + <a href="{{ baseUrl("/settings/users") }}" class="button muted">{{ trans('common.cancel') }}</a>
24 - <button class="button pos" type="submit">Save</button> 24 + <button class="button pos" type="submit">{{ trans('common.save') }}</button>
25 </div> 25 </div>
26 +
......
...@@ -9,12 +9,12 @@ ...@@ -9,12 +9,12 @@
9 <div class="container small" ng-non-bindable> 9 <div class="container small" ng-non-bindable>
10 <div class="row action-header"> 10 <div class="row action-header">
11 <div class="col-sm-8"> 11 <div class="col-sm-8">
12 - <h1>Users</h1> 12 + <h1>{{ trans('settings.users') }}</h1>
13 </div> 13 </div>
14 <div class="col-sm-4"> 14 <div class="col-sm-4">
15 <p></p> 15 <p></p>
16 @if(userCan('users-manage')) 16 @if(userCan('users-manage'))
17 - <a href="{{ baseUrl("/settings/users/create") }}" class="pos button float right"><i class="zmdi zmdi-account-add"></i>Add new user</a> 17 + <a href="{{ baseUrl("/settings/users/create") }}" class="pos button float right"><i class="zmdi zmdi-account-add"></i>{{ trans('settings.users_add_new') }}</a>
18 @endif 18 @endif
19 </div> 19 </div>
20 </div> 20 </div>
...@@ -30,20 +30,17 @@ ...@@ -30,20 +30,17 @@
30 @foreach(collect($listDetails)->except('search') as $name => $val) 30 @foreach(collect($listDetails)->except('search') as $name => $val)
31 <input type="hidden" name="{{ $name }}" value="{{ $val }}"> 31 <input type="hidden" name="{{ $name }}" value="{{ $val }}">
32 @endforeach 32 @endforeach
33 - <input type="text" name="search" placeholder="Search Users" @if($listDetails['search']) value="{{$listDetails['search']}}" @endif> 33 + <input type="text" name="search" placeholder="{{ trans('settings.users_search') }}" @if($listDetails['search']) value="{{$listDetails['search']}}" @endif>
34 </form> 34 </form>
35 </div> 35 </div>
36 </div> 36 </div>
37 - <div class="text-center">
38 -
39 - </div>
40 37
41 <table class="table"> 38 <table class="table">
42 <tr> 39 <tr>
43 <th></th> 40 <th></th>
44 - <th><a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'name']) }}">Name</a></th> 41 + <th><a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'name']) }}">{{ trans('auth.name') }}</a></th>
45 - <th><a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'email']) }}">Email</a></th> 42 + <th><a href="{{ sortUrl('/settings/users', $listDetails, ['sort' => 'email']) }}">{{ trans('auth.email') }}</a></th>
46 - <th>User Roles</th> 43 + <th>{{ trans('settings.role_user_roles') }}</th>
47 </tr> 44 </tr>
48 @foreach($users as $user) 45 @foreach($users as $user)
49 <tr> 46 <tr>
......
...@@ -17,21 +17,21 @@ ...@@ -17,21 +17,21 @@
17 <div> 17 <div>
18 <h3 style="margin-top: 0;">{{ $user->name }}</h3> 18 <h3 style="margin-top: 0;">{{ $user->name }}</h3>
19 <p class="text-muted"> 19 <p class="text-muted">
20 - User for {{ $user->created_at->diffForHumans(null, true) }} 20 + {{ trans('entities.profile_user_for_x', ['time' => $user->created_at->diffForHumans(null, true)]) }}
21 </p> 21 </p>
22 </div> 22 </div>
23 </div> 23 </div>
24 </div> 24 </div>
25 <div class="col-md-5 text-bigger" id="content-counts"> 25 <div class="col-md-5 text-bigger" id="content-counts">
26 - <div class="text-muted">Created Content</div> 26 + <div class="text-muted">{{ trans('entities.profile_created_content') }}</div>
27 <div class="text-book"> 27 <div class="text-book">
28 - <i class="zmdi zmdi-book zmdi-hc-fw"></i> {{ $assetCounts['books'] }} {{ str_plural('Book', $assetCounts['books']) }} 28 + <i class="zmdi zmdi-book zmdi-hc-fw"></i> {{ $assetCounts['books'] }} {{ str_plural(trans('entities.book'), $assetCounts['books']) }}
29 </div> 29 </div>
30 <div class="text-chapter"> 30 <div class="text-chapter">
31 - <i class="zmdi zmdi-collection-bookmark zmdi-hc-fw"></i> {{ $assetCounts['chapters'] }} {{ str_plural('Chapter', $assetCounts['chapters']) }} 31 + <i class="zmdi zmdi-collection-bookmark zmdi-hc-fw"></i> {{ $assetCounts['chapters'] }} {{ str_plural(trans('entities.chapter'), $assetCounts['chapters']) }}
32 </div> 32 </div>
33 <div class="text-page"> 33 <div class="text-page">
34 - <i class="zmdi zmdi-file-text zmdi-hc-fw"></i> {{ $assetCounts['pages'] }} {{ str_plural('Page', $assetCounts['pages']) }} 34 + <i class="zmdi zmdi-file-text zmdi-hc-fw"></i> {{ $assetCounts['pages'] }} {{ str_plural(trans('entities.page'), $assetCounts['pages']) }}
35 </div> 35 </div>
36 </div> 36 </div>
37 </div> 37 </div>
...@@ -39,34 +39,34 @@ ...@@ -39,34 +39,34 @@
39 39
40 <hr class="even"> 40 <hr class="even">
41 41
42 - <h3>Recently Created Pages</h3> 42 + <h3>{{ trans('entities.recently_created_pages') }}</h3>
43 @if (count($recentlyCreated['pages']) > 0) 43 @if (count($recentlyCreated['pages']) > 0)
44 @include('partials/entity-list', ['entities' => $recentlyCreated['pages']]) 44 @include('partials/entity-list', ['entities' => $recentlyCreated['pages']])
45 @else 45 @else
46 - <p class="text-muted">{{ $user->name }} has not created any pages</p> 46 + <p class="text-muted">{{ trans('entities.profile_not_created_pages', ['userName' => $user->name]) }}</p>
47 @endif 47 @endif
48 48
49 <hr class="even"> 49 <hr class="even">
50 50
51 - <h3>Recently Created Chapters</h3> 51 + <h3>{{ trans('entities.recently_created_chapters') }}</h3>
52 @if (count($recentlyCreated['chapters']) > 0) 52 @if (count($recentlyCreated['chapters']) > 0)
53 @include('partials/entity-list', ['entities' => $recentlyCreated['chapters']]) 53 @include('partials/entity-list', ['entities' => $recentlyCreated['chapters']])
54 @else 54 @else
55 - <p class="text-muted">{{ $user->name }} has not created any chapters</p> 55 + <p class="text-muted">{{ trans('entities.profile_not_created_chapters', ['userName' => $user->name]) }}</p>
56 @endif 56 @endif
57 57
58 <hr class="even"> 58 <hr class="even">
59 59
60 - <h3>Recently Created Books</h3> 60 + <h3>{{ trans('entities.recently_created_books') }}</h3>
61 @if (count($recentlyCreated['books']) > 0) 61 @if (count($recentlyCreated['books']) > 0)
62 @include('partials/entity-list', ['entities' => $recentlyCreated['books']]) 62 @include('partials/entity-list', ['entities' => $recentlyCreated['books']])
63 @else 63 @else
64 - <p class="text-muted">{{ $user->name }} has not created any books</p> 64 + <p class="text-muted">{{ trans('entities.profile_not_created_books', ['userName' => $user->name]) }}</p>
65 @endif 65 @endif
66 </div> 66 </div>
67 67
68 <div class="col-sm-4 col-sm-offset-1" id="recent-activity"> 68 <div class="col-sm-4 col-sm-offset-1" id="recent-activity">
69 - <h3>Recent Activity</h3> 69 + <h3>{{ trans('entities.recent_activity') }}</h3>
70 @include('partials/activity-list', ['activity' => $activity]) 70 @include('partials/activity-list', ['activity' => $activity])
71 </div> 71 </div>
72 72
......
...@@ -18,5 +18,5 @@ if (! empty($outroLines)) { ...@@ -18,5 +18,5 @@ if (! empty($outroLines)) {
18 echo implode("\n", $outroLines), "\n\n"; 18 echo implode("\n", $outroLines), "\n\n";
19 } 19 }
20 20
21 -echo 'Regards,', "\n"; 21 +echo "\n";
22 -echo config('app.name'), "\n"; 22 +echo setting('app-name'), "\n";
......
...@@ -159,8 +159,7 @@ $style = [ ...@@ -159,8 +159,7 @@ $style = [
159 <tr> 159 <tr>
160 <td style="{{ $fontFamily }}"> 160 <td style="{{ $fontFamily }}">
161 <p style="{{ $style['paragraph-sub'] }}"> 161 <p style="{{ $style['paragraph-sub'] }}">
162 - If you’re having trouble clicking the "{{ $actionText }}" button, 162 + {{ trans('common.email_action_help', ['actionText' => $actionText]) }}
163 - copy and paste the URL below into your web browser:
164 </p> 163 </p>
165 164
166 <p style="{{ $style['paragraph-sub'] }}"> 165 <p style="{{ $style['paragraph-sub'] }}">
...@@ -188,7 +187,7 @@ $style = [ ...@@ -188,7 +187,7 @@ $style = [
188 <p style="{{ $style['paragraph-sub'] }}"> 187 <p style="{{ $style['paragraph-sub'] }}">
189 &copy; {{ date('Y') }} 188 &copy; {{ date('Y') }}
190 <a style="{{ $style['anchor'] }}" href="{{ baseUrl('/') }}" target="_blank">{{ setting('app-name') }}</a>. 189 <a style="{{ $style['anchor'] }}" href="{{ baseUrl('/') }}" target="_blank">{{ setting('app-name') }}</a>.
191 - All rights reserved. 190 + {{ trans('common.email_rights') }}
192 </p> 191 </p>
193 </td> 192 </td>
194 </tr> 193 </tr>
......
1 <?php 1 <?php
2 2
3 +Route::get('/translations.js', 'HomeController@getTranslations');
4 +
3 // Authenticated routes... 5 // Authenticated routes...
4 Route::group(['middleware' => 'auth'], function () { 6 Route::group(['middleware' => 'auth'], function () {
5 7
...@@ -107,7 +109,6 @@ Route::group(['middleware' => 'auth'], function () { ...@@ -107,7 +109,6 @@ Route::group(['middleware' => 'auth'], function () {
107 Route::get('/get/{entityType}/{entityId}', 'TagController@getForEntity'); 109 Route::get('/get/{entityType}/{entityId}', 'TagController@getForEntity');
108 Route::get('/suggest/names', 'TagController@getNameSuggestions'); 110 Route::get('/suggest/names', 'TagController@getNameSuggestions');
109 Route::get('/suggest/values', 'TagController@getValueSuggestions'); 111 Route::get('/suggest/values', 'TagController@getValueSuggestions');
110 - Route::post('/update/{entityType}/{entityId}', 'TagController@updateForEntity');
111 }); 112 });
112 113
113 Route::get('/ajax/search/entities', 'SearchController@searchEntitiesAjax'); 114 Route::get('/ajax/search/entities', 'SearchController@searchEntitiesAjax');
......
...@@ -24,7 +24,7 @@ class AuthTest extends TestCase ...@@ -24,7 +24,7 @@ class AuthTest extends TestCase
24 $settings->put('app-public', 'true'); 24 $settings->put('app-public', 'true');
25 $this->visit('/') 25 $this->visit('/')
26 ->seePageIs('/') 26 ->seePageIs('/')
27 - ->see('Sign In'); 27 + ->see('Log In');
28 } 28 }
29 29
30 public function test_registration_showing() 30 public function test_registration_showing()
...@@ -132,7 +132,7 @@ class AuthTest extends TestCase ...@@ -132,7 +132,7 @@ class AuthTest extends TestCase
132 132
133 $this->asAdmin() 133 $this->asAdmin()
134 ->visit('/settings/users') 134 ->visit('/settings/users')
135 - ->click('Add new user') 135 + ->click('Add New User')
136 ->type($user->name, '#name') 136 ->type($user->name, '#name')
137 ->type($user->email, '#email') 137 ->type($user->email, '#email')
138 ->check('roles[admin]') 138 ->check('roles[admin]')
...@@ -245,7 +245,7 @@ class AuthTest extends TestCase ...@@ -245,7 +245,7 @@ class AuthTest extends TestCase
245 { 245 {
246 $this->setSettings(['registration-enabled' => 'true']); 246 $this->setSettings(['registration-enabled' => 'true']);
247 $this->visit('/password/email') 247 $this->visit('/password/email')
248 - ->seeLink('Sign in') 248 + ->seeLink('Log in')
249 ->seeLink('Sign up'); 249 ->seeLink('Sign up');
250 } 250 }
251 251
...@@ -260,6 +260,6 @@ class AuthTest extends TestCase ...@@ -260,6 +260,6 @@ class AuthTest extends TestCase
260 return $this->visit('/login') 260 return $this->visit('/login')
261 ->type($email, '#email') 261 ->type($email, '#email')
262 ->type($password, '#password') 262 ->type($password, '#password')
263 - ->press('Sign In'); 263 + ->press('Log In');
264 } 264 }
265 } 265 }
......
...@@ -36,11 +36,11 @@ class LdapTest extends \TestCase ...@@ -36,11 +36,11 @@ class LdapTest extends \TestCase
36 ->see('Username') 36 ->see('Username')
37 ->type($this->mockUser->name, '#username') 37 ->type($this->mockUser->name, '#username')
38 ->type($this->mockUser->password, '#password') 38 ->type($this->mockUser->password, '#password')
39 - ->press('Sign In') 39 + ->press('Log In')
40 ->seePageIs('/login')->see('Please enter an email to use for this account.'); 40 ->seePageIs('/login')->see('Please enter an email to use for this account.');
41 41
42 $this->type($this->mockUser->email, '#email') 42 $this->type($this->mockUser->email, '#email')
43 - ->press('Sign In') 43 + ->press('Log In')
44 ->seePageIs('/') 44 ->seePageIs('/')
45 ->see($this->mockUser->name) 45 ->see($this->mockUser->name)
46 ->seeInDatabase('users', ['email' => $this->mockUser->email, 'email_confirmed' => false, 'external_auth_id' => $this->mockUser->name]); 46 ->seeInDatabase('users', ['email' => $this->mockUser->email, 'email_confirmed' => false, 'external_auth_id' => $this->mockUser->name]);
...@@ -64,7 +64,7 @@ class LdapTest extends \TestCase ...@@ -64,7 +64,7 @@ class LdapTest extends \TestCase
64 ->see('Username') 64 ->see('Username')
65 ->type($this->mockUser->name, '#username') 65 ->type($this->mockUser->name, '#username')
66 ->type($this->mockUser->password, '#password') 66 ->type($this->mockUser->password, '#password')
67 - ->press('Sign In') 67 + ->press('Log In')
68 ->seePageIs('/') 68 ->seePageIs('/')
69 ->see($this->mockUser->name) 69 ->see($this->mockUser->name)
70 ->seeInDatabase('users', ['email' => $this->mockUser->email, 'email_confirmed' => false, 'external_auth_id' => $ldapDn]); 70 ->seeInDatabase('users', ['email' => $this->mockUser->email, 'email_confirmed' => false, 'external_auth_id' => $ldapDn]);
...@@ -87,7 +87,7 @@ class LdapTest extends \TestCase ...@@ -87,7 +87,7 @@ class LdapTest extends \TestCase
87 ->see('Username') 87 ->see('Username')
88 ->type($this->mockUser->name, '#username') 88 ->type($this->mockUser->name, '#username')
89 ->type($this->mockUser->password, '#password') 89 ->type($this->mockUser->password, '#password')
90 - ->press('Sign In') 90 + ->press('Log In')
91 ->seePageIs('/login')->see('These credentials do not match our records.') 91 ->seePageIs('/login')->see('These credentials do not match our records.')
92 ->dontSeeInDatabase('users', ['external_auth_id' => $this->mockUser->name]); 92 ->dontSeeInDatabase('users', ['external_auth_id' => $this->mockUser->name]);
93 } 93 }
......
...@@ -15,8 +15,8 @@ class EntitySearchTest extends TestCase ...@@ -15,8 +15,8 @@ class EntitySearchTest extends TestCase
15 ->type($page->name, 'term') 15 ->type($page->name, 'term')
16 ->press('header-search-box-button') 16 ->press('header-search-box-button')
17 ->see('Search Results') 17 ->see('Search Results')
18 - ->see($page->name) 18 + ->seeInElement('.entity-list', $page->name)
19 - ->click($page->name) 19 + ->clickInElement('.entity-list', $page->name)
20 ->seePageIs($page->getUrl()); 20 ->seePageIs($page->getUrl());
21 } 21 }
22 22
......
...@@ -136,7 +136,7 @@ class EntityTest extends TestCase ...@@ -136,7 +136,7 @@ class EntityTest extends TestCase
136 $this->asAdmin() 136 $this->asAdmin()
137 ->visit('/books') 137 ->visit('/books')
138 // Choose to create a book 138 // Choose to create a book
139 - ->click('Add new book') 139 + ->click('Create New Book')
140 ->seePageIs('/books/create') 140 ->seePageIs('/books/create')
141 // Fill out form & save 141 // Fill out form & save
142 ->type($book->name, '#name') 142 ->type($book->name, '#name')
......
...@@ -28,7 +28,7 @@ class SortTest extends TestCase ...@@ -28,7 +28,7 @@ class SortTest extends TestCase
28 $currentBook = $page->book; 28 $currentBook = $page->book;
29 $newBook = \BookStack\Book::where('id', '!=', $currentBook->id)->first(); 29 $newBook = \BookStack\Book::where('id', '!=', $currentBook->id)->first();
30 $this->asAdmin()->visit($page->getUrl() . '/move') 30 $this->asAdmin()->visit($page->getUrl() . '/move')
31 - ->see('Move Page')->see($page->name) 31 + ->see('Move Page')
32 ->type('book:' . $newBook->id, 'entity_selection')->press('Move Page'); 32 ->type('book:' . $newBook->id, 'entity_selection')->press('Move Page');
33 33
34 $page = \BookStack\Page::find($page->id); 34 $page = \BookStack\Page::find($page->id);
...@@ -48,7 +48,7 @@ class SortTest extends TestCase ...@@ -48,7 +48,7 @@ class SortTest extends TestCase
48 $newBook = \BookStack\Book::where('id', '!=', $currentBook->id)->first(); 48 $newBook = \BookStack\Book::where('id', '!=', $currentBook->id)->first();
49 49
50 $this->asAdmin()->visit($chapter->getUrl() . '/move') 50 $this->asAdmin()->visit($chapter->getUrl() . '/move')
51 - ->see('Move Chapter')->see($chapter->name) 51 + ->see('Move Chapter')
52 ->type('book:' . $newBook->id, 'entity_selection')->press('Move Chapter'); 52 ->type('book:' . $newBook->id, 'entity_selection')->press('Move Chapter');
53 53
54 $chapter = \BookStack\Chapter::find($chapter->id); 54 $chapter = \BookStack\Chapter::find($chapter->id);
......
...@@ -81,7 +81,7 @@ class RolesTest extends TestCase ...@@ -81,7 +81,7 @@ class RolesTest extends TestCase
81 $this->asAdmin()->visit('/settings') 81 $this->asAdmin()->visit('/settings')
82 ->click('Roles') 82 ->click('Roles')
83 ->seePageIs('/settings/roles') 83 ->seePageIs('/settings/roles')
84 - ->click('Add new role') 84 + ->click('Create New Role')
85 ->type('Test Role', 'display_name') 85 ->type('Test Role', 'display_name')
86 ->type('A little test description', 'description') 86 ->type('A little test description', 'description')
87 ->press('Save Role') 87 ->press('Save Role')
...@@ -211,7 +211,7 @@ class RolesTest extends TestCase ...@@ -211,7 +211,7 @@ class RolesTest extends TestCase
211 $this->checkAccessPermission('book-create-all', [ 211 $this->checkAccessPermission('book-create-all', [
212 '/books/create' 212 '/books/create'
213 ], [ 213 ], [
214 - '/books' => 'Add new book' 214 + '/books' => 'Create New Book'
215 ]); 215 ]);
216 216
217 $this->visit('/books/create') 217 $this->visit('/books/create')
......
...@@ -64,7 +64,7 @@ class PublicActionTest extends TestCase ...@@ -64,7 +64,7 @@ class PublicActionTest extends TestCase
64 $this->visit($chapter->book->getUrl()); 64 $this->visit($chapter->book->getUrl());
65 $this->visit($chapter->getUrl()) 65 $this->visit($chapter->getUrl())
66 ->click('New Page') 66 ->click('New Page')
67 - ->see('Create Page') 67 + ->see('New Page')
68 ->seePageIs($chapter->getUrl('/create-page')); 68 ->seePageIs($chapter->getUrl('/create-page'));
69 69
70 $this->submitForm('Continue', [ 70 $this->submitForm('Continue', [
......