tg-prepare 1.0.0__tar.gz → 1.1.0__tar.gz

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 (59) hide show
  1. {tg_prepare-1.0.0/tg_prepare.egg-info → tg_prepare-1.1.0}/PKG-INFO +1 -1
  2. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/setup.py +1 -1
  3. {tg_prepare-1.0.0 → tg_prepare-1.1.0/tg_prepare.egg-info}/PKG-INFO +1 -1
  4. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tg_prepare.egg-info/SOURCES.txt +2 -12
  5. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_backend/directories.py +0 -4
  6. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_backend/project.py +9 -9
  7. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_backend/tgclient.py +0 -1
  8. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/app.py +9 -11
  9. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/js/main.js +48 -13
  10. tg_prepare-1.0.0/tgp_ui/templates/layout2.html → tg_prepare-1.1.0/tgp_ui/templates/layout.html +3 -2
  11. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/macros.html +28 -25
  12. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/project.html +4 -3
  13. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/projects.html +1 -1
  14. tg_prepare-1.1.0/tgp_ui/templates/publication.html +156 -0
  15. tg_prepare-1.0.0/tgp_ui/static/js/jstree.min.js +0 -3
  16. tg_prepare-1.0.0/tgp_ui/templates/conversions/gender.html +0 -15
  17. tg_prepare-1.0.0/tgp_ui/templates/conversions/reverse_input.html +0 -16
  18. tg_prepare-1.0.0/tgp_ui/templates/conversions/time_slot.html +0 -15
  19. tg_prepare-1.0.0/tgp_ui/templates/empty.html +0 -4
  20. tg_prepare-1.0.0/tgp_ui/templates/jsfiler.html +0 -6
  21. tg_prepare-1.0.0/tgp_ui/templates/layout.html +0 -59
  22. tg_prepare-1.0.0/tgp_ui/templates/main.html +0 -5
  23. tg_prepare-1.0.0/tgp_ui/templates/project_nxc.html +0 -37
  24. tg_prepare-1.0.0/tgp_ui/templates/publish.html +0 -120
  25. tg_prepare-1.0.0/tgp_ui/templates/tei_browser.html +0 -14
  26. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/LICENSE +0 -0
  27. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/MANIFEST.in +0 -0
  28. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/README.md +0 -0
  29. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/pyproject.toml +0 -0
  30. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/setup.cfg +0 -0
  31. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tg_prepare.egg-info/dependency_links.txt +0 -0
  32. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tg_prepare.egg-info/entry_points.txt +0 -0
  33. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tg_prepare.egg-info/requires.txt +0 -0
  34. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tg_prepare.egg-info/top_level.txt +0 -0
  35. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_backend/__init__.py +0 -0
  36. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_backend/auth.py +0 -0
  37. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_backend/cli.py +0 -0
  38. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_backend/interfaces.py +0 -0
  39. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_backend/nextcloud.py +0 -0
  40. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_backend/util.py +0 -0
  41. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/__init__.py +0 -0
  42. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/css/bootstrap-icons.min.css +0 -0
  43. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/css/bootstrap.min.css +0 -0
  44. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/css/bootstrap.min.css.map +0 -0
  45. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/css/main.css +0 -0
  46. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/css/simpleXML.css +0 -0
  47. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/img/favicon.ico +0 -0
  48. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/js/bootstrap.bundle.min.js +0 -0
  49. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/js/jquery.min.js +0 -0
  50. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/static/js/simpleXML.js +0 -0
  51. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/collection.html +0 -0
  52. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/file_tree.html +0 -0
  53. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/file_upload.html +0 -0
  54. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/nxc_file_tree.html +0 -0
  55. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/nxc_login.html +0 -0
  56. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/nxc_tab.html +0 -0
  57. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/storage.html +0 -0
  58. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/tei_explorer.html +0 -0
  59. {tg_prepare-1.0.0 → tg_prepare-1.1.0}/tgp_ui/templates/xpath_parser_modal_content.html +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tg_prepare
3
- Version: 1.0.0
3
+ Version: 1.1.0
4
4
  Summary: Simple UI to handle TextGrid imports visually.
5
5
  Author: Ralf Klammer, Moritz Wilhelm
