explorer move & add ok
This commit is contained in:
parent
3aff1b4c1f
commit
001ce36336
File diff suppressed because one or more lines are too long
Binary file not shown.
|
Before Width: | Height: | Size: 300 B After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 364 B After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 220 B After Width: | Height: | Size: 1.5 KiB |
@ -15,7 +15,7 @@ const hideDropdowns = function () {
|
||||
};
|
||||
|
||||
jQuery(document).ready(function ($) {
|
||||
$('.dropdown .trigger').on('click', function(event) {
|
||||
$('.dropdown .trigger').on('click', function (event) {
|
||||
event.stopPropagation();
|
||||
var $dropdown = $(this).closest('.dropdown');
|
||||
var $menu = $dropdown.find('ul.dropdown-menu');
|
||||
@ -23,7 +23,7 @@ jQuery(document).ready(function ($) {
|
||||
$('.dropdown').not($dropdown).removeClass('dropdown-show');
|
||||
$dropdown.toggleClass('dropdown-show');
|
||||
|
||||
// Adjust dropdown position to prevent overflow
|
||||
// Adjust dropdown position to prevent overflow
|
||||
var triggerHeight = $(this).outerHeight() + 20;
|
||||
var triggerOffset = $(this).offset();
|
||||
var menuWidth = $menu.outerWidth();
|
||||
@ -52,11 +52,11 @@ jQuery(document).ready(function ($) {
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', function() {
|
||||
$(document).on('click', function () {
|
||||
$('.dropdown').removeClass('dropdown-show');
|
||||
});
|
||||
|
||||
$(window).on('resize', function() {
|
||||
$(window).on('resize', function () {
|
||||
$('.dropdown.dropdown-show .trigger').trigger('click');
|
||||
});
|
||||
|
||||
@ -71,7 +71,8 @@ jQuery(document).ready(function ($) {
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', '.protected', function(e) {
|
||||
// Link protection
|
||||
$(document).on('click', '.protected', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
@ -88,6 +89,7 @@ jQuery(document).ready(function ($) {
|
||||
return false;
|
||||
});
|
||||
|
||||
// Datetime and owner tracking
|
||||
$(document).on('click', '.item-utrack', function () {
|
||||
const entity = JSON.parse($(this).parents('tr:eq(0)').attr('data-entity'));
|
||||
showModal('modal-entity-utrack');
|
||||
@ -97,4 +99,32 @@ jQuery(document).ready(function ($) {
|
||||
$('#entity-utrack-updated-at').val(prettyTimestamp(entity.updated_at * 1000));
|
||||
});
|
||||
|
||||
|
||||
// Explorer item selection
|
||||
$(document).on('click', 'a.explr-link', function (event) {
|
||||
event.preventDefault();
|
||||
$('a.explr-link').removeClass('highlight-clicked');
|
||||
$('a.explr-link').parent().removeClass('highlight-clicked');
|
||||
$(this).addClass('highlight-clicked');
|
||||
$(this).parent().addClass('highlight-clicked');
|
||||
$('body').addClass('explr-selection');
|
||||
});
|
||||
$(document).on('dblclick', 'a.explr-link', function (event) {
|
||||
event.preventDefault();
|
||||
$(this).off('click');
|
||||
if ($(this).attr('target') === '_blank') {
|
||||
window.open($(this).attr('href'));
|
||||
} else {
|
||||
window.location.href = $(this).attr('href');
|
||||
}
|
||||
});
|
||||
$(document).on('click', function (event) {
|
||||
const $parentClickable = $(event.target).parents('a, button');
|
||||
if ($parentClickable.length === 0) {
|
||||
$('a.explr-link').removeClass('highlight-clicked');
|
||||
$('a.explr-link').parent().removeClass('highlight-clicked');
|
||||
$('body').removeClass('explr-selection');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
19070
data/www/js/lib/jquery-ui.min.js
vendored
Normal file
19070
data/www/js/lib/jquery-ui.min.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -29,18 +29,63 @@ jQuery(document).ready(function ($) {
|
||||
;
|
||||
};
|
||||
|
||||
const main = function () {
|
||||
const a= $('.explr').explr({
|
||||
const initExplr = function () {
|
||||
$('.explr').explr({
|
||||
classesPlus: 'fa fa-plus',
|
||||
classesMinus: 'fa fa-minus',
|
||||
onLoadFinish: function($tree) {
|
||||
onLoadFinish: function ($tree) {
|
||||
$tree.removeClass('hidden');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const initDrags = function () {
|
||||
$(".draggable").draggable({
|
||||
revert: "invalid",
|
||||
});
|
||||
$(".droppable").droppable({
|
||||
accept: ".draggable",
|
||||
over: function (event, ui) {
|
||||
$(this).addClass("highlight-drop");
|
||||
},
|
||||
out: function (event, ui) {
|
||||
$(this).removeClass("highlight-drop");
|
||||
},
|
||||
drop: function (event, ui) {
|
||||
$(this).removeClass("highlight-drop");
|
||||
const $form = $('#folder-move-form');
|
||||
const $moved = ui.draggable;
|
||||
const $target = $(this);
|
||||
$form.find('[name=is_folder]').val($moved.attr('data-folder'))
|
||||
$form.find('[name=entity_id]').val($moved.attr('data-id'))
|
||||
$form.find('[name=new_folder_id]').val($target.attr('data-id'))
|
||||
ui.draggable.position({
|
||||
my: "center",
|
||||
at: "center",
|
||||
of: $(this),
|
||||
using: function (pos) {
|
||||
$(this).animate(pos, 50);
|
||||
}
|
||||
});
|
||||
$form.submit();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const main = function () {
|
||||
initExplr();
|
||||
initDrags();
|
||||
};
|
||||
|
||||
$(document).on('change', '#content-add-type', inputTypeUpdate);
|
||||
|
||||
$(document).on('click', '.folder-add', function () {
|
||||
$('.dirview .new-folder').removeClass('hidden');
|
||||
$('.page-content').animate({scrollTop: 0}, 0);
|
||||
$('.dirview input').focus();
|
||||
});
|
||||
|
||||
|
||||
$(document).on('click', '.content-add', function () {
|
||||
showModal('modal-content-add');
|
||||
inputTypeUpdate();
|
||||
|
||||
@ -1,36 +1,105 @@
|
||||
.left-panel {
|
||||
flex: 0.5;
|
||||
overflow-y: auto;
|
||||
padding: 0;
|
||||
background: $layoutBackground;
|
||||
box-shadow: 1px 1px .5px .5px inset rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid #222;
|
||||
max-width: 250px;
|
||||
ul.explr-tree {
|
||||
height: 100% !important;
|
||||
|
||||
ul.explr-tree {
|
||||
height: 100% !important;
|
||||
li {
|
||||
span {
|
||||
color: #AAA;
|
||||
font-size: 17px;
|
||||
padding-left: 1px;
|
||||
}
|
||||
|
||||
li {
|
||||
span {
|
||||
color: #AAA;
|
||||
font-size: 17px;
|
||||
padding-left: 1px;
|
||||
a {
|
||||
color: white;
|
||||
padding-right: 80px;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
padding-right: 80px;
|
||||
|
||||
&.active {
|
||||
background: rgba(255,255,255,.1);
|
||||
border-radius: $baseRadius;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
margin-left: 35px;
|
||||
padding-left: 5px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
&.active {
|
||||
background: rgba(255, 255, 255, .1);
|
||||
border-radius: $baseRadius;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
margin-left: 35px;
|
||||
padding-left: 5px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul.explr-dirview {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin: 18px;
|
||||
min-width: 90px;
|
||||
min-height: 104px;
|
||||
padding-top: 5px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: $baseRadius;
|
||||
|
||||
&.new-folder {
|
||||
a {
|
||||
color: $seaBlue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.highlight-drop {
|
||||
border: 1px dashed rgba($white, .2);
|
||||
background: rgba($white, .1);
|
||||
}
|
||||
|
||||
&.highlight-clicked {
|
||||
border: 1px dashed rgba($seaBlue, .4);
|
||||
background: rgba($seaBlue, .3);
|
||||
}
|
||||
|
||||
a {
|
||||
color: #BBB;
|
||||
text-decoration: none;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
max-width: 84px;
|
||||
|
||||
i {
|
||||
font-size: 64px;
|
||||
margin-bottom: 12px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ui-draggable-dragging {
|
||||
z-index: 20;
|
||||
a {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
// Import utility styles
|
||||
@import 'utils/variables';
|
||||
@import 'utils/mixins';
|
||||
@import 'utils/variables';
|
||||
|
||||
// Import base styles
|
||||
@import 'base/fonts';
|
||||
|
||||
@ -1,50 +1,25 @@
|
||||
|
||||
.view-content-list main .main-container {
|
||||
|
||||
.left-panel {
|
||||
flex: 0.5;
|
||||
overflow-y: auto;
|
||||
padding: 0;
|
||||
background: $layoutBackground;
|
||||
box-shadow: 1px 1px .5px .5px inset rgba(0, 0, 0, 0.2);
|
||||
border: 1px solid #222;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-start;
|
||||
background: rgba(0,0,0,.9);
|
||||
|
||||
.dirview {
|
||||
padding: 0 10px 40px 10px;
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin: 18px;
|
||||
|
||||
a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
font-size: 64px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #DDD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,4 +28,18 @@
|
||||
|
||||
@mixin pixel-box($pixelOffset: 1) {
|
||||
box-shadow: #{$pixelOffset}px 0 0 #fff, 0 #{$pixelOffset}px 0 $limeGreen, -#{$pixelOffset}px 0 0 $seaBlue, 0 -#{$pixelOffset}px 0 $pinkyRed;
|
||||
}
|
||||
|
||||
@mixin generate-color-classes($color-map) {
|
||||
@each $name, $color in $color-map {
|
||||
.#{"#{$name}"} {
|
||||
color: $color;
|
||||
}
|
||||
.bg-#{"#{$name}"} {
|
||||
background-color: $color;
|
||||
}
|
||||
.border-#{"#{$name}"} {
|
||||
border-color: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,15 +12,27 @@ $neutralGrey: rgb(70, 70, 70);
|
||||
$lightGrey: rgb(153, 153, 153);
|
||||
$white: rgb(255, 255, 255);
|
||||
$black: rgb(0, 0, 0);
|
||||
$youtube: rgb(253, 60, 1);
|
||||
|
||||
// Type Colors
|
||||
$info: $seaBlue;
|
||||
$success: $limeGreen;
|
||||
$danger: $pinkyRed;
|
||||
|
||||
$primary: $seaBlue;
|
||||
|
||||
// Common styles
|
||||
$baseRadius: 4px;
|
||||
|
||||
$layoutBorder: 1px solid #222;
|
||||
$layoutBackground: #111;
|
||||
|
||||
// Packs
|
||||
$colors: (
|
||||
info: $info,
|
||||
success: $success,
|
||||
danger: $danger,
|
||||
purple: $sweetPurple,
|
||||
youtube: $youtube,
|
||||
);
|
||||
|
||||
// Classes
|
||||
@include generate-color-classes($colors);
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
"js_slideshow_slide_delete_confirmation": "Are you sure?",
|
||||
|
||||
"slideshow_content_page_title": "Content Library",
|
||||
"slideshow_content_button_add": "Add a content",
|
||||
"slideshow_content_button_add": "New Content",
|
||||
"slideshow_content_panel_active": "Content",
|
||||
"slideshow_content_panel_empty": "Currently, there are no content. %link% now.",
|
||||
"slideshow_content_panel_th_name": "Name",
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
"js_slideshow_slide_delete_confirmation": "¿Estás seguro?",
|
||||
|
||||
"slideshow_content_page_title": "Biblioteca de contenidos",
|
||||
"slideshow_content_button_add": "Agregar un contenido",
|
||||
"slideshow_content_button_add": "Nuevo Contenido",
|
||||
"slideshow_content_panel_active": "Contenido",
|
||||
"slideshow_content_panel_empty": "Actualmente, no hay contenido. %link% ahora.",
|
||||
"slideshow_content_panel_th_name": "Nombre",
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
"js_slideshow_slide_delete_confirmation": "Êtes-vous sûr ?",
|
||||
|
||||
"slideshow_content_page_title": "Bibliothèque de contenus",
|
||||
"slideshow_content_button_add": "Ajouter un contenu",
|
||||
"slideshow_content_button_add": "Nouveau Contenu",
|
||||
"slideshow_content_panel_active": "Contenus",
|
||||
"slideshow_content_panel_empty": "Actuellement, il n'y a aucun contenu. %link% maintenant.",
|
||||
"slideshow_content_panel_th_name": "Nom",
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
"js_slideshow_slide_delete_confirmation": "Sei sicuro?",
|
||||
|
||||
"slideshow_content_page_title": "Libreria dei contenuti",
|
||||
"slideshow_content_button_add": "Aggiungi un contenuto",
|
||||
"slideshow_content_button_add": "Nuovo Contenuto",
|
||||
"slideshow_content_panel_active": "Contenuti",
|
||||
"slideshow_content_panel_empty": "Attualmente non ci sono contenuti. %link% adesso.",
|
||||
"slideshow_content_panel_th_name": "Nome",
|
||||
|
||||
@ -6,6 +6,7 @@ from flask import Flask, render_template, redirect, request, url_for, send_from_
|
||||
from werkzeug.utils import secure_filename
|
||||
from src.service.ModelStore import ModelStore
|
||||
from src.model.entity.Content import Content
|
||||
from src.model.entity.Folder import Folder
|
||||
from src.model.enum.ContentType import ContentType
|
||||
from src.model.enum.FolderEntity import FolderEntity, FOLDER_ROOT_PATH
|
||||
from src.interface.ObController import ObController
|
||||
@ -17,6 +18,8 @@ class ContentController(ObController):
|
||||
|
||||
def register(self):
|
||||
self._app.add_url_rule('/slideshow/content', 'slideshow_content_list', self._auth(self.slideshow_content_list), methods=['GET'])
|
||||
self._app.add_url_rule('/slideshow/content/add-folder', 'slideshow_content_folder_add', self._auth(self.slideshow_content_folder_add), methods=['POST'])
|
||||
self._app.add_url_rule('/slideshow/content/move-folder', 'slideshow_content_folder_move', self._auth(self.slideshow_content_folder_move), methods=['POST'])
|
||||
self._app.add_url_rule('/slideshow/content/add', 'slideshow_content_add', self._auth(self.slideshow_content_add), methods=['POST'])
|
||||
self._app.add_url_rule('/slideshow/content/edit', 'slideshow_content_edit', self._auth(self.slideshow_content_edit), methods=['POST'])
|
||||
self._app.add_url_rule('/slideshow/content/delete', 'slideshow_content_delete', self._auth(self.slideshow_content_delete), methods=['DELETE'])
|
||||
@ -34,9 +37,27 @@ class ContentController(ObController):
|
||||
working_folder_path=working_folder_path,
|
||||
working_folder=working_folder,
|
||||
working_folder_children=self._model_store.folder().get_children(working_folder),
|
||||
enum_content_type=ContentType
|
||||
enum_content_type=ContentType,
|
||||
enum_folder_entity=FolderEntity,
|
||||
)
|
||||
|
||||
def slideshow_content_folder_add(self):
|
||||
self._model_store.folder().add_folder(
|
||||
entity=FolderEntity.CONTENT,
|
||||
name=request.form['name'],
|
||||
)
|
||||
|
||||
return redirect(url_for('slideshow_content_list'))
|
||||
|
||||
def slideshow_content_folder_move(self):
|
||||
self._model_store.folder().move_to_folder(
|
||||
entity_id=request.form['entity_id'],
|
||||
folder_id=request.form['new_folder_id'],
|
||||
entity_is_folder=True if request.form['is_folder'] == '1' else False,
|
||||
)
|
||||
|
||||
return redirect(url_for('slideshow_content_list'))
|
||||
|
||||
def slideshow_content_add(self):
|
||||
self._model_store.content().add_form_raw(
|
||||
name=request.form['name'],
|
||||
|
||||
@ -3,6 +3,7 @@ from typing import Dict, Optional, List, Tuple, Union
|
||||
from src.model.entity.Folder import Folder
|
||||
from src.model.enum.FolderEntity import FolderEntity, FOLDER_ROOT_PATH, FOLDER_ROOT_NAME
|
||||
from src.manager.DatabaseManager import DatabaseManager
|
||||
from src.manager.ContentManager import ContentManager
|
||||
from src.manager.LangManager import LangManager
|
||||
from src.manager.UserManager import UserManager
|
||||
from src.manager.VariableManager import VariableManager
|
||||
@ -10,7 +11,6 @@ from src.service.ModelManager import ModelManager
|
||||
|
||||
|
||||
class FolderManager(ModelManager):
|
||||
|
||||
TABLE_NAME = "folder"
|
||||
TABLE_MODEL = [
|
||||
"name CHAR(255)",
|
||||
@ -23,7 +23,8 @@ class FolderManager(ModelManager):
|
||||
"updated_at INTEGER"
|
||||
]
|
||||
|
||||
def __init__(self, lang_manager: LangManager, database_manager: DatabaseManager, user_manager: UserManager, variable_manager: VariableManager):
|
||||
def __init__(self, lang_manager: LangManager, database_manager: DatabaseManager, user_manager: UserManager,
|
||||
variable_manager: VariableManager):
|
||||
super().__init__(lang_manager, database_manager, user_manager, variable_manager)
|
||||
self._db = database_manager.open(self.TABLE_NAME, self.TABLE_MODEL)
|
||||
|
||||
@ -54,9 +55,10 @@ class FolderManager(ModelManager):
|
||||
|
||||
def get_one_by_path(self, path: str, entity: FolderEntity) -> Folder:
|
||||
parts = path[1:].split('/')
|
||||
return self.get_one_by("name = '{}' and depth = {} and entity = '{}'".format(parts[-1], len(parts) - 1, entity.value))
|
||||
return self.get_one_by(
|
||||
"name = '{}' and depth = {} and entity = '{}'".format(parts[-1], len(parts) - 1, entity.value))
|
||||
|
||||
def hydrate_parents(self, folder: Optional[Folder]) -> Optional[Folder]:
|
||||
def hydrate_parents(self, folder: Optional[Folder], deep=False) -> Optional[Folder]:
|
||||
if not folder:
|
||||
return None
|
||||
|
||||
@ -67,6 +69,12 @@ class FolderManager(ModelManager):
|
||||
folder.set_previous(parent)
|
||||
return self.hydrate_parents(parent)
|
||||
|
||||
def get_parent_folder(self, folder: Optional[Folder]) -> Optional[Folder]:
|
||||
if not folder or not folder.parent_id:
|
||||
return None
|
||||
|
||||
return self.get(folder.parent_id)
|
||||
|
||||
def get_one_by(self, query) -> Optional[Folder]:
|
||||
object = self._db.get_one_by_query(self.TABLE_NAME, query=query)
|
||||
|
||||
@ -110,6 +118,50 @@ class FolderManager(ModelManager):
|
||||
self._db.update_by_id(self.TABLE_NAME, id, self.pre_update({"name": name}))
|
||||
self.post_update(id)
|
||||
|
||||
def move_to_folder(self, entity_id: int, folder_id: int, entity_is_folder=False) -> None:
|
||||
folder = self.get(folder_id)
|
||||
|
||||
if not folder:
|
||||
return
|
||||
|
||||
if entity_is_folder:
|
||||
return self._db.execute_write_query(
|
||||
query="UPDATE {} set parent_id = ?, depth = ? WHERE id = ?".format(self.TABLE_NAME),
|
||||
params=(folder_id, folder.depth + 1, entity_id)
|
||||
)
|
||||
elif folder.entity == FolderEntity.CONTENT:
|
||||
return self._db.execute_write_query(
|
||||
query="UPDATE {} set folder_id = ? WHERE id = ?".format(ContentManager.TABLE_NAME),
|
||||
params=(folder_id, entity_id)
|
||||
)
|
||||
|
||||
def get_working_folder(self, entity: FolderEntity) -> str:
|
||||
var_name = None
|
||||
if entity == FolderEntity.CONTENT:
|
||||
var_name = "last_folder_content"
|
||||
|
||||
if not var_name:
|
||||
raise Error("No variable for entity {}".format(entity.value))
|
||||
|
||||
return self.variable_manager.get_one_by_name(var_name).as_string()
|
||||
|
||||
def add_folder(self, entity: FolderEntity, name: str) -> Folder:
|
||||
working_folder_path = self.get_working_folder(entity)
|
||||
working_folder = self.get_one_by_path(path=working_folder_path, entity=FolderEntity.CONTENT)
|
||||
folder_path = "{}/{}".format(working_folder_path, name)
|
||||
parts = folder_path[1:].split('/')
|
||||
depth = len(parts) - 1
|
||||
|
||||
folder = Folder(
|
||||
entity=entity,
|
||||
name=name,
|
||||
depth=depth,
|
||||
parent_id=working_folder.id if working_folder else 1
|
||||
)
|
||||
|
||||
self.add_form(folder)
|
||||
return folder
|
||||
|
||||
def add_form(self, folder: Union[Folder, Dict]) -> None:
|
||||
form = folder
|
||||
|
||||
|
||||
@ -96,7 +96,7 @@ class Folder:
|
||||
self._depth = value
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"NodePlayer(" \
|
||||
return f"Folder(" \
|
||||
f"id='{self.id}',\n" \
|
||||
f"name='{self.name}',\n" \
|
||||
f"parent_id='{self.parent_id}',\n" \
|
||||
|
||||
@ -10,7 +10,7 @@ from src.model.hook.HookRegistration import HookRegistration
|
||||
from src.model.hook.StaticHookRegistration import StaticHookRegistration
|
||||
from src.model.hook.FunctionalHookRegistration import FunctionalHookRegistration
|
||||
from src.constant.WebDirConstant import WebDirConstant
|
||||
from src.util.utils import get_safe_cron_descriptor, is_valid_cron_date_time, seconds_to_hhmmss, am_i_in_docker
|
||||
from src.util.utils import get_safe_cron_descriptor, is_valid_cron_date_time, seconds_to_hhmmss, am_i_in_docker, truncate
|
||||
|
||||
|
||||
class TemplateRenderer:
|
||||
@ -41,6 +41,7 @@ class TemplateRenderer:
|
||||
seconds_to_hhmmss=seconds_to_hhmmss,
|
||||
is_valid_cron_date_time=is_valid_cron_date_time,
|
||||
json_dumps=json.dumps,
|
||||
truncate=truncate,
|
||||
l=self._model_store.lang().map(),
|
||||
t=self._model_store.lang().translate,
|
||||
)
|
||||
|
||||
@ -240,3 +240,10 @@ def restart(debug=False) -> None:
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
|
||||
|
||||
def truncate(s, length, ellipsis=None):
|
||||
if ellipsis and len(s) > length:
|
||||
return s[:length].strip() + ellipsis
|
||||
return s[:length]
|
||||
|
||||
|
||||
|
||||
@ -13,6 +13,8 @@
|
||||
{% block add_js %}
|
||||
<script src="{{ STATIC_PREFIX }}js/lib/jquery-explr-1.4.js"></script>
|
||||
<script src="{{ STATIC_PREFIX }}js/slideshow/contents.js"></script>
|
||||
<script src="{{ STATIC_PREFIX }}js/lib/jquery-ui.min.js"></script>
|
||||
|
||||
{{ HOOK(H_SLIDESHOW_CONTENT_JAVASCRIPT) }}
|
||||
{% endblock %}
|
||||
|
||||
@ -50,12 +52,12 @@
|
||||
{% if loop.last %}
|
||||
<span>
|
||||
<i class="explr-icon explr-icon-folder"></i>
|
||||
{{ dir }}
|
||||
{{ truncate(dir, 25, '...') }}
|
||||
</span>
|
||||
{% else %}
|
||||
<a href="{{ url_for('slideshow_content_cd', path=ns.breadpath) }}">
|
||||
<i class="explr-icon explr-icon-folder"></i>
|
||||
{{ dir }}
|
||||
{{ truncate(dir, 25, '...') }}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
@ -112,16 +114,40 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
<form id="folder-move-form" action="{{ url_for('slideshow_content_folder_move') }}" class="hidden" method="POST">
|
||||
<input type="text" name="entity_id" />
|
||||
<input type="text" name="new_folder_id" />
|
||||
<input type="text" name="is_folder" />
|
||||
</form>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="dirview">
|
||||
<ul>
|
||||
{% for folder in working_folder_children %}
|
||||
<li>
|
||||
<a href="{{ url_for('slideshow_content_cd', path=working_folder_path~'/'~folder.name) }}">
|
||||
<ul class="explr-dirview">
|
||||
<li class="new-folder hidden">
|
||||
<a href="javascript:void(0);">
|
||||
<i class="fa fa-folder"></i>
|
||||
<form action="{{ url_for('slideshow_content_folder_add') }}" method="POST">
|
||||
<input type="text" name="name" />
|
||||
</form>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% set parent_path = '/'.join(working_folder_path.rstrip('/').split('/')[:-1]) %}
|
||||
{% if parent_path %}
|
||||
<li class="previous-folder droppable" data-path="{{ parent_path }}" data-id="{{ working_folder.parent_id }}">
|
||||
<a href="{{ url_for('slideshow_content_cd', path=parent_path) }}" class="explr-link">
|
||||
<i class="fa fa-folder"></i>
|
||||
{{ folder.name }}
|
||||
..
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% for folder in working_folder_children %}
|
||||
{% set folder_path = working_folder_path ~ '/' ~ folder.name %}
|
||||
<li class="draggable droppable" data-path="{{ folder_path }}" data-id="{{ folder.id }}" data-folder="1">
|
||||
<a href="{{ url_for('slideshow_content_cd', path=folder_path) }}" class="explr-link">
|
||||
<i class="fa fa-folder"></i>
|
||||
{{ truncate(folder.name, 25, '...') }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
@ -129,21 +155,22 @@
|
||||
{% for content in contents[working_folder.id]|default([]) %}
|
||||
{% set icon = 'fa-file' %}
|
||||
{% if content.type.value == 'picture' %}
|
||||
{% set icon = 'fa-image' %}
|
||||
{% set icon = 'fa-regular fa-image info' %}
|
||||
{% elif content.type.value == 'video' %}
|
||||
{% set icon = 'fa-film' %}
|
||||
{% set icon = 'fa-video-camera success' %}
|
||||
{% elif content.type.value == 'url' %}
|
||||
{% set icon = 'fa-globe' %}
|
||||
{% set icon = 'fa-link danger' %}
|
||||
{% elif content.type.value == 'youtube' %}
|
||||
{% set icon = 'fa-video' %}
|
||||
{% set icon = 'fa-brands fa-youtube youtube' %}
|
||||
{% endif %}
|
||||
|
||||
<li>
|
||||
<a href="{{ url_for('slideshow_content_show', content_id=content.id) }}" target="_blank">
|
||||
<li class="draggable" data-path="{{ working_folder_path }}" data-id="{{ content.id }}" data-folder="0">
|
||||
<a href="{{ url_for('slideshow_content_show', content_id=content.id) }}" target="_blank" class="explr-link">
|
||||
<i class="fa {{ icon }}"></i>
|
||||
{{ content.name }}
|
||||
{{ truncate(content.name, 25, '...') }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user