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.

Files changed (70) hide show
  1. {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b2.dist-info}/METADATA +3 -3
  2. tg_prepare-2.1.0b2.dist-info/RECORD +78 -0
  3. {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b2.dist-info}/WHEEL +1 -1
  4. tg_prepare-2.1.0b2.dist-info/projects/.secret_key +1 -0
  5. tgp_backend/__init__.py +3 -4
  6. tgp_backend/config.py +31 -0
  7. tgp_backend/directories.py +6 -8
  8. tgp_backend/nextcloud.py +40 -19
  9. tgp_backend/project.py +172 -45
  10. tgp_backend/session_manager.py +47 -0
  11. tgp_backend/util.py +73 -25
  12. tgp_ui/app.py +43 -335
  13. tgp_ui/routes/__init__.py +0 -0
  14. tgp_ui/routes/collection.py +272 -0
  15. tgp_ui/routes/data.py +228 -0
  16. tgp_ui/routes/project.py +102 -0
  17. tgp_ui/routes/publication.py +129 -0
  18. tgp_ui/routes/tabs.py +34 -0
  19. tgp_ui/routes/views.py +62 -0
  20. tgp_ui/static/css/bootstrap.min.css.map +1 -0
  21. tgp_ui/static/css/navbar.css +92 -0
  22. tgp_ui/static/img/favicon.ico +0 -0
  23. tgp_ui/static/img/textgrid-logo.svg +1 -0
  24. tgp_ui/static/js/collectionManager.js +60 -0
  25. tgp_ui/static/js/fileManager.js +186 -0
  26. tgp_ui/static/js/main.js +32 -485
  27. tgp_ui/static/js/modalManager.js +105 -0
  28. tgp_ui/static/js/navbarManager.js +151 -0
  29. tgp_ui/static/js/projectManager.js +60 -0
  30. tgp_ui/static/js/require.js +5 -0
  31. tgp_ui/static/js/sidebarManager.js +32 -0
  32. tgp_ui/static/js/tabManager.js +79 -0
  33. tgp_ui/templates/details/empty_container.html +16 -0
  34. tgp_ui/templates/details/manage_collection.html +205 -0
  35. tgp_ui/templates/includes/set_session_id_form.html +16 -0
  36. tgp_ui/templates/includes/upload_form.html +131 -0
  37. tgp_ui/templates/layout.html +9 -48
  38. tgp_ui/templates/macros.html +79 -72
  39. tgp_ui/templates/modal/delete_project.html +25 -0
  40. tgp_ui/templates/modal/empty_container.html +9 -0
  41. tgp_ui/templates/modal/file_explorer_content.html +34 -0
  42. tgp_ui/templates/modal/file_explorer_main.html +22 -0
  43. tgp_ui/templates/modal/file_explorer_nextcloud.html +27 -0
  44. tgp_ui/templates/modal/github_modal.html +29 -0
  45. tgp_ui/templates/modal/nextcloud_login.html +48 -0
  46. tgp_ui/templates/modal/tei_explorer.html +58 -0
  47. tgp_ui/templates/modal/xpath_parser.html +52 -0
  48. tgp_ui/templates/project_main.html +36 -0
  49. tgp_ui/templates/project_navbar.html +81 -0
  50. tgp_ui/templates/{projects.html → projects_main.html} +13 -28
  51. tgp_ui/templates/tab_final_upload.html +29 -0
  52. tgp_ui/templates/tabs/check_result.html +90 -0
  53. tgp_ui/templates/tabs/edit_project.html +113 -0
  54. tgp_ui/templates/tabs/empty_container.html +12 -0
  55. tgp_ui/templates/tabs/import_data.html +138 -0
  56. tgp_ui/templates/tabs/manage_collections.html +88 -0
  57. tgp_ui/templates/tabs/select_directories.html +41 -0
  58. tgp_ui/templates/tabs/upload.html +42 -0
  59. tgp_ui/templates/tabs/validate_metadata.html +227 -0
  60. tg_prepare-1.1.0.dist-info/RECORD +0 -39
  61. tgp_ui/templates/collection.html +0 -194
  62. tgp_ui/templates/file_upload.html +0 -24
  63. tgp_ui/templates/nxc_file_tree.html +0 -33
  64. tgp_ui/templates/project.html +0 -26
  65. tgp_ui/templates/storage.html +0 -49
  66. tgp_ui/templates/tei_explorer.html +0 -48
  67. tgp_ui/templates/xpath_parser_modal_content.html +0 -37
  68. {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b2.dist-info}/entry_points.txt +0 -0
  69. {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b2.dist-info}/licenses/LICENSE +0 -0
  70. {tg_prepare-1.1.0.dist-info → tg_prepare-2.1.0b2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,58 @@
1
+ <div class="modal-dialog modal-xl">
2
+ <div class="modal-content">
3
+ <div class="modal-header align-items-center">
4
+ <h5 id="teiExplorerModalLabel" class="mb-0">TEI Explorer</h5>
5
+ <button type="button" class="btn-close ms-auto" data-bs-dismiss="modal" aria-label="Close"></button>
6
+ </div>
7
+ <div class="modal-body">
8
+ <!-- Tabs Navigation -->
9
+ <ul class="nav nav-tabs" id="teiExplorerTabs" role="tablist">
10
+ <li class="nav-item" role="presentation">
11
+ <button class="nav-link active" id="filesTab" data-bs-toggle="tab" data-bs-target="#files"
12
+ type="button" role="tab" aria-controls="files" aria-selected="true">
13
+ TEI Files
14
+ </button>
15
+ </li>
16
+ <li class="nav-item" role="presentation">
17
+ <button class="nav-link" id="contentTab" data-bs-toggle="tab" data-bs-target="#content"
18
+ type="button" role="tab" aria-controls="content" aria-selected="false">
19
+ TEI Content
20
+ </button>
21
+ </li>
22
+ </ul>
23
+
24
+ <!-- Tabs Content -->
25
+ <div class="tab-content" id="teiExplorerTabsContent" style="height: 70vh; overflow-y: auto;">
26
+ <!-- Tab: TEI Files -->
27
+ <div class="tab-pane fade show active" id="files" role="tabpanel" aria-labelledby="filesTab">
28
+ <ul class="list-group">
29
+ {% for file in file_list %}
30
+ <li class="list-group-item d-flex justify-content-between align-items-center">
31
+ <span class="text-truncate">{{ file.name_stripped }}</span>
32
+ <div class="btn-group">
33
+ <button class="btn btn-sm btn-outline-secondary load-tei-content"
34
+ data-url="{{ url_for('collection.load_tei_content') }}"
35
+ data-path="{{ file['fullpath'] }}" data-type="header" data-heading="TEI Header">
36
+ Header
37
+ </button>
38
+ <button class="btn btn-sm btn-outline-secondary load-tei-content"
39
+ data-url="{{ url_for('collection.load_tei_content') }}"
40
+ data-path="{{ file['fullpath'] }}" data-type="text" data-heading="TEI Text">
41
+ Text
42
+ </button>
43
+ </div>
44
+ </li>
45
+ {% endfor %}
46
+ </ul>
47
+ </div>
48
+
49
+ <!-- Tab: TEI Content -->
50
+ <div class="tab-pane fade" id="content" role="tabpanel" aria-labelledby="contentTab">
51
+ <div id="teiContentOutput" class="m-3">
52
+ <p class="text-muted">Select a file to view its content.</p>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </div>
@@ -0,0 +1,52 @@
1
+ <div class="modal-dialog modal-xl">
2
+ <div class="modal-content">
3
+ <div class="modal-header align-items-center">
4
+ <h5 id="xpathParserModalLabel" class="mb-0">Parse XPath:</h5>
5
+ <button type="button" class="btn-close ms-auto" data-bs-dismiss="modal" aria-label="Close"></button>
6
+ </div>
7
+ <div class="modal-body">
8
+ <form class="js-modal-submit mb-4" id="parseXPath"
9
+ action="{{ url_for('collection.modal_xpath_parser', projectname=projectname, collectionname=collectionname) }}">
10
+ <div class="input-group">
11
+ <input type="text" class="form-control" placeholder="Enter XPath query" name="xpath"
12
+ value="{{ xpath }}">
13
+ <button type="submit" class="btn btn-secondary">Parse</button>
14
+ </div>
15
+ </form>
16
+ {% set elements = collection_parser.elements %}
17
+ <div class="row">
18
+ {% if elements %}
19
+ {% for element in elements %}
20
+ {% set result = element['tei_parser'].find(xpath) if xpath else None %}
21
+ <div class="col mb-3">
22
+ <div class="card shadow-sm">
23
+ <div class="card-header bg-light">
24
+ <h6 class="mb-0 text-truncate">
25
+ <i class="bi bi-file-earmark-text"></i> {{ element['file']['filename'] }}
26
+ </h6>
27
+ </div>
28
+ {% if xpath %}
29
+ <div class="card-body border border-2 {{'border-success' if result else 'border-danger'}}">
30
+ {% else %}
31
+ <div class="card-body">
32
+ {% endif %}
33
+ {% if xpath %}
34
+ <p class="mb-0 text-muted small">
35
+ <b>XPath Result:</b>
36
+ <br>
37
+ {{ result }}
38
+ </p>
39
+ {% endif %}
40
+ </div>
41
+ </div>
42
+ </div>
43
+ {% endfor %}
44
+ {% else %}
45
+ <div class="col-12">
46
+ <p class="text-center text-muted">No files available for parsing.</p>
47
+ </div>
48
+ {% endif %}
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </div>
@@ -0,0 +1,36 @@
1
+ <!DOCTYPE html>
2
+ {% extends 'layout.html' %}
3
+ {% block content %}
4
+ <section class="">
5
+ <div class="container bg" id="navbar">
6
+ {% include 'project_navbar.html' %}
7
+ </div>
8
+ <div class="container tab-area mt-4 p-4 rounded-3">
9
+ <div class="tab-content">
10
+ <div class="tab-pane" id="tab-edit-project" role="tabpanel" aria-labelledby="tab-edit-project-tab"></div>
11
+ <div class="tab-pane" id="tab-edit-other-files" role="tabpanel" aria-labelledby="tab-edit-other-files-tab">
12
+ </div>
13
+ <div class="tab-pane" id="tab-import-data" role="tabpanel" aria-labelledby="tab-import-data-tab">
14
+ </div>
15
+ <div class="tab-pane" id="tab-select-directories" role="tabpanel" aria-labelledby="tab-set-collections-tab">
16
+ </div>
17
+ <div class="tab-pane" id="tab-set-collections" role="tabpanel" aria-labelledby="tab-set-collections-tab">
18
+ </div>
19
+ <div class="tab-pane" id="tab-prepare-metadata" role="tabpanel" aria-labelledby="tab-prepare-metadata-tab">
20
+ </div>
21
+ <div class="tab-pane" id="tab-check-metadata" role="tabpanel" aria-labelledby="tab-check-metadata-tab">
22
+ </div>
23
+ <div class="tab-pane" id="tab-prepare-upload" role="tabpanel" aria-labelledby="tab-prepare-upload-tab">
24
+ </div>
25
+ <div class="tab-pane" id="tab-check-results" role="tabpanel" aria-labelledby="tab-check-results-tab">
26
+ </div>
27
+ <div class="tab-pane" id="tab-final-upload" role="tabpanel" aria-labelledby="tab-final-upload-tab"></div>
28
+ </div>
29
+
30
+ <!-- <a href="#" class="m-4 text-muted helper position-fixed bottom-0 end-0 mx-5"
31
+ data-bs-toggle="Contact ... for help" title="Need help?">
32
+ <i class="bi bi-question-circle fs-1"></i>
33
+ </a> -->
34
+ </div>
35
+ </section>
36
+ {% endblock %}
@@ -0,0 +1,81 @@
1
+ <!DOCTYPE html>
2
+ <div class="row align-items-center justify-content-between position-relative">
3
+ <!-- Line -->
4
+ <div class="line blank"></div>
5
+ <div class="line blue"></div>
6
+
7
+ <!-- Main Button 1: Manage Project -->
8
+ <div class="col-auto expanding-button text-center">
9
+ <button type="button" class="btn btn-light btn-circle btn-xl" id="tab-group-project" title="Manage Project">
10
+ <i class="bi bi-archive main-icon"></i>
11
+ <div class="row sub-buttons d-none nav">
12
+ <!-- Sub-Button: Project Settings -->
13
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary last-opened " data-bs-toggle="tab"
14
+ data-bs-target="#tab-edit-project"
15
+ data-url="{{ url_for('project.tab_edit_project', projectname=project.name) }}">
16
+ <i class="bi bi-pen fs-4"></i>
17
+ </div>
18
+ <!-- Sub-Button: Upload Data -->
19
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
20
+ data-bs-target="#tab-import-data"
21
+ data-url="{{ url_for('data.tab_import_data', projectname=project.name)}}">
22
+ <i class="bi bi-archive fs-4"></i>
23
+ </div>
24
+ </div>
25
+ </button>
26
+ </div>
27
+
28
+ <!-- Main Button 2: Manage Collections -->
29
+ <div class="col-auto text-center">
30
+ <button type="button" class="btn btn-light btn-circle btn-xl" id="tab-group-collections"
31
+ title="Manage Collections">
32
+ <i class="bi bi-pencil"></i>
33
+ <div class="row sub-buttons d-none nav">
34
+ <!-- Sub-Button: Select Data -->
35
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
36
+ data-bs-target="#tab-select-directories"
37
+ data-url="{{ url_for('collection.tab_select_directories', projectname=project.name)}}">
38
+ <i class="bi bi-list-nested fs-4"></i>
39
+ </div>
40
+ <!-- Sub-Button: Manage Metadata -->
41
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
42
+ data-bs-target="#tab-set-collections"
43
+ data-url="{{ url_for('collection.tab_manage_collections', projectname=project.name)}}">
44
+ <i class="bi bi-pen fs-4"></i>
45
+ </div>
46
+ <!-- Sub-Button: Check Settings & Metadata -->
47
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
48
+ data-bs-target="#tab-check-metadata"
49
+ data-url="{{ url_for('collection.tab_validate_metadata', projectname=project.name)}}">
50
+ <i class="bi bi-list-check fs-4"></i>
51
+ </div>
52
+ </div>
53
+ </button>
54
+ </div>
55
+ <!-- Main Button 3: Upload & Publish to TextGrid -->
56
+ <div class="col-auto text-center">
57
+ <button type="button" class="btn btn-light btn-circle btn-xl" id="tab-group-upload">
58
+ <i class="bi bi-cloud"></i>
59
+ <div class="row sub-buttons d-none nav">
60
+ <!-- Sub-Button: TG-Sesssion-ID, -Project-ID & -Upload -->
61
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
62
+ data-bs-target="#tab-prepare-upload"
63
+ data-url="{{ url_for('publication.tab_upload', projectname=project.name)}}">
64
+ <i class="bi bi-key fs-4"></i>
65
+ </div>
66
+ <!-- Sub-Button: Check TG-Project -->
67
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
68
+ data-bs-target="#tab-check-results"
69
+ data-url="{{ url_for('publication.tab_check_result', projectname=project.name) }}">
70
+ <i class="bi bi-arrow-repeat fs-4"></i>
71
+ </div>
72
+ <!-- Sub-Button: TG-Publish -->
73
+ <div class="col-4 mx-3 btn-circle btn-sm btn-outline-secondary" data-bs-toggle="tab"
74
+ data-bs-target="#tab-final-upload"
75
+ data-url="{{ url_for('tab_final_upload', projectname=project.name)}}">
76
+ <i class="bi bi-cloud-upload fs-4"></i>
77
+ </div>
78
+ </div>
79
+ </button>
80
+ </div>
81
+ </div>
@@ -1,15 +1,22 @@
1
+ <!DOCTYPE html>
1
2
  {% extends 'layout.html' %}
2
3
  {% block content %}
4
+ <div class="row">
5
+ <div class="col-12">
6
+ <h1 class="text-center">Projects</h1>
7
+ <p class="text-center text-muted">Manage your projects here. You can create, edit, and delete projects.</p>
8
+ </div>
9
+ </div>
3
10
  <div class="row row-cols-xxl-6 row-cols-lg-4 row-cols-md-2">
4
- {% for project in projects%}
11
+ {% for project in get_projects() %}
5
12
  <div class="card text-center m-1">
6
13
  <div class="card-body">
7
14
  <h5 class="card-title">{{ project.name }}</h5>
8
- <a class="btn btn-secondary btn-forward" href="project/{{ project.name }}" title="Edit project">
15
+ <a class="btn btn-secondary btn-forward" href="project/{{ project.path }}" title="Edit project">
9
16
  <span class="bi bi-pencil-square"></span>
10
17
  </a>
11
- <a class="btn btn-danger btn-forward" title="Delete project" data-bs-toggle="modal"
12
- data-bs-target="#deleteProject" data-projectname="{{ project.name }}">
18
+ <a class="btn btn-danger load-modal" title="Delete project"
19
+ data-url="{{ url_for('project.modal_delete_project', projectname=project.path) }}">
13
20
  <span class="bi bi-trash"></span>
14
21
  </a>
15
22
  </div>
@@ -29,14 +36,14 @@
29
36
  <div class="modal fade" id="newProject" tabindex="-1" aria-labelledby="newProjectLabel" aria-hidden="true">
30
37
  <div class="modal-dialog">
31
38
  <div class="modal-content">
32
- <form action="{{ url_for('new_project') }}" method="POST">
39
+ <form action="{{ url_for('project.new_project') }}" method="POST">
33
40
  <div class="modal-header">
34
41
  <h5 class="modal-title" id="newProjectLabel">Create new Project</h5>
35
42
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
36
43
  </div>
37
44
  <div class="modal-body">
38
45
  <div class="mb-3">
39
- <input type="text" class="form-control" id="project" name="projectname"
46
+ <input type="text" id="projectNameInput" class="form-control" name="projectname"
40
47
  placeholder="Projectname" value="{{ projectname }}">
41
48
  </div>
42
49
  </div>
@@ -48,26 +55,4 @@
48
55
  </div>
49
56
  </div>
50
57
  </div>
51
-
52
- <div class="modal fade" id="deleteProject" tabindex="-1" aria-labelledby="deleteProjectLabel" aria-hidden="true">
53
- <div class="modal-dialog">
54
- <div class="modal-content">
55
- <form action="{{ url_for('projects') }}" method="POST">
56
- <div class="modal-header">
57
- <h5 class="modal-title" id="deleteProjectLabel">
58
- <span>Delete Project:</span>
59
- <i class="projectname"></i>
60
- </h5>
61
- <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
62
- </div>
63
- <div class="modal-footer">
64
- <input type="hidden" name="delete" value="true">
65
- <input type="hidden" name="projectname">
66
- <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
67
- <button type="submit" class="btn btn-danger">Delete</button>
68
- </div>
69
- </form>
70
- </div>
71
- </div>
72
- </div>
73
58
  {% endblock %}
@@ -0,0 +1,29 @@
1
+ <div class="container bg-white my-4 p-4 rounded">
2
+ <div class="row justify-content-center">
3
+ <div class="col-lg-8">
4
+ <div
5
+ class="bg-light rounded p-5 h-100 d-flex flex-column align-items-center justify-content-center shadow-sm">
6
+ <!-- TextGrid Logo -->
7
+ <img src="{{ url_for('static', filename='img/textgrid-logo.svg') }}" alt="TextGrid Logo"
8
+ style="max-width: 320px; height: auto;" class="mb-4">
9
+ <h2 class="fs-3 mb-4 text-center">
10
+ <i class="bi bi-cloud-upload text-primary me-2"></i>
11
+ Publish Project to <span class="text-primary">TextGrid Official Instance</span>
12
+ </h2>
13
+ <form method="POST"
14
+ action="{{ url_for('publication.upload_project', projectname=project.name, instance='live') }}"
15
+ class="w-100">
16
+ <button type="submit" class="btn btn-success btn-lg w-100 py-3" style="font-size:1.5rem;">
17
+ <i class="bi bi-rocket-takeoff me-2"></i>
18
+ Publish to Official Instance
19
+ </button>
20
+ </form>
21
+ <div class="alert alert-warning text-center mt-4 w-100" role="alert" style="font-size:1.1rem;">
22
+ <i class="bi bi-exclamation-triangle me-2"></i>
23
+ <b>Attention:</b> This action will publish your project to the official TextGrid instance.<br>
24
+ Please make sure you have checked your data carefully before proceeding!
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </div>
@@ -0,0 +1,90 @@
1
+ <div class="container py-4">
2
+ <div class="row">
3
+ <!-- Form Title -->
4
+ <div class="col-12 text-center mb-4">
5
+ <h1 class="fs-3 fw-bold">Check Upload Results</h1>
6
+ <p class="text-muted">Manually check for Issues</p>
7
+ </div>
8
+ </div>
9
+
10
+ <div class="row">
11
+ <div class="col-12 text-center mb-4">
12
+ <a href="https://test.textgridrep.org/projects" target="_blank" class="btn btn-lg btn-primary px-5 py-3">
13
+ <i class="bi bi-eye"></i> Open Preview Webview
14
+ </a>
15
+ </div>
16
+ </div>
17
+
18
+ <div class="row">
19
+ <!-- Bootstrap Carousel -->
20
+ <div class="col-md-6 d-flex align-items-center">
21
+ <div id="carouselExampleIndicators" class="carousel slide w-100" data-bs-ride="carousel">
22
+ <div class="carousel-indicators">
23
+ <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0"
24
+ class="active" aria-current="true" aria-label="Slide 1"></button>
25
+ <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1"
26
+ aria-label="Slide 2"></button>
27
+ <button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2"
28
+ aria-label="Slide 3"></button>
29
+ </div>
30
+ <div class="carousel-inner">
31
+ <div class="carousel-item active">
32
+ <img src="https://placehold.co/600x400" class="d-block w-100 rounded" alt="Slide 1">
33
+ </div>
34
+ <div class="carousel-item">
35
+ <img src="https://placehold.co/600x400" class="d-block w-100 rounded" alt="Slide 2">
36
+ </div>
37
+ <div class="carousel-item">
38
+ <img src="https://placehold.co/600x400" class="d-block w-100 rounded" alt="Slide 3">
39
+ </div>
40
+ </div>
41
+ <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleIndicators"
42
+ data-bs-slide="prev">
43
+ <span class="carousel-control-prev-icon" aria-hidden="true"></span>
44
+ <span class="visually-hidden">Previous</span>
45
+ </button>
46
+ <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleIndicators"
47
+ data-bs-slide="next">
48
+ <span class="carousel-control-next-icon" aria-hidden="true"></span>
49
+ <span class="visually-hidden">Next</span>
50
+ </button>
51
+ </div>
52
+ </div>
53
+ <!-- Info-Bereich: Hinweise für die Prüfung -->
54
+ <div class="col-md-6 mb-4 mb-md-0">
55
+ <div class="bg-light rounded p-4 h-100">
56
+ <h2 class="fs-4 mb-3">What to check in the preview?</h2>
57
+ <ul class="list-group mb-3">
58
+ <li class="list-group-item">
59
+ <i class="bi bi-spellcheck text-primary me-2"></i>
60
+ Check for typos and spelling mistakes.
61
+ </li>
62
+ <li class="list-group-item">
63
+ <i class="bi bi-card-list text-secondary me-2"></i>
64
+ Ensure all required metadata fields are present and correct.
65
+ </li>
66
+ <li class="list-group-item">
67
+ <i class="bi bi-calendar-check text-success me-2"></i>
68
+ Verify date formats and values.
69
+ </li>
70
+ <li class="list-group-item">
71
+ <i class="bi bi-person-check text-info me-2"></i>
72
+ Confirm author and contributor information.
73
+ </li>
74
+ <li class="list-group-item">
75
+ <i class="bi bi-eye text-warning me-2"></i>
76
+ Review the overall layout and formatting.
77
+ </li>
78
+ <li class="list-group-item">
79
+ <i class="bi bi-exclamation-triangle text-danger me-2"></i>
80
+ Look for missing or inconsistent data.
81
+ </li>
82
+ </ul>
83
+ <div class="alert alert-info mt-3" role="alert">
84
+ <b>Tip:</b> You can repeat this process as often as needed!
85
+ </div>
86
+ </div>
87
+ </div>
88
+
89
+ </div>
90
+ </div>
@@ -0,0 +1,113 @@
1
+ <!DOCTYPE html>
2
+ {% from "macros.html" import multi_input with context %}
3
+ <div class="container py-4">
4
+ <div class="row">
5
+ <!-- Form Title -->
6
+ <div class="col-12 text-center mb-4">
7
+ <h1 class="fs-3 fw-bold">Project Settings</h1>
8
+ <p class="text-muted">Define some basic settings of your project.</p>
9
+ </div>
10
+ </div>
11
+ <div class="row justify-content-center">
12
+ <div class="col-xl-8 col-lg-12">
13
+ <div class="bg-white border rounded-3 shadow-sm p-4">
14
+ <form method="POST" enctype="multipart/form-data"
15
+ action="{{ url_for('project.tab_edit_project', projectname=project.path) }}" id="editProjectForm"
16
+ class="js-tab-submit" data-next-target="#tab-import-data">
17
+ <div class="row">
18
+ <!-- Linke Seite: Name & Bild -->
19
+ <div class="col-md-5 d-flex flex-column align-items-center justify-content-start">
20
+ <div class="mb-3 w-100">
21
+ <label for="inlineFormInputName" class="form-label small">Name</label>
22
+ <input type="text" class="form-control" name="title" id="inlineFormInputName"
23
+ value="{{ project.title }}" placeholder="Name of the project">
24
+ </div>
25
+ <label for="inlineImage"
26
+ class="ratio ratio-1x1 d-block rounded overflow-hidden bg-light border mb-3"
27
+ style="cursor: pointer; height: 18rem; width: 100%;">
28
+ {% if project.avatar %}
29
+ <!-- Display existing project image -->
30
+ <div class="w-100 h-100" style="background-image: url({{ url_for('data.serve_image', filepath=project.avatar) }});
31
+ background-size: cover;
32
+ background-position: center;">
33
+ </div>
34
+ {% else %}
35
+ <div class="d-flex align-items-center justify-content-center bg-light h-100">
36
+ <div class="text-center">
37
+ <i class="bi bi-cloud-upload text-secondary d-block mb-2"
38
+ style="font-size: 2.5rem;"></i>
39
+ <span class="text-secondary">Upload image</span>
40
+ </div>
41
+ </div>
42
+ {% endif %}
43
+ </label>
44
+ <input type="file" class="showPreviewOfAvatar d-none" id="inlineImage" name="avatar"
45
+ accept="image/*">
46
+ </div>
47
+ <!-- Rechte Seite: Rest -->
48
+ <div class="col-md-7 d-flex flex-column">
49
+ <div class="">
50
+ <label for="xsltFileUpload" class="form-label small">Upload XSLT File</label>
51
+ <div class="d-flex align-items-center">
52
+ <!-- Custom File Input -->
53
+ <input class="form-control me-2" type="file" id="xsltFileUpload" name="xslt"
54
+ accept=".xslt,.xsl" title="Upload XSLT">
55
+
56
+ <!-- Löschen-Button -->
57
+ <button {{ "disabled" if not project.xslt else "" }} type="button"
58
+ data-projectname="{{project.name}}" id="deleteXsltButton"
59
+ class="btn btn-outline-danger me-2" title="Delete XSLT">
60
+ <i class="bi bi-trash"></i>
61
+ </button>
62
+
63
+ <!-- Anzeigen-Button -->
64
+ {% set path = url_for('data.serve_file', filepath=project.xslt or "") %}
65
+ <button {{ "disabled" if not project.xslt else "" }} type="button"
66
+ id="viewXsltButton" class="btn btn-outline-primary" title="View XSLT"
67
+ onclick="window.open('{{ path }}', '_blank' )">
68
+ <i class="bi bi-eye"></i>
69
+ </button>
70
+ </div>
71
+ </div>
72
+ <label for="formFile" class="form-label mb-2">
73
+ <div id="uploadStatus" class="mt-2 d-flex align-items-center gap-2">
74
+ {% if project.xslt %}
75
+ <span class="text-success d-flex align-items-center xslt-upload">
76
+ <i class="bi bi-check-circle me-2"></i>
77
+ {{ project.xslt.split('/')[-1] }}
78
+ </span>
79
+ {% else %}
80
+ <span class="text-danger d-flex align-items-center xslt-upload">
81
+ <i class="bi bi-exclamation-circle me-2"></i>
82
+ No file uploaded
83
+ </span>
84
+ {% endif %}
85
+ </div>
86
+ </label>
87
+ <div class="mb-3 flex-grow-1 d-flex flex-column">
88
+ <label for="inlineFormInputDescription" class="form-label small">Description</label>
89
+ <textarea class="form-control flex-grow-1" name="description"
90
+ id="inlineFormInputDescription">{{ project.description or '' }}</textarea>
91
+ </div>
92
+ </div>
93
+ <div class="col-12">
94
+ <div class="mb-3">
95
+ <label for="inlineFormInputCollector" class="form-label small">Collector/s</label>
96
+ {{ multi_input(project.collectors, 'collector') }}
97
+ </div>
98
+ </div>
99
+ <div class="col-12">
100
+ <div class="text-center mt-1">
101
+ <button type="submit" class="btn btn-primary px-4 rounded-3">
102
+ <i class="bi bi-chevron-right"></i> Next
103
+ </button>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </form>
108
+
109
+ </div>
110
+ </div>
111
+ </div>
112
+ </div>
113
+ </div>
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <div class="container py-5">
3
+ <div class="row justify-content-center">
4
+ <div class="col-md-6 text-center">
5
+ <div class="spinner-container my-5">
6
+ <div class="spinner-border text-secondary" style="width: 4rem; height: 4rem;" role="status">
7
+ <span class="visually-hidden">Loading...</span>
8
+ </div>
9
+ </div>
10
+ </div>
11
+ </div>
12
+ </div>