mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
Merge branch 'master' of git://github.com/BookStackApp/BookStack into BookStackApp-master
Conflicts: app/Http/Controllers/BookController.php resources/lang/en/common.php resources/views/books/create.blade.php resources/views/books/form.blade.php resources/views/books/index.blade.php resources/views/users/edit.blade.php tests/Entity/EntityTest.php
This commit is contained in:
commit
6200948eec
@ -231,7 +231,6 @@ class RegisterController extends Controller
|
||||
return redirect('/register/confirm');
|
||||
}
|
||||
|
||||
$this->emailConfirmationService->sendConfirmation($user);
|
||||
session()->flash('success', trans('auth.email_confirm_resent'));
|
||||
return redirect('/register/confirm');
|
||||
}
|
||||
|
@ -36,12 +36,17 @@ class BookController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$books = $this->entityRepo->getAllPaginated('book', 16);
|
||||
$books = $this->entityRepo->getAllPaginated('book', 20);
|
||||
$recents = $this->signedIn ? $this->entityRepo->getRecentlyViewed('book', 4, 0) : false;
|
||||
$popular = $this->entityRepo->getPopular('book', 3, 0);
|
||||
$books_display = $this->currentUser->books_display;
|
||||
$popular = $this->entityRepo->getPopular('book', 4, 0);
|
||||
$new = $this->entityRepo->getRecentlyCreated('book', 4, 0);
|
||||
$this->setPageTitle('Books');
|
||||
return view('books/index', ['books' => $books, 'recents' => $recents, 'popular' => $popular, 'books_display' => $books_display] );
|
||||
return view('books/index', [
|
||||
'books' => $books,
|
||||
'recents' => $recents,
|
||||
'popular' => $popular,
|
||||
'new' => $new
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,7 +90,12 @@ class BookController extends Controller
|
||||
$bookChildren = $this->entityRepo->getBookChildren($book);
|
||||
Views::add($book);
|
||||
$this->setPageTitle($book->getShortName());
|
||||
return view('books/show', ['book' => $book, 'current' => $book, 'bookChildren' => $bookChildren]);
|
||||
return view('books/show', [
|
||||
'book' => $book,
|
||||
'current' => $book,
|
||||
'bookChildren' => $bookChildren,
|
||||
'activity' => Activity::entityActivity($book, 20, 0)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,15 +29,25 @@ class HomeController extends Controller
|
||||
$activity = Activity::latest(10);
|
||||
$draftPages = $this->signedIn ? $this->entityRepo->getUserDraftPages(6) : [];
|
||||
$recentFactor = count($draftPages) > 0 ? 0.5 : 1;
|
||||
$recents = $this->signedIn ? Views::getUserRecentlyViewed(12*$recentFactor, 0) : $this->entityRepo->getRecentlyCreated('book', 10*$recentFactor);
|
||||
$recentlyCreatedPages = $this->entityRepo->getRecentlyCreated('page', 5);
|
||||
$recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdated('page', 5);
|
||||
return view('home', [
|
||||
$recents = $this->signedIn ? Views::getUserRecentlyViewed(12*$recentFactor, 0) : $this->entityRepo->getRecentlyCreated('book', 12*$recentFactor);
|
||||
$recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdated('page', 12);
|
||||
|
||||
// Custom homepage
|
||||
$customHomepage = false;
|
||||
$homepageSetting = setting('app-homepage');
|
||||
if ($homepageSetting) {
|
||||
$id = intval(explode(':', $homepageSetting)[0]);
|
||||
$customHomepage = $this->entityRepo->getById('page', $id, false, true);
|
||||
$this->entityRepo->renderPage($customHomepage, true);
|
||||
}
|
||||
|
||||
$view = $customHomepage ? 'home-custom' : 'home';
|
||||
return view($view, [
|
||||
'activity' => $activity,
|
||||
'recents' => $recents,
|
||||
'recentlyCreatedPages' => $recentlyCreatedPages,
|
||||
'recentlyUpdatedPages' => $recentlyUpdatedPages,
|
||||
'draftPages' => $draftPages
|
||||
'draftPages' => $draftPages,
|
||||
'customHomepage' => $customHomepage
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ class PageController extends Controller
|
||||
return view('pages/show', [
|
||||
'page' => $page,'book' => $page->book,
|
||||
'current' => $page, 'sidebarTree' => $sidebarTree,
|
||||
'pageNav' => $pageNav, 'pageContent' => $pageContent]);
|
||||
'pageNav' => $pageNav]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -380,6 +380,7 @@ class PageController extends Controller
|
||||
return view('pages/revision', [
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'revision' => $revision
|
||||
]);
|
||||
}
|
||||
|
||||
@ -409,6 +410,7 @@ class PageController extends Controller
|
||||
'page' => $page,
|
||||
'book' => $page->book,
|
||||
'diff' => $diff,
|
||||
'revision' => $revision
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -47,4 +47,16 @@ class PageRevision extends Model
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows checking of the exact class, Used to check entity type.
|
||||
* Included here to align with entities in similar use cases.
|
||||
* (Yup, Bit of an awkward hack)
|
||||
* @param $type
|
||||
* @return bool
|
||||
*/
|
||||
public static function isA($type)
|
||||
{
|
||||
return $type === 'revision';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -137,10 +137,15 @@ class EntityRepo
|
||||
* @param string $type
|
||||
* @param integer $id
|
||||
* @param bool $allowDrafts
|
||||
* @param bool $ignorePermissions
|
||||
* @return Entity
|
||||
*/
|
||||
public function getById($type, $id, $allowDrafts = false)
|
||||
public function getById($type, $id, $allowDrafts = false, $ignorePermissions = false)
|
||||
{
|
||||
if ($ignorePermissions) {
|
||||
$entity = $this->getEntity($type);
|
||||
return $entity->newQuery()->find($id);
|
||||
}
|
||||
return $this->entityQuery($type, $allowDrafts)->find($id);
|
||||
}
|
||||
|
||||
@ -671,9 +676,10 @@ class EntityRepo
|
||||
/**
|
||||
* Render the page for viewing, Parsing and performing features such as page transclusion.
|
||||
* @param Page $page
|
||||
* @param bool $ignorePermissions
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function renderPage(Page $page)
|
||||
public function renderPage(Page $page, $ignorePermissions = false)
|
||||
{
|
||||
$content = $page->html;
|
||||
$matches = [];
|
||||
@ -685,7 +691,7 @@ class EntityRepo
|
||||
$pageId = intval($splitInclude[0]);
|
||||
if (is_nan($pageId)) continue;
|
||||
|
||||
$page = $this->getById('page', $pageId);
|
||||
$page = $this->getById('page', $pageId, false, $ignorePermissions);
|
||||
if ($page === null) {
|
||||
$content = str_replace($matches[0][$index], '', $content);
|
||||
continue;
|
||||
@ -710,6 +716,7 @@ class EntityRepo
|
||||
$content = str_replace($matches[0][$index], trim($innerContent), $content);
|
||||
}
|
||||
|
||||
$page->renderedHTML = $content;
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,9 @@ class ExportService
|
||||
*/
|
||||
public function pageToContainedHtml(Page $page)
|
||||
{
|
||||
$this->entityRepo->renderPage($page);
|
||||
$pageHtml = view('pages/export', [
|
||||
'page' => $page,
|
||||
'pageContent' => $this->entityRepo->renderPage($page)
|
||||
'page' => $page
|
||||
])->render();
|
||||
return $this->containHtml($pageHtml);
|
||||
}
|
||||
@ -74,9 +74,9 @@ class ExportService
|
||||
*/
|
||||
public function pageToPdf(Page $page)
|
||||
{
|
||||
$this->entityRepo->renderPage($page);
|
||||
$html = view('pages/pdf', [
|
||||
'page' => $page,
|
||||
'pageContent' => $this->entityRepo->renderPage($page)
|
||||
'page' => $page
|
||||
])->render();
|
||||
return $this->htmlToPdf($html);
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ class SearchService
|
||||
return [
|
||||
'total' => $total,
|
||||
'count' => count($results),
|
||||
'results' => $results->sortByDesc('score')
|
||||
'results' => $results->sortByDesc('score')->values()
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ class ViewService
|
||||
$query->whereIn('viewable_type', $filterModel);
|
||||
} else if ($filterModel) {
|
||||
$query->where('viewable_type', '=', get_class($filterModel));
|
||||
};
|
||||
}
|
||||
|
||||
return $query->with('viewable')->skip($skipCount)->take($count)->get()->pluck('viewable');
|
||||
}
|
||||
|
@ -3,16 +3,20 @@
|
||||
const argv = require('yargs').argv;
|
||||
const gulp = require('gulp'),
|
||||
plumber = require('gulp-plumber');
|
||||
|
||||
const autoprefixer = require('gulp-autoprefixer');
|
||||
const uglify = require('gulp-uglify');
|
||||
const minifycss = require('gulp-clean-css');
|
||||
const sass = require('gulp-sass');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
|
||||
const browserify = require("browserify");
|
||||
const source = require('vinyl-source-stream');
|
||||
const buffer = require('vinyl-buffer');
|
||||
const babelify = require("babelify");
|
||||
const watchify = require("watchify");
|
||||
const envify = require("envify");
|
||||
const uglify = require('gulp-uglify');
|
||||
|
||||
const gutil = require("gulp-util");
|
||||
const liveReload = require('gulp-livereload');
|
||||
|
||||
@ -21,6 +25,7 @@ let isProduction = argv.production || process.env.NODE_ENV === 'production';
|
||||
|
||||
gulp.task('styles', () => {
|
||||
let chain = gulp.src(['resources/assets/sass/**/*.scss'])
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(plumber({
|
||||
errorHandler: function (error) {
|
||||
console.log(error.message);
|
||||
@ -29,6 +34,7 @@ gulp.task('styles', () => {
|
||||
.pipe(sass())
|
||||
.pipe(autoprefixer('last 2 versions'));
|
||||
if (isProduction) chain = chain.pipe(minifycss());
|
||||
chain = chain.pipe(sourcemaps.write());
|
||||
return chain.pipe(gulp.dest('public/css/')).pipe(liveReload());
|
||||
});
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
"clipboard": "^1.7.1",
|
||||
"codemirror": "^5.26.0",
|
||||
"dropzone": "^4.0.1",
|
||||
"gulp-sourcemaps": "^2.6.1",
|
||||
"gulp-util": "^3.0.8",
|
||||
"markdown-it": "^8.3.1",
|
||||
"markdown-it-task-lists": "^2.0.0",
|
||||
|
10
readme.md
10
readme.md
@ -1,7 +1,7 @@
|
||||
# BookStack
|
||||
|
||||
[![GitHub release](https://img.shields.io/github/release/BookStackApp/BookStack.svg?maxAge=2592000)](https://github.com/BookStackApp/BookStack/releases/latest)
|
||||
[![license](https://img.shields.io/github/license/BookStackApp/BookStack.svg?maxAge=2592000)](https://github.com/BookStackApp/BookStack/blob/master/LICENSE)
|
||||
[![GitHub release](https://img.shields.io/github/release/BookStackApp/BookStack.svg)](https://github.com/BookStackApp/BookStack/releases/latest)
|
||||
[![license](https://img.shields.io/github/license/BookStackApp/BookStack.svg)](https://github.com/BookStackApp/BookStack/blob/master/LICENSE)
|
||||
[![Build Status](https://travis-ci.org/BookStackApp/BookStack.svg)](https://travis-ci.org/BookStackApp/BookStack)
|
||||
|
||||
A platform for storing and organising information and documentation. General information and documentation for BookStack can be found at https://www.bookstackapp.com/.
|
||||
@ -13,6 +13,12 @@ A platform for storing and organising information and documentation. General inf
|
||||
* *Password: `password`*
|
||||
* [BookStack Blog](https://www.bookstackapp.com/blog)
|
||||
|
||||
## Project Definition
|
||||
|
||||
BookStack is an opinionated wiki system that provides a pleasant and simple out of the box experience. New users to an instance should find the experience intuitive and only basic word-processing skills should be required to get involved in creating content on BookStack. The platform should provide advanced power features to those that desire it but they should not interfere with the core simple user experience.
|
||||
|
||||
BookStack is not designed as an extensible platform to be used for purposes that differ to the statement above.
|
||||
|
||||
## Development & Testing
|
||||
|
||||
All development on BookStack is currently done on the master branch. When it's time for a release the master branch is merged into release with built & minified CSS & JS then tagged at it's version. Here are the current development requirements:
|
||||
|
47
resources/assets/js/components/entity-selector-popup.js
Normal file
47
resources/assets/js/components/entity-selector-popup.js
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
class EntitySelectorPopup {
|
||||
|
||||
constructor(elem) {
|
||||
this.elem = elem;
|
||||
window.EntitySelectorPopup = this;
|
||||
|
||||
this.callback = null;
|
||||
this.selection = null;
|
||||
|
||||
this.selectButton = elem.querySelector('.entity-link-selector-confirm');
|
||||
this.selectButton.addEventListener('click', this.onSelectButtonClick.bind(this));
|
||||
|
||||
window.$events.listen('entity-select-change', this.onSelectionChange.bind(this));
|
||||
window.$events.listen('entity-select-confirm', this.onSelectionConfirm.bind(this));
|
||||
}
|
||||
|
||||
show(callback) {
|
||||
this.callback = callback;
|
||||
this.elem.components.overlay.show();
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.elem.components.overlay.hide();
|
||||
}
|
||||
|
||||
onSelectButtonClick() {
|
||||
this.hide();
|
||||
if (this.selection !== null && this.callback) this.callback(this.selection);
|
||||
}
|
||||
|
||||
onSelectionConfirm(entity) {
|
||||
this.hide();
|
||||
if (this.callback && entity) this.callback(entity);
|
||||
}
|
||||
|
||||
onSelectionChange(entity) {
|
||||
this.selection = entity;
|
||||
if (entity === null) {
|
||||
this.selectButton.setAttribute('disabled', 'true');
|
||||
} else {
|
||||
this.selectButton.removeAttribute('disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = EntitySelectorPopup;
|
118
resources/assets/js/components/entity-selector.js
Normal file
118
resources/assets/js/components/entity-selector.js
Normal file
@ -0,0 +1,118 @@
|
||||
|
||||
class EntitySelector {
|
||||
|
||||
constructor(elem) {
|
||||
this.elem = elem;
|
||||
this.search = '';
|
||||
this.lastClick = 0;
|
||||
|
||||
let entityTypes = elem.hasAttribute('entity-types') ? elem.getAttribute('entity-types') : 'page,book,chapter';
|
||||
this.searchUrl = window.baseUrl(`/ajax/search/entities?types=${encodeURIComponent(entityTypes)}`);
|
||||
|
||||
this.input = elem.querySelector('[entity-selector-input]');
|
||||
this.searchInput = elem.querySelector('[entity-selector-search]');
|
||||
this.loading = elem.querySelector('[entity-selector-loading]');
|
||||
this.resultsContainer = elem.querySelector('[entity-selector-results]');
|
||||
|
||||
this.elem.addEventListener('click', this.onClick.bind(this));
|
||||
|
||||
let lastSearch = 0;
|
||||
this.searchInput.addEventListener('input', event => {
|
||||
lastSearch = Date.now();
|
||||
this.showLoading();
|
||||
setTimeout(() => {
|
||||
if (Date.now() - lastSearch < 199) return;
|
||||
this.searchEntities(this.searchInput.value);
|
||||
}, 200);
|
||||
});
|
||||
this.searchInput.addEventListener('keydown', event => {
|
||||
if (event.keyCode === 13) event.preventDefault();
|
||||
});
|
||||
|
||||
this.showLoading();
|
||||
this.initialLoad();
|
||||
}
|
||||
|
||||
showLoading() {
|
||||
this.loading.style.display = 'block';
|
||||
this.resultsContainer.style.display = 'none';
|
||||
}
|
||||
|
||||
hideLoading() {
|
||||
this.loading.style.display = 'none';
|
||||
this.resultsContainer.style.display = 'block';
|
||||
}
|
||||
|
||||
initialLoad() {
|
||||
window.$http.get(this.searchUrl).then(resp => {
|
||||
this.resultsContainer.innerHTML = resp.data;
|
||||
this.hideLoading();
|
||||
})
|
||||
}
|
||||
|
||||
searchEntities(searchTerm) {
|
||||
this.input.value = '';
|
||||
let url = this.searchUrl + `&term=${encodeURIComponent(searchTerm)}`;
|
||||
window.$http.get(url).then(resp => {
|
||||
this.resultsContainer.innerHTML = resp.data;
|
||||
this.hideLoading();
|
||||
});
|
||||
}
|
||||
|
||||
isDoubleClick() {
|
||||
let now = Date.now();
|
||||
let answer = now - this.lastClick < 300;
|
||||
this.lastClick = now;
|
||||
return answer;
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
let t = event.target;
|
||||
console.log('click', t);
|
||||
|
||||
if (t.matches('.entity-list-item *')) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
let item = t.closest('[data-entity-type]');
|
||||
this.selectItem(item);
|
||||
} else if (t.matches('[data-entity-type]')) {
|
||||
this.selectItem(t)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
selectItem(item) {
|
||||
let isDblClick = this.isDoubleClick();
|
||||
let type = item.getAttribute('data-entity-type');
|
||||
let id = item.getAttribute('data-entity-id');
|
||||
let isSelected = !item.classList.contains('selected') || isDblClick;
|
||||
|
||||
this.unselectAll();
|
||||
this.input.value = isSelected ? `${type}:${id}` : '';
|
||||
|
||||
if (!isSelected) window.$events.emit('entity-select-change', null);
|
||||
if (isSelected) {
|
||||
item.classList.add('selected');
|
||||
item.classList.add('primary-background');
|
||||
}
|
||||
if (!isDblClick && !isSelected) return;
|
||||
|
||||
let link = item.querySelector('.entity-list-item-link').getAttribute('href');
|
||||
let name = item.querySelector('.entity-list-item-name').textContent;
|
||||
let data = {id: Number(id), name: name, link: link};
|
||||
|
||||
if (isDblClick) window.$events.emit('entity-select-confirm', data);
|
||||
if (isSelected) window.$events.emit('entity-select-change', data);
|
||||
}
|
||||
|
||||
unselectAll() {
|
||||
let selected = this.elem.querySelectorAll('.selected');
|
||||
for (let i = 0, len = selected.length; i < len; i++) {
|
||||
selected[i].classList.remove('selected');
|
||||
selected[i].classList.remove('primary-background');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = EntitySelector;
|
@ -6,6 +6,10 @@ let componentMapping = {
|
||||
'notification': require('./notification'),
|
||||
'chapter-toggle': require('./chapter-toggle'),
|
||||
'expand-toggle': require('./expand-toggle'),
|
||||
'entity-selector-popup': require('./entity-selector-popup'),
|
||||
'entity-selector': require('./entity-selector'),
|
||||
'sidebar': require('./sidebar'),
|
||||
'page-picker': require('./page-picker'),
|
||||
};
|
||||
|
||||
window.components = {};
|
||||
|
@ -6,7 +6,7 @@ class Notification {
|
||||
this.type = elem.getAttribute('notification');
|
||||
this.textElem = elem.querySelector('span');
|
||||
this.autohide = this.elem.hasAttribute('data-autohide');
|
||||
window.Events.listen(this.type, text => {
|
||||
window.$events.listen(this.type, text => {
|
||||
this.show(text);
|
||||
});
|
||||
elem.addEventListener('click', this.hide.bind(this));
|
||||
|
60
resources/assets/js/components/page-picker.js
Normal file
60
resources/assets/js/components/page-picker.js
Normal file
@ -0,0 +1,60 @@
|
||||
|
||||
class PagePicker {
|
||||
|
||||
constructor(elem) {
|
||||
this.elem = elem;
|
||||
this.input = elem.querySelector('input');
|
||||
this.resetButton = elem.querySelector('[page-picker-reset]');
|
||||
this.selectButton = elem.querySelector('[page-picker-select]');
|
||||
this.display = elem.querySelector('[page-picker-display]');
|
||||
this.defaultDisplay = elem.querySelector('[page-picker-default]');
|
||||
this.buttonSep = elem.querySelector('span.sep');
|
||||
|
||||
this.value = this.input.value;
|
||||
this.setupListeners();
|
||||
}
|
||||
|
||||
setupListeners() {
|
||||
// Select click
|
||||
this.selectButton.addEventListener('click', event => {
|
||||
window.EntitySelectorPopup.show(entity => {
|
||||
this.setValue(entity.id, entity.name);
|
||||
});
|
||||
});
|
||||
|
||||
this.resetButton.addEventListener('click', event => {
|
||||
this.setValue('', '');
|
||||
});
|
||||
}
|
||||
|
||||
setValue(value, name) {
|
||||
this.value = value;
|
||||
this.input.value = value;
|
||||
this.controlView(name);
|
||||
}
|
||||
|
||||
controlView(name) {
|
||||
let hasValue = this.value && this.value !== 0;
|
||||
toggleElem(this.resetButton, hasValue);
|
||||
toggleElem(this.buttonSep, hasValue);
|
||||
toggleElem(this.defaultDisplay, !hasValue);
|
||||
toggleElem(this.display, hasValue);
|
||||
if (hasValue) {
|
||||
let id = this.getAssetIdFromVal();
|
||||
this.display.textContent = `#${id}, ${name}`;
|
||||
this.display.href = window.baseUrl(`/link/${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
getAssetIdFromVal() {
|
||||
return Number(this.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function toggleElem(elem, show) {
|
||||
let display = (elem.tagName === 'BUTTON' || elem.tagName === 'SPAN') ? 'inline-block' : 'block';
|
||||
elem.style.display = show ? display : 'none';
|
||||
}
|
||||
|
||||
module.exports = PagePicker;
|
16
resources/assets/js/components/sidebar.js
Normal file
16
resources/assets/js/components/sidebar.js
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
class Sidebar {
|
||||
|
||||
constructor(elem) {
|
||||
this.elem = elem;
|
||||
this.toggleElem = elem.querySelector('.sidebar-toggle');
|
||||
this.toggleElem.addEventListener('click', this.toggle.bind(this));
|
||||
}
|
||||
|
||||
toggle(show = true) {
|
||||
this.elem.classList.toggle('open');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Sidebar;
|
@ -252,7 +252,7 @@ module.exports = function (ngApp, events) {
|
||||
// Show the popup link selector and insert a link when finished
|
||||
function showLinkSelector() {
|
||||
let cursorPos = cm.getCursor('from');
|
||||
window.showEntityLinkSelector(entity => {
|
||||
window.EntitySelectorPopup.show(entity => {
|
||||
let selectedText = cm.getSelection() || entity.name;
|
||||
let newText = `[${selectedText}](${entity.link})`;
|
||||
cm.focus();
|
||||
@ -387,154 +387,6 @@ module.exports = function (ngApp, events) {
|
||||
}
|
||||
}]);
|
||||
|
||||
ngApp.directive('entityLinkSelector', [function($http) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
|
||||
const selectButton = element.find('.entity-link-selector-confirm');
|
||||
let callback = false;
|
||||
let entitySelection = null;
|
||||
|
||||
// Handle entity selection change, Stores the selected entity locally
|
||||
function entitySelectionChange(entity) {
|
||||
entitySelection = entity;
|
||||
if (entity === null) {
|
||||
selectButton.attr('disabled', 'true');
|
||||
} else {
|
||||
selectButton.removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
events.listen('entity-select-change', entitySelectionChange);
|
||||
|
||||
// Handle selection confirm button click
|
||||
selectButton.click(event => {
|
||||
hide();
|
||||
if (entitySelection !== null) callback(entitySelection);
|
||||
});
|
||||
|
||||
// Show selector interface
|
||||
function show() {
|
||||
element.fadeIn(240);
|
||||
}
|
||||
|
||||
// Hide selector interface
|
||||
function hide() {
|
||||
element.fadeOut(240);
|
||||
}
|
||||
scope.hide = hide;
|
||||
|
||||
// Listen to confirmation of entity selections (doubleclick)
|
||||
events.listen('entity-select-confirm', entity => {
|
||||
hide();
|
||||
callback(entity);
|
||||
});
|
||||
|
||||
// Show entity selector, Accessible globally, and store the callback
|
||||
window.showEntityLinkSelector = function(passedCallback) {
|
||||
show();
|
||||
callback = passedCallback;
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
|
||||
ngApp.directive('entitySelector', ['$http', '$sce', function ($http, $sce) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: true,
|
||||
link: function (scope, element, attrs) {
|
||||
scope.loading = true;
|
||||
scope.entityResults = false;
|
||||
scope.search = '';
|
||||
|
||||
// Add input for forms
|
||||
const input = element.find('[entity-selector-input]').first();
|
||||
|
||||
// Detect double click events
|
||||
let lastClick = 0;
|
||||
function isDoubleClick() {
|
||||
let now = Date.now();
|
||||
let answer = now - lastClick < 300;
|
||||
lastClick = now;
|
||||
return answer;
|
||||
}
|
||||
|
||||
// Listen to entity item clicks
|
||||
element.on('click', '.entity-list a', function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
let item = $(this).closest('[data-entity-type]');
|
||||
itemSelect(item, isDoubleClick());
|
||||
});
|
||||
element.on('click', '[data-entity-type]', function(event) {
|
||||
itemSelect($(this), isDoubleClick());
|
||||
});
|
||||
|
||||
// Select entity action
|
||||
function itemSelect(item, doubleClick) {
|
||||
let entityType = item.attr('data-entity-type');
|
||||
let entityId = item.attr('data-entity-id');
|
||||
let isSelected = !item.hasClass('selected') || doubleClick;
|
||||
element.find('.selected').removeClass('selected').removeClass('primary-background');
|
||||
if (isSelected) item.addClass('selected').addClass('primary-background');
|
||||
let newVal = isSelected ? `${entityType}:${entityId}` : '';
|
||||
input.val(newVal);
|
||||
|
||||
if (!isSelected) {
|
||||
events.emit('entity-select-change', null);
|
||||
}
|
||||
|
||||
if (!doubleClick && !isSelected) return;
|
||||
|
||||
let link = item.find('.entity-list-item-link').attr('href');
|
||||
let name = item.find('.entity-list-item-name').text();
|
||||
|
||||
if (doubleClick) {
|
||||
events.emit('entity-select-confirm', {
|
||||
id: Number(entityId),
|
||||
name: name,
|
||||
link: link
|
||||
});
|
||||
}
|
||||
|
||||
if (isSelected) {
|
||||
events.emit('entity-select-change', {
|
||||
id: Number(entityId),
|
||||
name: name,
|
||||
link: link
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Get search url with correct types
|
||||
function getSearchUrl() {
|
||||
let types = (attrs.entityTypes) ? encodeURIComponent(attrs.entityTypes) : encodeURIComponent('page,book,chapter');
|
||||
return window.baseUrl(`/ajax/search/entities?types=${types}`);
|
||||
}
|
||||
|
||||
// Get initial contents
|
||||
$http.get(getSearchUrl()).then(resp => {
|
||||
scope.entityResults = $sce.trustAsHtml(resp.data);
|
||||
scope.loading = false;
|
||||
});
|
||||
|
||||
// Search when typing
|
||||
scope.searchEntities = function() {
|
||||
scope.loading = true;
|
||||
input.val('');
|
||||
let url = getSearchUrl() + '&term=' + encodeURIComponent(scope.search);
|
||||
$http.get(url).then(resp => {
|
||||
scope.entityResults = $sce.trustAsHtml(resp.data);
|
||||
scope.loading = false;
|
||||
});
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
ngApp.directive('commentReply', [function () {
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
20
resources/assets/js/dom-polyfills.js
Normal file
20
resources/assets/js/dom-polyfills.js
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Polyfills for DOM API's
|
||||
*/
|
||||
|
||||
if (!Element.prototype.matches) {
|
||||
Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
||||
}
|
||||
|
||||
if (!Element.prototype.closest) {
|
||||
Element.prototype.closest = function (s) {
|
||||
var el = this;
|
||||
var ancestor = this;
|
||||
if (!document.documentElement.contains(el)) return null;
|
||||
do {
|
||||
if (ancestor.matches(s)) return ancestor;
|
||||
ancestor = ancestor.parentElement;
|
||||
} while (ancestor !== null);
|
||||
return null;
|
||||
};
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
"use strict";
|
||||
require("babel-polyfill");
|
||||
require('./dom-polyfills');
|
||||
|
||||
// Url retrieval function
|
||||
window.baseUrl = function(path) {
|
||||
@ -13,9 +14,11 @@ window.baseUrl = function(path) {
|
||||
class EventManager {
|
||||
constructor() {
|
||||
this.listeners = {};
|
||||
this.stack = [];
|
||||
}
|
||||
|
||||
emit(eventName, eventData) {
|
||||
this.stack.push({name: eventName, data: eventData});
|
||||
if (typeof this.listeners[eventName] === 'undefined') return this;
|
||||
let eventsToStart = this.listeners[eventName];
|
||||
for (let i = 0; i < eventsToStart.length; i++) {
|
||||
@ -32,7 +35,7 @@ class EventManager {
|
||||
}
|
||||
}
|
||||
|
||||
window.Events = new EventManager();
|
||||
window.$events = new EventManager();
|
||||
|
||||
const Vue = require("vue");
|
||||
const axios = require("axios");
|
||||
@ -47,13 +50,13 @@ axiosInstance.interceptors.request.use(resp => {
|
||||
return resp;
|
||||
}, err => {
|
||||
if (typeof err.response === "undefined" || typeof err.response.data === "undefined") return Promise.reject(err);
|
||||
if (typeof err.response.data.error !== "undefined") window.Events.emit('error', err.response.data.error);
|
||||
if (typeof err.response.data.message !== "undefined") window.Events.emit('error', err.response.data.message);
|
||||
if (typeof err.response.data.error !== "undefined") window.$events.emit('error', err.response.data.error);
|
||||
if (typeof err.response.data.message !== "undefined") window.$events.emit('error', err.response.data.message);
|
||||
});
|
||||
window.$http = axiosInstance;
|
||||
|
||||
Vue.prototype.$http = axiosInstance;
|
||||
Vue.prototype.$events = window.Events;
|
||||
Vue.prototype.$events = window.$events;
|
||||
|
||||
|
||||
// AngularJS - Create application and load components
|
||||
@ -78,8 +81,8 @@ require("./components");
|
||||
// Load in angular specific items
|
||||
const Directives = require('./directives');
|
||||
const Controllers = require('./controllers');
|
||||
Directives(ngApp, window.Events);
|
||||
Controllers(ngApp, window.Events);
|
||||
Directives(ngApp, window.$events);
|
||||
Controllers(ngApp, window.$events);
|
||||
|
||||
//Global jQuery Config & Extensions
|
||||
|
||||
|
@ -274,7 +274,7 @@ module.exports = function() {
|
||||
file_browser_callback: function (field_name, url, type, win) {
|
||||
|
||||
if (type === 'file') {
|
||||
window.showEntityLinkSelector(function(entity) {
|
||||
window.EntitySelectorPopup.show(function(entity) {
|
||||
let originalField = win.document.getElementById(field_name);
|
||||
originalField.value = entity.link;
|
||||
$(originalField).closest('.mce-form').find('input').eq(2).val(entity.name);
|
||||
|
@ -106,25 +106,25 @@ let setupPageShow = window.setupPageShow = function (pageId) {
|
||||
goToText(event.target.getAttribute('href').substr(1));
|
||||
});
|
||||
|
||||
// Make the book-tree sidebar stick in view on scroll
|
||||
// Make the sidebar stick in view on scroll
|
||||
let $window = $(window);
|
||||
let $bookTree = $(".book-tree");
|
||||
let $bookTreeParent = $bookTree.parent();
|
||||
let $sidebar = $("#sidebar .scroll-body");
|
||||
let $bookTreeParent = $sidebar.parent();
|
||||
// Check the page is scrollable and the content is taller than the tree
|
||||
let pageScrollable = ($(document).height() > $window.height()) && ($bookTree.height() < $('.page-content').height());
|
||||
let pageScrollable = ($(document).height() > $window.height()) && ($sidebar.height() < $('.page-content').height());
|
||||
// Get current tree's width and header height
|
||||
let headerHeight = $("#header").height() + $(".toolbar").height();
|
||||
let isFixed = $window.scrollTop() > headerHeight;
|
||||
// Function to fix the tree as a sidebar
|
||||
function stickTree() {
|
||||
$bookTree.width($bookTreeParent.width() + 15);
|
||||
$bookTree.addClass("fixed");
|
||||
$sidebar.width($bookTreeParent.width() + 15);
|
||||
$sidebar.addClass("fixed");
|
||||
isFixed = true;
|
||||
}
|
||||
// Function to un-fix the tree back into position
|
||||
function unstickTree() {
|
||||
$bookTree.css('width', 'auto');
|
||||
$bookTree.removeClass("fixed");
|
||||
$sidebar.css('width', 'auto');
|
||||
$sidebar.removeClass("fixed");
|
||||
isFixed = false;
|
||||
}
|
||||
// Checks if the tree stickiness state should change
|
||||
|
@ -181,3 +181,27 @@
|
||||
content: '\f1f1';
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
margin: $-m;
|
||||
background-color: #FFF;
|
||||
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.2);
|
||||
h3 {
|
||||
padding: $-m;
|
||||
border-bottom: 1px solid #E8E8E8;
|
||||
margin: 0;
|
||||
font-size: $fs-s;
|
||||
color: #888;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.body, p.empty-text {
|
||||
padding: $-m;
|
||||
}
|
||||
}
|
||||
|
||||
.well {
|
||||
background-color: #F8F8F8;
|
||||
padding: $-m;
|
||||
border: 1px solid #DDD;
|
||||
}
|
@ -2,9 +2,12 @@
|
||||
@mixin generate-button-colors($textColor, $backgroundColor) {
|
||||
background-color: $backgroundColor;
|
||||
color: $textColor;
|
||||
text-transform: uppercase;
|
||||
border: 1px solid $backgroundColor;
|
||||
vertical-align: top;
|
||||
&:hover {
|
||||
background-color: lighten($backgroundColor, 8%);
|
||||
box-shadow: $bs-med;
|
||||
//box-shadow: $bs-med;
|
||||
text-decoration: none;
|
||||
color: $textColor;
|
||||
}
|
||||
@ -26,16 +29,16 @@ $button-border-radius: 2px;
|
||||
text-decoration: none;
|
||||
font-size: $fs-m;
|
||||
line-height: 1.4em;
|
||||
padding: $-xs $-m;
|
||||
padding: $-xs*1.3 $-m;
|
||||
margin: $-xs $-xs $-xs 0;
|
||||
display: inline-block;
|
||||
border: none;
|
||||
font-weight: 500;
|
||||
font-weight: 400;
|
||||
outline: 0;
|
||||
border-radius: $button-border-radius;
|
||||
cursor: pointer;
|
||||
transition: all ease-in-out 120ms;
|
||||
box-shadow: 0 0.5px 1.5px 0 rgba(0, 0, 0, 0.21);
|
||||
box-shadow: 0;
|
||||
@include generate-button-colors(#EEE, $primary);
|
||||
}
|
||||
|
||||
@ -51,13 +54,47 @@ $button-border-radius: 2px;
|
||||
@include generate-button-colors(#EEE, $secondary);
|
||||
}
|
||||
&.muted {
|
||||
@include generate-button-colors(#EEE, #888);
|
||||
@include generate-button-colors(#EEE, #AAA);
|
||||
}
|
||||
&.muted-light {
|
||||
@include generate-button-colors(#666, #e4e4e4);
|
||||
}
|
||||
}
|
||||
|
||||
.button.outline {
|
||||
background-color: transparent;
|
||||
color: #888;
|
||||
border: 1px solid #DDD;
|
||||
&:hover, &:focus, &:active {
|
||||
box-shadow: none;
|
||||
background-color: #EEE;
|
||||
}
|
||||
&.page {
|
||||
border-color: $color-page;
|
||||
color: $color-page;
|
||||
&:hover, &:focus, &:active {
|
||||
background-color: $color-page;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
&.chapter {
|
||||
border-color: $color-chapter;
|
||||
color: $color-chapter;
|
||||
&:hover, &:focus, &:active {
|
||||
background-color: $color-chapter;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
&.book {
|
||||
border-color: $color-book;
|
||||
color: $color-book;
|
||||
&:hover, &:focus, &:active {
|
||||
background-color: $color-book;
|
||||
color: #FFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text-button {
|
||||
@extend .link;
|
||||
background-color: transparent;
|
||||
|
@ -366,9 +366,9 @@ span.CodeMirror-selectedtext { background: none; }
|
||||
.cm-s-base16-light span.cm-atom { color: #aa759f; }
|
||||
.cm-s-base16-light span.cm-number { color: #aa759f; }
|
||||
|
||||
.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #90a959; }
|
||||
.cm-s-base16-light span.cm-property, .cm-s-base16-light span.cm-attribute { color: #678c30; }
|
||||
.cm-s-base16-light span.cm-keyword { color: #ac4142; }
|
||||
.cm-s-base16-light span.cm-string { color: #f4bf75; }
|
||||
.cm-s-base16-light span.cm-string { color: #e09c3c; }
|
||||
|
||||
.cm-s-base16-light span.cm-variable { color: #90a959; }
|
||||
.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; }
|
||||
@ -392,7 +392,7 @@ span.CodeMirror-selectedtext { background: none; }
|
||||
}
|
||||
.cm-s-base16-light .CodeMirror-gutters { background: #f5f5f5; border-right: 1px solid #DDD; }
|
||||
|
||||
.flex-fill .CodeMirror {
|
||||
.code-fill .CodeMirror {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
@ -2,14 +2,13 @@
|
||||
.input-base {
|
||||
background-color: #FFF;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #CCC;
|
||||
border: 1px solid #D4D4D4;
|
||||
display: inline-block;
|
||||
font-size: $fs-s;
|
||||
padding: $-xs;
|
||||
color: #222;
|
||||
padding: $-xs*1.5;
|
||||
color: #666;
|
||||
width: 250px;
|
||||
max-width: 100%;
|
||||
//-webkit-appearance:none;
|
||||
&.neg, &.invalid {
|
||||
border: 1px solid $negative;
|
||||
}
|
||||
@ -24,6 +23,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
.fake-input {
|
||||
@extend .input-base;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#html-editor {
|
||||
display: none;
|
||||
}
|
||||
@ -84,8 +88,9 @@ label {
|
||||
display: block;
|
||||
line-height: 1.4em;
|
||||
font-size: 0.94em;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
color: #999;
|
||||
text-transform: uppercase;
|
||||
padding-bottom: 2px;
|
||||
margin-bottom: 0.2em;
|
||||
&.inline {
|
||||
@ -186,28 +191,15 @@ input:checked + .toggle-switch {
|
||||
}
|
||||
|
||||
.inline-input-style {
|
||||
border: 2px dotted #BBB;
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: $-xs $-s;
|
||||
}
|
||||
|
||||
.title-input .input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title-input label, .description-input label{
|
||||
margin-top: $-m;
|
||||
color: #666;
|
||||
padding: $-s;
|
||||
}
|
||||
|
||||
.title-input input[type="text"] {
|
||||
@extend h1;
|
||||
@extend .inline-input-style;
|
||||
margin-top: 0;
|
||||
padding-right: 0;
|
||||
width: 100%;
|
||||
color: #444;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
.title-input.page-title {
|
||||
@ -250,8 +242,8 @@ div[editor-type="markdown"] .title-input.page-title input[type="text"] {
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
left: 7px;
|
||||
top: 7px;
|
||||
left: 8px;
|
||||
top: 9.5px;
|
||||
}
|
||||
input {
|
||||
display: block;
|
||||
|
@ -20,19 +20,122 @@ body.flexbox {
|
||||
align-items: stretch;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
.flex, &.flex {
|
||||
&.rows {
|
||||
flex-direction: row;
|
||||
}
|
||||
&.columns {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.flex {
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex.scroll {
|
||||
//overflow-y: auto;
|
||||
display: flex;
|
||||
&.sidebar {
|
||||
margin-right: -14px;
|
||||
}
|
||||
}
|
||||
.flex.scroll .scroll-body {
|
||||
overflow-y: scroll;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.flex-child > div {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
//body.ie .flex-child > div {
|
||||
// flex: 1 0 0px;
|
||||
//}
|
||||
.flex.sidebar {
|
||||
flex: 1;
|
||||
background-color: #F2F2F2;
|
||||
max-width: 360px;
|
||||
min-height: 90vh;
|
||||
}
|
||||
.flex.sidebar + .flex.content {
|
||||
flex: 3;
|
||||
background-color: #FFFFFF;
|
||||
padding: 0 $-l;
|
||||
border-left: 1px solid #DDD;
|
||||
max-width: 100%;
|
||||
}
|
||||
.flex.sidebar .sidebar-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@include smaller-than($xl) {
|
||||
body.sidebar-layout {
|
||||
padding-left: 30px;
|
||||
}
|
||||
.flex.sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 100;
|
||||
padding-right: 30px;
|
||||
width: 360px;
|
||||
box-shadow: none;
|
||||
transform: translate3d(-330px, 0, 0);
|
||||
transition: transform ease-in-out 120ms;
|
||||
}
|
||||
.flex.sidebar.open {
|
||||
box-shadow: 1px 2px 2px 1px rgba(0,0,0,.10);
|
||||
transform: translate3d(0, 0, 0);
|
||||
.sidebar-toggle i {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
.flex.sidebar .sidebar-toggle {
|
||||
display: block;
|
||||
position: absolute;
|
||||
opacity: 0.9;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 30px;
|
||||
color: #666;
|
||||
font-size: 20px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
border: 1px solid #DDD;
|
||||
border-top: 1px solid #BBB;
|
||||
padding-top: $-m;
|
||||
cursor: pointer;
|
||||
i {
|
||||
opacity: 0.5;
|
||||
transition: all ease-in-out 120ms;
|
||||
padding: 0;
|
||||
}
|
||||
&:hover i {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
#sidebar .scroll-body.fixed {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
@include larger-than($xl) {
|
||||
#sidebar .scroll-body.fixed {
|
||||
z-index: 5;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
padding-right: $-m;
|
||||
width: 30%;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none;
|
||||
//background-color: $primary-faded;
|
||||
border-left: 1px solid #DDD;
|
||||
&::-webkit-scrollbar { width: 0 !important }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Rules for all columns */
|
||||
div[class^="col-"] img {
|
||||
|
@ -85,7 +85,7 @@ header {
|
||||
}
|
||||
header .search-box {
|
||||
display: inline-block;
|
||||
margin-top: $-s;
|
||||
margin-top: 10px;
|
||||
input {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
@ -171,6 +171,10 @@ header .search-box {
|
||||
background-color: $primary-faded;
|
||||
}
|
||||
|
||||
.toolbar-container {
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
.breadcrumbs .text-button, .action-buttons .text-button {
|
||||
display: inline-block;
|
||||
padding: $-s;
|
||||
|
@ -9,6 +9,9 @@ html {
|
||||
&.flexbox {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
&.shaded {
|
||||
background-color: #F2F2F2;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
@ -16,6 +19,9 @@ body {
|
||||
line-height: 1.6;
|
||||
color: #616161;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
&.shaded {
|
||||
background-color: #F2F2F2;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
|
@ -86,31 +86,8 @@
|
||||
|
||||
// Sidebar list
|
||||
.book-tree {
|
||||
padding: $-xs 0 0 0;
|
||||
position: relative;
|
||||
right: 0;
|
||||
top: 0;
|
||||
transition: ease-in-out 240ms;
|
||||
transition-property: right, border;
|
||||
border-left: 0px solid #FFF;
|
||||
background-color: #FFF;
|
||||
max-width: 320px;
|
||||
&.fixed {
|
||||
background-color: #FFF;
|
||||
z-index: 5;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
padding-left: $-l;
|
||||
padding-right: $-l + 15;
|
||||
width: 30%;
|
||||
right: -15px;
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
-ms-overflow-style: none;
|
||||
//background-color: $primary-faded;
|
||||
border-left: 1px solid #DDD;
|
||||
&::-webkit-scrollbar { width: 0 !important }
|
||||
}
|
||||
}
|
||||
.book-tree h4 {
|
||||
padding: $-m $-s 0 $-s;
|
||||
@ -245,6 +222,9 @@
|
||||
.left + .right {
|
||||
margin-left: 30px + $-s;
|
||||
}
|
||||
&:last-of-type {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul.pagination {
|
||||
@ -297,9 +277,6 @@ ul.pagination {
|
||||
h4 {
|
||||
margin: 0;
|
||||
}
|
||||
p {
|
||||
margin: $-xs 0 0 0;
|
||||
}
|
||||
hr {
|
||||
margin: 0;
|
||||
}
|
||||
@ -316,6 +293,11 @@ ul.pagination {
|
||||
}
|
||||
}
|
||||
|
||||
.card .entity-list-item, .card .activity-list-item {
|
||||
padding-left: $-m;
|
||||
padding-right: $-m;
|
||||
}
|
||||
|
||||
.entity-list.compact {
|
||||
font-size: 0.6em;
|
||||
h4, a {
|
||||
@ -324,9 +306,11 @@ ul.pagination {
|
||||
.entity-item-snippet {
|
||||
display: none;
|
||||
}
|
||||
p {
|
||||
.entity-list-item p {
|
||||
font-size: $fs-m * 0.8;
|
||||
padding-top: $-xs;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
> p.empty-text {
|
||||
|
@ -1,12 +1,3 @@
|
||||
#page-show {
|
||||
>.row .col-md-9 {
|
||||
z-index: 2;
|
||||
}
|
||||
>.row .col-md-3 {
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.page-editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -36,6 +27,8 @@
|
||||
|
||||
.page-content {
|
||||
max-width: 840px;
|
||||
margin: 0 auto;
|
||||
margin-top: $-xxl;
|
||||
overflow-wrap: break-word;
|
||||
.align-left {
|
||||
text-align: left;
|
||||
@ -252,8 +245,6 @@
|
||||
}
|
||||
|
||||
.tag-display {
|
||||
width: 100%;
|
||||
//opacity: 0.7;
|
||||
position: relative;
|
||||
table {
|
||||
width: 100%;
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Fonts
|
||||
*/
|
||||
|
||||
body, button, input, select, label {
|
||||
body, button, input, select, label, textarea {
|
||||
font-family: $text;
|
||||
}
|
||||
.Codemirror, pre, #markdown-editor-input, .editor-toolbar, .code-base {
|
||||
@ -378,12 +378,6 @@ span.sep {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.action-header {
|
||||
h1 {
|
||||
margin-top: $-m;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Icons
|
||||
*/
|
||||
|
@ -217,22 +217,15 @@ $btt-size: 40px;
|
||||
}
|
||||
|
||||
.center-box {
|
||||
margin: $-xl auto 0 auto;
|
||||
padding: $-m $-xxl $-xl $-xxl;
|
||||
margin: $-xxl auto 0 auto;
|
||||
width: 420px;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
//border: 1px solid #DDD;
|
||||
input {
|
||||
width: 100%;
|
||||
}
|
||||
&.login {
|
||||
background-color: #EEE;
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid #DDD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,6 +10,7 @@ return [
|
||||
'save' => 'Save',
|
||||
'continue' => 'Continue',
|
||||
'select' => 'Select',
|
||||
'more' => 'More',
|
||||
|
||||
/**
|
||||
* Form Labels
|
||||
@ -36,7 +37,6 @@ return [
|
||||
'remove' => 'Remove',
|
||||
'add' => 'Add',
|
||||
|
||||
|
||||
/**
|
||||
* Misc
|
||||
*/
|
||||
@ -46,7 +46,7 @@ return [
|
||||
'back_to_top' => 'Back to top',
|
||||
'toggle_details' => 'Toggle Details',
|
||||
'toggle_thumbnails' => 'Toggle Thumbnails',
|
||||
|
||||
'details' => 'Details',
|
||||
/**
|
||||
* Header
|
||||
*/
|
||||
|
@ -73,11 +73,13 @@ return [
|
||||
'books_empty' => 'No books have been created',
|
||||
'books_popular' => 'Popular Books',
|
||||
'books_recent' => 'Recent Books',
|
||||
'books_new' => 'New Books',
|
||||
'books_popular_empty' => 'The most popular books will appear here.',
|
||||
'books_new_empty' => 'The most recently created books will appear here.',
|
||||
'books_create' => 'Create New Book',
|
||||
'books_delete' => 'Delete Book',
|
||||
'books_delete_named' => 'Delete Book :bookName',
|
||||
'books_delete_explain' => 'This will delete the book with the name \':bookName\', All pages and chapters will be removed.',
|
||||
'books_delete_explain' => 'This will delete the book with the name \':bookName\'. All pages and chapters will be removed.',
|
||||
'books_delete_confirmation' => 'Are you sure you want to delete this book?',
|
||||
'books_edit' => 'Edit Book',
|
||||
'books_edit_named' => 'Edit Book :bookName',
|
||||
@ -108,8 +110,7 @@ return [
|
||||
'chapters_create' => 'Create New Chapter',
|
||||
'chapters_delete' => 'Delete Chapter',
|
||||
'chapters_delete_named' => 'Delete Chapter :chapterName',
|
||||
'chapters_delete_explain' => 'This will delete the chapter with the name \':chapterName\', All pages will be removed
|
||||
and added directly to the parent book.',
|
||||
'chapters_delete_explain' => 'This will delete the chapter with the name \':chapterName\'. All pages will be removed and added directly to the parent book.',
|
||||
'chapters_delete_confirm' => 'Are you sure you want to delete this chapter?',
|
||||
'chapters_edit' => 'Edit Chapter',
|
||||
'chapters_edit_named' => 'Edit Chapter :chapterName',
|
||||
@ -164,6 +165,7 @@ return [
|
||||
'pages_move_success' => 'Page moved to ":parentName"',
|
||||
'pages_permissions' => 'Page Permissions',
|
||||
'pages_permissions_success' => 'Page permissions updated',
|
||||
'pages_revision' => 'Revision',
|
||||
'pages_revisions' => 'Page Revisions',
|
||||
'pages_revisions_named' => 'Page Revisions for :pageName',
|
||||
'pages_revision_named' => 'Page Revision for :pageName',
|
||||
|
@ -31,6 +31,9 @@ return [
|
||||
'app_logo_desc' => 'This image should be 43px in height. <br>Large images will be scaled down.',
|
||||
'app_primary_color' => 'Application primary color',
|
||||
'app_primary_color_desc' => 'This should be a hex value. <br>Leave empty to reset to the default color.',
|
||||
'app_homepage' => 'Application Homepage',
|
||||
'app_homepage_desc' => 'Select a page to show on the homepage instead of the default view. Page permissions are ignored for selected pages.',
|
||||
'app_homepage_default' => 'Default homepage view chosen',
|
||||
|
||||
/**
|
||||
* Registration settings
|
||||
|
@ -9,9 +9,10 @@
|
||||
@section('content')
|
||||
|
||||
<div class="text-center">
|
||||
<div class="center-box">
|
||||
<h1>{{ title_case(trans('auth.log_in')) }}</h1>
|
||||
<div class="card center-box">
|
||||
<h3><i class="zmdi zmdi-sign-in"></i> {{ title_case(trans('auth.log_in')) }}</h3>
|
||||
|
||||
<div class="body">
|
||||
<form action="{{ baseUrl("/login") }}" method="POST" id="login-form">
|
||||
{!! csrf_field() !!}
|
||||
|
||||
@ -41,5 +42,6 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
@ -9,10 +9,12 @@
|
||||
@section('content')
|
||||
|
||||
<div class="text-center">
|
||||
<div class="center-box">
|
||||
<h2>{{ trans('auth.register_thanks') }}</h2>
|
||||
<div class="card center-box">
|
||||
<h3><i class="zmdi zmdi-accounts"></i> {{ trans('auth.register_thanks') }}</h3>
|
||||
<div class="body">
|
||||
<p>{{ trans('auth.register_confirm', ['appName' => setting('app-name')]) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -7,9 +7,9 @@
|
||||
@section('content')
|
||||
|
||||
<div class="text-center">
|
||||
<div class="center-box">
|
||||
<h1>{{ title_case(trans('auth.sign_up')) }}</h1>
|
||||
|
||||
<div class="card center-box">
|
||||
<h3><i class="zmdi zmdi-account-add"></i> {{ title_case(trans('auth.sign_up')) }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ baseUrl("/register") }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
|
||||
@ -44,6 +44,7 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
||||
|
@ -2,9 +2,11 @@
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
<h2>{{ trans('auth.email_not_confirmed') }}</h2>
|
||||
<div class="container small">
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-accounts"></i> {{ trans('auth.email_not_confirmed') }}</h3>
|
||||
<div class="body">
|
||||
<p class="text-muted">{{ trans('auth.email_not_confirmed_text') }}<br>
|
||||
{{ trans('auth.email_not_confirmed_click_link') }} <br>
|
||||
{{ trans('auth.email_not_confirmed_resend') }}
|
||||
@ -27,4 +29,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -34,7 +34,7 @@
|
||||
@include('partials/notifications')
|
||||
|
||||
<header id="header">
|
||||
<div class="container">
|
||||
<div class="container fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-4" ng-non-bindable>
|
||||
<a href="{{ baseUrl('/') }}" class="logo">
|
||||
|
@ -1,12 +1,27 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
@section('toolbar')
|
||||
<div class="col-sm-8 faded">
|
||||
<div class="breadcrumbs">
|
||||
<a href="{{ baseUrl('/books') }}" class="text-button"><i class="zmdi zmdi-book"></i>{{ trans('entities.books') }}</a>
|
||||
<span class="sep">»</span>
|
||||
<a href="{{ baseUrl('/books/create') }}" class="text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.books_create') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('entities.books_create') }}</h1>
|
||||
@section('body')
|
||||
|
||||
<div ng-non-bindable class="container small">
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-plus"></i> {{ trans('entities.books_create') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ baseUrl("/books") }}" method="POST" enctype="multipart/form-data">
|
||||
@include('books/form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="margin-top large"><br></p>
|
||||
@include('components.image-manager', ['imageType' => 'cover'])
|
||||
|
@ -1,28 +1,30 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('books._breadcrumbs', ['book' => $book])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('entities.books_delete') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-delete"></i> {{ trans('entities.books_delete') }}</h3>
|
||||
<div class="body">
|
||||
<p>{{ trans('entities.books_delete_explain', ['bookName' => $book->name]) }}</p>
|
||||
<p class="text-neg">{{ trans('entities.books_delete_confirmation') }}</p>
|
||||
|
||||
<form action="{{$book->getUrl()}}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
<input type="hidden" name="_method" value="DELETE">
|
||||
<a href="{{$book->getUrl()}}" class="button">{{ trans('common.cancel') }}</a>
|
||||
<a href="{{$book->getUrl()}}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@stop
|
@ -1,23 +1,24 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('books._breadcrumbs', ['book' => $book])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('entities.books_edit') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-edit"></i> {{ trans('entities.books_edit') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ $book->getUrl() }}" method="POST">
|
||||
<input type="hidden" name="_method" value="PUT">
|
||||
@include('books/form', ['model' => $book])
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('components.image-manager', ['imageType' => 'cover'])
|
||||
@stop
|
@ -24,7 +24,8 @@
|
||||
'imageClass' => 'cover'
|
||||
])
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<a href="{{ isset($book) ? $book->getUrl() : baseUrl('/books') }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
|
||||
<div class="form-group text-right">
|
||||
<a href="{{ isset($book) ? $book->getUrl() : baseUrl('/books') }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button pos">{{ trans('entities.books_save') }}</button>
|
||||
</div>
|
@ -1,43 +1,53 @@
|
||||
@extends('base')
|
||||
@extends('sidebar-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 faded">
|
||||
<div class="action-buttons text-left">
|
||||
<a data-action="expand-thumbnail" class="text-primary text-button"><i class="zmdi zmdi-wrap-text"></i>{{ trans('common.toggle_thumbnails') }}</a>
|
||||
@section('toolbar')
|
||||
<div class="col-xs-1"></div>
|
||||
<div class="col-xs-11 faded">
|
||||
<div class="action-buttons">
|
||||
@if($currentUser->can('book-create-all'))
|
||||
<a href="{{ baseUrl("/books/create") }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.books_create') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('sidebar')
|
||||
@if($recents)
|
||||
<div id="recents" class="card">
|
||||
<h3><i class="zmdi zmdi-eye"></i> {{ trans('entities.recently_viewed') }}</h3>
|
||||
@include('partials/entity-list', ['entities' => $recents, 'style' => 'compact'])
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div id="popular" class="card">
|
||||
<h3><i class="zmdi zmdi-fire"></i> {{ trans('entities.books_popular') }}</h3>
|
||||
@if(count($popular) > 0)
|
||||
@include('partials/entity-list', ['entities' => $popular, 'style' => 'compact'])
|
||||
@else
|
||||
<div class="body text-muted">{{ trans('entities.books_popular_empty') }}</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div id="new" class="card">
|
||||
<h3><i class="zmdi zmdi-star-circle"></i> {{ trans('entities.books_new') }}</h3>
|
||||
@if(count($popular) > 0)
|
||||
@include('partials/entity-list', ['entities' => $new, 'style' => 'compact'])
|
||||
@else
|
||||
<div class="body text-muted">{{ trans('entities.books_new_empty') }}</div>
|
||||
@endif
|
||||
</div>
|
||||
@stop
|
||||
|
||||
<div class="container" ng-non-bindable>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-9">
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('entities.books') }}</h1>
|
||||
@if(count($books) > 0)
|
||||
@if($books_display=='grid')
|
||||
<div class="row">
|
||||
@foreach($books as $book)
|
||||
@include('books/grid-item', ['book' => $book])
|
||||
@endforeach
|
||||
<div class="col-xs-12">
|
||||
{!! $books->render() !!}
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
@foreach($books as $book)
|
||||
@include('books/list-item', ['book' => $book])
|
||||
<hr>
|
||||
@endforeach
|
||||
{!! $books->render() !!}
|
||||
@endif
|
||||
@else
|
||||
<p class="text-muted">{{ trans('entities.books_empty') }}</p>
|
||||
@if(userCan('books-create-all'))
|
||||
@ -45,25 +55,5 @@
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-12 col-md-3">
|
||||
<div id="recents">
|
||||
@if($recents)
|
||||
<div class="margin-top"> </div>
|
||||
<h3>{{ trans('entities.recently_viewed') }}</h3>
|
||||
@include('partials/entity-list', ['entities' => $recents])
|
||||
@endif
|
||||
</div>
|
||||
<div class="margin-top large"> </div>
|
||||
<div id="popular">
|
||||
<h3>{{ trans('entities.books_popular') }}</h3>
|
||||
@if(count($popular) > 0)
|
||||
@include('partials/entity-list', ['entities' => $popular])
|
||||
@else
|
||||
<p class="text-muted">{{ trans('entities.books_popular_empty') }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
@ -1,21 +1,21 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('books._breadcrumbs', ['book' => $book])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container" ng-non-bindable>
|
||||
<h1>{{ trans('entities.books_permissions') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-lock-outline"></i> {{ trans('entities.books_permissions') }}</h3>
|
||||
<div class="body">
|
||||
@include('form/restriction-form', ['model' => $book])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -1,10 +1,6 @@
|
||||
@extends('base')
|
||||
@extends('sidebar-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-6 col-xs-1 faded">
|
||||
@include('books._breadcrumbs', ['book' => $book])
|
||||
</div>
|
||||
@ -24,14 +20,12 @@
|
||||
@if(userCan('chapter-create', $book))
|
||||
<a href="{{ $book->getUrl('/chapter/create') }}" class="text-pos text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.chapters_new') }}</a>
|
||||
@endif
|
||||
@if(userCan('book-update', $book))
|
||||
<a href="{{$book->getEditUrl()}}" class="text-primary text-button"><i class="zmdi zmdi-edit"></i>{{ trans('common.edit') }}</a>
|
||||
@endif
|
||||
@if(userCan('book-update', $book) || userCan('restrictions-manage', $book) || userCan('book-delete', $book))
|
||||
<div dropdown class="dropdown-container">
|
||||
<a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i></a>
|
||||
<a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i>{{ trans('common.more') }}</a>
|
||||
<ul>
|
||||
@if(userCan('book-update', $book))
|
||||
<li><a href="{{$book->getEditUrl()}}" class="text-primary"><i class="zmdi zmdi-edit"></i>{{ trans('common.edit') }}</a></li>
|
||||
<li><a href="{{ $book->getUrl('/sort') }}" class="text-primary"><i class="zmdi zmdi-sort"></i>{{ trans('common.sort') }}</a></li>
|
||||
@endif
|
||||
@if(userCan('restrictions-manage', $book))
|
||||
@ -45,22 +39,65 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('sidebar')
|
||||
|
||||
<div class="card">
|
||||
<div class="body">
|
||||
<form v-on:submit.prevent="searchBook" class="search-box">
|
||||
<input v-model="searchTerm" v-on:change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.books_search_this') }}">
|
||||
<button type="submit"><i class="zmdi zmdi-search"></i></button>
|
||||
<button v-if="searching" v-cloak class="text-neg" v-on:click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($book->restricted)
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-key"></i> {{ trans('entities.permissions') }}</h3>
|
||||
<div class="body">
|
||||
<p class="text-muted">
|
||||
@if(userCan('restrictions-manage', $book))
|
||||
<a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}</a>
|
||||
@else
|
||||
<i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div ng-non-bindable class="container" id="entity-dashboard" entity-id="{{ $book->id }}" entity-type="book">
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
@if(count($activity) > 0)
|
||||
<div class="activity card">
|
||||
<h3><i class="zmdi zmdi-time"></i> {{ trans('entities.recent_activity') }}</h3>
|
||||
@include('partials/activity-list', ['activity' => $activity])
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-info-outline"></i> {{ trans('common.details') }}</h3>
|
||||
<div class="body">
|
||||
@include('partials.entity-meta', ['entity' => $book])
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('container-attrs')
|
||||
id="entity-dashboard"
|
||||
entity-id="{{ $book->id }}"
|
||||
entity-type="book"
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div ng-non-bindable class="container small">
|
||||
<h1>{{$book->name}}</h1>
|
||||
<div class="book-content" v-show="!searching">
|
||||
<p class="text-muted" v-pre>{!! nl2br(e($book->description)) !!}</p>
|
||||
|
||||
@if(count($bookChildren) > 0)
|
||||
<div class="page-list" v-pre>
|
||||
<hr>
|
||||
@if(count($bookChildren) > 0)
|
||||
@foreach($bookChildren as $childElement)
|
||||
@if($childElement->isA('chapter'))
|
||||
@include('chapters/list-item', ['chapter' => $childElement])
|
||||
@ -69,23 +106,22 @@
|
||||
@endif
|
||||
<hr>
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<p class="text-muted">{{ trans('entities.books_empty_contents') }}</p>
|
||||
<p>
|
||||
<div class="well">
|
||||
<p class="text-muted italic">{{ trans('entities.books_empty_contents') }}</p>
|
||||
@if(userCan('page-create', $book))
|
||||
<a href="{{ $book->getUrl('/page/create') }}" class="text-page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.books_empty_create_page') }}</a>
|
||||
<a href="{{ $book->getUrl('/page/create') }}" class="button outline page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.books_empty_create_page') }}</a>
|
||||
@endif
|
||||
@if(userCan('page-create', $book) && userCan('chapter-create', $book))
|
||||
<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>
|
||||
@endif
|
||||
@if(userCan('chapter-create', $book))
|
||||
<a href="{{ $book->getUrl('/chapter/create') }}" class="text-chapter"><i class="zmdi zmdi-collection-bookmark"></i>{{ trans('entities.books_empty_add_chapter') }}</a>
|
||||
<a href="{{ $book->getUrl('/chapter/create') }}" class="button outline chapter"><i class="zmdi zmdi-collection-bookmark"></i>{{ trans('entities.books_empty_add_chapter') }}</a>
|
||||
@endif
|
||||
</p>
|
||||
<hr>
|
||||
@endif
|
||||
@include('partials.entity-meta', ['entity' => $book])
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
<div class="search-results" v-cloak v-show="searching">
|
||||
<h3 class="text-muted">{{ trans('entities.search_results') }} <a v-if="searching" v-on:click="clearSearch()" class="text-small"><i class="zmdi zmdi-close"></i>{{ trans('entities.search_clear') }}</a></h3>
|
||||
@ -94,35 +130,6 @@
|
||||
</div>
|
||||
<div v-html="searchResults"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 col-md-offset-1">
|
||||
<div class="margin-top large"></div>
|
||||
|
||||
@if($book->restricted)
|
||||
<p class="text-muted">
|
||||
@if(userCan('restrictions-manage', $book))
|
||||
<a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}</a>
|
||||
@else
|
||||
<i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}
|
||||
@endif
|
||||
</p>
|
||||
@endif
|
||||
|
||||
<form v-on:submit.prevent="searchBook" class="search-box">
|
||||
<input v-model="searchTerm" v-on:change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.books_search_this') }}">
|
||||
<button type="submit"><i class="zmdi zmdi-search"></i></button>
|
||||
<button v-if="searching" v-cloak class="text-neg" v-on:click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>
|
||||
</form>
|
||||
|
||||
<div class="activity">
|
||||
<h3>{{ trans('entities.recent_activity') }}</h3>
|
||||
@include('partials/activity-list', ['activity' => Activity::entityActivity($book, 20, 0)])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -1,34 +1,45 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('head')
|
||||
<script src="{{ baseUrl("/libs/jquery-sortable/jquery-sortable.min.js") }}"></script>
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('books._breadcrumbs', ['book' => $book])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container" ng-non-bindable>
|
||||
<h1>{{ trans('entities.books_sort') }}</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8" id="sort-boxes">
|
||||
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-sort"></i> {{ trans('entities.books_sort') }}</h3>
|
||||
<div class="body">
|
||||
<div id="sort-boxes">
|
||||
@include('books/sort-box', ['book' => $book, 'bookChildren' => $bookChildren])
|
||||
|
||||
</div>
|
||||
|
||||
<form action="{{ $book->getUrl('/sort') }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
<input type="hidden" name="_method" value="PUT">
|
||||
<input type="hidden" id="sort-tree-input" name="sort-tree">
|
||||
<div class="list">
|
||||
<a href="{{ $book->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button class="button pos" type="submit">{{ trans('entities.books_sort_save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@if(count($books) > 1)
|
||||
<div class="col-md-4">
|
||||
<h3>{{ trans('entities.books_sort_show_other') }}</h3>
|
||||
<div id="additional-books">
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-book"></i> {{ trans('entities.books_sort_show_other') }}</h3>
|
||||
<div class="body" id="additional-books">
|
||||
@foreach($books as $otherBook)
|
||||
@if($otherBook->id !== $book->id)
|
||||
<div>
|
||||
@ -38,19 +49,11 @@
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
<form action="{{ $book->getUrl('/sort') }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
<input type="hidden" name="_method" value="PUT">
|
||||
<input type="hidden" id="sort-tree-input" name="sort-tree">
|
||||
<div class="list">
|
||||
<a href="{{ $book->getUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<button class="button pos" type="submit">{{ trans('entities.books_sort_save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -1,12 +1,26 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
<div class="breadcrumbs">
|
||||
<a href="{{$book->getUrl()}}" class="text-book text-button"><i class="zmdi zmdi-book"></i>{{ $book->getShortName() }}</a>
|
||||
<span class="sep">»</span>
|
||||
<a href="{{ baseUrl('/books/chapter/create') }}" class="text-button"><i class="zmdi zmdi-plus"></i>{{ trans('entities.chapters_create') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('entities.chapters_create') }}</h1>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-plus"></i> {{ trans('entities.chapters_create') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ $book->getUrl('/chapter/create') }}" method="POST">
|
||||
@include('chapters/form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
@ -1,28 +1,30 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('chapters._breadcrumbs', ['chapter' => $chapter])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('entities.chapters_delete') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-delete"></i> {{ trans('entities.chapters_delete') }}</h3>
|
||||
|
||||
<div class="body">
|
||||
<p>{{ trans('entities.chapters_delete_explain', ['chapterName' => $chapter->name]) }}</p>
|
||||
<p class="text-neg">{{ trans('entities.chapters_delete_confirm') }}</p>
|
||||
|
||||
<form action="{{ $chapter->getUrl() }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
<input type="hidden" name="_method" value="DELETE">
|
||||
<a href="{{ $chapter->getUrl() }}" class="button primary">{{ trans('common.cancel') }}</a>
|
||||
<a href="{{ $chapter->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
@ -1,13 +1,24 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('chapters._breadcrumbs', ['chapter' => $chapter])
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('entities.chapters_edit') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-edit"></i> {{ trans('entities.chapters_edit') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ $chapter->getUrl() }}" method="POST">
|
||||
<input type="hidden" name="_method" value="PUT">
|
||||
@include('chapters/form', ['model' => $chapter])
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
@ -11,7 +11,7 @@
|
||||
@include('form/textarea', ['name' => 'description'])
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<a href="{{ back()->getTargetUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<div class="form-group text-right">
|
||||
<a href="{{ back()->getTargetUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button pos">{{ trans('entities.chapters_save') }}</button>
|
||||
</div>
|
||||
|
@ -1,29 +1,34 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('chapters._breadcrumbs', ['chapter' => $chapter])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container">
|
||||
<h1>{{ trans('entities.chapters_move') }}</h1>
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-folder"></i> {{ trans('entities.chapters_move') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ $chapter->getUrl('/move') }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
<input type="hidden" name="_method" value="PUT">
|
||||
|
||||
@include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book'])
|
||||
|
||||
<a href="{{ $chapter->getUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<div class="form-group text-right">
|
||||
<a href="{{ $chapter->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button pos">{{ trans('entities.chapters_move') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -1,20 +1,21 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('chapters._breadcrumbs', ['chapter' => $chapter])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container" ng-non-bindable>
|
||||
<h1>{{ trans('entities.chapters_permissions') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-lock-outline"></i> {{ trans('entities.chapters_permissions') }}</h3>
|
||||
<div class="body">
|
||||
@include('form/restriction-form', ['model' => $chapter])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -1,10 +1,6 @@
|
||||
@extends('base')
|
||||
@extends('sidebar-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-6 col-xs-3 faded" ng-non-bindable>
|
||||
@include('chapters._breadcrumbs', ['chapter' => $chapter])
|
||||
</div>
|
||||
@ -26,7 +22,7 @@
|
||||
@endif
|
||||
@if(userCan('chapter-update', $chapter) || userCan('restrictions-manage', $chapter) || userCan('chapter-delete', $chapter))
|
||||
<div dropdown class="dropdown-container">
|
||||
<a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i></a>
|
||||
<a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i> {{ trans('common.more') }}</a>
|
||||
<ul>
|
||||
@if(userCan('chapter-update', $chapter))
|
||||
<li><a href="{{ $chapter->getUrl('/move') }}" class="text-primary"><i class="zmdi zmdi-folder"></i>{{ trans('common.move') }}</a></li>
|
||||
@ -42,14 +38,65 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('container-attrs')
|
||||
id="entity-dashboard"
|
||||
entity-id="{{ $chapter->id }}"
|
||||
entity-type="chapter"
|
||||
@stop
|
||||
|
||||
@section('sidebar')
|
||||
<div class="card">
|
||||
<div class="body">
|
||||
<form @submit.prevent="searchBook" class="search-box">
|
||||
<input v-model="searchTerm" @change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.chapters_search_this') }}">
|
||||
<button type="submit"><i class="zmdi zmdi-search"></i></button>
|
||||
<button v-if="searching" v-cloak class="text-neg" @click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($book->restricted || $chapter->restricted)
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-key"></i> {{ trans('entities.permissions') }}</h3>
|
||||
<div class="body">
|
||||
@if($book->restricted)
|
||||
<p class="text-muted">
|
||||
@if(userCan('restrictions-manage', $book))
|
||||
<a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}</a>
|
||||
@else
|
||||
<i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}
|
||||
@endif
|
||||
</p>
|
||||
@endif
|
||||
|
||||
<div class="container" id="entity-dashboard" ng-non-bindable entity-id="{{ $chapter->id }}" entity-type="chapter">
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
@if($chapter->restricted)
|
||||
<p class="text-muted">
|
||||
@if(userCan('restrictions-manage', $chapter))
|
||||
<a href="{{ $chapter->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.chapters_permissions_active') }}</a>
|
||||
@else
|
||||
<i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.chapters_permissions_active') }}
|
||||
@endif
|
||||
</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-info-outline"></i> {{ trans('common.details') }}</h3>
|
||||
<div class="body">
|
||||
@include('partials.entity-meta', ['entity' => $chapter])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('partials/book-tree', ['book' => $book, 'sidebarTree' => $sidebarTree])
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable >
|
||||
<h1>{{ $chapter->name }}</h1>
|
||||
<div class="chapter-content" v-show="!searching">
|
||||
<p class="text-muted">{!! nl2br(e($chapter->description)) !!}</p>
|
||||
@ -63,71 +110,30 @@
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<hr>
|
||||
<p class="text-muted">{{ trans('entities.chapters_empty') }}</p>
|
||||
<div class="well">
|
||||
<p class="text-muted italic">{{ trans('entities.chapters_empty') }}</p>
|
||||
<p>
|
||||
@if(userCan('page-create', $chapter))
|
||||
<a href="{{ $chapter->getUrl('/create-page') }}" class="text-page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.books_empty_create_page') }}</a>
|
||||
<a href="{{ $chapter->getUrl('/create-page') }}" class="button outline page"><i class="zmdi zmdi-file-text"></i>{{ trans('entities.books_empty_create_page') }}</a>
|
||||
@endif
|
||||
@if(userCan('page-create', $chapter) && userCan('book-update', $book))
|
||||
<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>
|
||||
<em class="text-muted">-{{ trans('entities.books_empty_or') }}-</em>
|
||||
@endif
|
||||
@if(userCan('book-update', $book))
|
||||
<a href="{{ $book->getUrl('/sort') }}" class="text-book"><i class="zmdi zmdi-book"></i>{{ trans('entities.books_empty_sort_current_book') }}</a>
|
||||
<a href="{{ $book->getUrl('/sort') }}" class="button outline book"><i class="zmdi zmdi-book"></i>{{ trans('entities.books_empty_sort_current_book') }}</a>
|
||||
@endif
|
||||
</p>
|
||||
<hr>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('partials.entity-meta', ['entity' => $chapter])
|
||||
</div>
|
||||
|
||||
<div class="search-results" v-cloak v-show="searching">
|
||||
<h3 class="text-muted">{{ trans('entities.search_results') }} <a v-if="searching" v-on:click="clearSearch()" class="text-small"><i class="zmdi zmdi-close"></i>{{ trans('entities.search_clear') }}</a></h3>
|
||||
<h3 class="text-muted">{{ trans('entities.search_results') }} <a v-if="searching" @click="clearSearch()" class="text-small"><i class="zmdi zmdi-close"></i>{{ trans('entities.search_clear') }}</a></h3>
|
||||
<div v-if="!searchResults">
|
||||
@include('partials/loading-icon')
|
||||
</div>
|
||||
<div v-html="searchResults"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 col-md-offset-1">
|
||||
<div class="margin-top large"></div>
|
||||
@if($book->restricted || $chapter->restricted)
|
||||
<div class="text-muted">
|
||||
|
||||
@if($book->restricted)
|
||||
<p class="text-muted">
|
||||
@if(userCan('restrictions-manage', $book))
|
||||
<a href="{{ $book->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}</a>
|
||||
@else
|
||||
<i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.books_permissions_active') }}
|
||||
@endif
|
||||
</p>
|
||||
@endif
|
||||
|
||||
@if($chapter->restricted)
|
||||
@if(userCan('restrictions-manage', $chapter))
|
||||
<a href="{{ $chapter->getUrl('/permissions') }}"><i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.chapters_permissions_active') }}</a>
|
||||
@else
|
||||
<i class="zmdi zmdi-lock-outline"></i>{{ trans('entities.chapters_permissions_active') }}
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form v-on:submit.prevent="searchBook" class="search-box">
|
||||
<input v-model="searchTerm" v-on:change="checkSearchForm()" type="text" name="term" placeholder="{{ trans('entities.chapters_search_this') }}">
|
||||
<button type="submit"><i class="zmdi zmdi-search"></i></button>
|
||||
<button v-if="searching" v-cloak class="text-neg" v-on:click="clearSearch()" type="button"><i class="zmdi zmdi-close"></i></button>
|
||||
</form>
|
||||
|
||||
@include('pages/sidebar-tree-list', ['book' => $book, 'sidebarTree' => $sidebarTree])
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
@stop
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div id="entity-selector-wrap">
|
||||
<div overlay entity-link-selector>
|
||||
<div overlay entity-selector-popup>
|
||||
<div class="popup-body small flex-child">
|
||||
<div class="popup-header primary-background">
|
||||
<div class="popup-title">{{ trans('entities.entity_select') }}</div>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<div class="form-group">
|
||||
<div entity-selector class="entity-selector {{$selectorSize or ''}}" entity-types="{{ $entityTypes or 'book,chapter,page' }}">
|
||||
<input type="hidden" entity-selector-input name="{{$name}}" value="">
|
||||
<input type="text" placeholder="{{ trans('common.search') }}" ng-model="search" ng-model-options="{debounce: 200}" ng-change="searchEntities()">
|
||||
<div class="text-center loading" ng-show="loading">@include('partials.loading-icon')</div>
|
||||
<div ng-show="!loading" ng-bind-html="entityResults"></div>
|
||||
<input type="text" placeholder="{{ trans('common.search') }}" entity-selector-search>
|
||||
<div class="text-center loading" entity-selector-loading>@include('partials.loading-icon')</div>
|
||||
<div entity-selector-results></div>
|
||||
</div>
|
||||
</div>
|
13
resources/views/components/page-picker.blade.php
Normal file
13
resources/views/components/page-picker.blade.php
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
{{--Depends on entity selector popup--}}
|
||||
<div page-picker>
|
||||
<div class="input-base">
|
||||
<span @if($value) style="display: none" @endif page-picker-default class="text-muted italic">{{ $placeholder }}</span>
|
||||
<a @if(!$value) style="display: none" @endif href="{{ baseUrl('/link/' . $value) }}" target="_blank" class="text-page" page-picker-display>#{{$value}}, {{$value ? \BookStack\Page::find($value)->name : '' }}</a>
|
||||
</div>
|
||||
<br>
|
||||
<input type="hidden" value="{{$value}}" name="{{$name}}" id="{{$name}}">
|
||||
<button @if(!$value) style="display: none" @endif type="button" page-picker-reset class="text-button">{{ trans('common.reset') }}</button>
|
||||
<span @if(!$value) style="display: none" @endif class="sep">|</span>
|
||||
<button type="button" page-picker-select class="text-button">{{ trans('common.select') }}</button>
|
||||
</div>
|
@ -1,32 +1,42 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
|
||||
<div class="container">
|
||||
|
||||
<p> </p>
|
||||
|
||||
<h1>{{ $message or trans('errors.404_page_not_found') }}</h1>
|
||||
<p>{{ trans('errors.sorry_page_not_found') }}</p>
|
||||
<p><a href="{{ baseUrl('/') }}" class="button">{{ trans('errors.return_home') }}</a></p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-alert-octagon"></i> {{ $message or trans('errors.404_page_not_found') }}</h3>
|
||||
<div class="body">
|
||||
<h5>{{ trans('errors.sorry_page_not_found') }}</h5>
|
||||
<p><a href="{{ baseUrl('/') }}" class="button outline">{{ trans('errors.return_home') }}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (setting('app-public') || !user()->isDefault())
|
||||
<hr>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h3 class="text-muted">{{ trans('entities.pages_popular') }}</h3>
|
||||
<div class="card">
|
||||
<h3 class="text-muted"><i class="zmdi zmdi-file-text"></i> {{ trans('entities.pages_popular') }}</h3>
|
||||
@include('partials.entity-list', ['entities' => Views::getPopular(10, 0, [\BookStack\Page::class]), 'style' => 'compact'])
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h3 class="text-muted">{{ trans('entities.books_popular') }}</h3>
|
||||
@include('partials.entity-list', ['entities' => Views::getPopular(10, 0, [\BookStack\Book::class]), 'style' => 'compact'])
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h3 class="text-muted">{{ trans('entities.chapters_popular') }}</h3>
|
||||
<div class="card">
|
||||
<h3 class="text-muted"><i class="zmdi zmdi-book"></i> {{ trans('entities.books_popular') }}</h3>
|
||||
@include('partials.entity-list', ['entities' => Views::getPopular(10, 0, [\BookStack\Book::class]), 'style' => 'compact'])
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<h3 class="text-muted"><i class="zmdi zmdi-collection-bookmark"></i> {{ trans('entities.chapters_popular') }}</h3>
|
||||
@include('partials.entity-list', ['entities' => Views::getPopular(10, 0, [\BookStack\Chapter::class]), 'style' => 'compact'])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
|
@ -3,8 +3,13 @@
|
||||
@section('content')
|
||||
|
||||
<div class="container">
|
||||
<h1 class="text-muted">{{ trans('errors.error_occurred') }}</h1>
|
||||
<p>{{ $message }}</p>
|
||||
<div class="card">
|
||||
<h3 class="text-muted">{{ trans('errors.error_occurred') }}</h3>
|
||||
<div class="body">
|
||||
<h5>{{ $message }}</h5>
|
||||
<p><a href="{{ baseUrl('/') }}" class="button outline">{{ trans('errors.return_home') }}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
@ -2,9 +2,13 @@
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="container">
|
||||
<h1 class="text-muted">{{ trans('errors.app_down', ['appName' => setting('app-name')]) }}</h1>
|
||||
<div class="container small">
|
||||
<div class="card">
|
||||
<div class="body">
|
||||
<h4 class="text-muted"><i class="zmdi zmdi-alert-octagon"></i> {{ trans('errors.app_down', ['appName' => setting('app-name')]) }}</h4>
|
||||
<p>{{ trans('errors.back_soon') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
@ -27,6 +27,8 @@
|
||||
@endforeach
|
||||
</table>
|
||||
|
||||
<a href="{{ $model->getUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<div class="text-right">
|
||||
<a href="{{ $model->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button pos">{{ trans('entities.permissions_save') }}</button>
|
||||
</div>
|
||||
</form>
|
56
resources/views/home-custom.blade.php
Normal file
56
resources/views/home-custom.blade.php
Normal file
@ -0,0 +1,56 @@
|
||||
@extends('sidebar-layout')
|
||||
|
||||
@section('toolbar')
|
||||
<div class="col-sm-6 faded">
|
||||
<div class="action-buttons text-left">
|
||||
<a expand-toggle=".entity-list.compact .entity-item-snippet" class="text-primary text-button"><i class="zmdi zmdi-wrap-text"></i>{{ trans('common.toggle_details') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('sidebar')
|
||||
@if(count($draftPages) > 0)
|
||||
<div id="recent-drafts" class="card">
|
||||
<h3><i class="zmdi zmdi-edit"></i> {{ trans('entities.my_recent_drafts') }}</h3>
|
||||
@include('partials/entity-list', ['entities' => $draftPages, 'style' => 'compact'])
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-{{ $signedIn ? 'eye' : 'star-circle' }}"></i> {{ trans('entities.' . ($signedIn ? 'my_recently_viewed' : 'books_recent')) }}</h3>
|
||||
@include('partials/entity-list', [
|
||||
'entities' => $recents,
|
||||
'style' => 'compact',
|
||||
'emptyText' => $signedIn ? trans('entities.no_pages_viewed') : trans('entities.books_empty')
|
||||
])
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-file"></i> <a class="no-color" href="{{ baseUrl("/pages/recently-updated") }}">{{ trans('entities.recently_updated_pages') }}</a></h3>
|
||||
<div id="recently-updated-pages">
|
||||
@include('partials/entity-list', [
|
||||
'entities' => $recentlyUpdatedPages,
|
||||
'style' => 'compact',
|
||||
'emptyText' => trans('entities.no_pages_recently_updated')
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="recent-activity" class="card">
|
||||
<h3><i class="zmdi zmdi-time"></i> {{ trans('entities.recent_activity') }}</h3>
|
||||
@include('partials/activity-list', ['activity' => $activity])
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
<div class="page-content" ng-non-bindable>
|
||||
@include('pages/page-display', ['page' => $customHomepage])
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('scripts')
|
||||
<script>
|
||||
setupPageShow({{$customHomepage->id}});
|
||||
</script>
|
||||
@stop
|
||||
|
@ -1,52 +1,39 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-6 faded">
|
||||
<div class="action-buttons text-left">
|
||||
<a expand-toggle=".entity-list.compact .entity-item-snippet" class="text-primary text-button"><i class="zmdi zmdi-wrap-text"></i>{{ trans('common.toggle_details') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container" ng-non-bindable>
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-4">
|
||||
<div id="recent-drafts">
|
||||
@if(count($draftPages) > 0)
|
||||
<h4>{{ trans('entities.my_recent_drafts') }}</h4>
|
||||
<div id="recent-drafts" class="card">
|
||||
<h3><i class="zmdi zmdi-edit"></i> {{ trans('entities.my_recent_drafts') }}</h3>
|
||||
@include('partials/entity-list', ['entities' => $draftPages, 'style' => 'compact'])
|
||||
@endif
|
||||
</div>
|
||||
@if($signedIn)
|
||||
<h4>{{ trans('entities.my_recently_viewed') }}</h4>
|
||||
@else
|
||||
<h4>{{ trans('entities.books_recent') }}</h4>
|
||||
@endif
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-{{ $signedIn ? 'eye' : 'star-circle' }}"></i> {{ trans('entities.' . ($signedIn ? 'my_recently_viewed' : 'books_recent')) }}</h3>
|
||||
@include('partials/entity-list', [
|
||||
'entities' => $recents,
|
||||
'style' => 'compact',
|
||||
'emptyText' => $signedIn ? trans('entities.no_pages_viewed') : trans('entities.books_empty')
|
||||
])
|
||||
</div>
|
||||
|
||||
<div class="col-sm-4">
|
||||
<h4><a class="no-color" href="{{ baseUrl("/pages/recently-created") }}">{{ trans('entities.recently_created_pages') }}</a></h4>
|
||||
<div id="recently-created-pages">
|
||||
@include('partials/entity-list', [
|
||||
'entities' => $recentlyCreatedPages,
|
||||
'style' => 'compact',
|
||||
'emptyText' => trans('entities.no_pages_recently_created')
|
||||
])
|
||||
</div>
|
||||
|
||||
<h4><a class="no-color" href="{{ baseUrl("/pages/recently-updated") }}">{{ trans('entities.recently_updated_pages') }}</a></h4>
|
||||
<div class="col-sm-4">
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-file"></i> <a class="no-color" href="{{ baseUrl("/pages/recently-updated") }}">{{ trans('entities.recently_updated_pages') }}</a></h3>
|
||||
<div id="recently-updated-pages">
|
||||
@include('partials/entity-list', [
|
||||
'entities' => $recentlyUpdatedPages,
|
||||
@ -55,11 +42,14 @@
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-4" id="recent-activity">
|
||||
<h4>{{ trans('entities.recent_activity') }}</h4>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-time"></i> {{ trans('entities.recent_activity') }}</h3>
|
||||
@include('partials/activity-list', ['activity' => $activity])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,27 +1,30 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('pages._breadcrumbs', ['page' => $page])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ $page->draft ? trans('entities.pages_delete_draft') : trans('entities.pages_delete') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-delete"></i> {{ $page->draft ? trans('entities.pages_delete_draft') : trans('entities.pages_delete') }}</h3>
|
||||
<div class="body">
|
||||
<p class="text-neg">{{ $page->draft ? trans('entities.pages_delete_draft_confirm'): trans('entities.pages_delete_confirm') }}</p>
|
||||
|
||||
<form action="{{ $page->getUrl() }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
<input type="hidden" name="_method" value="DELETE">
|
||||
<a href="{{ $page->getUrl() }}" class="button primary">{{ trans('common.cancel') }}</a>
|
||||
<div class="form-group">
|
||||
<a href="{{ $page->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
@ -1,18 +1,15 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
||||
<div class="col-sm-7">
|
||||
<h1>{{ $title }}</h1>
|
||||
@section('body')
|
||||
<div class="container small">
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3>{{ $title }}</h3>
|
||||
@include('partials/entity-list', ['entities' => $pages, 'style' => 'detailed'])
|
||||
<div class="body text-center">
|
||||
{!! $pages->links() !!}
|
||||
</div>
|
||||
|
||||
<div class="col-sm-4 col-sm-offset-1"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@stop
|
@ -16,8 +16,6 @@
|
||||
@include('pages/form', ['model' => $page])
|
||||
@include('pages/form-toolbox')
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@include('components.image-manager', ['imageType' => 'gallery', 'uploaded_to' => $page->id])
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
{{--Header Bar--}}
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="container fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-4 faded">
|
||||
<div class="action-buttons text-left">
|
||||
@ -74,7 +74,7 @@
|
||||
|
||||
{{--Markdown Editor--}}
|
||||
@if(setting('app-editor') === 'markdown')
|
||||
<div id="markdown-editor" markdown-editor class="flex-fill flex">
|
||||
<div id="markdown-editor" markdown-editor class="flex-fill flex code-fill">
|
||||
|
||||
<div class="markdown-editor-wrap">
|
||||
<div class="editor-toolbar">
|
||||
|
@ -1,29 +1,31 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('pages._breadcrumbs', ['page' => $page])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container">
|
||||
<h1>{{ trans('entities.pages_move') }}</h1>
|
||||
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-folder"></i> {{ trans('entities.pages_move') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ $page->getUrl('/move') }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
<input type="hidden" name="_method" value="PUT">
|
||||
|
||||
@include('components.entity-selector', ['name' => 'entity_selection', 'selectorSize' => 'large', 'entityTypes' => 'book,chapter'])
|
||||
|
||||
<a href="{{ $page->getUrl() }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<div class="form-group text-right">
|
||||
<a href="{{ $page->getUrl() }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button pos">{{ trans('entities.pages_move') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -7,6 +7,6 @@
|
||||
@if (isset($diff) && $diff)
|
||||
{!! $diff !!}
|
||||
@else
|
||||
{!! isset($pageContent) ? $pageContent : $page->html !!}
|
||||
{!! isset($page->renderedHTML) ? $page->renderedHTML : $page->html !!}
|
||||
@endif
|
||||
</div>
|
@ -1,20 +1,19 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('pages._breadcrumbs', ['page' => $page])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
<div class="container" ng-non-bindable>
|
||||
<h1>{{ trans('entities.pages_permissions') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-lock-outline"></i> {{ trans('entities.pages_permissions') }}</h3>
|
||||
<div class="body">
|
||||
@include('form.restriction-form', ['model' => $page])
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
@ -1,12 +1,20 @@
|
||||
@extends('base')
|
||||
@extends('sidebar-layout')
|
||||
|
||||
@section('content')
|
||||
@section('sidebar')
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-info-outline"></i> {{ trans('common.details') }}</h3>
|
||||
<div class="body">
|
||||
@include('partials.entity-meta', ['entity' => $revision])
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container" ng-non-bindable>
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
<div class="page-content anim fadeIn">
|
||||
<div class="page-content">
|
||||
@include('pages.page-display')
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,20 +1,18 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
@include('pages._breadcrumbs', ['page' => $page])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
<div class="container" ng-non-bindable>
|
||||
<h1>{{ trans('entities.pages_revisions') }}</h1>
|
||||
<p> </p>
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-replay"></i> {{ trans('entities.pages_revisions') }}</h3>
|
||||
<div class="body">
|
||||
@if(count($page->revisions) > 0)
|
||||
|
||||
<table class="table">
|
||||
@ -57,6 +55,8 @@
|
||||
@else
|
||||
<p>{{ trans('entities.pages_revisions_none') }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -1,10 +1,6 @@
|
||||
@extends('base')
|
||||
@extends('sidebar-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-8 col-xs-5 faded">
|
||||
@include('pages._breadcrumbs', ['page' => $page])
|
||||
</div>
|
||||
@ -23,7 +19,7 @@
|
||||
@endif
|
||||
@if(userCan('page-update', $page) || userCan('restrictions-manage', $page) || userCan('page-delete', $page))
|
||||
<div dropdown class="dropdown-container">
|
||||
<a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i></a>
|
||||
<a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-more-vert"></i> {{ trans('common.more') }}</a>
|
||||
<ul>
|
||||
@if(userCan('page-update', $page))
|
||||
<li><a href="{{ $page->getUrl('/move') }}" class="text-primary" ><i class="zmdi zmdi-folder"></i>{{ trans('common.move') }}</a></li>
|
||||
@ -41,37 +37,13 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
|
||||
<div class="container" id="page-show">
|
||||
<div class="row">
|
||||
<div class="col-md-9 print-full-width">
|
||||
<div class="page-content" ng-non-bindable>
|
||||
|
||||
<div class="pointer-container" id="pointer">
|
||||
<div class="pointer anim" >
|
||||
<span class="icon text-primary"><i class="zmdi zmdi-link"></i></span>
|
||||
<input readonly="readonly" type="text" id="pointer-url" placeholder="url">
|
||||
<button class="button icon" data-clipboard-target="#pointer-url" type="button" title="{{ trans('entities.pages_copy_link') }}"><i class="zmdi zmdi-copy"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('pages/page-display')
|
||||
|
||||
<hr>
|
||||
|
||||
@include('partials.entity-meta', ['entity' => $page])
|
||||
|
||||
</div>
|
||||
@include('comments/comments', ['pageId' => $page->id])
|
||||
</div>
|
||||
|
||||
<div class="col-md-3 print-hidden">
|
||||
<div class="margin-top large"></div>
|
||||
@section('sidebar')
|
||||
@if($book->restricted || ($page->chapter && $page->chapter->restricted) || $page->restricted)
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-key"></i> {{ trans('entities.permissions') }}</h3>
|
||||
<div class="body">
|
||||
<div class="text-muted">
|
||||
|
||||
@if($book->restricted)
|
||||
@ -101,14 +73,82 @@
|
||||
<br>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($page->tags->count() > 0)
|
||||
<div class="card tag-display">
|
||||
<h3><i class="zmdi zmdi-tag"></i> {{ trans('entities.page_tags') }}</h3>
|
||||
<div class="body">
|
||||
<table>
|
||||
<tbody>
|
||||
@foreach($page->tags as $tag)
|
||||
<tr class="tag">
|
||||
<td @if(!$tag->value) colspan="2" @endif><a href="{{ baseUrl('/search?term=%5B' . urlencode($tag->name) .'%5D') }}">{{ $tag->name }}</a></td>
|
||||
@if($tag->value) <td class="tag-value"><a href="{{ baseUrl('/search?term=%5B' . urlencode($tag->name) .'%3D' . urlencode($tag->value) . '%5D') }}">{{$tag->value}}</a></td> @endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if ($page->attachments->count() > 0)
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-attachment-alt"></i> {{ trans('entities.pages_attachments') }}</h3>
|
||||
<div class="body">
|
||||
@foreach($page->attachments as $attachment)
|
||||
<div class="attachment">
|
||||
<a href="{{ $attachment->getUrl() }}" @if($attachment->external) target="_blank" @endif><i class="zmdi zmdi-{{ $attachment->external ? 'open-in-new' : 'file' }}"></i>{{ $attachment->name }}</a>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('pages/sidebar-tree-list', ['book' => $book, 'sidebarTree' => $sidebarTree, 'pageNav' => $pageNav])
|
||||
@if (isset($pageNav) && count($pageNav))
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-compass"></i> {{ trans('entities.pages_navigation') }}</h3>
|
||||
<div class="body">
|
||||
<div class="sidebar-page-nav menu">
|
||||
@foreach($pageNav as $navItem)
|
||||
<li class="page-nav-item h{{ $navItem['level'] }}">
|
||||
<a href="{{ $navItem['link'] }}">{{ $navItem['text'] }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('partials/book-tree', ['book' => $book, 'sidebarTree' => $sidebarTree])
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-info-outline"></i> {{ trans('common.details') }}</h3>
|
||||
<div class="body">
|
||||
@include('partials.entity-meta', ['entity' => $page])
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
<div class="page-content" ng-non-bindable>
|
||||
|
||||
<div class="pointer-container" id="pointer">
|
||||
<div class="pointer anim" >
|
||||
<span class="icon text-primary"><i class="zmdi zmdi-link"></i></span>
|
||||
<input readonly="readonly" type="text" id="pointer-url" placeholder="url">
|
||||
<button class="button icon" data-clipboard-target="#pointer-url" type="button" title="{{ trans('entities.pages_copy_link') }}"><i class="zmdi zmdi-copy"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('pages/page-display')
|
||||
|
||||
</div>
|
||||
<div class="container small">
|
||||
@include('comments/comments', ['pageId' => $page->id])
|
||||
</div>
|
||||
@stop
|
||||
|
||||
|
@ -1,74 +0,0 @@
|
||||
|
||||
<div class="book-tree" ng-non-bindable>
|
||||
|
||||
@if(isset($page) && $page->tags->count() > 0)
|
||||
<div class="tag-display">
|
||||
<h6 class="text-muted">{{ trans('entities.page_tags') }}</h6>
|
||||
<table>
|
||||
<tbody>
|
||||
@foreach($page->tags as $tag)
|
||||
<tr class="tag">
|
||||
<td @if(!$tag->value) colspan="2" @endif><a href="{{ baseUrl('/search?term=%5B' . urlencode($tag->name) .'%5D') }}">{{ $tag->name }}</a></td>
|
||||
@if($tag->value) <td class="tag-value"><a href="{{ baseUrl('/search?term=%5B' . urlencode($tag->name) .'%3D' . urlencode($tag->value) . '%5D') }}">{{$tag->value}}</a></td> @endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (isset($page) && $page->attachments->count() > 0)
|
||||
<h6 class="text-muted">{{ trans('entities.pages_attachments') }}</h6>
|
||||
@foreach($page->attachments as $attachment)
|
||||
<div class="attachment">
|
||||
<a href="{{ $attachment->getUrl() }}" @if($attachment->external) target="_blank" @endif><i class="zmdi zmdi-{{ $attachment->external ? 'open-in-new' : 'file' }}"></i>{{ $attachment->name }}</a>
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
|
||||
@if (isset($pageNav) && count($pageNav))
|
||||
<h6 class="text-muted">{{ trans('entities.pages_navigation') }}</h6>
|
||||
<div class="sidebar-page-nav menu">
|
||||
@foreach($pageNav as $navItem)
|
||||
<li class="page-nav-item h{{ $navItem['level'] }}">
|
||||
<a href="{{ $navItem['link'] }}">{{ $navItem['text'] }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<h6 class="text-muted">{{ trans('entities.books_navigation') }}</h6>
|
||||
<ul class="sidebar-page-list menu">
|
||||
|
||||
@if (userCan('view', $book))
|
||||
<li class="book-header"><a href="{{ $book->getUrl() }}" class="book {{ $current->matches($book)? 'selected' : '' }}"><i class="zmdi zmdi-book"></i>{{$book->name}}</a></li>
|
||||
@endif
|
||||
|
||||
@foreach($sidebarTree as $bookChild)
|
||||
<li class="list-item-{{ $bookChild->getClassName() }} {{ $bookChild->getClassName() }} {{ $bookChild->isA('page') && $bookChild->draft ? 'draft' : '' }}">
|
||||
<a href="{{ $bookChild->getUrl() }}" class="{{ $bookChild->getClassName() }} {{ $current->matches($bookChild)? 'selected' : '' }}">
|
||||
@if($bookChild->isA('chapter'))<i class="zmdi zmdi-collection-bookmark"></i>@else <i class="zmdi zmdi-file-text"></i>@endif{{ $bookChild->name }}
|
||||
</a>
|
||||
|
||||
@if($bookChild->isA('chapter') && count($bookChild->pages) > 0)
|
||||
<p chapter-toggle class="text-muted @if($bookChild->matchesOrContains($current)) open @endif">
|
||||
<i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ trans('entities.x_pages', ['count' => $bookChild->pages->count()]) }}</span>
|
||||
</p>
|
||||
<ul class="menu sub-menu inset-list @if($bookChild->matchesOrContains($current)) open @endif">
|
||||
@foreach($bookChild->pages as $childPage)
|
||||
<li class="list-item-page {{ $childPage->isA('page') && $childPage->draft ? 'draft' : '' }}">
|
||||
<a href="{{ $childPage->getUrl() }}" class="page {{ $current->matches($childPage)? 'selected' : '' }}">
|
||||
<i class="zmdi zmdi-file-text"></i> {{ $childPage->name }}
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
|
||||
</li>
|
||||
@endforeach
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
@ -8,5 +8,5 @@
|
||||
@endforeach
|
||||
</div>
|
||||
@else
|
||||
<p class="text-muted">{{ trans('common.no_activity') }}</p>
|
||||
<p class="text-muted empty-text">{{ trans('common.no_activity') }}</p>
|
||||
@endif
|
36
resources/views/partials/book-tree.blade.php
Normal file
36
resources/views/partials/book-tree.blade.php
Normal file
@ -0,0 +1,36 @@
|
||||
<div class="card book-tree" ng-non-bindable>
|
||||
<h3><i class="zmdi zmdi-book"></i> {{ trans('entities.books_navigation') }}</h3>
|
||||
<div class="body">
|
||||
<ul class="sidebar-page-list menu">
|
||||
|
||||
@if (userCan('view', $book))
|
||||
<li class="book-header"><a href="{{ $book->getUrl() }}" class="book {{ $current->matches($book)? 'selected' : '' }}"><i class="zmdi zmdi-book"></i>{{$book->name}}</a></li>
|
||||
@endif
|
||||
|
||||
@foreach($sidebarTree as $bookChild)
|
||||
<li class="list-item-{{ $bookChild->getClassName() }} {{ $bookChild->getClassName() }} {{ $bookChild->isA('page') && $bookChild->draft ? 'draft' : '' }}">
|
||||
<a href="{{ $bookChild->getUrl() }}" class="{{ $bookChild->getClassName() }} {{ $current->matches($bookChild)? 'selected' : '' }}">
|
||||
@if($bookChild->isA('chapter'))<i class="zmdi zmdi-collection-bookmark"></i>@else <i class="zmdi zmdi-file-text"></i>@endif{{ $bookChild->name }}
|
||||
</a>
|
||||
|
||||
@if($bookChild->isA('chapter') && count($bookChild->pages) > 0)
|
||||
<p chapter-toggle class="text-muted @if($bookChild->matchesOrContains($current)) open @endif">
|
||||
<i class="zmdi zmdi-caret-right"></i> <i class="zmdi zmdi-file-text"></i> <span>{{ trans('entities.x_pages', ['count' => $bookChild->pages->count()]) }}</span>
|
||||
</p>
|
||||
<ul class="menu sub-menu inset-list @if($bookChild->matchesOrContains($current)) open @endif">
|
||||
@foreach($bookChild->pages as $childPage)
|
||||
<li class="list-item-page {{ $childPage->isA('page') && $childPage->draft ? 'draft' : '' }}">
|
||||
<a href="{{ $childPage->getUrl() }}" class="page {{ $current->matches($childPage)? 'selected' : '' }}">
|
||||
<i class="zmdi zmdi-file-text"></i> {{ $childPage->name }}
|
||||
</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
|
||||
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
@ -1,5 +1,4 @@
|
||||
<style id="custom-styles" data-color="{{ setting('app-color') }}" data-color-light="{{ setting('app-color-light') }}">
|
||||
@if(setting('app-color'))
|
||||
header, [back-to-top], .primary-background {
|
||||
background-color: {{ setting('app-color') }} !important;
|
||||
}
|
||||
@ -18,5 +17,4 @@
|
||||
.text-primary, p.primary, p .primary, span.primary:hover, .text-primary:hover, a, a:hover, a:focus, .text-button, .text-button:hover, .text-button:focus {
|
||||
color: {{ setting('app-color') }};
|
||||
}
|
||||
@endif
|
||||
</style>
|
@ -1,4 +1,9 @@
|
||||
<p class="text-muted small">
|
||||
@if($entity->isA('revision'))
|
||||
{{ trans('entities.pages_revision') }}
|
||||
{{ trans('entities.pages_revisions_number') }}{{ $entity->revision_number == 0 ? '' : $entity->revision_number }}
|
||||
<br>
|
||||
@endif
|
||||
@if ($entity->isA('page')) {{ trans('entities.meta_revision', ['revisionCount' => $entity->revision_count]) }} <br> @endif
|
||||
@if ($entity->createdBy)
|
||||
{!! trans('entities.meta_created_name', [
|
||||
@ -14,7 +19,7 @@
|
||||
'timeLength' => '<span title="' . $entity->updated_at->toDayDateTimeString() .'">' . $entity->updated_at->diffForHumans() .'</span>',
|
||||
'user' => "<a href='{$entity->updatedBy->getProfileUrl()}'>".htmlentities($entity->updatedBy->name). "</a>"
|
||||
]) !!}
|
||||
@else
|
||||
@elseif (!$entity->isA('revision'))
|
||||
<span title="{{ $entity->updated_at->toDayDateTimeString() }}">{{ trans('entities.meta_updated', ['timeLength' => $entity->updated_at->diffForHumans()]) }}</span>
|
||||
@endif
|
||||
</p>
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html class="shaded">
|
||||
<head>
|
||||
<title>{{ setting('app-name') }}</title>
|
||||
|
||||
@ -23,12 +23,12 @@
|
||||
{!! setting('app-custom-head') !!}
|
||||
@endif
|
||||
</head>
|
||||
<body class="@yield('body-class')" ng-app="bookStack">
|
||||
<body class="@yield('body-class')">
|
||||
|
||||
@include('partials.notifications')
|
||||
|
||||
<header id="header">
|
||||
<div class="container">
|
||||
<div class="container fluid">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
|
||||
|
@ -1,39 +1,23 @@
|
||||
@extends('base')
|
||||
@extends('sidebar-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<input type="hidden" name="searchTerm" value="{{$searchTerm}}">
|
||||
|
||||
<div id="search-system">
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@section('toolbar')
|
||||
<div class="col-sm-12 faded">
|
||||
<div class="breadcrumbs">
|
||||
<a href="{{ baseUrl("/search?term=" . urlencode($searchTerm)) }}" class="text-button"><i class="zmdi zmdi-search"></i>{{ trans('entities.search_for_term', ['term' => $searchTerm]) }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
<div class="container" ng-non-bindable id="searchSystem">
|
||||
@section('container-attrs')
|
||||
id="search-system"
|
||||
ng-non-bindable=""
|
||||
@stop
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-6">
|
||||
<h1>{{ trans('entities.search_results') }}</h1>
|
||||
<h6 class="text-muted">{{ trans_choice('entities.search_total_results_found', $totalResults, ['count' => $totalResults]) }}</h6>
|
||||
@include('partials/entity-list', ['entities' => $entities])
|
||||
@if ($hasNextPage)
|
||||
<a href="{{ $nextPageLink }}" class="button">{{ trans('entities.search_more') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="col-md-5 col-md-offset-1">
|
||||
@section('sidebar')
|
||||
<div class="card">
|
||||
<h3>{{ trans('entities.search_filters') }}</h3>
|
||||
|
||||
<div class="body">
|
||||
<form v-on:submit="updateSearch" v-cloak class="v-cloak anim fadeIn">
|
||||
<h6 class="text-muted">{{ trans('entities.search_content_type') }}</h6>
|
||||
<div class="form-group">
|
||||
@ -200,14 +184,21 @@
|
||||
|
||||
<button type="submit" class="button primary">{{ trans('entities.search_update') }}</button>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small">
|
||||
<input type="hidden" name="searchTerm" value="{{$searchTerm}}">
|
||||
|
||||
<h1>{{ trans('entities.search_results') }}</h1>
|
||||
<h6 class="text-muted">{{ trans_choice('entities.search_total_results_found', $totalResults, ['count' => $totalResults]) }}</h6>
|
||||
@include('partials/entity-list', ['entities' => $entities])
|
||||
@if ($hasNextPage)
|
||||
<a href="{{ $nextPageLink }}" class="button">{{ trans('entities.search_more') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
@stop
|
@ -1,18 +1,22 @@
|
||||
@extends('base')
|
||||
|
||||
@section('content')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('toolbar')
|
||||
@include('settings/navbar', ['selected' => 'settings'])
|
||||
@stop
|
||||
|
||||
<div class="container small settings-container">
|
||||
@section('body')
|
||||
<div class="container small">
|
||||
|
||||
<h1>{{ trans('settings.settings') }}</h1>
|
||||
<div class="text-right text-muted container">
|
||||
<br>
|
||||
BookStack @if(strpos($version, 'v') !== 0) version @endif {{ $version }}
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-settings-square"></i> {{ trans('settings.app_settings') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ baseUrl("/settings") }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
|
||||
<h3>{{ trans('settings.app_settings') }}</h3>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-6">
|
||||
@ -64,8 +68,13 @@
|
||||
<div class="form-group" id="color-control">
|
||||
<label for="setting-app-color">{{ trans('settings.app_primary_color') }}</label>
|
||||
<p class="small">{!! trans('settings.app_primary_color_desc') !!}</p>
|
||||
<input type="text" value="{{ setting('app-color', '') }}" name="setting-app-color" id="setting-app-color" placeholder="#0288D1">
|
||||
<input type="hidden" value="{{ setting('app-color-light', '') }}" name="setting-app-color-light" id="setting-app-color-light" placeholder="rgba(21, 101, 192, 0.15)">
|
||||
<input type="text" value="{{ setting('app-color') }}" name="setting-app-color" id="setting-app-color" placeholder="#0288D1">
|
||||
<input type="hidden" value="{{ setting('app-color-light') }}" name="setting-app-color-light" id="setting-app-color-light">
|
||||
</div>
|
||||
<div class="form-group" id="homepage-control">
|
||||
<label for="setting-app-homepage">{{ trans('settings.app_homepage') }}</label>
|
||||
<p class="small">{{ trans('settings.app_homepage_desc') }}</p>
|
||||
@include('components.page-picker', ['name' => 'setting-app-homepage', 'placeholder' => trans('settings.app_homepage_default'), 'value' => setting('app-homepage')])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -77,9 +86,20 @@
|
||||
<textarea name="setting-app-custom-head" id="setting-app-custom-head">{{ setting('app-custom-head', '') }}</textarea>
|
||||
</div>
|
||||
|
||||
<hr class="margin-top">
|
||||
<div class="form-group text-right">
|
||||
<button type="submit" class="button pos">{{ trans('settings.settings_save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>{{ trans('settings.reg_settings') }}</h3>
|
||||
<p> </p>
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-accounts-add"></i> {{ trans('settings.reg_settings') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ baseUrl("/settings") }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
@ -114,19 +134,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="margin-top">
|
||||
|
||||
<div class="form-group">
|
||||
<span class="float right muted">
|
||||
BookStack @if(strpos($version, 'v') !== 0) version @endif {{ $version }}
|
||||
</span>
|
||||
<div class="form-group text-right">
|
||||
<button type="submit" class="button pos">{{ trans('settings.settings_save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@include('components.image-manager', ['imageType' => 'system'])
|
||||
@include('components.entity-selector-popup', ['entityTypes' => 'page'])
|
||||
|
||||
@stop
|
||||
|
||||
@ -139,6 +158,7 @@
|
||||
var hexVal = '#' + this.color.colors.HEX;
|
||||
var rgb = this.color.colors.RND.rgb;
|
||||
var rgbLightVal = 'rgba('+ [rgb.r, rgb.g, rgb.b, '0.15'].join(',') +')';
|
||||
|
||||
// Set textbox color to hex color code.
|
||||
var isEmpty = $.trim($elm.val()).length === 0;
|
||||
if (!isEmpty) $elm.val(hexVal);
|
||||
|
@ -1,8 +1,5 @@
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12 setting-nav nav-tabs">
|
||||
<div class="col-md-12 setting-nav nav-tabs">
|
||||
@if($currentUser->can('settings-manage'))
|
||||
<a href="{{ baseUrl('/settings') }}" @if($selected == 'settings') class="selected text-button" @endif><i class="zmdi zmdi-settings"></i>{{ trans('settings.settings') }}</a>
|
||||
@endif
|
||||
@ -12,7 +9,4 @@
|
||||
@if($currentUser->can('user-roles-manage'))
|
||||
<a href="{{ baseUrl('/settings/roles') }}" @if($selected == 'roles') class="selected text-button" @endif><i class="zmdi zmdi-lock-open"></i>{{ trans('settings.roles') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,15 +1,17 @@
|
||||
@extends('base')
|
||||
|
||||
@section('content')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('toolbar')
|
||||
@include('settings/navbar', ['selected' => 'roles'])
|
||||
@stop
|
||||
|
||||
<div class="container">
|
||||
<h1>{{ trans('settings.role_create') }}</h1>
|
||||
@section('body')
|
||||
|
||||
<form action="{{ baseUrl("/settings/roles/new") }}" method="POST">
|
||||
@include('settings/roles/form')
|
||||
</form>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@include('settings/roles/form', ['title' => trans('settings.role_create'), 'icon' => 'plus'])
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@stop
|
||||
|
@ -1,11 +1,15 @@
|
||||
@extends('base')
|
||||
|
||||
@section('content')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('toolbar')
|
||||
@include('settings/navbar', ['selected' => 'roles'])
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('settings.role_delete') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-delete"></i> {{ trans('settings.role_delete') }}</h3>
|
||||
<div class="body">
|
||||
<p>{{ trans('settings.role_delete_confirm', ['roleName' => $role->display_name]) }}</p>
|
||||
|
||||
<form action="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" method="POST">
|
||||
@ -20,9 +24,13 @@
|
||||
@endif
|
||||
|
||||
<p class="text-neg">{{ trans('settings.role_delete_sure') }}</p>
|
||||
<a href="{{ baseUrl("/settings/roles/{$role->id}") }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<div class="form-group">
|
||||
<a href="{{ baseUrl("/settings/roles/{$role->id}") }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@stop
|
||||
|
@ -1,24 +1,17 @@
|
||||
@extends('base')
|
||||
|
||||
@section('content')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('toolbar')
|
||||
@include('settings/navbar', ['selected' => 'roles'])
|
||||
@stop
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<h1>{{ trans('settings.role_edit') }}</h1>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<p></p>
|
||||
<a href="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" class="button neg float right">{{ trans('settings.role_delete') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
@section('body')
|
||||
|
||||
<form action="{{ baseUrl("/settings/roles/{$role->id}") }}" method="POST">
|
||||
<input type="hidden" name="_method" value="PUT">
|
||||
@include('settings/roles/form', ['model' => $role])
|
||||
</form>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@include('settings/roles/form', ['model' => $role, 'title' => trans('settings.role_edit'), 'icon' => 'edit'])
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
@stop
|
||||
|
@ -1,11 +1,12 @@
|
||||
{!! csrf_field() !!}
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-9">
|
||||
<div class="col-md-9">
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-{{$icon}}"></i> {{$title}}</h3>
|
||||
<div class="body">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<h3>{{ trans('settings.role_details') }}</h3>
|
||||
<h5>{{ trans('settings.role_details') }}</h5>
|
||||
<div class="form-group">
|
||||
<label for="name">{{ trans('settings.role_name') }}</label>
|
||||
@include('form/text', ['name' => 'display_name'])
|
||||
@ -14,7 +15,7 @@
|
||||
<label for="name">{{ trans('settings.role_desc') }}</label>
|
||||
@include('form/text', ['name' => 'description'])
|
||||
</div>
|
||||
<h3>{{ trans('settings.role_system') }}</h3>
|
||||
<h5>{{ trans('settings.role_system') }}</h5>
|
||||
<label>@include('settings/roles/checkbox', ['permission' => 'users-manage']) {{ trans('settings.role_manage_users') }}</label>
|
||||
<label>@include('settings/roles/checkbox', ['permission' => 'user-roles-manage']) {{ trans('settings.role_manage_roles') }}</label>
|
||||
<label>@include('settings/roles/checkbox', ['permission' => 'restrictions-manage-all']) {{ trans('settings.role_manage_entity_permissions') }}</label>
|
||||
@ -24,7 +25,7 @@
|
||||
|
||||
<div class="col-md-6">
|
||||
|
||||
<h3>{{ trans('settings.role_asset') }}</h3>
|
||||
<h5>{{ trans('settings.role_asset') }}</h5>
|
||||
<p>{{ trans('settings.role_asset_desc') }}</p>
|
||||
|
||||
<table class="table">
|
||||
@ -133,12 +134,20 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<a href="{{ baseUrl("/settings/roles") }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<div class="form-group text-right">
|
||||
<a href="{{ baseUrl("/settings/roles") }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
@if (isset($role) && $role->id)
|
||||
<a href="{{ baseUrl("/settings/roles/delete/{$role->id}") }}" class="button neg">{{ trans('settings.role_delete') }}</a>
|
||||
@endif
|
||||
<button type="submit" class="button pos">{{ trans('settings.role_save') }}</button>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h3>{{ trans('settings.role_users') }}</h3>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-accounts"></i> {{ trans('settings.role_users') }}</h3>
|
||||
<div class="body">
|
||||
@if(isset($role) && count($role->users) > 0)
|
||||
<table class="list-table">
|
||||
@foreach($role->users as $user)
|
||||
@ -161,9 +170,6 @@
|
||||
{{ trans('settings.role_users_none') }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
@ -1,21 +1,16 @@
|
||||
@extends('base')
|
||||
|
||||
@section('content')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('toolbar')
|
||||
@include('settings/navbar', ['selected' => 'roles'])
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small">
|
||||
|
||||
<div class="row action-header">
|
||||
<div class="col-sm-8">
|
||||
<h1>{{ trans('settings.role_user_roles') }}</h1>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p></p>
|
||||
<a href="{{ baseUrl("/settings/roles/new") }}" class="button float right pos"><i class="zmdi zmdi-lock-open"></i>{{ trans('settings.role_create') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-lock-open"></i> {{ trans('settings.role_user_roles') }}</h3>
|
||||
<div class="body">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>{{ trans('settings.role_name') }}</th>
|
||||
@ -30,6 +25,12 @@
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
|
||||
<div class="form-group">
|
||||
<a href="{{ baseUrl("/settings/roles/new") }}" class="button pos">{{ trans('settings.role_create') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
34
resources/views/sidebar-layout.blade.php
Normal file
34
resources/views/sidebar-layout.blade.php
Normal file
@ -0,0 +1,34 @@
|
||||
@extends('base')
|
||||
|
||||
@section('body-class', 'sidebar-layout')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="toolbar-container">
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container fluid">
|
||||
<div class="row">
|
||||
@yield('toolbar')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex-fill flex" @yield('container-attrs') >
|
||||
|
||||
<div sidebar class="sidebar flex print-hidden" id="sidebar">
|
||||
<div class="sidebar-toggle primary-background-light"><i class="zmdi zmdi-caret-right-circle"></i>
|
||||
</div>
|
||||
<div class="scroll-body">
|
||||
@yield('sidebar')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content flex">
|
||||
@yield('body')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
27
resources/views/simple-layout.blade.php
Normal file
27
resources/views/simple-layout.blade.php
Normal file
@ -0,0 +1,27 @@
|
||||
@extends('base')
|
||||
|
||||
@section('body-class', 'shaded')
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="toolbar-container">
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container fluid">
|
||||
<div class="row">
|
||||
@yield('toolbar')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex-fill flex">
|
||||
<div class="content flex">
|
||||
<div class="scroll-body">
|
||||
@yield('body')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
@ -1,31 +1,26 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('toolbar')
|
||||
@include('settings/navbar', ['selected' => 'users'])
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 faded">
|
||||
<div class="breadcrumbs">
|
||||
<a href="{{ baseUrl('/settings/users') }}" class="text-button"><i class="zmdi zmdi-accounts"></i>{{ trans('settings.users') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('settings.users_add_new') }}</h1>
|
||||
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-accounts-add"></i> {{ trans('settings.users_add_new') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ baseUrl("/settings/users/create") }}" method="post">
|
||||
{!! csrf_field() !!}
|
||||
@include('users/forms/' . $authMethod)
|
||||
<div class="form-group">
|
||||
<a href="{{ baseUrl($currentUser->can('users-manage') ? "/settings/users" : "/") }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<div class="form-group text-right">
|
||||
<a href="{{ baseUrl($currentUser->can('users-manage') ? "/settings/users" : "/") }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button class="button pos" type="submit">{{ trans('common.save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -1,32 +1,27 @@
|
||||
@extends('base')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('content')
|
||||
@section('toolbar')
|
||||
@include('settings/navbar', ['selected' => 'users'])
|
||||
@stop
|
||||
|
||||
<div class="faded-small toolbar">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 faded">
|
||||
<div class="breadcrumbs">
|
||||
<a href="{{ baseUrl("/settings/users") }}" class="text-button"><i class="zmdi zmdi-accounts"></i>Users</a>
|
||||
<span class="sep">»</span>
|
||||
<a href="{{ baseUrl("/settings/users/{$user->id}") }}" class="text-button"><i class="zmdi zmdi-account"></i>{{ $user->name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
<h1>{{ trans('settings.users_delete') }}</h1>
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-delete"></i> {{ trans('settings.users_delete') }}</h3>
|
||||
<div class="body">
|
||||
<p>{{ trans('settings.users_delete_warning', ['userName' => $user->name]) }}</p>
|
||||
<p class="text-neg">{{ trans('settings.users_delete_confirm') }}</p>
|
||||
|
||||
<form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="POST">
|
||||
{!! csrf_field() !!}
|
||||
<input type="hidden" name="_method" value="DELETE">
|
||||
<a href="{{ baseUrl("/settings/users/{$user->id}") }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<a href="{{ baseUrl("/settings/users/{$user->id}") }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
<button type="submit" class="button neg">{{ trans('common.confirm') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -1,23 +1,17 @@
|
||||
@extends('base')
|
||||
|
||||
|
||||
@section('content')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('toolbar')
|
||||
@include('settings/navbar', ['selected' => 'users'])
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small">
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi-edit zmdi"></i> {{ $user->id === $currentUser->id ? trans('settings.users_edit_profile') : trans('settings.users_edit') }}</h3>
|
||||
<div class="body">
|
||||
<form action="{{ baseUrl("/settings/users/{$user->id}") }}" method="post">
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<h1>{{ $user->id === $currentUser->id ? trans('settings.users_edit_profile') : trans('settings.users_edit') }}</h1>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p></p>
|
||||
@if($authMethod !== 'system')
|
||||
<a href="{{ baseUrl("/settings/users/{$user->id}/delete") }}" class="neg button float right">{{ trans('settings.users_delete') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6" ng-non-bindable>
|
||||
{!! csrf_field() !!}
|
||||
@ -49,29 +43,28 @@
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="books_display">{{ trans('settings.users_books_display_type') }}</label>
|
||||
<select name="books_display" id="books_display">
|
||||
<option @if($user->books_display === 'grid') selected @endif value="grid">Grid</option>
|
||||
<option @if($user->books_display === 'list') selected @endif value="list">List</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<a href="{{ baseUrl($currentUser->can('users-manage') ? "/settings/users" : "/") }}" class="button muted">{{ trans('common.cancel') }}</a>
|
||||
<div class="form-group text-right">
|
||||
<a href="{{ baseUrl($currentUser->can('users-manage') ? "/settings/users" : "/") }}" class="button outline">{{ trans('common.cancel') }}</a>
|
||||
@if($authMethod !== 'system')
|
||||
<a href="{{ baseUrl("/settings/users/{$user->id}/delete") }}" class="neg button">{{ trans('settings.users_delete') }}</a>
|
||||
@endif
|
||||
<button class="button pos" type="submit">{{ trans('common.save') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<hr class="margin-top large">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($currentUser->id === $user->id && count($activeSocialDrivers) > 0)
|
||||
<h3>{{ trans('settings.users_social_accounts') }}</h3>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-sign-in"></i> {{ trans('settings.users_social_accounts') }}</h3>
|
||||
<div class="body">
|
||||
<p class="text-muted">{{ trans('settings.users_social_accounts_info') }}</p>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@foreach($activeSocialDrivers as $driver => $enabled)
|
||||
<div class="col-sm-3 col-xs-6 text-center">
|
||||
<div class="col-sm-4 col-xs-6 text-center">
|
||||
<div>@icon($driver, ['width' => 56])</div>
|
||||
<div>
|
||||
@if($user->hasSocialAccount($driver))
|
||||
@ -80,9 +73,13 @@
|
||||
<a href="{{ baseUrl("/login/service/{$driver}") }}" class="button pos">{{ trans('settings.users_social_connect') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
<div> </div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
|
@ -1,38 +1,31 @@
|
||||
@extends('base')
|
||||
|
||||
|
||||
@section('content')
|
||||
@extends('simple-layout')
|
||||
|
||||
@section('toolbar')
|
||||
@include('settings/navbar', ['selected' => 'users'])
|
||||
@stop
|
||||
|
||||
|
||||
@section('body')
|
||||
<div class="container small" ng-non-bindable>
|
||||
<div class="row action-header">
|
||||
<div class="col-sm-8">
|
||||
<h1>{{ trans('settings.users') }}</h1>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p></p>
|
||||
@if(userCan('users-manage'))
|
||||
<a href="{{ baseUrl("/settings/users/create") }}" class="pos button float right"><i class="zmdi zmdi-account-add"></i>{{ trans('settings.users_add_new') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p> </p>
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-accounts"></i> {{ trans('settings.users') }}</h3>
|
||||
<div class="body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<div class="compact">
|
||||
{{ $users->links() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<form method="get" class="float right" action="{{ baseUrl("/settings/users") }}">
|
||||
<form method="get" action="{{ baseUrl("/settings/users") }}">
|
||||
@foreach(collect($listDetails)->except('search') as $name => $val)
|
||||
<input type="hidden" name="{{ $name }}" value="{{ $val }}">
|
||||
@endforeach
|
||||
<input type="text" name="search" placeholder="{{ trans('settings.users_search') }}" @if($listDetails['search']) value="{{$listDetails['search']}}" @endif>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-sm-8 text-right">
|
||||
@if(userCan('users-manage'))
|
||||
<a href="{{ baseUrl("/settings/users/create") }}" style="margin-top: 0;" class="pos button">{{ trans('settings.users_add_new') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table">
|
||||
@ -75,6 +68,10 @@
|
||||
<div>
|
||||
{{ $users->links() }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
@ -1,10 +1,23 @@
|
||||
@extends('base')
|
||||
@extends('sidebar-layout')
|
||||
|
||||
@section('content')
|
||||
@section('toolbar')
|
||||
<div class="col-sm-6 col-xs-1 faded">
|
||||
<div class="breadcrumbs">
|
||||
<a href="{{ $user->getProfileUrl() }}" class="text-button"><i class="zmdi zmdi-account"></i>{{ $user->name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
<div class="container" ng-non-bindable>
|
||||
<div class="row">
|
||||
<div class="col-sm-7">
|
||||
@section('sidebar')
|
||||
<div class="card" id="recent-activity">
|
||||
<h3><i class="zmdi zmdi-time"></i> {{ trans('entities.recent_activity') }}</h3>
|
||||
@include('partials/activity-list', ['activity' => $activity])
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
<div class="container small" ng-non-bindable>
|
||||
|
||||
<div class="padded-top large"></div>
|
||||
|
||||
@ -65,13 +78,5 @@
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="col-sm-4 col-sm-offset-1" id="recent-activity">
|
||||
<h3>{{ trans('entities.recent_activity') }}</h3>
|
||||
@include('partials/activity-list', ['activity' => $activity])
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
33
tests/HomepageTest.php
Normal file
33
tests/HomepageTest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php namespace Tests;
|
||||
|
||||
use BookStack\JointPermission;
|
||||
use BookStack\Page;
|
||||
use BookStack\Repos\EntityRepo;
|
||||
|
||||
class HomepageTest extends TestCase
|
||||
{
|
||||
|
||||
public function test_default_homepage_visible()
|
||||
{
|
||||
$this->asEditor();
|
||||
$homeVisit = $this->get('/');
|
||||
$homeVisit->assertSee('My Recently Viewed');
|
||||
$homeVisit->assertSee('Recently Updated Pages');
|
||||
$homeVisit->assertSee('Recent Activity');
|
||||
}
|
||||
|
||||
public function test_custom_homepage() {
|
||||
$this->asEditor();
|
||||
$name = 'My custom homepage';
|
||||
$content = 'This is the body content of my custom homepage.';
|
||||
$customPage = $this->newPage(['name' => $name, 'html' => $content]);
|
||||
$this->setSettings(['app-homepage' => $customPage->id]);
|
||||
|
||||
$homeVisit = $this->get('/');
|
||||
$homeVisit->assertSee($name);
|
||||
$homeVisit->assertSee($content);
|
||||
$homeVisit->assertSee('My Recently Viewed');
|
||||
$homeVisit->assertSee('Recently Updated Pages');
|
||||
$homeVisit->assertSee('Recent Activity');
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ use BookStack\Book;
|
||||
use BookStack\Chapter;
|
||||
use BookStack\Repos\EntityRepo;
|
||||
use BookStack\Role;
|
||||
use BookStack\Services\SettingService;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||
|
||||
@ -88,4 +89,16 @@ abstract class TestCase extends BaseTestCase
|
||||
$draftPage = $entityRepo->getDraftPage($book);
|
||||
return $entityRepo->publishPageDraft($draftPage, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quickly sets an array of settings.
|
||||
* @param $settingsArray
|
||||
*/
|
||||
protected function setSettings($settingsArray)
|
||||
{
|
||||
$settings = app(SettingService::class);
|
||||
foreach ($settingsArray as $key => $value) {
|
||||
$settings->put($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user