tg-prepare 1.1.0__py3-none-any.whl → 2.1.0b2__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.0b2.dist-info}/METADATA +3 -3
- tg_prepare-2.1.0b2.dist-info/RECORD +78 -0
- {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b2.dist-info}/WHEEL +1 -1
- tg_prepare-2.1.0b2.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/bootstrap.min.css.map +1 -0
- tgp_ui/static/css/navbar.css +92 -0
- tgp_ui/static/img/favicon.ico +0 -0
- tgp_ui/static/img/textgrid-logo.svg +1 -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/details/empty_container.html +16 -0
- tgp_ui/templates/details/manage_collection.html +205 -0
- tgp_ui/templates/includes/set_session_id_form.html +16 -0
- tgp_ui/templates/includes/upload_form.html +131 -0
- tgp_ui/templates/layout.html +9 -48
- tgp_ui/templates/macros.html +79 -72
- tgp_ui/templates/modal/delete_project.html +25 -0
- tgp_ui/templates/modal/empty_container.html +9 -0
- tgp_ui/templates/modal/file_explorer_content.html +34 -0
- tgp_ui/templates/modal/file_explorer_main.html +22 -0
- tgp_ui/templates/modal/file_explorer_nextcloud.html +27 -0
- tgp_ui/templates/modal/github_modal.html +29 -0
- tgp_ui/templates/modal/nextcloud_login.html +48 -0
- tgp_ui/templates/modal/tei_explorer.html +58 -0
- tgp_ui/templates/modal/xpath_parser.html +52 -0
- 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
- tgp_ui/templates/tabs/check_result.html +90 -0
- tgp_ui/templates/tabs/edit_project.html +113 -0
- tgp_ui/templates/tabs/empty_container.html +12 -0
- tgp_ui/templates/tabs/import_data.html +138 -0
- tgp_ui/templates/tabs/manage_collections.html +88 -0
- tgp_ui/templates/tabs/select_directories.html +41 -0
- tgp_ui/templates/tabs/upload.html +42 -0
- tgp_ui/templates/tabs/validate_metadata.html +227 -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.0b2.dist-info}/entry_points.txt +0 -0
- {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b2.dist-info}/licenses/LICENSE +0 -0
- {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<div class="row">
|
|
3
|
+
{% set tg_session_id = project.main_config.get_tg_session_id(instance) %}
|
|
4
|
+
|
|
5
|
+
<!-- Left column: Project management -->
|
|
6
|
+
{% if not tg_session_id %}
|
|
7
|
+
<div class="col-12 text-center">
|
|
8
|
+
<!-- Show note when no session ID is set -->
|
|
9
|
+
<div class="alert alert-warning fst-italic">
|
|
10
|
+
<h6 class="fw-bold">Attention</h6>
|
|
11
|
+
<p>
|
|
12
|
+
<b>You need to provide a "TgAuth Session ID" in order to publish your project to
|
|
13
|
+
TextGrid-{{ instance|capitalize }} Instance!</b>
|
|
14
|
+
</p>
|
|
15
|
+
<ol class="mb-0">
|
|
16
|
+
<li>Please first go to <a href="{{ get_textgrid_login_url(instance) }}" target="_blank">this
|
|
17
|
+
page</a>!
|
|
18
|
+
(You may need to log in via DARIAH-AAI)</li>
|
|
19
|
+
<li>Then click on "More Details" and copy the "TgAuth Session ID" to your clipboard.</li>
|
|
20
|
+
<li>Finally, paste it into the input field below and save it.</li>
|
|
21
|
+
</ol>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
{% endif %}
|
|
25
|
+
|
|
26
|
+
<div class="col-lg-7 mb-4 mb-lg-0">
|
|
27
|
+
<div class="bg-light rounded p-4 h-100">
|
|
28
|
+
|
|
29
|
+
<h4 class="mb-3">Set Session ID of TextGrid-{{ instance|capitalize }} Instance</h4>
|
|
30
|
+
<form class="row js-tab-submit" method="POST"
|
|
31
|
+
action="{{ url_for('publication.save_session_id', projectname=project.path, instance=instance) }}">
|
|
32
|
+
<input type="hidden" name="selected_instance" value="{{ instance }}">
|
|
33
|
+
<div class="col-9">
|
|
34
|
+
<input type="text" class="form-control" name="tg_auth_session_id" placeholder="TgAuth Session ID"
|
|
35
|
+
value="{{ tg_session_id if tg_session_id }}">
|
|
36
|
+
</div>
|
|
37
|
+
<div class="col-3">
|
|
38
|
+
<button type="submit" class="btn btn-primary w-100" style="min-width: 48px;">
|
|
39
|
+
<span class="bi bi-floppy2-fill"></span>
|
|
40
|
+
<span class="spinner-border spinner-border-sm" style="display:none;" role="status"
|
|
41
|
+
aria-hidden="true"></span>
|
|
42
|
+
</button>
|
|
43
|
+
</div>
|
|
44
|
+
</form>
|
|
45
|
+
|
|
46
|
+
{% if tg_session_id %}
|
|
47
|
+
<h4 class="my-3 border-top pt-3">Select from existing projects</h4>
|
|
48
|
+
<div class="row pb-1">
|
|
49
|
+
{% set tg_project_id = project.main_config.get_tg_project_id(instance) %}
|
|
50
|
+
{% for tg_project in project.get_tgp(instance).get_tg_projects() %}
|
|
51
|
+
<div class="col-md-6 mb-3">
|
|
52
|
+
<div
|
|
53
|
+
class="card h-100 {{'border-primary' if tg_project_id == tg_project.id else 'border-secondary'}}">
|
|
54
|
+
<div class="card-body">
|
|
55
|
+
<h5 class="card-title text-truncate">{{ tg_project.name }}</h5>
|
|
56
|
+
<p class="card-text text-muted mb-1">({{ tg_project.contents }} Elements)</p>
|
|
57
|
+
<p class="card-text text-muted small"><i>ID: {{ tg_project.id }}</i></p>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="card-footer d-flex justify-content-between align-items-center">
|
|
60
|
+
<form method="POST" class="js-tab-submit"
|
|
61
|
+
action="{{ url_for('publication.save_tg_project_id', projectname=project.path, instance=instance, tg_project_id=tg_project.id) }}">
|
|
62
|
+
<button type="submit" class="btn btn-sm btn-outline-primary">
|
|
63
|
+
{% if tg_project_id == tg_project.id %}
|
|
64
|
+
<span class="bi bi-check-circle-fill text-primary"></span> Selected
|
|
65
|
+
{% else %}
|
|
66
|
+
<span class="bi bi-circle"></span> Select
|
|
67
|
+
{% endif %}
|
|
68
|
+
</button>
|
|
69
|
+
</form>
|
|
70
|
+
<form method="POST" class="js-tab-submit"
|
|
71
|
+
action="{{ url_for('publication.delete_tg_project_id', projectname=project.path, instance=instance, tg_project_id=tg_project.id) }}">
|
|
72
|
+
<button type="submit" class="btn btn-sm btn-outline-danger" title="Delete project">
|
|
73
|
+
<span class="bi bi-trash"></span> Delete
|
|
74
|
+
</button>
|
|
75
|
+
</form>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
{% endfor %}
|
|
80
|
+
</div>
|
|
81
|
+
<h5 class="border-top pt-3 pb-2">New project:</h5>
|
|
82
|
+
<form class="row tab-submit js-tab-submit" method="POST"
|
|
83
|
+
action="{{ url_for('publication.create_tg_project', projectname=project.path, instance=instance) }}">
|
|
84
|
+
<div class="col-9">
|
|
85
|
+
<input type="text" class="form-control" name="tg_projectname" placeholder="TG Projectname" required>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="col-3">
|
|
88
|
+
<button type="submit" class="btn btn-primary w-100">
|
|
89
|
+
<span class="bi bi-pencil-square"></span>
|
|
90
|
+
<span class="spinner-border spinner-border-sm" style="display:none;" role="status"
|
|
91
|
+
aria-hidden="true"></span>
|
|
92
|
+
</button>
|
|
93
|
+
</div>
|
|
94
|
+
</form>
|
|
95
|
+
</div>
|
|
96
|
+
{% endif %}
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<!-- Rechte Spalte: Upload -->
|
|
100
|
+
<div class="col-lg-5 border-start">
|
|
101
|
+
<div class="bg-light rounded p-4 h-100">
|
|
102
|
+
{% if tg_session_id %}
|
|
103
|
+
<div class="text-center mb-4">
|
|
104
|
+
<h4 class="mb-2"><i
|
|
105
|
+
class="bi bi-cloud-upload {% if instance == 'test' %}text-primary{% else %}text-danger{% endif %} me-2"></i>Upload
|
|
106
|
+
to {{ instance|capitalize }} Instance</h4>
|
|
107
|
+
{% if instance == 'test' %}
|
|
108
|
+
<span class="badge bg-warning text-dark mb-2">
|
|
109
|
+
This upload is for <b>testing purposes</b>.
|
|
110
|
+
</span>
|
|
111
|
+
{% else %}
|
|
112
|
+
<span class="badge bg-danger text-light mb-2">
|
|
113
|
+
This starts a <b>real publication</b>.
|
|
114
|
+
<br />
|
|
115
|
+
Please ensure all data is correct.
|
|
116
|
+
</span>
|
|
117
|
+
{% endif %}
|
|
118
|
+
</div>
|
|
119
|
+
<form method="POST"
|
|
120
|
+
action="{{ url_for('publication.upload_project', projectname=project.path, instance=instance) }}"
|
|
121
|
+
class="w-100 js-tab-submit">
|
|
122
|
+
<button type="submit"
|
|
123
|
+
class="btn {% if instance == 'test' %}btn-success{% else %}btn-danger{% endif %} w-100 py-3"
|
|
124
|
+
style="font-size:1.25rem;">
|
|
125
|
+
<i class="bi bi-rocket-takeoff me-2"></i>Upload to {{ instance|capitalize }} Instance
|
|
126
|
+
</button>
|
|
127
|
+
</form>
|
|
128
|
+
{% endif %}
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
tgp_ui/templates/layout.html
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
|
13
13
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/simpleXML.css') }}" />
|
|
14
14
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/main.css') }}" />
|
|
15
|
+
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/navbar.css') }}" />
|
|
15
16
|
</head>
|
|
16
17
|
|
|
17
18
|
<body>
|
|
@@ -27,14 +28,14 @@
|
|
|
27
28
|
</div>
|
|
28
29
|
<ul class="sidebar-nav">
|
|
29
30
|
<li class="sidebar-item">
|
|
30
|
-
<a href={{ url_for(
|
|
31
|
+
<a href="{{ url_for('views.overview') }}" class="sidebar-link" title="Projects">
|
|
31
32
|
<i class="bi bi-view-list"></i>
|
|
32
33
|
<span>Overview</span>
|
|
33
34
|
</a>
|
|
34
35
|
</li>
|
|
35
36
|
{% for project in get_projects() %}
|
|
36
|
-
<li class="sidebar-item">
|
|
37
|
-
<a href="{{ url_for('
|
|
37
|
+
<li class="sidebar-item project-btn">
|
|
38
|
+
<a href="{{ url_for('views.project_view', projectname=project.name) }}" class="sidebar-link"
|
|
38
39
|
data-bs-target="#project_{{ loop.index }}" aria-expanded="false"
|
|
39
40
|
aria-controls="project_{{ loop.index }}">
|
|
40
41
|
{% if current_project == project.name %}
|
|
@@ -42,59 +43,19 @@
|
|
|
42
43
|
{% else %}
|
|
43
44
|
<i class="bi bi-circle"></i>
|
|
44
45
|
{% endif %}
|
|
45
|
-
<span>{{ project.name }}</span>
|
|
46
|
+
<span class="projectname">{{ project.name }}</span>
|
|
46
47
|
</a>
|
|
47
|
-
|
|
48
|
-
class="sidebar-dropdown nav list-unstyled ps-3 {{ 'collapse' if current_project != project.name }}"
|
|
49
|
-
data-bs-parent="#sidebar">
|
|
50
|
-
<li class="sidebar-item">
|
|
51
|
-
<a class="sidebar-link nav-link" data-bs-toggle="tab" href="#tab_storage" role="tab"
|
|
52
|
-
aria-controls="tab_storage" aria-selected="false">
|
|
53
|
-
<i class="bi bi-folder2-open"></i>
|
|
54
|
-
Storage
|
|
55
|
-
</a>
|
|
56
|
-
</li>
|
|
57
|
-
{% for c in project.collections %}
|
|
58
|
-
{% set collection_config = project.collections[c]['config'] %}
|
|
59
|
-
<li class="sidebar-item">
|
|
60
|
-
<a class="sidebar-link nav-link collection-tab" data-bs-toggle="tab" href="#tab_{{ c }}"
|
|
61
|
-
role="tab" aria-controls="tab_{{ c }} aria-selected=" false"
|
|
62
|
-
data-url="{{ url_for('collection', projectname=project.name, name=c) }}"
|
|
63
|
-
data-name="{{ c }}">
|
|
64
|
-
<i class="spinner-border spinner-border-sm" role="status" style="display:none;"></i>
|
|
65
|
-
<i class="bi bi-{{ loop.index }}-circle"></i>
|
|
66
|
-
{{collection_config.short_title}}
|
|
67
|
-
</a>
|
|
68
|
-
</li>
|
|
69
|
-
{% endfor %}
|
|
70
|
-
<li class="sidebar-item">
|
|
71
|
-
<a class="sidebar-link nav-link publication-tab" data-bs-toggle="tab" href="#tab_publish"
|
|
72
|
-
role="tab" aria-controls="tab_publish" data-projectname="{{ project.name }}"
|
|
73
|
-
aria-selected="false">
|
|
74
|
-
<i class="bi bi-cloud-upload"></i>
|
|
75
|
-
Publish
|
|
76
|
-
</a>
|
|
77
|
-
</li>
|
|
78
|
-
</ul>
|
|
48
|
+
|
|
79
49
|
</li>
|
|
80
50
|
{% endfor %}
|
|
51
|
+
</ul>
|
|
81
52
|
</aside>
|
|
82
53
|
<div class="main p-3">
|
|
83
|
-
<div class="text-center">
|
|
84
|
-
<h1>
|
|
85
|
-
<span>
|
|
86
|
-
{{ sub_title }}
|
|
87
|
-
</span>
|
|
88
|
-
</h1>
|
|
89
|
-
</div>
|
|
90
54
|
{% block content %}{% endblock content %}
|
|
55
|
+
{% include 'modal/empty_container.html' %}
|
|
91
56
|
</div>
|
|
92
57
|
</div>
|
|
93
|
-
<script src="{{ url_for('static', filename='js/
|
|
94
|
-
<script src="{{ url_for('static', filename='js/bootstrap.bundle.min.js') }}"></script>
|
|
95
|
-
<script src="{{ url_for('static', filename='js/simpleXML.js') }}"></script>
|
|
96
|
-
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
|
|
97
|
-
</script>
|
|
58
|
+
<script data-main="/static/js/main" src="{{ url_for('static', filename='js/require.js') }}"></script>
|
|
98
59
|
</body>
|
|
99
60
|
|
|
100
61
|
</html>
|
tgp_ui/templates/macros.html
CHANGED
|
@@ -1,94 +1,101 @@
|
|
|
1
|
-
{% macro
|
|
1
|
+
{% macro multi_input(_items, input_name) %}
|
|
2
|
+
{% set items = _items or [None] %}
|
|
3
|
+
{% for item in items %}
|
|
4
|
+
<div class="input-group mb-2">
|
|
5
|
+
<input type="text" class="form-control" title="Name" name="{{input_name}}_name" placeholder="e.g.: Jane Doe"
|
|
6
|
+
value="{{ item.fullname or item.name }}" required>
|
|
7
|
+
<input type="url" class="form-control" title="URL" name="{{input_name}}_url" value="{{ item.url or '' }}"
|
|
8
|
+
placeholder="e.g.: https://orcid.org/0000-0001-2345-6789">
|
|
9
|
+
{% if loop.first %}
|
|
10
|
+
<button class="input-group-text add-multi-input">
|
|
11
|
+
<i class="bi bi-plus-circle-dotted"></i>
|
|
12
|
+
</button>
|
|
13
|
+
{% else %}
|
|
14
|
+
<button class="input-group-text remove-multi-input">
|
|
15
|
+
<i class="bi bi-dash-circle-dotted"></i>
|
|
16
|
+
</button>
|
|
17
|
+
{% endif %}
|
|
18
|
+
</div>
|
|
19
|
+
{% endif %}
|
|
20
|
+
{% endfor %}
|
|
21
|
+
{% endmacro %}
|
|
22
|
+
|
|
23
|
+
{% macro form_field_with_xpath(type, label, field_key, elem, delete_button=False) %}
|
|
2
24
|
<div class="mb-2 row">
|
|
3
|
-
<div class="col-12
|
|
4
|
-
<label class="form-label">
|
|
5
|
-
|
|
6
|
-
<span class="bi bi-trash"></span>
|
|
7
|
-
</a>
|
|
25
|
+
<div class="col-12 d-flex justify-content-between align-items-center">
|
|
26
|
+
<label class="form-label mb-0">
|
|
27
|
+
{{ label }}
|
|
8
28
|
</label>
|
|
29
|
+
{% if delete_button %}
|
|
30
|
+
<a href="#" class="badge text-dark remove-multi-field-classification ms-3">
|
|
31
|
+
<span class="bi bi-trash"></span>
|
|
32
|
+
</a>
|
|
33
|
+
{% endif %}
|
|
34
|
+
</div>
|
|
35
|
+
<div class="col-12">
|
|
9
36
|
<div class="input-group">
|
|
10
37
|
<input type="text" class="form-control" data-key="{{ field_key }}" data-type="value" placeholder="Value"
|
|
11
|
-
value="{{ elem['value'] if elem and elem.get('value') }}">
|
|
38
|
+
value="{{ elem['value'] if elem and elem.get('value') }}" name="{{ type }}-{{ field_key }}-value">
|
|
12
39
|
<input type="text" class="form-control" data-key="{{ field_key }}" data-type="xpath" placeholder="XPath"
|
|
13
|
-
value="{{ elem['xpath'] if elem and elem.get('xpath') }}">
|
|
40
|
+
value="{{ elem['xpath'] if elem and elem.get('xpath') }}" name="{{ type }}-{{ field_key }}-xpath">
|
|
14
41
|
</div>
|
|
15
42
|
</div>
|
|
16
43
|
</div>
|
|
17
44
|
{% endmacro %}
|
|
18
45
|
|
|
19
|
-
{% macro
|
|
20
|
-
<div class="border-
|
|
21
|
-
<
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
<a href="#" class="add-multi-input btn btn-md" title="Add {{ heading }}">
|
|
25
|
-
<span class="bi bi-plus-circle"></span>
|
|
26
|
-
</a>
|
|
27
|
-
</div>
|
|
28
|
-
</label>
|
|
29
|
-
</div>
|
|
30
|
-
{% for item in elements or [None] %}
|
|
31
|
-
{% if version == 1 %}
|
|
32
|
-
<div class="multi-input-xpath" data-name="{{ type }}">
|
|
33
|
-
{{ form_field_with_xpath('ID', 'id', item.get('id') if item) }}
|
|
34
|
-
{{ form_field_with_xpath('URL', 'url', item.get('url') if item) }}
|
|
35
|
-
{{ form_field_with_xpath('Value', 'value', item.get('value') if item, has_next=loop.nextitem) }}
|
|
36
|
-
</div>
|
|
37
|
-
{% elif version == 2 %}
|
|
38
|
-
<div class="multi-input-fixed" data-name="{{ type }}">
|
|
39
|
-
<div class="mb-3 row {{'pb-2 border-bottom' if not loop.last }}">
|
|
40
|
-
<label class="col-lg-2 col-form-label">
|
|
41
|
-
Fullname
|
|
46
|
+
{% macro classification_input(type, heading, elements) %}
|
|
47
|
+
<div class="border-bottom mb-3 row">
|
|
48
|
+
<div class="d-flex justify-content-between align-items-center">
|
|
49
|
+
<label class="form-label text-center flex-grow-1 mb-0">
|
|
50
|
+
<i>{{ heading }}</i>
|
|
42
51
|
</label>
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
</div>
|
|
47
|
-
<label class="col-lg-1 col-form-label">URL</label>
|
|
48
|
-
<div class="col-lg-4 ">
|
|
49
|
-
<input type="text" class="form-control" data-key="url" value="{{ item['url'] if item['url'] }}">
|
|
50
|
-
</div>
|
|
51
|
-
<div class="col-lg-1 mt-lg-0 mt-2">
|
|
52
|
-
<a href="#" class="btn btn-md remove-multi-field">
|
|
53
|
-
<span class="bi bi-trash"></span>
|
|
54
|
-
</a>
|
|
55
|
-
</div>
|
|
52
|
+
<a href="#" class="add-multi-input-classifications btn btn-md ms-3" title="Add {{ heading }}">
|
|
53
|
+
<span class="bi bi-plus-circle"></span>
|
|
54
|
+
</a>
|
|
56
55
|
</div>
|
|
57
56
|
</div>
|
|
58
|
-
{%
|
|
57
|
+
{% for item in elements or [None] %}
|
|
58
|
+
<div class="multi-input {{'mb-3 pb-3 border-bottom' if loop.nextitem }}" data-name="{{ type }}">
|
|
59
|
+
{{ form_field_with_xpath(type, 'ID', 'id', item.get('id') if item, delete_button=True) }}
|
|
60
|
+
{{ form_field_with_xpath(type, 'URL', 'url', item.get('url') if item) }}
|
|
61
|
+
{{ form_field_with_xpath(type, 'Value', 'value', item.get('value') if item) }}
|
|
62
|
+
</div>
|
|
59
63
|
{% endfor %}
|
|
60
64
|
{% endmacro %}
|
|
61
65
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
{{ heading }}
|
|
67
|
-
{%
|
|
68
|
-
<b>{{ heading }}</b>
|
|
69
|
-
{% endif %}
|
|
66
|
+
|
|
67
|
+
{% macro xpath_or_value_input(heading, input_name, item, collection_parser, required=False) %}
|
|
68
|
+
<div class="mb-3">
|
|
69
|
+
<label class="form-label">
|
|
70
|
+
<span>{{ heading }}</span>
|
|
71
|
+
{% if required %}<span class="text-danger">*</span>{% endif %}
|
|
70
72
|
</label>
|
|
71
|
-
<div class="
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
<div class="row g-2">
|
|
74
|
+
<!-- Value Input -->
|
|
75
|
+
<div class="col-lg-6">
|
|
76
|
+
<input type="text" class="form-control" id="valueInput_{{ input_name }}" name="{{ input_name }}_value"
|
|
77
|
+
value="{{ item['value'] if item['value'] }}" placeholder="Value">
|
|
76
78
|
</div>
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<div class="
|
|
80
|
-
<input type="text" class="form-control" id="xpathInput_{{ input_name }}"
|
|
81
|
-
|
|
82
|
-
<
|
|
79
|
+
|
|
80
|
+
<!-- XPath Input -->
|
|
81
|
+
<div class="col-lg-6 position-relative">
|
|
82
|
+
<input type="text" class="form-control" id="xpathInput_{{ input_name }}" name="{{ input_name }}_xpath"
|
|
83
|
+
value="{{ item['xpath'] if item['xpath'] }}" placeholder="XPath">
|
|
84
|
+
<a href="#" class="load-modal" title="Hitrate of xpath (in %) - CLICK to see results"
|
|
85
|
+
data-args_xpath="{{ item['xpath'] }}"
|
|
86
|
+
data-url="{{ url_for('collection.modal_xpath_parser', projectname=project.name, collectionname=collectionname) }}">
|
|
87
|
+
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-success"
|
|
88
|
+
data-bs-placement="top" title="Hitrate of XPath in percentage">
|
|
89
|
+
{{ collection_parser.test_xpath(item['xpath'])['count']['percentage'] if item['xpath'] else '-' }}
|
|
90
|
+
</span>
|
|
91
|
+
</a>
|
|
83
92
|
</div>
|
|
84
|
-
<a href="#" class="show-xpath-in-tei-explorer" title="Hitrate of xpath (in %) - CLICK to see results"
|
|
85
|
-
data-url="{{ url_for('xpath_parser_modal', projectname=project.name, title=collection_title) }}"
|
|
86
|
-
data-xpath="{{ item['xpath'] }}">
|
|
87
|
-
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-success"
|
|
88
|
-
data-bs-toggle="tooltip" data-bs-placement="top" title="Hitrate of XPath in percentage">
|
|
89
|
-
{{ collection_parser.test_xpath(item['xpath'])['count']['percentage'] if item['xpath'] else '-' }}
|
|
90
|
-
</span>
|
|
91
|
-
</a>
|
|
92
93
|
</div>
|
|
93
94
|
</div>
|
|
95
|
+
{% endmacro %}
|
|
96
|
+
|
|
97
|
+
{% macro required_fields_disclaimer() %}
|
|
98
|
+
<div class="mb-3 mt-3">
|
|
99
|
+
<small class="text-muted"><span class="text-danger">*</span> indicates required fields</small>
|
|
100
|
+
</div>
|
|
94
101
|
{% endmacro %}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div class="modal fade" id="deleteProject" tabindex="-1" aria-labelledby="deleteProjectLabel" aria-hidden="true">
|
|
2
|
+
<div class="modal-dialog">
|
|
3
|
+
<div class="modal-content">
|
|
4
|
+
<form action="{{ url_for('project.delete_project', projectname=projectname) }}" method="POST"
|
|
5
|
+
data-reload-location="1">
|
|
6
|
+
<div class="modal-header">
|
|
7
|
+
<h5 class="modal-title" id="deleteProjectLabel">
|
|
8
|
+
<span>Delete Project</span>
|
|
9
|
+
</h5>
|
|
10
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="modal-body">
|
|
13
|
+
<p>Are you sure you want to delete the project
|
|
14
|
+
<p><strong>{{ projectname }}</strong>?</p>
|
|
15
|
+
This action cannot be undone.</p>
|
|
16
|
+
<p>All associated data will be permanently removed.</p>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="modal-footer">
|
|
19
|
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
20
|
+
<button type="submit" class="btn btn-danger">Delete</button>
|
|
21
|
+
</div>
|
|
22
|
+
</form>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div class="modal fade" id="genericModalContainer" tabindex="-1" aria-hidden="true">
|
|
2
|
+
<div class="modal-dialog modal-dialog-centered">
|
|
3
|
+
<div class="modal-body text-center bg-transparent border-0">
|
|
4
|
+
<div class="spinner-border text-white" style="width: 4rem; height: 4rem;" role="status">
|
|
5
|
+
<span class="visually-hidden">Loading...</span>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{% for item in items %}
|
|
2
|
+
<div class="list-group-item border-0">
|
|
3
|
+
<div class="d-flex align-items-center">
|
|
4
|
+
<div style="width: {{ item.depth * 1.2 }}rem"></div>
|
|
5
|
+
{% if item.type == 'folder' %}
|
|
6
|
+
<div class="form-check me-1">
|
|
7
|
+
{% if item.contains_xml or show_all_folders %}
|
|
8
|
+
{% if show_checkbox %}
|
|
9
|
+
<input class="form-check-input nextcloud-folder" type="checkbox" name="selected_folder"
|
|
10
|
+
value="{{ item.path }}" {{'checked' if item.path in selected_directories else '' }}>
|
|
11
|
+
{% endif %}
|
|
12
|
+
<label class="form-check-label">
|
|
13
|
+
<i class="bi bi-folder-fill text-warning me-1"></i>
|
|
14
|
+
{{ item.name }}
|
|
15
|
+
</label>
|
|
16
|
+
{% else %}
|
|
17
|
+
<i class="bi bi-folder-fill text-warning me-1"></i>
|
|
18
|
+
<span>{{ item.name }}</span>
|
|
19
|
+
{% endif %}
|
|
20
|
+
</div>
|
|
21
|
+
{% else %}
|
|
22
|
+
<i class="bi bi-file-text me-1 small"></i>
|
|
23
|
+
<span style="font-size: 0.7rem;">{{ item.name }}</span>
|
|
24
|
+
{% endif %}
|
|
25
|
+
</div>
|
|
26
|
+
{% if item.type == 'folder' and item.children.count > 0 %}
|
|
27
|
+
<div class="mt-1">
|
|
28
|
+
{% with items=item.children.list %}
|
|
29
|
+
{% include 'modal/file_explorer_content.html' %}
|
|
30
|
+
{% endwith %}
|
|
31
|
+
</div>
|
|
32
|
+
{% endif %}
|
|
33
|
+
</div>
|
|
34
|
+
{% endfor %}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="modal fade" id="folderModal{{ index }}" tabindex="-1">
|
|
2
|
+
<div class="modal-dialog modal-lg">
|
|
3
|
+
<div class="modal-content">
|
|
4
|
+
<div class="modal-header">
|
|
5
|
+
<h5 class="modal-title">
|
|
6
|
+
<i class="bi bi-folder2-open text-warning me-2"></i>
|
|
7
|
+
{{ folder.name }}
|
|
8
|
+
</h5>
|
|
9
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="modal-body">
|
|
12
|
+
{% if folder.children.count > 0 %}
|
|
13
|
+
{% with items=folder.children.list %}
|
|
14
|
+
{% include 'modal/file_explorer_content.html' %}
|
|
15
|
+
{% endwith %}
|
|
16
|
+
{% else %}
|
|
17
|
+
<p class="text-muted text-center py-3">Dieser Ordner ist leer</p>
|
|
18
|
+
{% endif %}
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<!-- Nextcloud <tree> Modal -->
|
|
3
|
+
<div class="modal-dialog modal-dialog-scrollable modal-lg">
|
|
4
|
+
<form class="modal-content js-modal-submit" data-reload-location="true"
|
|
5
|
+
action="{{ url_for('data.download_nextcloud', projectname=project.name) }}" method="POST"
|
|
6
|
+
id="nextcloudUploadForm">
|
|
7
|
+
<div class="modal-header">
|
|
8
|
+
<h5 class="modal-title" id="nextcloudModalLabel">Nextcloud Folders</h5>
|
|
9
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="modal-body">
|
|
12
|
+
{% for item in items %}
|
|
13
|
+
{% if item.type == 'folder' %}
|
|
14
|
+
{% with folder=item, index=loop.index %}
|
|
15
|
+
{% include 'modal/file_explorer_content.html' %}
|
|
16
|
+
{% endwith %}
|
|
17
|
+
{% endif %}
|
|
18
|
+
{% endfor %}
|
|
19
|
+
</div>
|
|
20
|
+
<div class="modal-footer">
|
|
21
|
+
<button type="submit" class="btn btn-success">Download selected</button>
|
|
22
|
+
<button type="button" name="form_type" value="logout"
|
|
23
|
+
data-url="{{ url_for('data.modal_nextcloud', projectname=project.name, logout=True) }}"
|
|
24
|
+
class="load-modal btn btn-danger">Logout</button>
|
|
25
|
+
</div>
|
|
26
|
+
</form>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<div class="modal fade" id="githubModal" tabindex="-1">
|
|
2
|
+
<div class="modal-dialog">
|
|
3
|
+
<div class="modal-content">
|
|
4
|
+
<div class="modal-header">
|
|
5
|
+
<h5 class="modal-title">Clone from GitHub</h5>
|
|
6
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="modal-body">
|
|
9
|
+
<form class="reloadModal" action="{{ url_for('data.clone_git_project', projectname=project.name) }}"
|
|
10
|
+
method="POST" id="cloneFromGit">
|
|
11
|
+
<div class="mb-3">
|
|
12
|
+
<input type="text" class="form-control" name="github_repo" placeholder="GitHub Repository URL">
|
|
13
|
+
</div>
|
|
14
|
+
<div class="d-flex justify-content-between align-items-center">
|
|
15
|
+
<small class="text-muted">
|
|
16
|
+
<i>Please be aware, that this can take a while (depending on the size of the git
|
|
17
|
+
project)!</i>
|
|
18
|
+
</small>
|
|
19
|
+
</div>
|
|
20
|
+
<button type="submit" class="btn btn-primary mt-3">
|
|
21
|
+
<span class="spinner-border spinner-border-sm me-2 d-none" role="status"
|
|
22
|
+
aria-hidden="true"></span>
|
|
23
|
+
<span>Clone Repository</span>
|
|
24
|
+
</button>
|
|
25
|
+
</form>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<!-- Nextcloud Upload Modal -->
|
|
3
|
+
<div class="modal-dialog modal-sm">
|
|
4
|
+
<div class="modal-content">
|
|
5
|
+
<form class="js-modal-submit" action="{{ url_for('data.modal_nextcloud', projectname=projectname) }}"
|
|
6
|
+
method="POST" id="nextcloudUploadForm">
|
|
7
|
+
<div class="modal-header">
|
|
8
|
+
<h5 class="modal-title">Login to Nextcloud</h5>
|
|
9
|
+
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="modal-body">
|
|
12
|
+
<div class="mb-3">
|
|
13
|
+
<label for="nextcloudUrl" class="form-label">Endpoint/URL *</label>
|
|
14
|
+
<input type="url" class="form-control" id="nextcloudUrl" name="nextcloud_url"
|
|
15
|
+
placeholder="https://cloud.example.com" required>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="mb-3">
|
|
18
|
+
<label for="nextcloudUser" class="form-label">Username *</label>
|
|
19
|
+
<input type="text" class="form-control" id="nextcloudUser" name="nextcloud_user" required>
|
|
20
|
+
</div>
|
|
21
|
+
<div class="mb-3">
|
|
22
|
+
<label for="nextcloudPassword" class="form-label">Password *</label>
|
|
23
|
+
<input type="password" class="form-control" id="nextcloudPassword" name="nextcloud_password"
|
|
24
|
+
required>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="mb-3">
|
|
27
|
+
<label for="nextcloudFolder" class="form-label">Folder</label>
|
|
28
|
+
<input type="text" class="form-control" id="nextcloudFolder" name="nextcloud_folder"
|
|
29
|
+
placeholder="/path/to/folder">
|
|
30
|
+
</div>
|
|
31
|
+
<div class="alert alert-info" role="alert">
|
|
32
|
+
<small>* Required fields</small>
|
|
33
|
+
</div>
|
|
34
|
+
{% if message %}
|
|
35
|
+
<div class="alert text-center alert-warning" role="alert">
|
|
36
|
+
{{ message }}
|
|
37
|
+
</div>
|
|
38
|
+
{% endif %}
|
|
39
|
+
</div>
|
|
40
|
+
<div class="modal-footer d-flex justify-content-center">
|
|
41
|
+
<button type="submit" class="btn btn-primary">
|
|
42
|
+
<span class="spinner-border spinner-border-sm me-2 d-none" role="status" aria-hidden="true"></span>
|
|
43
|
+
<span>Login</span>
|
|
44
|
+
</button>
|
|
45
|
+
</div>
|
|
46
|
+
</form>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|