tg-prepare 1.1.0__py3-none-any.whl → 2.1.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tg-prepare might be problematic. Click here for more details.
- {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b1.dist-info}/METADATA +3 -3
- tg_prepare-2.1.0b1.dist-info/RECORD +54 -0
- {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b1.dist-info}/WHEEL +1 -1
- tg_prepare-2.1.0b1.dist-info/projects/.secret_key +1 -0
- tgp_backend/__init__.py +3 -4
- tgp_backend/config.py +31 -0
- tgp_backend/directories.py +6 -8
- tgp_backend/nextcloud.py +40 -19
- tgp_backend/project.py +172 -45
- tgp_backend/session_manager.py +47 -0
- tgp_backend/util.py +73 -25
- tgp_ui/app.py +43 -335
- tgp_ui/routes/__init__.py +0 -0
- tgp_ui/routes/collection.py +272 -0
- tgp_ui/routes/data.py +228 -0
- tgp_ui/routes/project.py +102 -0
- tgp_ui/routes/publication.py +129 -0
- tgp_ui/routes/tabs.py +34 -0
- tgp_ui/routes/views.py +62 -0
- tgp_ui/static/css/navbar.css +92 -0
- tgp_ui/static/js/collectionManager.js +60 -0
- tgp_ui/static/js/fileManager.js +186 -0
- tgp_ui/static/js/main.js +32 -485
- tgp_ui/static/js/modalManager.js +105 -0
- tgp_ui/static/js/navbarManager.js +151 -0
- tgp_ui/static/js/projectManager.js +60 -0
- tgp_ui/static/js/require.js +5 -0
- tgp_ui/static/js/sidebarManager.js +32 -0
- tgp_ui/static/js/tabManager.js +79 -0
- tgp_ui/templates/layout.html +9 -48
- tgp_ui/templates/macros.html +79 -72
- tgp_ui/templates/project_main.html +36 -0
- tgp_ui/templates/project_navbar.html +81 -0
- tgp_ui/templates/{projects.html → projects_main.html} +13 -28
- tgp_ui/templates/tab_final_upload.html +29 -0
- tg_prepare-1.1.0.dist-info/RECORD +0 -39
- tgp_ui/templates/collection.html +0 -194
- tgp_ui/templates/file_upload.html +0 -24
- tgp_ui/templates/nxc_file_tree.html +0 -33
- tgp_ui/templates/project.html +0 -26
- tgp_ui/templates/storage.html +0 -49
- tgp_ui/templates/tei_explorer.html +0 -48
- tgp_ui/templates/xpath_parser_modal_content.html +0 -37
- {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b1.dist-info}/entry_points.txt +0 -0
- {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b1.dist-info}/licenses/LICENSE +0 -0
- {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2023-2025 TU-Dresden (ZIH)
|
|
3
|
+
# ralf.klammer@tu-dresden.de
|
|
4
|
+
# moritz.wilhelm@tu-dresden.de
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
from flask import Blueprint, render_template, request
|
|
9
|
+
from flask_json import json_response
|
|
10
|
+
|
|
11
|
+
from tgp_backend.project import Project, TGProject
|
|
12
|
+
|
|
13
|
+
log = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
publication_routes = Blueprint("publication", __name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@publication_routes.route(
|
|
19
|
+
"/tab-prepare-upload/<string:projectname>", methods=["GET"]
|
|
20
|
+
)
|
|
21
|
+
def tab_upload(projectname):
|
|
22
|
+
project = Project(projectname)
|
|
23
|
+
|
|
24
|
+
return render_template(
|
|
25
|
+
"tabs/upload.html",
|
|
26
|
+
project=project,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# ***TAB CHECK RESULTS***
|
|
31
|
+
# ***********************
|
|
32
|
+
@publication_routes.route(
|
|
33
|
+
"/tab-check-result/<string:projectname>", methods=["GET"]
|
|
34
|
+
)
|
|
35
|
+
def tab_check_result(projectname):
|
|
36
|
+
# Erstelle das Project-Objekt
|
|
37
|
+
project = Project(projectname)
|
|
38
|
+
|
|
39
|
+
# Übergib das Project-Objekt an das Template
|
|
40
|
+
return render_template(
|
|
41
|
+
"tabs/check_result.html",
|
|
42
|
+
project=project, # Das Project-Objekt wird hier übergeben
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TGProjectHandler:
|
|
47
|
+
def __init__(self, projectname, instance):
|
|
48
|
+
self.project = Project(projectname)
|
|
49
|
+
self.tg_project = self.project.get_tgp(instance)
|
|
50
|
+
self.instance = instance
|
|
51
|
+
|
|
52
|
+
def _render_template(self):
|
|
53
|
+
return render_template(
|
|
54
|
+
"includes/upload_form.html",
|
|
55
|
+
project=self.project,
|
|
56
|
+
instance=self.instance,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def save_session_id(self, session_id):
|
|
60
|
+
self.tg_project.tg_session_id = session_id
|
|
61
|
+
return self._render_template()
|
|
62
|
+
|
|
63
|
+
def save_tg_project_id(self, tg_project_id):
|
|
64
|
+
self.tg_project.tg_project_id = tg_project_id
|
|
65
|
+
return self._render_template()
|
|
66
|
+
|
|
67
|
+
def delete_tg_project(self, tg_project_id):
|
|
68
|
+
self.tg_project.delete_tg_project(tg_project_id)
|
|
69
|
+
return self._render_template()
|
|
70
|
+
|
|
71
|
+
def create_tg_project(self, tg_projectname):
|
|
72
|
+
self.tg_project.create_tg_project(tg_projectname)
|
|
73
|
+
return self._render_template()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@publication_routes.route(
|
|
77
|
+
"/save_session_id/<string:projectname>/<string:instance>", methods=["POST"]
|
|
78
|
+
)
|
|
79
|
+
def save_session_id(projectname, instance):
|
|
80
|
+
return TGProjectHandler(projectname, instance).save_session_id(
|
|
81
|
+
request.form.get("tg_auth_session_id")
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@publication_routes.route(
|
|
86
|
+
"/save_tg_project_id/<string:projectname>/<string:instance>/<string:tg_project_id>",
|
|
87
|
+
methods=["POST"],
|
|
88
|
+
)
|
|
89
|
+
def save_tg_project_id(projectname, instance, tg_project_id):
|
|
90
|
+
return TGProjectHandler(projectname, instance).save_tg_project_id(
|
|
91
|
+
tg_project_id
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@publication_routes.route(
|
|
96
|
+
"/delete_tg_project_id/<string:projectname>/<string:instance>/<string:tg_project_id>",
|
|
97
|
+
methods=["POST"],
|
|
98
|
+
)
|
|
99
|
+
def delete_tg_project_id(projectname, instance, tg_project_id):
|
|
100
|
+
return TGProjectHandler(projectname, instance).delete_tg_project(
|
|
101
|
+
tg_project_id
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@publication_routes.route(
|
|
106
|
+
"/create_tg_project/<string:projectname>/<string:instance>",
|
|
107
|
+
methods=["POST"],
|
|
108
|
+
)
|
|
109
|
+
def create_tg_project(projectname, instance):
|
|
110
|
+
return TGProjectHandler(projectname, instance).create_tg_project(
|
|
111
|
+
request.form.get("tg_projectname")
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@publication_routes.route(
|
|
116
|
+
"/upload_project/<string:projectname>/<string:instance>", methods=["POST"]
|
|
117
|
+
)
|
|
118
|
+
def upload_project(projectname, instance):
|
|
119
|
+
TGProject(projectname, instance).upload_tg_project()
|
|
120
|
+
return json_response(response="OK")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# @publication_routes.route(
|
|
124
|
+
# "/get_tg_project_hits/<string:projectname>/<string:instance>/<string:tg_project_id>",
|
|
125
|
+
# methods=["GET"],
|
|
126
|
+
# )
|
|
127
|
+
# def get_tg_project_hits(projectname, instance, tg_project_id):
|
|
128
|
+
# hits = TGProject(projectname, instance).get_tg_project_hits(tg_project_id)
|
|
129
|
+
# return json_response(response="OK", hits=hits)
|
tgp_ui/routes/tabs.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2023-2025 TU-Dresden (ZIH)
|
|
3
|
+
# ralf.klammer@tu-dresden.de
|
|
4
|
+
# moritz.wilhelm@tu-dresden.de
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
from flask import Blueprint, session
|
|
9
|
+
from flask_json import json_response
|
|
10
|
+
|
|
11
|
+
log = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
tab_manager = Blueprint("tab_manager", __name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@tab_manager.route("/get_last_tab/<string:projectname>", methods=["GET"])
|
|
17
|
+
def get_last_tab(projectname):
|
|
18
|
+
|
|
19
|
+
tabname = session.get(f"last_tab_{projectname}", None)
|
|
20
|
+
|
|
21
|
+
return json_response(status=200, initial_tab=tabname or "tab-edit-project")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@tab_manager.route(
|
|
25
|
+
"/set_last_tab/<string:projectname>/<string:tabname>", methods=["POST"]
|
|
26
|
+
)
|
|
27
|
+
def set_last_tab(projectname, tabname):
|
|
28
|
+
|
|
29
|
+
if tabname:
|
|
30
|
+
session[f"last_tab_{projectname}"] = tabname
|
|
31
|
+
return json_response(
|
|
32
|
+
response="OK",
|
|
33
|
+
message=f"Last tab for project '{projectname}' set to '{tabname}'",
|
|
34
|
+
)
|
tgp_ui/routes/views.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (C) 2023-2025 TU-Dresden (ZIH)
|
|
3
|
+
# ralf.klammer@tu-dresden.de
|
|
4
|
+
# moritz.wilhelm@tu-dresden.de
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
from flask import Blueprint, render_template, request, session
|
|
9
|
+
|
|
10
|
+
from tgp_backend.project import Project
|
|
11
|
+
|
|
12
|
+
log = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
main_views = Blueprint("views", __name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# favored route
|
|
18
|
+
@main_views.route("/overview", methods=["GET", "POST"])
|
|
19
|
+
# additional routes for compatibility
|
|
20
|
+
@main_views.route("/", methods=["GET"])
|
|
21
|
+
@main_views.route("/project", methods=["GET", "POST"])
|
|
22
|
+
@main_views.route("/projects", methods=["GET", "POST"])
|
|
23
|
+
def overview():
|
|
24
|
+
return render_template("projects_main.html", sub_title="Projects Overview")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@main_views.route("/project/<string:projectname>", methods=["GET", "POST"])
|
|
28
|
+
def project_view(projectname=None):
|
|
29
|
+
return render_template(
|
|
30
|
+
"project_main.html",
|
|
31
|
+
user=session.get("user", "-"),
|
|
32
|
+
current_project=projectname,
|
|
33
|
+
project=Project(projectname),
|
|
34
|
+
tab=request.args.get("tab"),
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@main_views.route("/modal/container", methods=["GET"])
|
|
39
|
+
def modal_container():
|
|
40
|
+
"""
|
|
41
|
+
Render a modal spinner template.
|
|
42
|
+
This is used to show a loading spinner while processing requests.
|
|
43
|
+
"""
|
|
44
|
+
return render_template("modal/empty_container.html")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@main_views.route("/tabs/container", methods=["GET"])
|
|
48
|
+
def tab_container():
|
|
49
|
+
"""
|
|
50
|
+
Render a tab spinner template.
|
|
51
|
+
This is used to show a loading spinner while processing requests.
|
|
52
|
+
"""
|
|
53
|
+
return render_template("tabs/empty_container.html")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@main_views.route("/details/container", methods=["GET"])
|
|
57
|
+
def details_container():
|
|
58
|
+
"""
|
|
59
|
+
Render a details spinner template.
|
|
60
|
+
This is used to show a loading spinner while processing requests.
|
|
61
|
+
"""
|
|
62
|
+
return render_template("details/empty_container.html", show_spinner=True)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
.btn-circle.btn-xl {
|
|
2
|
+
width: 4.2rem;
|
|
3
|
+
height: 4.2rem;
|
|
4
|
+
border-radius: 50%;
|
|
5
|
+
text-align: center;
|
|
6
|
+
font-size: 1.5rem;
|
|
7
|
+
display: flex;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
align-items: center;
|
|
10
|
+
position: relative;
|
|
11
|
+
z-index: 1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.btn-circle.btn-sm {
|
|
15
|
+
width: 3.2rem;
|
|
16
|
+
height: 3.2rem;
|
|
17
|
+
border-radius: 50%;
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
justify-content: center;
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Animation für den Übergang */
|
|
25
|
+
.btn-xl.animate-to-long {
|
|
26
|
+
width: 25rem;
|
|
27
|
+
height: 4.2rem;
|
|
28
|
+
border-width: 0.2rem;
|
|
29
|
+
border-radius: 3rem;
|
|
30
|
+
transition: all 5.2s ease-in-out;
|
|
31
|
+
display: flex;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
align-items: center;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.btn-xl.animate-to-long i .main-icon {
|
|
37
|
+
opacity: 0;
|
|
38
|
+
/* Icon ausblenden */
|
|
39
|
+
transition: opacity 0.3s ease-in-out;
|
|
40
|
+
/* Sanftes Ausblenden */
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.line {
|
|
44
|
+
height: 20px;
|
|
45
|
+
border-radius: 10px;
|
|
46
|
+
position: absolute;
|
|
47
|
+
top: 50%;
|
|
48
|
+
height: 4px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.line.blank {
|
|
52
|
+
width: 95%;
|
|
53
|
+
background-color: #f8f9fa;
|
|
54
|
+
left: 1rem;
|
|
55
|
+
z-index: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.line.blue {
|
|
59
|
+
width: 0%;
|
|
60
|
+
background-color: #0d6efd;
|
|
61
|
+
left: 1rem;
|
|
62
|
+
z-index: 0.5;
|
|
63
|
+
transition: width 0.3s ease-in-out;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.btn-xl.animate-to-long {
|
|
67
|
+
z-index: 2;
|
|
68
|
+
/* Erweiterte Buttons über die Linie legen */
|
|
69
|
+
transition: all 0.3s ease-in-out;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.border-primary{
|
|
73
|
+
border-width: 0.2rem;
|
|
74
|
+
transition: all 0.2s ease-in-out;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
/* tab-edit-other-files */
|
|
79
|
+
.tab-button {
|
|
80
|
+
width: 12rem;
|
|
81
|
+
height: 12rem;
|
|
82
|
+
color: #0d6efd;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.tab-button.active,
|
|
86
|
+
.tab-button:active {
|
|
87
|
+
background-color: #FFFFFF !important;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.big-icon {
|
|
91
|
+
font-size: 5rem;
|
|
92
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
define([], function () {
|
|
2
|
+
const CollectionManager = {
|
|
3
|
+
loadDetailsInSidebar: function () {
|
|
4
|
+
const self = $(this);
|
|
5
|
+
const url = self.data('url');
|
|
6
|
+
const detailsContent = $('#detailsContent');
|
|
7
|
+
detailsContent.load("/details/container");
|
|
8
|
+
self.closest('.card-body')
|
|
9
|
+
.find('button.btn-primary')
|
|
10
|
+
.addClass('btn-secondary')
|
|
11
|
+
.removeClass('btn-primary');
|
|
12
|
+
|
|
13
|
+
self.addClass('btn-primary').removeClass('btn-secondary');
|
|
14
|
+
|
|
15
|
+
$.get(url, function (data) {
|
|
16
|
+
detailsContent.html(data);
|
|
17
|
+
}).fail(function () {
|
|
18
|
+
detailsContent.html('<p class="text-danger">Failed to load details. Please try again.</p>');
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
addMultiInputClassifications: function (e) {
|
|
23
|
+
e.preventDefault();
|
|
24
|
+
const self = $(this);
|
|
25
|
+
const thisRow = self.closest('.row');
|
|
26
|
+
thisRow.next().clone()
|
|
27
|
+
.insertAfter(thisRow)
|
|
28
|
+
.find('input').val('');
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
removeMultiInputClassifications: function (e) {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
const self = $(this);
|
|
34
|
+
const thisMultiInput = self.closest('.multi-input');
|
|
35
|
+
thisMultiInput.remove();
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
highlightFolder: function (e) {
|
|
39
|
+
const self = $(this);
|
|
40
|
+
const selectedFolder = self.closest('.card');
|
|
41
|
+
selectedFolder.toggleClass('border-primary').toggleClass('border-secondary');
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
init: function () {
|
|
45
|
+
// Load details in sidebar
|
|
46
|
+
$(document).on('click', '.edit-collection-button', this.loadDetailsInSidebar);
|
|
47
|
+
|
|
48
|
+
// Add a new multi input-field (e.g., 'Basic classification', 'Rights Holder')
|
|
49
|
+
$(document).on('click', '.add-multi-input-classifications', this.addMultiInputClassifications);
|
|
50
|
+
|
|
51
|
+
// Remove a multi input-field (e.g., 'Basic classification', 'Rights Holder')
|
|
52
|
+
$(document).on('click', '.remove-multi-field-classification', this.removeMultiInputClassifications);
|
|
53
|
+
|
|
54
|
+
// Highlight folder
|
|
55
|
+
$(document).on('change', 'input[name="selected_folder"]', this.highlightFolder);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return CollectionManager;
|
|
60
|
+
});
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
define([], function () {
|
|
2
|
+
const FileManager = {
|
|
3
|
+
triggerFileInput: function () {
|
|
4
|
+
$('#fileInput').trigger('click');
|
|
5
|
+
},
|
|
6
|
+
|
|
7
|
+
submitFileUpload: function () {
|
|
8
|
+
$('#fileUploadLocal').trigger('submit');
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
// New functions from main_new.js
|
|
12
|
+
showPreviewOfAvatar: function () {
|
|
13
|
+
const uploadFile = $(this);
|
|
14
|
+
const files = this.files;
|
|
15
|
+
|
|
16
|
+
if (files && files.length && window.FileReader) {
|
|
17
|
+
const reader = new FileReader();
|
|
18
|
+
reader.readAsDataURL(files[0]);
|
|
19
|
+
|
|
20
|
+
reader.onloadend = function () {
|
|
21
|
+
uploadFile.closest("div").find('.ratio').html(`
|
|
22
|
+
<div class="w-100 h-100"
|
|
23
|
+
style="background-image: url(${this.result});
|
|
24
|
+
background-size: cover;
|
|
25
|
+
background-position: center;">
|
|
26
|
+
</div>
|
|
27
|
+
`);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
cloneFromGit: function (e) {
|
|
33
|
+
e.preventDefault();
|
|
34
|
+
const form = $(e.target);
|
|
35
|
+
const button = form.find('button[type="submit"]');
|
|
36
|
+
const spinner = button.find('.spinner-border');
|
|
37
|
+
const buttonText = button.find('span:not(.spinner-border)');
|
|
38
|
+
const modal = form.closest('.modal');
|
|
39
|
+
|
|
40
|
+
button.prop('disabled', true);
|
|
41
|
+
spinner.removeClass('d-none');
|
|
42
|
+
buttonText.text('Cloning...');
|
|
43
|
+
|
|
44
|
+
$.ajax({
|
|
45
|
+
url: form.attr('action'),
|
|
46
|
+
method: 'POST',
|
|
47
|
+
data: form.serialize(),
|
|
48
|
+
success: function (response) {
|
|
49
|
+
$(modal).modal('hide');
|
|
50
|
+
$(form.closest('.tab-pane')).html(response);
|
|
51
|
+
},
|
|
52
|
+
error: function () {
|
|
53
|
+
button.removeClass('btn-primary').addClass('btn-danger');
|
|
54
|
+
buttonText.text('Clone Repository');
|
|
55
|
+
},
|
|
56
|
+
complete: function () {
|
|
57
|
+
spinner.addClass('d-none');
|
|
58
|
+
button.prop('disabled', false);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
deleteFolder: function (e) {
|
|
64
|
+
e.preventDefault();
|
|
65
|
+
const button = $(this);
|
|
66
|
+
const itemName = button.data('item-name');
|
|
67
|
+
const itemType = button.data('item-type');
|
|
68
|
+
|
|
69
|
+
if (confirm(`Do you want to delete ${itemType === 'folder' ? 'the folder' : 'the file'} "${itemName}"?`)) {
|
|
70
|
+
$.ajax({
|
|
71
|
+
url: '/api/delete-folder',
|
|
72
|
+
method: 'DELETE',
|
|
73
|
+
data: {
|
|
74
|
+
path: button.data('item-path'),
|
|
75
|
+
projectname: button.data('projectname')
|
|
76
|
+
},
|
|
77
|
+
success: function (response) {
|
|
78
|
+
$(button.closest('.tab-pane')).html(response);
|
|
79
|
+
},
|
|
80
|
+
error: function () {
|
|
81
|
+
alert('Error deleting item.');
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
deleteXSLT: function (e) {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
const projectname = $(this).data('projectname');
|
|
90
|
+
const self = this;
|
|
91
|
+
$.ajax({
|
|
92
|
+
url: `/delete-xslt/${projectname}`,
|
|
93
|
+
method: 'DELETE',
|
|
94
|
+
headers: {
|
|
95
|
+
'Content-Type': 'application/json'
|
|
96
|
+
},
|
|
97
|
+
success: function (response) {
|
|
98
|
+
FileManager.hideHint.call(self);
|
|
99
|
+
},
|
|
100
|
+
error: function () {
|
|
101
|
+
alert('Error deleting XSLT file.');
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
hideHint: function () {
|
|
107
|
+
const hint = $('.xslt-upload');
|
|
108
|
+
if (hint) {
|
|
109
|
+
hint.addClass('d-none');
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
selectNextcloudFolder: function () {
|
|
114
|
+
const self = $(this);
|
|
115
|
+
const new_state = self.is(':checked') ? 'checked' : '';
|
|
116
|
+
const checkboxes = self.closest('.list-group-item').find('.nextcloud-folder');
|
|
117
|
+
checkboxes
|
|
118
|
+
.prop("checked", new_state)
|
|
119
|
+
.not(':first')
|
|
120
|
+
.prop("disabled", true);
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
dragDropHandler: function (event) {
|
|
124
|
+
event.preventDefault();
|
|
125
|
+
|
|
126
|
+
const dropZone = $(event.target).closest('.js-file-upload');
|
|
127
|
+
const files = event.originalEvent.dataTransfer.files;
|
|
128
|
+
const uploadUrl = dropZone.data('url');
|
|
129
|
+
|
|
130
|
+
console.log(`Dropped ${files.length} files to upload`);
|
|
131
|
+
|
|
132
|
+
if (files.length > 0) {
|
|
133
|
+
// Create FormData with the dropped files
|
|
134
|
+
const formData = new FormData();
|
|
135
|
+
|
|
136
|
+
for (let i = 0; i < files.length; i++) {
|
|
137
|
+
formData.append('files', files[i]);
|
|
138
|
+
console.log(`File ${i + 1}: ${files[i].name}`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Upload files via AJAX
|
|
142
|
+
$.ajax({
|
|
143
|
+
url: uploadUrl,
|
|
144
|
+
type: 'POST',
|
|
145
|
+
data: formData,
|
|
146
|
+
processData: false,
|
|
147
|
+
contentType: false,
|
|
148
|
+
success: function (response) {
|
|
149
|
+
dropZone.closest('.container, .tab-pane').html(response);
|
|
150
|
+
},
|
|
151
|
+
error: function (xhr, status, error) {
|
|
152
|
+
console.error('Upload error:', error);
|
|
153
|
+
dropZone.addClass('border-danger text-danger').removeClass('border-success');
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
preventDefaults: function (event) {
|
|
160
|
+
event.preventDefault();
|
|
161
|
+
event.stopPropagation();
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
// Update the init function to include drag & drop event listeners
|
|
165
|
+
init: function () {
|
|
166
|
+
$(document).on('change', 'input#fileInput', this.submitFileUpload);
|
|
167
|
+
$(document).on('click', 'button#triggerFileInput', this.triggerFileInput);
|
|
168
|
+
$(document).on('click', '.delete-folder', this.deleteFolder);
|
|
169
|
+
$(document).on("change", ".showPreviewOfAvatar", this.showPreviewOfAvatar);
|
|
170
|
+
$(document).on('click', '#deleteXsltButton', this.deleteXSLT);
|
|
171
|
+
$(document).on('change', '.xslt-upload', this.hideHint);
|
|
172
|
+
$(document).on('click', 'input.nextcloud-folder', this.selectNextcloudFolder);
|
|
173
|
+
|
|
174
|
+
// Drag & Drop event listeners for elements with class 'js-file-upload'
|
|
175
|
+
$(document).on('dragenter', '.js-file-upload', this.preventDefaults);
|
|
176
|
+
$(document).on('dragover', '.js-file-upload', this.preventDefaults);
|
|
177
|
+
$(document).on('dragleave', '.js-file-upload', this.preventDefaults);
|
|
178
|
+
$(document).on('drop', '.js-file-upload', this.dragDropHandler);
|
|
179
|
+
$(document).on('click', '.js-file-upload', function (event) {
|
|
180
|
+
$('#triggerFileInput').click();
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
return FileManager;
|
|
186
|
+
});
|