summaryrefslogtreecommitdiff
path: root/public/assets
diff options
context:
space:
mode:
authorGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-04-24 04:36:57 +0300
committerGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-04-24 04:36:57 +0300
commit17d243371c43847e9dbdeb21395afc0e8f5437ae (patch)
tree7dfe75fe664826f2b1575d13f09e75a500b605fb /public/assets
parent74f1c04022328280b996dde0b7089e13d96acf70 (diff)
downloadclassroom-17d243371c43847e9dbdeb21395afc0e8f5437ae.tar.gz
classroom-17d243371c43847e9dbdeb21395afc0e8f5437ae.tar.bz2
classroom-17d243371c43847e9dbdeb21395afc0e8f5437ae.zip
edit lesson: putting all together; media with privile level
Diffstat (limited to 'public/assets')
-rw-r--r--public/assets/css/class.css1
-rw-r--r--public/assets/css/overides.css20
-rw-r--r--public/assets/js/admin/edit_lesson.js198
-rw-r--r--public/assets/js/admin/files.js264
-rw-r--r--public/assets/js/admin/panel.js1
5 files changed, 357 insertions, 127 deletions
diff --git a/public/assets/css/class.css b/public/assets/css/class.css
index 598f441..e87861a 100644
--- a/public/assets/css/class.css
+++ b/public/assets/css/class.css
@@ -345,6 +345,7 @@
color: var(--class-btn-blue);
border-bottom: 3px solid var(--class-blue);
padding: 0 8px;
+ text-align: revert-layer;
}
.classroom .article-body table tbody td {
padding: 6px 8px;
diff --git a/public/assets/css/overides.css b/public/assets/css/overides.css
index 568164b..e3d5e1b 100644
--- a/public/assets/css/overides.css
+++ b/public/assets/css/overides.css
@@ -109,3 +109,23 @@ ul.select2-results__options li { font-size: 14px; padding: 4px 8px; }
.admin-container .edit-post textarea[name=intro] { height: 94px ;} /* almost 3 (half-)lines */
+.admin-container .edit-post .post-media button.over-bar { margin: -26px 0 0 0; float: right; }
+.admin-container .edit-post .post-media ul {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ padding: 6px;
+}
+
+.admin-container .edit-post .post-media ul li {
+ border-bottom: 1px solid #ddd;
+ list-style-type: none;
+ padding: 3px 6px;
+
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+.admin-container .edit-post .post-media ul li:last-child { border-bottom: none ;}
+.admin-container .edit-post .post-media ul li:hover { background: #eee; }
+
+.edit-post .post-media li .btn-xs { font-size: 14px; width: 24px; height: 24px; padding:0; } \ No newline at end of file
diff --git a/public/assets/js/admin/edit_lesson.js b/public/assets/js/admin/edit_lesson.js
index ba31470..c5b0501 100644
--- a/public/assets/js/admin/edit_lesson.js
+++ b/public/assets/js/admin/edit_lesson.js
@@ -25,7 +25,6 @@ var files = []; // array of { id:.., title:.., type:.., path:.. } records
const files_root = '/media/'; // files root firectory
-var pageUrl = new URL(window.location.href);
// an alternative--id when a lesson_id not exists (needed for file-upload)
// ... consist of a 6-digit date string + random number up to 999
@@ -89,22 +88,9 @@ const upload_file_form = () => {
'<input type="text" class="form-control " value="" name="title" id="title" placeholder="Τίτλος για το Αρχείο" required="">',
'</div>',
- '<div class="row">',
-
- '<div class="col-7"><div class="form-group">',
- '<label class="control-label" for="file">Εισαγωγή Αρχείου</label>',
- '<input class="form-control" type="file" id="file" name="file" required="">',
- '</div></div>',
-
- '<div class="col-5"><div class="form-group">',
- '<label class="control-label" for="category_id">Είδος</label>',
- '<select class="form-control form-select" id="reference" name="reference" required="">',
- '<option"></option>',
- '<option value="1">Παραπομπή (εμφανίζεται)</option>',
- '<option value="0">Βοηθητικό αρχείο (κρυφό)</option>',
- '</select>',
- '</div></div>',
-
+ '<div class="form-group">',
+ '<label class="control-label" for="file">Εισαγωγή Αρχείου</label>',
+ '<input class="form-control" type="file" id="file" name="file" required="">',
'</div>',
'</div>',
@@ -172,6 +158,13 @@ $(document).ready(function() {
width: '100%'
});
+ // inti category (select2)
+ // ...
+ $("#privilege_id").select2({
+ placeholder: 'Επίπεδο Πρόσβασης',
+ width: '100%'
+ });
+
// // init tags (select2)
// // ...
@@ -200,33 +193,25 @@ $(document).ready(function() {
*/
if (id) { // if an `id` is given, load post .. then init_form
- $.getJSON( "/admin/api/", { action: "get_post", id: id } )
+ $.getJSON( "/admin/api/lesson/" + id )
.done( function (data) {
- post = data; // keep post
+ lesson = data; // keep post
// update fields' values
- $('input[name=id]').val(post.id); // id
- $('input[name=title]').val(post.title); // title
- $('textarea[name=intro]').val(post.intro); // intro
- $('textarea[name=body]').val(post.body); // body
+ $('input[name=id]').val(lesson.id); // id
+ $('input[name=title]').val(lesson.title); // title
+ $('textarea[name=intro]').val(lesson.intro); // intro
+ $('textarea[name=body]').val(lesson.body); // body
$('input[name=status]').prop( // status
'checked',
- ((post.status==1)? true : false))
+ ((lesson.status==1)? true : false))
.trigger('change');
- $('#post-info').html('Δημιουργία: '+post.creation_date+'<br>Τελευταία Ενημέρωση: '+ post.update_date);
-
- $('#delete').prop( "disabled", false ); // enable delete button
-
- // if intro exist, show intro (optinal) field
- if ((post.intro != null) && (post.intro != '')) {
- $('.optional label[for=intro]').addClass('show'); // unhide section
- }
+ // $('#post-info').html('Δημιουργία: '+post.creation_date+'<br>Τελευταία Ενημέρωση: '+ post.update_date);
// parse media files; then draw
- if (post.medias_json != null) {
- files = JSON.parse(post.medias_json);
- $('.optional label[for=media]').addClass('show'); // unhide section
+ if (lesson.medias_json != null) {
+ files = JSON.parse(lesson.medias_json);
}
draw_files_list(); // then draw the files list
@@ -234,7 +219,6 @@ $(document).ready(function() {
});
} else { // else ... just init_form
- $('#delete').prop( "disabled", true ); // disable delete button for new post attempt
init_form_values();
}
@@ -265,15 +249,15 @@ $(document).ready(function() {
});
categories.sort( compare_label ); // sort categories by breadcrumb
- // // construct tags data
- // // ---
- // Object.keys(tags_response[0]).forEach( key => {
- // tag = tags_response[0][key];
- // tags.push({
- // id: tag.id,
- // label: tag.name
- // });
- // });
+ // construct tags data
+ // ---
+ /// Object.keys(tags_response[0]).forEach( key => {
+ /// tag = tags_response[0][key];
+ /// tags.push({
+ /// id: tag.id,
+ /// label: tag.name
+ /// });
+ /// });
// construct provileges data
// ---
@@ -294,20 +278,20 @@ $(document).ready(function() {
} else {
// setup category_id options; select post's chosen category-id
- set_parent_options( $('#category_id'), categories, post.category_id );
+ set_parent_options( $('#course_id'), categories, lesson.course_id );
// parse selected tags
// ---
- var selected_tag_ids = [];
- if (post.tags_json != null) {
- var selected_tags = JSON.parse(post.tags_json);
- selected_tags.forEach( itag => { selected_tag_ids.push(itag.id); })
- }
+ /// var selected_tag_ids = [];
+ /// if (post.tags_json != null) {
+ /// var selected_tags = JSON.parse(post.tags_json);
+ /// selected_tags.forEach( itag => { selected_tag_ids.push(itag.id); })
+ /// }
// setup tags options; select post's chosen tags
- set_parent_options( $('#tags'), tags, selected_tag_ids );
+ set_parent_options( $('#privilege_id'), privileges, lesson.privilege_id );
// ALSO: if tags selectd, show tags field
- if (selected_tag_ids.length != 0) { $('.optional label[for=tags]').addClass('show'); }
+ // if (selected_tag_ids.length != 0) { $('.optional label[for=tags]').addClass('show'); }
}
});
@@ -347,28 +331,15 @@ $(document).ready(function() {
var ref_icon, ref_class;
files.forEach( item => {
- // preapre [show|hide]-file as reference
- if (item.reference == 1) {
- ref_icon = '<i class="fas fa-eye"></i>';
- ref_class = 'btn-default';
-
- } else {
- ref_icon = '<i class="fas fa-eye-slash"></i>';
- ref_class = 'btn-disabled';
- }
-
var copy = [ // copy button
'<button type="button" class="btn btn-xs btn-default js-copy"',
- 'data-url="' + item.path + '">',
+ ' data-url="' + item.path +'"',
+ ' data-type="' + item.type + '"',
+ '>',
'<i class="far fa-clone"></i>',
'</button>'
].join('');
- var ref = [ // show|hide (is_reference)
- '<button type="button" class="btn btn-xs '+ ref_class +' js-reference"',
- 'data-id="' + item.id + '">',
- ref_icon,
- '</button>'
- ].join('');
+
var del = [ // delete button
'<button type="button" class="btn btn-xs btn-danger js-delete"',
'data-id="' + item.id + '">',
@@ -377,9 +348,9 @@ $(document).ready(function() {
].join('');
var option = [ // li html
'<li>',
- '<div class="text">' + item.title + '</div>',
+ '<div class="text">' + item.label + '</div>',
'<div class="actions">',
- ref, ' ', copy, ' ', del,
+ copy, ' ', del,
'</div>',
'</li>'
].join('');
@@ -400,20 +371,20 @@ $(document).ready(function() {
$('.edit-post form').submit( event => {
event.preventDefault();
- // rearrange tags to old and new ones
- // ---
- var old_tags = [];
- var new_tags = [];
- var tags = $('#tags').select2('data');
- tags.forEach( t => {
- if (!parseInt(t.id)) {
- new_tags.push(t.text);
- } else { old_tags.push(t.id); }
- })
+ // // rearrange tags to old and new ones
+ // // ---
+ // var old_tags = [];
+ // var new_tags = [];
+ // var tags = $('#tags').select2('data');
+ // tags.forEach( t => {
+ // if (!parseInt(t.id)) {
+ // new_tags.push(t.text);
+ // } else { old_tags.push(t.id); }
+ // })
var attachments = [];
// attachments (array) of "`media_id`;`reference`" strings
- files.forEach( f => { attachments.push( f.id +';'+ f.reference ) });
+ files.forEach( f => { attachments.push( f.id ) });
// prepare data to POST
// ---
@@ -423,7 +394,7 @@ $(document).ready(function() {
course_id: parseInt($('#course_id').select2('data')[0].id),
intro: $('.edit-post form textarea[name=intro]').val(),
body: $('.edit-post form textarea[name=body]').val(),
- status: (($('input[name=status]').is(":checked")) ? 1 : 0),
+ status: ( ($('select[name=status]').val() == "0") ? 0 : 1 ),
privilege_id: parseInt($('#privilege_id').select2('data')[0].id),
// tags: old_tags,
// new_tags: new_tags,
@@ -432,65 +403,38 @@ $(document).ready(function() {
// select action url (add or update)
// ---
- var request = '/wiki/ajax?action=' + ((data.id == 0) ? 'add_post' : 'update_post');
+ var request = '/admin/api/lesson/' + ((data.id == 0) ? 'add' : 'update');
// send POST (ajax) request
$.post(request, data)
.done(function( data ) {
- window.location.href = '/wiki/admin?action=posts'; // seems ok; bach to articles
+ console.log(data);
+ //window.location.href = '/admin/lessons'; // seems ok; bach to articles
});
});
- // go-back (to posts)
+ // go-back (to lessons)
// --- -- -- - - -
$('#go-back').click( event => {
- window.location.href = '/wiki/admin?action=posts';
- });
-
-
- // delete
- // --- -- -- - - -
- $('#delete').click( event => {
- // ask before deletion
- swal({
- title: 'Είστε βέβαιος;',
- html: "Ζητήσατε να διαγραφεί το άρθρο.<br>Παρακαλώ επιβεβαιώστε την διαγραφή.<br>ΠΡΟΣΟΧΗ: Δεν θα έχετε την δυνατότητα αναίρεσης!",
- type: 'warning',
- showCancelButton: true,
- confirmButtonColor: '#3085d6',
- cancelButtonColor: '#d33',
- cancelButtonText: 'Ακύρωση',
- confirmButtonText: 'Ναι, να διαγραφεί',
- showLoaderOnConfirm: true,
- preConfirm: function() {
- return new Promise(function(resolve) {
- $.getJSON( "/wiki/ajax", { action: "delete_post", id: id } )
- .done( function (data) {
- // return to posts-administration
- window.location.href = '/wiki/admin?action=posts';
- });
- });
- },
- allowOutsideClick: false
- }).catch(swal.noop);
-
+ if (confirm('Θέλετε να ακυρώσετε τις όποιες αλλαγές και να φύγτε από τη σελίδα;')) {
+ window.location.href = '/admin/lessons';
+ }
});
-
// copy url button
// --- -- -- - - -
- $('.wiki').on('click', 'button.js-copy', function (e) {
+ $('.admin-container').on('click', 'button.js-copy', function (e) {
var copytext = ''; // default: copy nothing
if ($(this).data('id') !== undefined) {
- copytext = pageUrl.origin +'/wiki/post?id=' + $(this).data('id');
+ copytext = window.location.origin +'/lesson/' + $(this).data('id');
}
if ($(this).data('url') !== undefined) {
- copytext = files_root + $(this).data('url');
+ copytext = window.location.origin + '/serve/file/' + $(this).data('url') + '?type=' + $(this).data('type');
}
navigator.clipboard
@@ -498,6 +442,7 @@ $(document).ready(function() {
.then(() => { // notify the copy event
$(this).addClass('copied');
setTimeout( () => { $(this).removeClass('copied'); }, 700);
+ console.log(copytext, ' copied!');
})
.catch(() => {
console.log("error on coping text");
@@ -508,7 +453,8 @@ $(document).ready(function() {
// delete (remove) file button
// --- -- -- - - -
- $('.wiki').on('click', 'button.js-delete', function (e) {
+ $('.admin-container').on('click', 'button.js-delete', function (e) {
+ console.log('delete!');
var media_id = $(this).data('id');
// remove from files array the one with id == media_id
@@ -521,12 +467,11 @@ $(document).ready(function() {
});
-
-
+
// show|hide file as referece button
// --- -- -- - - -
- $('.wiki').on('click', 'button.js-reference', function (e) {
+ $('.admin-container').on('click', 'button.js-reference', function (e) {
var id = $(this).data('id');
// toggle reference attribute of item with `id` = id
@@ -608,8 +553,7 @@ $(document).ready(function() {
id: response.id,
title: response.title,
path: response.path,
- type: response.type,
- reference: $('#reference').val()
+ type: response.type
});
draw_files_list();
diff --git a/public/assets/js/admin/files.js b/public/assets/js/admin/files.js
new file mode 100644
index 0000000..bfb0c73
--- /dev/null
+++ b/public/assets/js/admin/files.js
@@ -0,0 +1,264 @@
+// Globals
+// -----------------------------------------------------------------------------
+var privileges = [];
+var files = [];
+var table;
+
+
+
+// Supplamentary functions
+// -----------------------------------------------------------------------------
+
+// array.indexOf polyfill
+// --- -- -- - - -
+if (!Array.prototype.indexOf)
+{
+ Array.prototype.indexOf = function(elt /*, from*/)
+ {
+ var len = this.length >>> 0;
+
+ var from = Number(arguments[1]) || 0;
+ from = (from < 0)
+ ? Math.ceil(from)
+ : Math.floor(from);
+ if (from < 0)
+ from += len;
+
+ for (; from < len; from++)
+ {
+ if (from in this &&
+ this[from] === elt)
+ return from;
+ }
+ return -1;
+ };
+}
+
+// return file record by file-id
+// --- -- -- - - -
+function privilege_record(id) {
+ var record = 0;
+ files.forEach(el => { if (el.id == id) record = el; });
+
+ return record;
+}
+
+
+// create actions html (edit and delete buttons)
+// --- -- -- - - -
+function create_actions_html(id) {
+
+ var del, edit;
+
+ del = "";
+
+ edit = [
+ '<button type="button" class="btn btn-sm btn-warning"',
+ 'data-bs-toggle="modal" data-bs-target="#manageFiles"',
+ 'data-id="'+ id +'">',
+ '<i class="fas fa-pencil-alt"></i>',
+ '</button>'
+ ].join('\n');
+
+ return edit +' '+ del;
+}
+
+
+
+$(document).ready(function() {
+
+ // When document is ready
+ // -------------------------------------------------------------------------
+
+
+ /** init selec2 element (used to specify parent-category)
+ * --- -- -- - - -
+ */
+ $("#privilege_id").select2({
+ placeholder: 'Επίπεδο πρόσβασης',
+ dropdownParent: $('#manageFiles'),
+ width: '100%',
+ });
+
+
+ /** init_table
+ * --- -- -- - - -
+ * get categories
+ * constuct categories array
+ * render dataTable
+ */
+ function init_table() {
+
+ // get all categories from server (ajax)
+ $.getJSON( "/admin/api/files")
+ .done(function( json ) {
+ // then ...
+
+ // reset categories
+ files.length = 0;
+
+ // construct (new) categories data
+ Object.keys(json).forEach( key => {
+ el = json[key];
+ files.push({
+ id: el.id,
+ label: el.label,
+ path: el.path,
+ type: el.type,
+ privilege_id: ((el.privilege_id == null) ? 0 : el.privilege_id),
+ actions: create_actions_html(el.id)
+ });
+ });
+
+ // sort by breadcrumb
+ // categories.sort( compare_breadcrumb );
+
+ // destroy previous datatable table instances
+ $('#dt-files').dataTable().fnClearTable();
+ $('#dt-files').dataTable().fnDestroy();
+
+ // (re-)create categories datatable
+ table = $('#dt-files').DataTable({
+ language: { url: '/libs/DataTables/localization/Greek.json' },
+ data: files,
+ ordering: false,
+ columns: [
+ { data: 'id' },
+ { data: 'label' },
+ { data: 'path' },
+ { data: 'type' },
+ { data: 'privilege_id' },
+ { data: 'actions' }
+ ]
+ });
+
+ })
+ .fail(function( jqxhr, textStatus, error ) {
+ console.log( "Request Failed (" + error +")" );
+ });
+
+ }
+ init_table(); // init table on first run
+
+
+
+ /** When modal show-up
+ * -------------------------------------------------------------------------
+ * ... prepare the manage-category form
+ * ... update select2 with possible parents
+ */
+ $('#managePrivileges').on('show.bs.modal', event => {
+ var button = $(event.relatedTarget); // Button that triggered the modal
+ var id = parseInt( button.data('id') ); // category_id from data-id
+ // var modal = $(this); // modal object
+
+ // update modal literature
+ // ---
+ $('#managePrivileges .modal-title').html( // modal title
+ (id) ? 'Ενημέρωση Επιπέδου Πρόσβασης' : 'Δημιουργία Επιπέδου Πρόσβασης'
+ );
+ $('#managePrivileges form input[name=id]').val( id ); // category id (hidden)
+ $('#managePrivileges form input[name=label]').val( // category label
+ (id) ? privilege_record(id).label : ""
+ );
+ prepare_included_element(id); // prepare <select> for parents
+ })
+
+ /** prepare_included_element()
+ * ---
+ * @param id (int) : id of selected privilege
+ * -> Get all posible included privileges
+ * -> call set_included_options() to render the options
+ */
+ function prepare_included_element(id) {
+ var may_included = [];
+
+ if (id) { // get all possible parents
+
+ // TODO:
+ // specify forbiden privilege IDs for being included
+
+ // filter privileges adn prepare possible included privileges
+ privileges.forEach( el => {
+ if (id != el.id) {
+ may_included.push({
+ id: el.id,
+ label: el.label
+ });
+ }
+ });
+ console.log(may_included);
+ set_included_options(may_included, privilege_record(id).included_id);
+
+
+ } else { // new record; all categories are possible parrents
+ privileges.forEach( el => {
+ may_included.push({
+ id: el.id,
+ label: el.label,
+ });
+ })
+ set_included_options(may_included, -1);
+ }
+ }
+
+ /** set_included_options()
+ * -> create options for parents <select>
+ * -> choose selected parent
+ * @param may_included (array): array of possible included privileges
+ * @param selected (int): selected included privilege
+ */
+ function set_included_options(may_included, selected) {
+ // sort parents by breadcrumb
+ // parents.sort( compare_breadcrumb );
+
+ // remove any olded options from select2
+ $('#included_id option').each(function() { $(this).remove(); });
+
+ // first option is the root category
+ $('#included_id').append('<option value="0">— κανένα —</option>')
+
+ // add all other parent options
+ may_included.forEach( i => {
+ $('#included_id').append(`<option value="${i.id}">${i.label}</option>`);
+ });
+
+ if (selected == -1) { // new category; remove any parent pre-selection
+ $('#included_id').val(0).trigger('change');
+
+ } else { // category exists; choose selected parent
+ $('#included_id').val(selected).trigger('change');
+ }
+ }
+
+
+
+
+ // When form is submited
+ // -------------------------------------------------------------------------
+
+ $('#manageCategory form').submit( event => {
+ event.preventDefault();
+
+ // prepare data to POST
+ var data = {
+ id: parseInt($('#manageCategory form input[name=id]').val()),
+ label: $('#manageCategory form input[name=label]').val(),
+ parent_id: parseInt($('#parent_id').select2('data')[0].id)
+ };
+
+ // select action url (add or update)
+ var request = '/admin/api/category/' + ((data.id == 0) ? 'add' : 'update');
+
+ // send POST request
+ $.post(request, data)
+ .done(function( data ) {
+
+ $('#manageCategory').modal('hide'); // when done, close modal
+
+ init_table(); // reload table of categories
+ });
+
+ });
+
+});
diff --git a/public/assets/js/admin/panel.js b/public/assets/js/admin/panel.js
new file mode 100644
index 0000000..24b465e
--- /dev/null
+++ b/public/assets/js/admin/panel.js
@@ -0,0 +1 @@
+console.log('Admin Panel!'); \ No newline at end of file