Archived
1
0

Several improvements to the admin panel

This commit is contained in:
Marcel 2019-01-04 19:47:29 +01:00
parent 83f0b2a596
commit e79cc9b4ff
6 changed files with 195 additions and 91 deletions

View File

@ -89,11 +89,19 @@ defined('BASEPATH') OR exit('No direct script access allowed');
.tags .bootstrap-tagsinput { .tags .bootstrap-tagsinput {
width: 100%; width: 100%;
max-width: 100%; max-width: 100%;
font-size: 14px;
}
.tags .bootstrap-tagsinput > input {
margin: 5px 0;
} }
.tags .tag { .tags .tag {
display: inline-block; display: inline-block;
width: unset; width: unset;
background: #2272ff;
color: #fff !important;
border-radius: 25px;
} }
.tags .tag::after { .tags .tag::after {
@ -162,7 +170,8 @@ defined('BASEPATH') OR exit('No direct script access allowed');
</div> </div>
<h1 class="post-title"><span id="postTitle" class="noEnter"></span></h1> <h1 class="post-title"><span id="postTitle" class="noEnter"></span></h1>
<h2 class="post-subtitle"><span id="postDescription"></span></h2> <h2 class="post-subtitle"><span id="postDescription"></span></h2>
<div id="postContent"></div> <!-- <div id="postContent"></div>-->
<textarea id="postContent"></textarea>
</div> </div>
<!--/.blog-item--> <!--/.blog-item-->
</div> </div>
@ -183,6 +192,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
<div class="tags"> <div class="tags">
<input type="text" data-role="tagsinput" id="postTags"> <input type="text" data-role="tagsinput" id="postTags">
</div> </div>
<!-- <input type="text" id="postTags">-->
</div> </div>
<div class="row"> <div class="row">
@ -207,11 +217,20 @@ defined('BASEPATH') OR exit('No direct script access allowed');
</label> </label>
</div> </div>
<div class="row">
<button class="btn btn-default btn-sm" id="blogPreview">
<i class="fa fa-eye"></i>
Vorschau
</button>
</div>
<div class="row"> <div class="row">
<button class="btn btn-default btn-sm" id="blogPostSave"> <button class="btn btn-default btn-sm" id="blogPostSave">
<i class="fa fa-save"></i>
Speichern Speichern
</button> </button>
<button class="btn btn-primary btn-sm" id="blogSubmit" data-loading-text="Lädt..."> <button class="btn btn-primary btn-sm" id="blogSubmit" data-loading-text="Lädt...">
<i class="fa fa-cloud"></i>
Veröffentlichen Veröffentlichen
</button> </button>
</div> </div>

View File

@ -10,8 +10,8 @@ defined('BASEPATH') OR exit('No direct script access allowed');
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<div class="x_content"> <div class="x_content">
<iframe src="https://stats.kingofdog.eu/" <!-- <iframe src="https://stats.kingofdog.eu/"-->
style="height:100vh;width:100%" frameborder="0" async></iframe> <!-- style="height:100vh;width:100%" frameborder="0" async></iframe>-->
</div> </div>
</div> </div>
</div> </div>

View File

@ -14,17 +14,16 @@ defined('BASEPATH') OR exit('No direct script access allowed');
<script src="/assets/js/lib/jquery.min.js"></script> <script src="/assets/js/lib/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="/assets/js/lib/tinymce5/tinymce.min.js"></script>
<?php <?php
$scripts = [ $scripts = [
'lib/jquery.min.js', 'lib/jquery.min.js',
'lib/bootstrap-3.3.7.min.js', 'lib/bootstrap-3.3.7.min.js',
'lib/typeahead.bundle.min.js',
'lib/datatables.js', 'lib/datatables.js',
'lib/jquery.tagsinput.min.js', 'lib/jquery.tagsinput.min.js',
'lib/moment.min.js', 'lib/moment.min.js',
'lib/bootstrap-datetimepicker.min.js', 'lib/bootstrap-datetimepicker.min.js',
'lib/bootstrap-tagsinput.min.js',
'fullcalendar/fullcalendar.min.js', 'fullcalendar/fullcalendar.min.js',
'fullcalendar/lang/de.js', 'fullcalendar/lang/de.js',
'lib/jquery.mCustomScrollbar.min.js', 'lib/jquery.mCustomScrollbar.min.js',
@ -41,7 +40,5 @@ defined('BASEPATH') OR exit('No direct script access allowed');
<script src="<?= $scriptName ?>"></script> <script src="<?= $scriptName ?>"></script>
</body> </body>
</html> </html>

View File

@ -19,7 +19,7 @@
'lib/jquery.mCustomScrollbar.min.css', 'lib/jquery.mCustomScrollbar.min.css',
'lib/prism.min.css', 'lib/prism.min.css',
'lib/datatables.min.css', 'lib/datatables.min.css',
'lib/bootstrap-tagsinput.min.css',
'lib/fullcalendar.min.css', 'lib/fullcalendar.min.css',
'lib/flag-icon.min.css' 'lib/flag-icon.min.css'
]; ];
@ -228,7 +228,7 @@
<ul class="nav navbar-nav navbar-right"> <ul class="nav navbar-nav navbar-right">
<li class=""> <li class="">
<a href="javascript:;" class="user-profile dropdown-toggle" data-toggle="dropdown" <a href="javascript:" class="user-profile dropdown-toggle" data-toggle="dropdown"
aria-expanded="false"> aria-expanded="false">
<img src="<?= $_SESSION['user']['profilePic'] ?>" <img src="<?= $_SESSION['user']['profilePic'] ?>"
alt=""><?= $_SESSION['user']['displayname'] ?> alt=""><?= $_SESSION['user']['displayname'] ?>
@ -257,7 +257,7 @@
</li> </li>
<li role="presentation" class="dropdown"> <li role="presentation" class="dropdown">
<a href="javascript:;" class="dropdown-toggle info-number" data-toggle="dropdown" <a href="javascript:" class="dropdown-toggle info-number" data-toggle="dropdown"
aria-expanded="false"> aria-expanded="false">
<i class="far fa-envelope"></i> <i class="far fa-envelope"></i>
<span class="badge bg-blue" id="notificationCount"></span> <span class="badge bg-blue" id="notificationCount"></span>

View File

@ -3,14 +3,14 @@
?> ?>
<div class="right_col" role="main"> <div class="right_col" role="main">
<div class="row"> <div class="row">
<div class="col-md-6 col-sm-8 col-xs-8"> <form class="form" method="POST">
<div class="x_panel"> <div class="col-md-6 col-sm-8 col-xs-8">
<div class="x_title"> <div class="x_panel">
<h2>Einstellungen von dem Nutzer <?= $user['displayname'] ?></h2> <div class="x_title">
<div class="clearfix"></div> <h2>Einstellungen von dem Nutzer <?= $user['displayname'] ?></h2>
</div> <div class="clearfix"></div>
<div class="x_content"> </div>
<form class="form" method="POST"> <div class="x_content">
<div class="form-group" aria-describedby="#rank-help"> <div class="form-group" aria-describedby="#rank-help">
<b>Rang</b> <b>Rang</b>
<br> <br>
@ -73,40 +73,42 @@
Unbeschränkter Zugriff auf alle Funktionen. Unbeschränkter Zugriff auf alle Funktionen.
</span> </span>
<input type="submit" class="btn btn-primary" value="Speichern"> <input type="submit" class="btn btn-primary" value="Speichern">
</form> </div>
</div> </div>
</div> </div>
</div>
<div class="col-md-6 col-sm-4 col-xs-4"> <div class="col-md-6 col-sm-4 col-xs-4">
<div class="x_panel"> <div class="x_panel">
<div class="x_title"> <div class="x_title">
<h2>Individuelle Rechte</h2> <h2>Individuelle Rechte</h2>
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<div class="x_content"> <div class="x_content">
<form method="POST" class="form"> <div class="permissions">
<?php foreach ($availablePermissions as $group => $perms): ?> <?php foreach ($availablePermissions as $group => $perms): ?>
<h4> <div class="permission-group">
<?= $group ?> <h4>
<?= $group ?>
<input type="checkbox" class="group-all"> <input type="checkbox" class="group-all">
</h4> </h4>
<ul> <ul>
<?php foreach ($perms as $perm): <?php foreach ($perms as $perm):
$name = $group . '.' . $perm; ?> $name = $group . '.' . $perm; ?>
<li> <li>
<label data-toggle="tooltip" title="blablabla" for="<?= $group . $perm ?>"><?= $name ?></label> <label data-toggle="tooltip" title="blablabla" for="<?= $group . $perm ?>"><?= $name ?></label>
<input type="checkbox" value="true" name="permissions[<?= $group . $perm ?>]" id="<?= $group . $perm ?>" <?= in_array($name, $permissions) ? 'checked' : '' ?>> <input type="checkbox" value="true" class="perm-box" name="permissions[<?= $group . $perm ?>]" id="<?= $group . $perm ?>" <?= in_array($name, $permissions) ? 'checked' : '' ?>>
</li> </li>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
<?php endforeach; ?> </div>
<?php endforeach; ?>
</div>
<input type="submit" class="btn btn-primary" value="Speichern"> <input type="submit" class="btn btn-primary" value="Speichern">
</form> </div>
</div> </div>
</div> </div>
</div> </form>
</div> </div>
</div> </div>

View File

@ -15,26 +15,36 @@ const toolbarOptions = [
['clean'] ['clean']
]; ];
const quill = new Quill('#postContent', { // const quill = new Quill('#postContent', {
theme: 'snow', // theme: 'snow',
bounds: '#postContent .ql-editor', // bounds: '#postContent .ql-editor',
modules: { // modules: {
syntax: true, // syntax: true,
toolbar: toolbarOptions // toolbar: toolbarOptions
} // }
// });
const editor = tinymce.init({
selector: '#postContent',
plugins: [
'advlist autolink link image lists charmap print preview hr anchor pagebreak spellchecker',
'searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking',
'save table contextmenu directionality emoticons template paste textcolor'
],
templates: '/admin/blog/getTemplates',
toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | print preview media fullpage | forecolor backcolor emoticons'
}); });
let changeUrl = true; let changeUrl = true;
// var edits = ["#title", "#description", "#content"];
// Prevent the backspace key from navigating back. // Prevent the backspace key from navigating back.
// $(document).on("keydown", function (e) { $(document).on("keydown", function (e) {
// if (e.which === 8 && !$(e.target||e.srcElement).is("span, [contenteditable=true]")) { if (e.which === 8 && !$(e.target || e.srcElement).is("span, [contenteditable=true], input")) {
// e.preventDefault(); e.preventDefault();
// return false; return false;
// } }
// }); });
// var autolist = new AutoList(); // var autolist = new AutoList();
// var editor = new MediumEditor('#content', { // var editor = new MediumEditor('#content', {
@ -101,43 +111,38 @@ function prepareString(input) {
return input; return input;
} }
/*$('#content').bind('click', function () {
$(this).attr('contentEditable', true);
}).blur(
function () {
$(this).attr('contentEditable', false);
});*/
var shift = false; var shift = false;
$('span').keydown(function (e) { const edits = ["#postTitle", "#postDescription", ".ql-editor"];
var key = e.keyCode; $(edits.toString()).keydown(function (e) {
console.log(key); const key = e.key;
// Shift Control // Shift Control
if (key === 'Shift') {
if (key === 16) {
shift = true; shift = true;
} }
// Ctrl + Return Control // Ctrl + Return Control
if (key === 13 && (e.ctrlKey || e.metaKey)) { if (key === 'Enter' && (e.ctrlKey || e.metaKey)) {
console.log('test');
e.preventDefault(); e.preventDefault();
$(this).attr('contentEditable', false); $(this).attr('contentEditable', false);
} }
// Tab Control // Tab Control
if (key === 9) { if (key === 'Tab') {
e.preventDefault(); e.preventDefault();
$(this).attr('contentEditable', false); $(this).attr('contentEditable', false);
var pos = edits.indexOf("#" + $(this).attr('id')); let pos = edits.findIndex(edit => edit === '#' + $(this).attr('id') || $(this).hasClass(edit.substr(1)));
console.log(pos);
if (shift) { if (shift) {
$(edits[pos - 1]).attr('contentEditable', true); pos--;
if (pos < 0)
pos = edits.length - 1;
} else { } else {
$(edits[pos + 1]).attr('contentEditable', true); pos++;
if (pos >= edits.length)
pos = 0;
} }
$(edits[pos]).attr('contenteditable', true).focus();
} }
@ -163,6 +168,37 @@ $('span').keyup(function (e) {
} }
}); });
const existingTags = new Bloodhound({
// datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
// queryTokenizer: Bloodhound.tokenizers.whitespace,
datumTokenizer: Bloodhound.tokenizers.whitespace,
queryTokenizer: Bloodhound.tokenizers.whitespace,
// prefetch: {
// url: '/admin/blog/tagsList',
// filter: function (list) {
// return $.map(list, function (cityname) {
// return {name: cityname};
// });
// }
// }
prefetch: {
url: '/admin/blog/tagsList',
cache: true
}
// local: ['Hallo Welt', 'Hund', 'Test', 'Geht doch']
});
existingTags.initialize();
// $('#postTags').typeahead({
// hint: true,
// highlight: true,
// minLength: 1
// }, {
// name: 'existingTags',
// source: existingTags,
// });
let tagsList = []; let tagsList = [];
$(function () { $(function () {
$.ajax({ $.ajax({
@ -176,12 +212,16 @@ $(function () {
} }
}); });
$('#postTags').tagsinput(); // $('#postTags').tagsinput();
//
$('#postTags').tagsinput({ $('#postTags').tagsinput({
// itemText: 'display_name',
typeaheadjs: { typeaheadjs: {
name: 'blogposttags', source: ['Test', 'Value'],
source: substringMatcher(tagsList) name: 'existingTags',
// displayKey: 'display_name',
// source: existingTags.ttAdapter()
// source: substringMatcher(['Hallo', 'test', 'Hund'])
} }
}); });
@ -219,9 +259,9 @@ $(function () {
}); });
}); });
Number.prototype.pad = function(size) { Number.prototype.pad = function (size) {
let s = String(this); let s = String(this);
while(s.length < (size || 2)) s = "0" + s; while (s.length < (size || 2)) s = "0" + s;
return s; return s;
}; };
@ -455,16 +495,61 @@ function publishPost() {
}) })
} }
$('#blogPostSave').on('click', () => { $('#blogPostSave').click(() => {
$(this).button('loading'); $(this).button('loading');
sendPost(); sendPost();
}); });
$('#blogSubmit').on('click', function () { $('#blogSubmit').click(() => {
$(this).button('loading'); $(this).button('loading');
sendPost(publishPost); sendPost(publishPost);
}); });
$('#blogPreview').click(() => openPreview());
let timeoutPreview;
$('body').keyup(() => {
if (timeoutPreview)
clearTimeout(timeoutPreview);
timeoutPreview = setTimeout(() => {
if (previewWindow)
openPreview();
}, 1000);
});
let previewID;
let previewWindow;
function openPreview() {
const data = {
postTitle: $('#postTitle').text(),
postDesc: $('#postDescription').text(),
// postContent: $('.ql-editor').html(),
postContent: tinymce.get('postContent').getContent(),
};
if (previewID)
data.previewID = previewID;
$.ajax({
url: '/admin/blog/updatePreview',
data: data,
method: 'POST',
success: (data) => {
if (data.success) {
previewID = data.previewID;
console.log(data.session);
if (!previewWindow) {
previewWindow = window.open('http://192.168.178.39/admin/blog/preview?id=' + previewID, '_BLANK');
} else {
previewWindow.location.reload();
previewWindow.opener.focus();
}
}
}
});
}
// Upload Header Image // Upload Header Image
$('.upload-btn').on('change', '.upload-image', function () { $('.upload-btn').on('change', '.upload-image', function () {
$('.upload-btn').fadeOut(); $('.upload-btn').fadeOut();
@ -512,9 +597,9 @@ $('.upload-btn').on('change', '.upload-image', function () {
reader.readAsDataURL(file); reader.readAsDataURL(file);
}); });
var substringMatcher = function (strs) { function substringMatcher(strs) {
return function findMatches(q, cb) { return function findMatches(q, cb) {
var matches, substringRegex; let matches, substrRegex;
// an array that will be populated with substring matches // an array that will be populated with substring matches
matches = []; matches = [];
@ -522,16 +607,17 @@ var substringMatcher = function (strs) {
// regex used to determine if a string contains the substring `q` // regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i'); substrRegex = new RegExp(q, 'i');
console.log('ich bin auc hdavbei #.');
// iterate through the pool of strings and for any string that // iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array // contains the substring `q`, add it to the `matches` array
$.each(strs, function (i, str) { $.each(strs, function (i, str) {
if (substrRegex.test(str)) { if (substrRegex.test(str)) {
console.log(str);
matches.push(str); matches.push(str);
} }
}); });
cb(matches); cb(matches);
}; };
}; }