6
6
  Author-email: ralf.klammer@tu-dresden.de, moritz.wilhelm@tu-dresden.de
@@ -7,7 +7,7 @@ from setuptools import setup, find_packages
7
7
 
8
8
  setup(
9
9
  name="tg_prepare",
10
- version="1.0.0",
10
+ version="1.1.0",
11
11
  description="Simple UI to handle TextGrid imports visually.",
12
12
  author="Ralf Klammer, Moritz Wilhelm",
13
13
  author_email="ralf.klammer@tu-dresden.de, moritz.wilhelm@tu-dresden.de",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tg_prepare
3
- Version: 1.0.0
3
+ Version: 1.1.0
4
4
  Summary: Simple UI to handle TextGrid imports visually.
5
5
  Author: Ralf Klammer, Moritz Wilhelm
6
6
  Author-email: ralf.klammer@tu-dresden.de, moritz.wilhelm@tu-dresden.de
@@ -28,29 +28,19 @@ tgp_ui/static/css/simpleXML.css
28
28
  tgp_ui/static/img/favicon.ico
29
29
  tgp_ui/static/js/bootstrap.bundle.min.js
30
30
  tgp_ui/static/js/jquery.min.js
31
- tgp_ui/static/js/jstree.min.js
32
31
  tgp_ui/static/js/main.js
33
32
  tgp_ui/static/js/simpleXML.js
34
33
  tgp_ui/templates/collection.html
35
- tgp_ui/templates/empty.html
36
34
  tgp_ui/templates/file_tree.html
37
35
  tgp_ui/templates/file_upload.html
38
- tgp_ui/templates/jsfiler.html
39
36
  tgp_ui/templates/layout.html
40
- tgp_ui/templates/layout2.html
41
37
  tgp_ui/templates/macros.html
42
- tgp_ui/templates/main.html
43
38
  tgp_ui/templates/nxc_file_tree.html
44
39
  tgp_ui/templates/nxc_login.html
45
40
  tgp_ui/templates/nxc_tab.html
46
41
  tgp_ui/templates/project.html
47
- tgp_ui/templates/project_nxc.html
48
42
  tgp_ui/templates/projects.html
49
- tgp_ui/templates/publish.html
43
+ tgp_ui/templates/publication.html
50
44
  tgp_ui/templates/storage.html
51
- tgp_ui/templates/tei_browser.html
52
45
  tgp_ui/templates/tei_explorer.html
53
- tgp_ui/templates/xpath_parser_modal_content.html
54
- tgp_ui/templates/conversions/gender.html
55
- tgp_ui/templates/conversions/reverse_input.html
56
- tgp_ui/templates/conversions/time_slot.html
46
+ tgp_ui/templates/xpath_parser_modal_content.html
@@ -28,7 +28,6 @@ def generateList(path=None):
28
28
  for name in os.listdir(path):
29
29
  fullpath = "%s/%s" % (path, name)
30
30
  if not name.startswith("."):
31
- print(name)
32
31
  if os.path.isdir(fullpath):
33
32
  dList.append({"fullpath": fullpath, "name": name})
34
33
  else:
@@ -79,7 +78,4 @@ def generateList(path=None):
79
78
 
80
79
  file_list_dict.append(temp_file)
81
80
 
82
- # log.debug("generateList - dir_list_dict: %s" % dir_list_dict)
83
- # print("generateList - file_list_dict: %s" % file_list_dict)
84
- # print(tp_dict)
85
81
  return dir_list_dict, file_list_dict
@@ -16,6 +16,8 @@ from tg_model.yaml import ( # type: ignore
16
16
  ProjectConfig,
17
17
  )
18
18
 
19
+ from tg_model.project import Project as TGMProject
20
+
19
21
  from tgp_backend.tgclient import TGclient
20
22
  from tgp_backend.util import config, list_files_and_folders
21
23
 
@@ -33,6 +35,7 @@ class Project(object):
33
35
  self._main_config = None
34
36
  self._collections = None
35
37
  self._nextcloud = None
38
+ self.tgm_project = TGMProject(self.metadatapath)
36
39
 
37
40
  def create(self):
38
41
  if not os.path.exists(self.fullpath):
@@ -62,7 +65,6 @@ class Project(object):
62
65
  file.save(filepath)
63
66
 
64
67
  def list_files_and_folders(self):
65
- print(self.datapath)
66
68
  return list_files_and_folders(self.datapath)
67
69
 
68
70
  @property
@@ -211,17 +213,16 @@ class TGProject(object):
211
213
  return False
212
214
 
213
215
  # step 1: create required metadata
214
- for c_name in self.collections:
215
- collection = self.collections[c_name]
216
- collection["modeler"].render_collection()
216
+ self.project.tgm_project.render_project()
217
217
 
218
218
  # step 2: push project to textgrid server
219
219
  for collection_name in self.collections:
220
220
  collection = self.collections[collection_name]
221
- self.tg_client.put_aggregation(
222
- self.tg_project_id,
223
- collection["modeler"].get_collection_path(),
224
- )
221
+ print(collection["modeler"].get_collection_path())
222
+ # self.tg_client.put_aggregation(
223
+ # self.tg_project_id,
224
+ # collection["modeler"].get_collection_path(),
225
+ # )
225
226
 
226
227
 
227
228
  class CollectionParser(object):
@@ -247,7 +248,6 @@ class CollectionParser(object):
247
248
  results = []
248
249
  for element in self.elements:
249
250
  result = element["tei_parser"].find(xpath)
250
- print(result)
251
251
  if result is not None:
252
252
  results.append(
253
253
  {
@@ -89,4 +89,3 @@ class TGclient(object):
89
89
  threaded=True,
90
90
  ignore_warnings=True,
91
91
  )
92
- print(res)
@@ -106,17 +106,6 @@ def startup(path):
106
106
  # *****************
107
107
  # VIEWS
108
108
  # *****************
109
- @app.route(
110
- "/sidebar",
111
- methods=["GET", "POST"],
112
- )
113
- def sidebar():
114
-
115
- return render_template(
116
- "layout2.html",
117
- )
118
-
119
-
120
109
  @app.route(
121
110
  "/xpath_parser_modal/<string:projectname>/<string:title>",
122
111
  methods=["GET", "POST"],
@@ -162,6 +151,15 @@ def collection(projectname, name):
162
151
  )
163
152
 
164
153
 
154
+ @app.route("/publication/<string:projectname>", methods=["GET", "POST"])
155
+ def publication(projectname):
156
+ project = Project(projectname)
157
+ return render_template(
158
+ "publication.html",
159
+ project=project,
160
+ )
161
+
162
+
165
163
  @app.route("/project/<string:projectname>", methods=["GET", "POST"])
166
164
  def project(projectname=None):
167
165
  params = {
@@ -51,7 +51,6 @@ const checkXPath = function (e) {
51
51
  const self = $(this);
52
52
  const tab = self.closest('form').find(
53
53
  '.tab-pane.tei-explorer-content.loaded');
54
- console.log(self.closest('.row').find('input[name=xpath]').val())
55
54
  $.ajax({
56
55
  url: self.data('url'),
57
56
  method: 'GET',
@@ -114,17 +113,35 @@ const saveCollectionSettings = function (e) {
114
113
  data[d.name] = d.value;
115
114
  })
116
115
 
117
- // loop through multi-inputs
118
- self.find('.multi-input').each(function (i, d1) {
119
- console.log(d1)
120
- let multi_input = $(d1);
116
+ self.find('.multi-input-xpath').each(function (i, mix) {
117
+ let multi_input = $(mix);
121
118
  if (data[multi_input.data('name')] === undefined) {
122
119
  data[multi_input.data('name')] = [];
123
120
  }
124
121
  // get all keys and values for each multi-input
125
122
  let item = {};
126
- multi_input.find('input').each(function (i, d2) {
127
- item[$(d2).data('key')] = $(d2).val();
123
+ multi_input.find('input').each(function (i, mix_input) {
124
+ const key = $(mix_input).data('key');
125
+ const type = $(mix_input).data('type');
126
+ if (item[key] === undefined) {
127
+ item[key] = {};
128
+ }
129
+ item[key][type] = $(mix_input).val();
130
+ });
131
+ console.table(item)
132
+ data[multi_input.data('name')].push(JSON.stringify(item))
133
+
134
+ })
135
+ // loop through multi-inputs with fixed values
136
+ self.find('.multi-input-fixed').each(function (i, mif) {
137
+ let multi_input = $(mif);
138
+ if (data[multi_input.data('name')] === undefined) {
139
+ data[multi_input.data('name')] = [];
140
+ }
141
+ // get all keys and values for each multi-input
142
+ let item = {};
143
+ multi_input.find('input').each(function (i, mif_input) {
144
+ item[$(mif_input).data('key')] = $(mif_input).val();
128
145
  });
129
146
  data[multi_input.data('name')].push(JSON.stringify(item))
130
147
  })
@@ -143,7 +160,6 @@ const saveCollectionSettings = function (e) {
143
160
  for (const [key, value] of Object.entries(_data)) {
144
161
  data[key] = JSON.stringify(value);
145
162
  }
146
- console.table(data)
147
163
 
148
164
  $.ajax({
149
165
  url: self.attr('action'),
@@ -319,6 +335,22 @@ const loadCollectionTab = function (e) {
319
335
  })
320
336
  }
321
337
  }
338
+ // Helper function to load the publication tab for a specific project
339
+ const _loadPublicationTab = function (projectname) {
340
+ // Select the tab element for the given project
341
+ const tab = $('#tab_publish_' + projectname);
342
+ tab.show(); // Make the tab visible
343
+ $('.tab-pane.active').hide(); // Hide the currently active tab
344
+ // Load the tab content via AJAX with the project name as data
345
+ tab.load(tab.data('url'), { projectname: projectname });
346
+ }
347
+
348
+ // Event handler to load the publication tab when triggered
349
+ const loadPublicationTab = function (e) {
350
+ const self = $(this); // Reference the clicked element
351
+ // Call the helper function with the project name from the data attribute
352
+ _loadPublicationTab(self.data('projectname'));
353
+ }
322
354
 
323
355
  // this function replaces (kind of) the normal submit
324
356
  // by sending the form data via ajax and reloading the tab content
@@ -327,10 +359,10 @@ const tabSubmit = function (e) {
327
359
  const self = $(this);
328
360
  const submit_icons = self.find('button[type=submit] span');
329
361
  submit_icons.toggle();
362
+
330
363
  $.post(self.attr('action'), self.serialize(), function (response) {
331
364
  if (response.response === 'OK') {
332
- submit_icons.toggle();
333
- // console.log(response)
365
+ _loadPublicationTab(self.data('projectname'));
334
366
  }
335
367
  })
336
368
  }
@@ -344,6 +376,7 @@ const selectTGProject = function (e) {
344
376
  .removeClass('bi-circle');
345
377
  $.post(self.data('url'), self.data(), function (response) {
346
378
  if (response.response === 'OK') {
379
+ _loadPublicationTab(self.data('projectname'));
347
380
  }
348
381
  })
349
382
  }
@@ -376,8 +409,7 @@ const deleteTGProject = function (e) {
376
409
  spans.toggle();
377
410
  // send delete request to server
378
411
  $.post(self.data('url'), function () {
379
- // hide spinner & show trash icon
380
- self.find('span').toggle();
412
+ _loadPublicationTab(self.data('projectname'));
381
413
  });
382
414
  // get the hits of the project
383
415
  getTGProjectHits(
@@ -435,8 +467,10 @@ $(document).ready(function () {
435
467
  // show xpath (of a 'dynamic attribute') in TEI Explorer
436
468
  $(document).on('click', '.show-xpath-in-tei-explorer', showXPathInTEIExplorer);
437
469
 
438
-
439
470
  // ##PUBLISH##
471
+ // load publication tab content
472
+ $(document).on('click', '.publication-tab', loadPublicationTab);
473
+
440
474
  // this is generic form-submit for all forms with class 'tab-submit'
441
475
  $(document).on('submit', 'form.tab-submit', tabSubmit);
442
476
  // select a listed TextGrid-Project
@@ -444,6 +478,7 @@ $(document).ready(function () {
444
478
  // delete a listed TextGrid-Project
445
479
  $(document).on('click', 'a.delete-tg-project', deleteTGProject);
446
480
 
481
+ // ###PROJECTS###
447
482
  $('#deleteProject').on('show.bs.modal', function (event) {
448
483
  const pressed_button = $(event.relatedTarget);
449
484
  const target_input = $(this).find('input[name=projectname]');
@@ -68,8 +68,9 @@
68
68
  </li>
69
69
  {% endfor %}
70
70
  <li class="sidebar-item">
71
- <a class="sidebar-link nav-link" data-bs-toggle="tab" href="#tab_publish" role="tab"
72
- aria-controls="tab_publish" aria-selected="false">
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">
73
74
  <i class="bi bi-cloud-upload"></i>
74
75
  Publish
75
76
  </a>
@@ -1,3 +1,21 @@
1
+ {% macro form_field_with_xpath(label, field_key, elem, has_next=False) %}
2
+ <div class="mb-2 row">
3
+ <div class="col-12 {{'pb-2 border-top' if has_next }}">
4
+ <label class="form-label">{{label}}
5
+ <a href="#" class="badge text-dark remove-multi-field">
6
+ <span class="bi bi-trash"></span>
7
+ </a>
8
+ </label>
9
+ <div class="input-group">
10
+ <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') }}">
12
+ <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') }}">
14
+ </div>
15
+ </div>
16
+ </div>
17
+ {% endmacro %}
18
+
1
19
  {% macro multi_input(type, heading, elements, version=1) %}
2
20
  <div class="border-top mb-3 row">
3
21
  <label class="col-sm-12 col-form-label">
@@ -10,30 +28,15 @@
10
28
  </label>
11
29
  </div>
12
30
  {% for item in elements or [None] %}
13
- <div class="multi-input" data-name="{{ type }}">
14
- {% if version == 1 %}
15
- <div class="mb-3 row">
16
- <label class="col-lg-2 col-form-label">ID
17
- <a href="#" class="badge text-dark remove-multi-field">
18
- <span class="bi bi-trash"></span>
19
- </a>
20
- </label>
21
- <div class="col-lg-4">
22
- <input type="text" class="form-control" data-key="id" value="{{ item['id'] if item['id'] }}">
23
- </div>
24
- <label class="col-lg-2 col-form-label">URL</label>
25
- <div class="col-lg-4">
26
- <input type="text" class="form-control" data-key="url" value="{{ item['url'] if item['url'] }}">
27
- </div>
28
- </div>
29
- <div class="mb-3 row">
30
- <label class="col-lg-2 col-form-label">Value</label>
31
- <div class="col-lg-10 {{'pb-2 border-bottom' if loop.nextitem }}">
32
- <input type="text" class="form-control" data-key="value" value="{{ item['value'] if item['value'] }}">
33
- </div>
34
- </div>
35
- {% elif version == 2 %}
36
- <div class="mb-3 row {{'pb-2 border-bottom' if loop.nextitem }}">
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 }}">
37
40
  <label class="col-lg-2 col-form-label">
38
41
  Fullname
39
42
  </label>
@@ -51,8 +54,8 @@
51
54
  </a>
52
55
  </div>
53
56
  </div>
54
- {% endif %}
55
57
  </div>
58
+ {% endif %}
56
59
  {% endfor %}
57
60
  {% endmacro %}
58
61
 
@@ -1,4 +1,4 @@
1
- {% extends 'layout2.html' %}
1
+ {% extends 'layout.html' %}
2
2
  {% block content %}
3
3
  <div class="row">
4
4
  <div class="tab-content pt-2" id="tab-content">
@@ -10,8 +10,9 @@
10
10
  <div class="tab-pane {{ 'active' if tab==collection_config.short_title }}" id="tab_{{ c }}" role="tabpanel">
11
11
  </div>
12
12
  {% endfor %}
13
- <div class="tab-pane {{'active' if tab=='publish' }}" id="tab_publish" role="tabpanel">
14
- {% include 'publish.html' %}
13
+ <div class="tab-pane {{'active' if tab=='publish' }}" id="tab_publish_{{ project.name }}"
14
+ data-url="{{ url_for('publication', projectname=project.name) }}" role="tabpanel">
15
+ <span class="spinner-border spinner-border-sm" role="status"></span>
15
16
  </div>
16
17
  </div>
17
18
  </div>
@@ -1,4 +1,4 @@
1
- {% extends 'layout2.html' %}
1
+ {% extends 'layout.html' %}
2
2
  {% block content %}
3
3
  <div class="row row-cols-xxl-6 row-cols-lg-4 row-cols-md-2">
4
4
  {% for project in projects%}
@@ -0,0 +1,156 @@
1
+ <div class="container-fluid p-4">
2
+ <div class="card shadow-sm border-0">
3
+ <div class="card-header bg-secondary bg-gradient text-white py-2">
4
+ <h5 class="mb-0">
5
+ <i class="bi bi-cloud-upload me-2"></i>
6
+ Publish project to TextGrid-Testinstance
7
+ </h5>
8
+ </div>
9
+
10
+ <div class="card-body p-3">
11
+ {% set tg_session_id = project.main_config.get_tg_session_id('test')%}
12
+
13
+ <!-- 1. Session ID Section -->
14
+ <div class="card bg-light border-0 shadow-sm mb-4">
15
+ <div class="card-body p-3">
16
+ <h5 class="card-title mb-3">Session ID</h5>
17
+ <form class="tab-submit" method="POST" data-projectname="{{ project.name }}"
18
+ action="{{ url_for('save_session_id', projectname=project.name, instance='test') }}">
19
+ <div class="row g-2 align-items-center">
20
+ <div class="col-md-8">
21
+ <div class="input-group shadow-sm">
22
+ <span class="input-group-text bg-light"><i class="bi bi-key"></i></span>
23
+ <input type="text" class="form-control" name="tg_auth_session_id"
24
+ placeholder="TgAuth Session ID" value="{{tg_session_id if tg_session_id}}">
25
+ </div>
26
+ </div>
27
+ <div class="col-md-4">
28
+ <button type="submit" class="btn btn-success w-100 shadow-sm">
29
+ <span class="bi bi-floppy2-fill me-2"></span>
30
+ <span class="spinner-border spinner-border-sm" style="display: none;"
31
+ role="status"></span>
32
+ Save Session ID
33
+ </button>
34
+ </div>
35
+ </div>
36
+ </form>
37
+ </div>
38
+ </div>
39
+
40
+ {% if tg_session_id %}
41
+ <!-- 2. Select Project Section -->
42
+ <div class="card bg-light border-0 shadow-sm mb-4">
43
+ <div class="card-body p-3">
44
+ <h5 class="card-title mb-3">Select from existing projects</h5>
45
+ <div class="list-group">
46
+ {% for tg_project in project.get_tgp('test').get_tg_projects() %}
47
+ <div
48
+ class="list-group-item list-group-item-action d-flex justify-content-between align-items-center py-2">
49
+ <div class="d-flex align-items-center">
50
+ <a href="#" class="text-success select-tg-project me-3"
51
+ data-url="{{ url_for('save_tg_project_id', projectname=project.name, instance='test') }}"
52
+ data-tg_project_id="{{ tg_project.id }}" data-projectname="{{ project.name }}">
53
+ <i
54
+ class="bi bi-{% if project.main_config.get_tg_project_id('test') == tg_project.id %}circle-fill{% else %}circle{% endif %} fs-5"></i>
55
+ <span class="spinner-border spinner-border-sm ms-2" style="display: none;"
56
+ role="status"></span>
57
+ </a>
58
+ <div>
59
+ <strong>{{ tg_project.name }}</strong>
60
+ <small class="text-muted d-block">
61
+ <span class="tgProjectHits badge bg-secondary me-2">{{ tg_project.contents
62
+ }}</span>
63
+ Elements | ID: {{ tg_project.id }}
64
+ </small>
65
+ </div>
66
+ </div>
67
+ <a href="#" class="btn btn-outline-danger btn-sm delete-tg-project"
68
+ data-projectname="{{ project.name }}"
69
+ data-url="{{ url_for('delete_tg_project_id', projectname=project.name, instance='test', tg_project_id= tg_project.id ) }}"
70
+ data-hits_url="{{ url_for('get_tg_project_hits', projectname=project.name, instance='test', tg_project_id= tg_project.id ) }}">
71
+ <span class="bi bi-trash me-1"></span>
72
+ <span class="spinner-border spinner-border-sm ms-2" style="display: none;"
73
+ role="status"></span>
74
+ <b>Delete</b>
75
+ </a>
76
+ </div>
77
+ {% endfor %}
78
+ </div>
79
+ </div>
80
+ </div>
81
+
82
+ <!-- 3. Create New Project Section -->
83
+ <div class="card bg-light border-0 shadow-sm mb-4">
84
+ <div class="card-body p-3">
85
+ <h5 class="card-title mb-3">Create new project</h5>
86
+ <form class="row g-2 tab-submit" method="POST" data-projectname="{{ project.name }}"
87
+ action="{{ url_for('create_tg_project', projectname=project.name, instance='test') }}">
88
+ <div class="col-md-8">
89
+ <input type="text" class="form-control" name="tg_projectname"
90
+ placeholder="Enter project name" required>
91
+ </div>
92
+ <div class="col-md-4">
93
+ <button type="submit" class="btn btn-secondary w-100">
94
+ <span class="bi bi-plus-circle me-2"></span>
95
+ <span class="spinner-border spinner-border-sm" style="display: none;"
96
+ role="status"></span>
97
+ <b>Create Project</b>
98
+ </button>
99
+ </div>
100
+ </form>
101
+ </div>
102
+ </div>
103
+
104
+ <!-- 4. Publish Project Section -->
105
+ <div class="card bg-light border-0 shadow-sm">
106
+ <div class="card-body p-3">
107
+ <h5 class="card-title mb-3">Publish project</h5>
108
+ <form class="tab-submit" method="POST" data-projectname="{{ project.name }}"
109
+ action="{{ url_for('publish_project', projectname=project.name, instance='test') }}">
110
+ <div class="d-flex justify-content-between align-items-center mb-3">
111
+ {% if project.main_config.get_tg_project_id('test') %}
112
+ <button type="submit" class="btn btn-success">
113
+ <span class="bi bi-rocket-takeoff me-2"></span>
114
+ <span class="spinner-border spinner-border-sm" style="display: none;"
115
+ role="status"></span>
116
+ Publish
117
+ </button>
118
+ {% endif %}
119
+ </div>
120
+
121
+ {% if project.main_config.get_tg_project_id('test') %}
122
+ <div class="alert alert-info mb-0">
123
+ <h6 class="alert-heading fw-bold mb-2">What's next?</h6>
124
+ <ol class="mb-0">
125
+ <li class="mb-2">Go to <a href="https://test.textgridrep.org/projects"
126
+ class="alert-link">Testinstance</a></li>
127
+ <li class="mb-2">Display 'Unpublished projects' <i>My TextGrid/Unpublished Data</i></li>
128
+ <li>Check if everything looks as favored</li>
129
+ </ol>
130
+ </div>
131
+ {% else %}
132
+ <div class="alert alert-warning mb-0">
133
+ <h6 class="alert-heading fw-bold mb-2">Attention</h6>
134
+ <p class="mb-0">You need to select a TextGrid project to publish!</p>
135
+ </div>
136
+ {% endif %}
137
+ </form>
138
+ </div>
139
+ </div>
140
+ {% else %}
141
+ <!-- No Session ID Warning -->
142
+ <div class="alert alert-warning shadow-sm">
143
+ <h5 class="alert-heading"><i class="bi bi-exclamation-triangle me-2"></i>Attention Required</h5>
144
+ <p class="mb-3">You need to provide a "TgAuth Session ID" to publish your project:</p>
145
+ <ol class="mb-0">
146
+ <li class="mb-2">Visit <a
147
+ href="https://test.textgridlab.org/1.0/Shibboleth.sso/Login?target=/1.0/secure/TextGrid-WebAuth.php?authZinstance=test.textgridlab.org"
148
+ class="alert-link" target="_blank">the authentication page</a></li>
149
+ <li class="mb-2">Click on "More Details" and copy the "TgAuth Session ID"</li>
150
+ <li>Paste the ID into the input field above and save</li>
151
+ </ol>
152
+ </div>
153
+ {% endif %}
154
+ </div>
155
+ </div>
156
+ </div>