zrb 1.0.0a18__py3-none-any.whl → 1.0.0a20__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.
Files changed (66) hide show
  1. zrb/__init__.py +5 -0
  2. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +1 -1
  3. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +1 -1
  4. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +1 -1
  5. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase.py +1 -5
  6. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py +6 -0
  7. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +3 -9
  8. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +44 -0
  9. zrb/config.py +17 -0
  10. zrb/input/any_input.py +4 -0
  11. zrb/input/base_input.py +4 -4
  12. zrb/input/bool_input.py +1 -1
  13. zrb/input/float_input.py +2 -2
  14. zrb/input/int_input.py +1 -1
  15. zrb/input/option_input.py +2 -2
  16. zrb/input/password_input.py +2 -2
  17. zrb/input/text_input.py +2 -2
  18. zrb/runner/cli.py +9 -34
  19. zrb/runner/common_util.py +31 -0
  20. zrb/runner/web_app.py +164 -44
  21. zrb/runner/web_config.py +288 -0
  22. zrb/runner/web_controller/error_page/controller.py +27 -0
  23. zrb/runner/web_controller/error_page/view.html +33 -0
  24. zrb/runner/web_controller/group_info_page/controller.py +40 -0
  25. zrb/runner/web_controller/group_info_page/view.html +36 -0
  26. zrb/runner/web_controller/home_page/controller.py +13 -48
  27. zrb/runner/web_controller/home_page/view.html +29 -20
  28. zrb/runner/web_controller/login_page/controller.py +25 -0
  29. zrb/runner/web_controller/login_page/view.html +50 -0
  30. zrb/runner/web_controller/logout_page/controller.py +26 -0
  31. zrb/runner/web_controller/logout_page/view.html +40 -0
  32. zrb/runner/web_controller/{task_ui → session_page}/controller.py +35 -26
  33. zrb/runner/web_controller/{task_ui → session_page}/partial/input.html +1 -1
  34. zrb/runner/web_controller/session_page/view.html +91 -0
  35. zrb/runner/web_controller/static/common.css +11 -0
  36. zrb/runner/web_controller/static/login/event.js +33 -0
  37. zrb/runner/web_controller/static/logout/event.js +20 -0
  38. zrb/runner/web_controller/static/pico.min.css +1 -1
  39. zrb/runner/web_controller/static/session/common-util.js +63 -0
  40. zrb/runner/web_controller/static/session/current-session.js +164 -0
  41. zrb/runner/web_controller/static/session/event.js +120 -0
  42. zrb/runner/web_controller/static/session/past-session.js +138 -0
  43. zrb/runner/web_util.py +53 -0
  44. {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/METADATA +2 -1
  45. {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/RECORD +50 -47
  46. zrb/runner/web_controller/group_info_ui/controller.py +0 -83
  47. zrb/runner/web_controller/group_info_ui/partial/group_info.html +0 -2
  48. zrb/runner/web_controller/group_info_ui/partial/group_li.html +0 -1
  49. zrb/runner/web_controller/group_info_ui/partial/task_info.html +0 -2
  50. zrb/runner/web_controller/group_info_ui/partial/task_li.html +0 -1
  51. zrb/runner/web_controller/group_info_ui/view.html +0 -31
  52. zrb/runner/web_controller/home_page/partial/group_info.html +0 -2
  53. zrb/runner/web_controller/home_page/partial/group_li.html +0 -1
  54. zrb/runner/web_controller/home_page/partial/task_info.html +0 -2
  55. zrb/runner/web_controller/home_page/partial/task_li.html +0 -1
  56. zrb/runner/web_controller/task_ui/__init__.py +0 -0
  57. zrb/runner/web_controller/task_ui/partial/common-util.js +0 -37
  58. zrb/runner/web_controller/task_ui/partial/main.js +0 -195
  59. zrb/runner/web_controller/task_ui/partial/show-existing-session.js +0 -97
  60. zrb/runner/web_controller/task_ui/partial/visualize-history.js +0 -104
  61. zrb/runner/web_controller/task_ui/view.html +0 -87
  62. /zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/{factory.py → user_repository_factory.py} +0 -0
  63. /zrb/{builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository → runner/web_controller/group_info_page}/__init__.py +0 -0
  64. /zrb/runner/web_controller/{group_info_ui → session_page}/__init__.py +0 -0
  65. {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/WHEEL +0 -0
  66. {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,120 @@
1
+ window.addEventListener("load", async function () {
2
+ // Get current session
3
+ if (cfg.SESSION_NAME != "") {
4
+ CURRENT_SESSION.pollCurrentSession();
5
+ }
6
+ // set maxStartDate to today
7
+ const tomorrow = new Date();
8
+ tomorrow.setDate(tomorrow.getDate() + 1); // Move to the next day
9
+ tomorrow.setHours(0, 0, 0, 0);
10
+ const formattedTomorrow = UTIL.toLocalDateInputValue(tomorrow);
11
+ const maxStartAtInput = document.getElementById("max-start-at-input");
12
+ maxStartAtInput.value = formattedTomorrow;
13
+ // set minStartDate to yesterday
14
+ const today = new Date();
15
+ today.setHours(0, 0, 0, 0); // Set time to 00:00:00
16
+ const formattedToday = UTIL.toLocalDateInputValue(today);
17
+ const minStartAtInput = document.getElementById("min-start-at-input");
18
+ minStartAtInput.value = formattedToday;
19
+ // Update session
20
+ PAST_SESSION.pollPastSession();
21
+ });
22
+
23
+
24
+ const submitTaskForm = document.getElementById("submit-task-form");
25
+ submitTaskForm.addEventListener("input", async function(event) {
26
+ const currentInput = event.target;
27
+ const inputs = Array.from(submitTaskForm.querySelectorAll("input[name]"));
28
+ const inputMap = {};
29
+ const fixedInputNames = [];
30
+ for (const input of inputs) {
31
+ fixedInputNames.push(input.name);
32
+ if (input === currentInput) {
33
+ inputMap[input.name] = currentInput.value;
34
+ break;
35
+ } else {
36
+ inputMap[input.name] = input.value;
37
+ }
38
+ }
39
+ const queryString = new URLSearchParams(
40
+ {query: JSON.stringify(inputMap)}
41
+ ).toString();
42
+ try {
43
+ // Send the AJAX request
44
+ const response = await fetch(`${cfg.INPUT_API_URL}?${queryString}`, {
45
+ method: "GET",
46
+ headers: {
47
+ "Content-Type": "application/json"
48
+ },
49
+ });
50
+ if (response.ok) {
51
+ const data = await response.json();
52
+ // Update the values of all subsequent inputs based on the response
53
+ Object.entries(data).forEach(([key, value]) => {
54
+ if (fixedInputNames.includes(key)) {
55
+ return;
56
+ }
57
+ const input = submitTaskForm.querySelector(`[name="${key}"]`);
58
+ input.value = value;
59
+ });
60
+ } else {
61
+ console.error("Failed to fetch updated values:", response.statusText);
62
+ }
63
+ } catch (error) {
64
+ console.error("Error during fetch:", error);
65
+ }
66
+ })
67
+
68
+
69
+ function openPastSessionDialog(event) {
70
+ event.preventDefault();
71
+ const dialog = document.getElementById("past-session-dialog")
72
+ dialog.showModal();
73
+ }
74
+
75
+
76
+ function closePastSessionDialog(event) {
77
+ event.preventDefault();
78
+ const dialog = document.getElementById("past-session-dialog")
79
+ dialog.close();
80
+ }
81
+
82
+
83
+ async function submitNewSessionForm(event) {
84
+ // Prevent the form from submitting the traditional way
85
+ event.preventDefault();
86
+ // Select the form
87
+ const form = document.getElementById("submit-task-form");
88
+ // Initialize an empty object to hold form data
89
+ const formData = {};
90
+ // Iterate through each input in the form
91
+ Array.from(form.elements).forEach(element => {
92
+ // Only include inputs with a name attribute and ignore buttons
93
+ if (element.name && (element.type !== "button" && element.type !== "submit")) {
94
+ formData[element.name] = element.value;
95
+ }
96
+ });
97
+ // Convert formData to JSON
98
+ const jsonData = JSON.stringify(formData);
99
+ try {
100
+ // Send the AJAX request
101
+ const response = await fetch(cfg.SESSION_API_URL, {
102
+ method: "POST",
103
+ headers: {
104
+ "Content-Type": "application/json"
105
+ },
106
+ body: jsonData
107
+ });
108
+ if (response.ok) {
109
+ const data = await response.json();
110
+ cfg.SESSION_NAME = data.session_name;
111
+ history.pushState(null, "", `${cfg.CURRENT_URL}${cfg.SESSION_NAME}`);
112
+ await PAST_SESSION.getAndRenderPastSession(0);
113
+ await CURRENT_SESSION.pollCurrentSession();
114
+ } else {
115
+ console.error("Error:", response);
116
+ }
117
+ } catch (error) {
118
+ console.error("Error:", error);
119
+ }
120
+ }
@@ -0,0 +1,138 @@
1
+ const PAST_SESSION = {
2
+
3
+ async pollPastSession() {
4
+ while (true) {
5
+ await this.getAndRenderPastSession(cfg.PAGE);
6
+ await UTIL.delay(5000);
7
+ }
8
+ },
9
+
10
+ async getAndRenderPastSession(page) {
11
+ cfg.PAGE=page
12
+ const minStartAtInput = document.getElementById("min-start-at-input");
13
+ const minStartAt = UTIL.formatDate(minStartAtInput.value);
14
+ const maxStartAtInput = document.getElementById("max-start-at-input");
15
+ const maxStartAt = UTIL.formatDate(maxStartAtInput.value);
16
+ const queryString = new URLSearchParams({
17
+ page: page,
18
+ from: minStartAt,
19
+ to: maxStartAt,
20
+ }).toString();
21
+ try {
22
+ // Send the AJAX request
23
+ const response = await fetch(`${cfg.SESSION_API_URL}list?${queryString}`, {
24
+ method: "GET",
25
+ headers: {
26
+ "Content-Type": "application/json"
27
+ },
28
+ });
29
+ if (response.ok) {
30
+ const {total, data} = await response.json();
31
+ this.showPastSession(page, total, data);
32
+ } else {
33
+ console.error("Error:", response);
34
+ }
35
+ } catch (error) {
36
+ console.error("Error:", error);
37
+ }
38
+ },
39
+
40
+ showPastSession(page, total, data) {
41
+ const ul = document.getElementById("past-session-ul");
42
+ ul.innerHTML = ''; // Clear existing content
43
+ data.forEach(item => {
44
+ const taskStatus = item.task_status[item.main_task_name];
45
+ const finalStatus = UTIL.getFinalTaskStatus(taskStatus);
46
+ const finalColor = UTIL.getFinalColor(finalStatus);
47
+ const taskHistories = taskStatus.history;
48
+ const taskStartTime = taskHistories.length > 0 ? taskHistories[0].time : ""
49
+ const li = document.createElement('li');
50
+ const a = document.createElement('a');
51
+ const dateSpan = document.createElement('span');
52
+ const statusSpan = document.createElement('span');
53
+ a.textContent = item.name;
54
+ a.target = '_blank';
55
+ a.href = `${cfg.UI_URL}${item.name}`;
56
+ li.appendChild(a);
57
+ statusSpan.style.marginLeft = "10px";
58
+ statusSpan.style.display = 'inline-block';
59
+ statusSpan.style.width = '15px';
60
+ statusSpan.style.height = '15px';
61
+ statusSpan.style.borderRadius = '50%';
62
+ statusSpan.style.border = '2px solid black';
63
+ statusSpan.style.backgroundColor = finalColor;
64
+ li.appendChild(statusSpan);
65
+ dateSpan.style.marginLeft = "10px";
66
+ dateSpan.textContent = taskStartTime;
67
+ li.appendChild(dateSpan);
68
+ ul.appendChild(li);
69
+ });
70
+ const paginationUl = document.getElementById("past-session-pagination-ul");
71
+ paginationUl.innerHTML = ''; // Clear previous pagination
72
+
73
+ const totalPages = Math.ceil(total / 10); // Calculate total pages based on page size
74
+ const maxPagesToShow = 5; // Number of pages to display around the current page
75
+ const halfMaxPages = Math.floor(maxPagesToShow / 2);
76
+
77
+ // Add first page and previous controls
78
+ if (page > 0) {
79
+ paginationUl.appendChild(this.createPageLink("⟪", 0)); // Go to first page
80
+ paginationUl.appendChild(this.createPageLink("⟨", page - 1)); // Go to previous page
81
+ }
82
+
83
+ let startPage = Math.max(0, page - halfMaxPages);
84
+ let endPage = Math.min(totalPages - 1, page + halfMaxPages);
85
+
86
+ if (page <= halfMaxPages) {
87
+ endPage = Math.min(totalPages - 1, maxPagesToShow - 1);
88
+ } else if (page + halfMaxPages >= totalPages) {
89
+ startPage = Math.max(0, totalPages - maxPagesToShow);
90
+ }
91
+
92
+ if (startPage > 1) {
93
+ paginationUl.appendChild(this.createEllipsis());
94
+ }
95
+
96
+ // Add page links within the calculated range
97
+ for (let i = startPage; i <= endPage; i++) {
98
+ if (i === page) {
99
+ const pageLi = document.createElement('li');
100
+ pageLi.textContent = i + 1;
101
+ paginationUl.append(pageLi)
102
+ } else {
103
+ paginationUl.appendChild(this.createPageLink(i + 1, i))
104
+ }
105
+ }
106
+
107
+ // Add ellipsis after the end page if needed
108
+ if (endPage < totalPages - 2) {
109
+ paginationUl.appendChild(this.createEllipsis());
110
+ }
111
+
112
+ // Add next and last page controls
113
+ if (page < totalPages - 1) {
114
+ paginationUl.appendChild(this.createPageLink("⟩", page + 1)); // Go to next page
115
+ paginationUl.appendChild(this.createPageLink("⟫", totalPages - 1)); // Go to last page
116
+ }
117
+ },
118
+
119
+ createPageLink(text, page) {
120
+ const li = document.createElement('li');
121
+ const link = document.createElement('a');
122
+ link.textContent = text;
123
+ link.href = '#';
124
+ link.onclick = (e) => {
125
+ e.preventDefault();
126
+ this.getAndRenderPastSession(page);
127
+ };
128
+ li.appendChild(link);
129
+ return li;
130
+ },
131
+
132
+ createEllipsis() {
133
+ const li = document.createElement('li');
134
+ li.textContent = '...';
135
+ return li;
136
+ },
137
+
138
+ }
zrb/runner/web_util.py CHANGED
@@ -1,5 +1,10 @@
1
1
  from pydantic import BaseModel
2
2
 
3
+ from zrb.group.any_group import AnyGroup
4
+ from zrb.runner.web_config import User
5
+ from zrb.task.any_task import AnyTask
6
+ from zrb.util.group import get_non_empty_subgroups, get_subtasks
7
+
3
8
 
4
9
  class NewSessionResponse(BaseModel):
5
10
  session_name: str
@@ -14,3 +19,51 @@ def node_path_to_url(args: list[str]) -> str:
14
19
  pruned_args = [part for part in args if part.strip() != ""]
15
20
  stripped_url = "/".join(pruned_args)
16
21
  return f"/{stripped_url}/"
22
+
23
+
24
+ def get_html_auth_link(user: User) -> str:
25
+ if user.is_guest and user.is_super_admin:
26
+ return f"Hi, {user.username}"
27
+ if user.is_guest:
28
+ return f'Hi, {user.username} <a href="/login">Login 🔑</a>'
29
+ return f'Hi, {user.username} <a href="/logout">Logout 🚪</a>'
30
+
31
+
32
+ def get_html_subtask_info(user: User, parent_url: str, parent_group: AnyGroup) -> str:
33
+ subtasks = get_subtasks(parent_group, web_only=True)
34
+ task_li = "\n".join(
35
+ [
36
+ get_html_task_li(parent_url, alias, subtask)
37
+ for alias, subtask in subtasks.items()
38
+ if user.can_access_task(subtask)
39
+ ]
40
+ )
41
+ if task_li.strip() == "":
42
+ return ""
43
+ return f"<h5>Tasks</h5><ul>{task_li}</ul>"
44
+
45
+
46
+ def get_html_task_li(parent_url: str, alias: str, task: AnyTask) -> str:
47
+ if not parent_url.endswith("/"):
48
+ parent_url += "/"
49
+ return f'<li><a href="{parent_url}{alias}">{alias}</a> {task.description}</li>'
50
+
51
+
52
+ def get_html_subgroup_info(user: User, parent_url: str, parent_group: AnyGroup) -> str:
53
+ subgroups = get_non_empty_subgroups(parent_group, web_only=True)
54
+ group_li = "\n".join(
55
+ [
56
+ get_html_group_li(parent_url, alias, subgroup)
57
+ for alias, subgroup in subgroups.items()
58
+ if user.can_access_group(subgroup)
59
+ ]
60
+ )
61
+ if group_li.strip() == "":
62
+ return ""
63
+ return f"<h5>Groups</h5><ul>{group_li}</ul>"
64
+
65
+
66
+ def get_html_group_li(parent_url: str, alias: str, group: AnyGroup) -> str:
67
+ if not parent_url.endswith("/"):
68
+ parent_url += "/"
69
+ return f'<li><a href="{parent_url}{alias}">{alias}</a> {group.description}</li>'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zrb
3
- Version: 1.0.0a18
3
+ Version: 1.0.0a20
4
4
  Summary: Your Automation Powerhouse
5
5
  Home-page: https://github.com/state-alchemists/zrb
6
6
  License: AGPL-3.0-or-later
@@ -24,6 +24,7 @@ Requires-Dist: libcst (>=1.5.0,<2.0.0)
24
24
  Requires-Dist: litellm (>=1.52.12,<2.0.0)
25
25
  Requires-Dist: pdfplumber (>=0.11.4,<0.12.0) ; extra == "rag"
26
26
  Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
27
+ Requires-Dist: python-jose[cryptography] (>=3.3.0,<4.0.0)
27
28
  Requires-Dist: requests (>=2.32.3,<3.0.0)
28
29
  Project-URL: Documentation, https://github.com/state-alchemists/zrb
29
30
  Project-URL: Repository, https://github.com/state-alchemists/zrb
@@ -1,4 +1,4 @@
1
- zrb/__init__.py,sha256=ESskletjBpLO78a6wLigi9wnEGtmhfc3i_rbyMvrSyU,2767
1
+ zrb/__init__.py,sha256=YY3rfl2gdDLe-t5RMWsvlChSQXv6izw24yv0V1MQ60E,2911
2
2
  zrb/__main__.py,sha256=tCRJm0qtx646ojZP8Rtgu8t_SDdSpply21HbR5poVvk,744
3
3
  zrb/attr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  zrb/attr/type.py,sha256=4TV5gPYMMrKh5V-yB6iRYKCbsXAH_AvGXMsjxKLHcUs,568
@@ -64,30 +64,30 @@ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/migrate.py,sha256=K
64
64
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
65
65
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/alembic.ini,sha256=mgQyBAIwdkZZJWLu_FQWPx1FkyaARCNp6-rLqSVvMbA,3723
66
66
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/any_client.py,sha256=jJLY951xnDQoLdRrKQTE0aan73gw2a7Zb_4QCu6qCu4,767
67
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py,sha256=71_2Z4aekO5lM05AW4n9OHMV_MpiY-QSa8_dGyOjenM,283
68
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py,sha256=wsybQzLhm7Gn4rJVy5FObhRg7WZS43L77sNAxXbkhs4,214
67
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py,sha256=qgjykg69zgrVz8V2wN8bBY0ptGwkPp3Ae5G5IZVkhs4,291
68
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py,sha256=OIoUcTsYoTFmnzIazSZhQM9-l-7lsG-Fe54rrMpRSp0,222
69
69
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/factory.py,sha256=3Z-PStpA-7D_LiVO50CRchOY5m77rRhQrWcxq3fBLF4,390
70
70
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
71
71
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/env.py,sha256=rtUFa4Gaoz3wmq7YfQ-lY8vYA5aWguwe2yvQQ1OLCL8,3343
72
72
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/script.py.mako,sha256=U9DYBoBRd_ooogMfRydCUGEjIDZ-aV8OsjBiBrdTvy4,680
73
73
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_user_table.py,sha256=j4tkh9NaTKNMefcy1dUdgRI5CzydUidli7i0Q6Ap-7Q,1021
74
74
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration_metadata.py,sha256=ZO-6D7V-KyESQ_e7LjiWRovsSNP5E3KS_oVo77xdFh8,157
75
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py,sha256=Qlrrl86HARNKxQHyw-C98z_om27nCmk4ptgrvGAyEUo,1089
75
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py,sha256=TdQ38QeVGvqJdLH3Ixdg_R6emcV6pLtX8CFln1lrE5o,1097
76
76
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
77
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/factory.py,sha256=-tpEF53042tyorTLvWXpf_ti-w8W8wsvPzOOi_FsqZM,449
80
78
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py,sha256=4nz9-PBjm_Jr06nUoHXLj90Ygwm4qgT1Gy5MOMdoRfU,1583
81
79
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py,sha256=titxurh5C0sMZ49OTb53EG32QGYzKfZhvHqpyCxlVag,961
82
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase.py,sha256=dGXIGXnZpiJokFauo59YZA3gfMfOPgEAhd0og1tszUs,1991
80
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository_factory.py,sha256=-tpEF53042tyorTLvWXpf_ti-w8W8wsvPzOOi_FsqZM,449
81
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase.py,sha256=LxnjFXxpnCKnpv7BqYukdP_W06Ax1NTfGujLAR1RENo,1862
82
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py,sha256=R5mK1_XGUnog0AmbNnPiuPfWAWdPanxSeI8v3NJ601E,244
83
83
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/alembic.ini,sha256=mgQyBAIwdkZZJWLu_FQWPx1FkyaARCNp6-rLqSVvMbA,3723
84
84
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration/README,sha256=MVlc9TYmr57RbhXET6QxgyCcwWP7w-vLkEsirENqiIQ,38
85
85
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration/env.py,sha256=xQ4UYy6aaHhE0NssPZ6QkeNFlC1KBd07EhDR0NNzj20,3349
86
86
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration/script.py.mako,sha256=U9DYBoBRd_ooogMfRydCUGEjIDZ-aV8OsjBiBrdTvy4,680
87
87
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration/versions/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
88
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/migration_metadata.py,sha256=NbIb5ncy6x5RrFD2TZMDwxBK_wDTyJEIvieMRmNpf9M,55
89
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py,sha256=EYozpvbK-nMGArnqFzbR6sm45vxajK_8bcXqtvt6-f8,1467
90
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py,sha256=O_ZAxrvwQesXRv2Fpy0rEVhWpU5HKoFESlXxrVVCifE,1084
90
+ zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py,sha256=VWSyJw-Ou96a5EENn1poa-GlthJZ3Js-Pbn9sY8bndI,1813
91
91
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/requirements.txt,sha256=B8CigKAHjauuEyQaKQ-U9g3pAbe70femEScpZgblNbI,90
92
92
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
93
  zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/permission.py,sha256=vK8Qb5dDd_b5Y9gpehUr5OMSKggp1NlkWSz8ePAa0No,769
@@ -120,7 +120,7 @@ zrb/callback/callback.py,sha256=hKefB_Jd1XGjPSLQdMKDsGLHPzEGO2dqrIArLl_EmD0,848
120
120
  zrb/cmd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
121
121
  zrb/cmd/cmd_result.py,sha256=L8bQJzWCpcYexIxHBNsXj2pT3BtLmWex0iJSMkvimOA,597
122
122
  zrb/cmd/cmd_val.py,sha256=hr8Ge0FRe7FZStvkDYnd1MUOOiJW2lDOQqBv338Ymas,963
123
- zrb/config.py,sha256=YaV42wiMuiRlMjb3YNBL7ygRj7SzIsaEVMfdRk8hFds,3080
123
+ zrb/config.py,sha256=tqOcu19vUxElbOOr0t55dbgVVD3ya6WoUP2PqlfY9N0,3823
124
124
  zrb/content_transformer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
125
125
  zrb/content_transformer/any_content_transformer.py,sha256=3XHM6ZdsJFXxRD7YlUkv0Gn7-mexsH8c8zdHt3C0x8k,741
126
126
  zrb/content_transformer/content_transformer.py,sha256=vNR8Z_fS7dG2A42O7scDG96JYKBz6IDuFa_B4zMVzZY,2012
@@ -140,44 +140,47 @@ zrb/group/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
140
140
  zrb/group/any_group.py,sha256=1rNcsi5eu_86JAx_6Jy46SK4BTeppcb89MORynJd-4o,1115
141
141
  zrb/group/group.py,sha256=JFmWVEQ9PVy2WCf5pUG74iwL2xcGxXaAjT-NArAeloM,1861
142
142
  zrb/input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
143
- zrb/input/any_input.py,sha256=07KgoPusxLMOwBHRjiImL955J33qC-24qGf_3My6fCE,701
144
- zrb/input/base_input.py,sha256=DfDnYQZ84Xc19FEynGuNQKSDrbdcMaCOxramnncaac0,3165
145
- zrb/input/bool_input.py,sha256=m_mwzFtcAs26QIjVSiEDcqTQBukRtQ535RPGmH-b1_A,1384
146
- zrb/input/float_input.py,sha256=FqpAIsszHw7-eFyOzVmXaXNcCCLEL1_M3XwsevsNWX0,1005
147
- zrb/input/int_input.py,sha256=1knorHwOvSLuCPkcqA9iuYQG6Huy-8Vel5JNZqEFc44,1006
148
- zrb/input/option_input.py,sha256=xG0K6uQCqEpsO0pRsOyPWPEE77PYl65t2VwtCfeHYbA,1941
149
- zrb/input/password_input.py,sha256=C0h3kWJDI5KdXXQa-IXTQzyuCfjbx5tO34mn7kjmf2M,1313
143
+ zrb/input/any_input.py,sha256=0YxEaXvWyG3mWmBgUf3Z0HqtFag-JSoFuBSnfdqvWWI,803
144
+ zrb/input/base_input.py,sha256=AiSCxxYqJd5rlYsuzO1zqXQQ_ZuJsSONvR7t_m9Kj-I,3161
145
+ zrb/input/bool_input.py,sha256=zI1fea1k--r57vX61YVRog9sL_O7XX3gS7J3MGE8654,1383
146
+ zrb/input/float_input.py,sha256=W_FGgnL26l6iaNkWGHDXeu20B9QHAlyHonOVR2evin0,1015
147
+ zrb/input/int_input.py,sha256=tOgjhR8KYyahcmEto05lLzYtBowBUckwpcX4v-5sJlM,1005
148
+ zrb/input/option_input.py,sha256=S9IjGNzjPBexMb6BEuyyrPOcb10xjkFwVH02k2v7C2A,1939
149
+ zrb/input/password_input.py,sha256=C2alr0hgO_YLWf9MDF2H8w0NIIf_DZlDJSdKQwEyM0E,1311
150
150
  zrb/input/str_input.py,sha256=NevZHX9rf1g8eMatPyy-kUX3DglrVAQpzvVpKAzf7bA,81
151
- zrb/input/text_input.py,sha256=2WCCMNhC2HPr78G7pn5ZVjBNfS1u9TqbBj4YYbEtqWc,3035
151
+ zrb/input/text_input.py,sha256=7i0lvWYw79ILp0NEOBn-Twwnv7sBEgxJsqVaai6LzAA,3033
152
152
  zrb/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
153
- zrb/runner/cli.py,sha256=-NTsUU-U5zxKaHKLWlUuP0l-zGTv8Nhp51iv9BUCnjg,7592
154
- zrb/runner/web_app.py,sha256=9OeXY72Dcr7JkeoFfPPHBg1piLSZCiCmnoLX0x_AU-k,6397
153
+ zrb/runner/cli.py,sha256=ycus4N2T4sTdvLSxocyqjK3Atacm2vGRwpZuPhk9dDA,6573
154
+ zrb/runner/common_util.py,sha256=JYBgNPSGyJHZo0X-Qp9sDi4B14NdcTi20n1fJP4SW3M,1298
155
+ zrb/runner/web_app.py,sha256=7_j-FAJqHvFNN1q03iOC7Dw4tnd4uBwpAheH-LwMmnI,11404
156
+ zrb/runner/web_config.py,sha256=9T21eEkyQYZpjdV9uAIn8um1leKL3VGB7M2SBrrxxvk,9852
155
157
  zrb/runner/web_controller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
156
- zrb/runner/web_controller/group_info_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
- zrb/runner/web_controller/group_info_ui/controller.py,sha256=zRbbJpmpu6jX6iaEZUMgGmyaIgUd4wS9Entc8o5ZC14,2763
158
- zrb/runner/web_controller/group_info_ui/partial/group_info.html,sha256=njcPd6_imhPiUy3eGqtDpY_oX2R9nEh2dJQsh5PAl3M,35
159
- zrb/runner/web_controller/group_info_ui/partial/group_li.html,sha256=n9d_EBEMUg1rGmNhkYloCwc1jHmwovw3ScxEB_fNL-w,61
160
- zrb/runner/web_controller/group_info_ui/partial/task_info.html,sha256=dKHHuLIXi37XBbq0Xv2mYFcmJ3oAmz5vH1yKgpunfdE,34
161
- zrb/runner/web_controller/group_info_ui/partial/task_li.html,sha256=x5Pqa_iN0IyUvzojseGUrHm2Y-xUeO8OFb7Zagui2g0,62
162
- zrb/runner/web_controller/group_info_ui/view.html,sha256=7yIMx0yxSsmdmwPvXkm8tLgbmw7iqW068xzfFROmh9Y,836
158
+ zrb/runner/web_controller/error_page/controller.py,sha256=Dh2vanfPMvc5aAW0rLYOd2WwUrcO1fGdNVk80-8Qzzs,857
159
+ zrb/runner/web_controller/error_page/view.html,sha256=ZlC0oLRv5WXNI-iwP0TcOoQfP5jYZJ-8ojWx_055CcE,1110
160
+ zrb/runner/web_controller/group_info_page/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
+ zrb/runner/web_controller/group_info_page/controller.py,sha256=PBPCyVXILa7gCIC8d-0Exip7EAnTm3ch5GWe1Fs3WxI,1311
162
+ zrb/runner/web_controller/group_info_page/view.html,sha256=X-LtSQcbJ2HwTWGSZhN0MhXaSI4OqDF26DzyXh1COJo,1234
163
163
  zrb/runner/web_controller/home_page/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
164
- zrb/runner/web_controller/home_page/controller.py,sha256=QBKTJYHaiu2n9IM32X-KigNTIVO2YsS5Kgre2aU_1As,2178
165
- zrb/runner/web_controller/home_page/partial/group_info.html,sha256=njcPd6_imhPiUy3eGqtDpY_oX2R9nEh2dJQsh5PAl3M,35
166
- zrb/runner/web_controller/home_page/partial/group_li.html,sha256=gHF-RP8LG2ur8_mo1JwPXAZWvPM8BevAsdYrsv0uN6U,60
167
- zrb/runner/web_controller/home_page/partial/task_info.html,sha256=dKHHuLIXi37XBbq0Xv2mYFcmJ3oAmz5vH1yKgpunfdE,34
168
- zrb/runner/web_controller/home_page/partial/task_li.html,sha256=m-fs4VhbX27fZKgxBA0_Gv_Utntq5aaXD4sFk3zNMlk,61
169
- zrb/runner/web_controller/home_page/view.html,sha256=RuYx2V52_kTzb4Fkjpc2H97ZpSvlSB8ElbMng2uMDUI,606
164
+ zrb/runner/web_controller/home_page/controller.py,sha256=2e_Oarts9nnau7ZSdBDiqqvsw7qd7jsIB14BXAsu4FI,1008
165
+ zrb/runner/web_controller/home_page/view.html,sha256=p1ZoX604_q8JEqyU2awXnqKUI2bR8RXSEF4hUsLLiLc,1024
166
+ zrb/runner/web_controller/login_page/controller.py,sha256=vCRGgp8mW5JnYt-sPzWdJLLqlaARQO2zTOHAcPzkqrw,733
167
+ zrb/runner/web_controller/login_page/view.html,sha256=XANr3qHbAx3g8dGwx677zVeYbKiX5znEZPVi4oqnfcc,1715
168
+ zrb/runner/web_controller/logout_page/controller.py,sha256=0mX3wyY5jNtI1Jnxfl_7N8fHtLfBwPE81x9yh2zO_u4,764
169
+ zrb/runner/web_controller/logout_page/view.html,sha256=5hGZeil1Z4_oLRmkXdvXsDW12UFwlUt6u7wjDHvQS5s,1278
170
+ zrb/runner/web_controller/session_page/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
171
+ zrb/runner/web_controller/session_page/controller.py,sha256=bsnslbWLEGWyKdMtqvqXRZzGLAkvjIY2tVkvSOizN3s,2616
172
+ zrb/runner/web_controller/session_page/partial/input.html,sha256=X2jy0q7TLQGP853exZMed0lqPezL3gzn6mnhB5QKfkc,178
173
+ zrb/runner/web_controller/session_page/view.html,sha256=k-jAF_AOOCcNg1vdqsXEHEQWOzkyyxPaaU2WqCIM3uM,3547
174
+ zrb/runner/web_controller/static/common.css,sha256=u5rGLsPx2943z324iQ2X81krM3z-kc-8e1SkBdYAvKU,157
170
175
  zrb/runner/web_controller/static/favicon-32x32.png,sha256=yu9AIU4k_qD4YHpul6XwJgOxIbmu0thv9ymm2QOsrAk,1456
171
- zrb/runner/web_controller/static/pico.min.css,sha256=3V_VWRr9ge4h3MEXrYXAFNw_HxncLXt9EB6grMKSdMI,82194
172
- zrb/runner/web_controller/task_ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
- zrb/runner/web_controller/task_ui/controller.py,sha256=rHQeqpQFWoIPUOcDoYCNftEyOVDhMVhLCIyhZdcHNq0,2507
174
- zrb/runner/web_controller/task_ui/partial/common-util.js,sha256=Un5HxlFMzNa16UBJZEWvEldFJaZpt6O3Qddd9Zlw0Io,931
175
- zrb/runner/web_controller/task_ui/partial/input.html,sha256=DDOCdHfwrU8ZF1SSNb0KDaQzbhzn-gipEGaa_ZH5k9I,154
176
- zrb/runner/web_controller/task_ui/partial/main.js,sha256=3rjahRpypoQ6U2FwDTg21Zx7qt9zfbgzSxk6b6mNOQY,6514
177
- zrb/runner/web_controller/task_ui/partial/show-existing-session.js,sha256=o5J-O5poWMIL1ujBXparwA4YalFuGXyA8S_wFw8obsM,3637
178
- zrb/runner/web_controller/task_ui/partial/visualize-history.js,sha256=xKFmE-eXy9PXTWXhG_aQZ15DWStSGRrA8xzHntO-rmY,3916
179
- zrb/runner/web_controller/task_ui/view.html,sha256=SARL-Dt03ar8IT9RJt7ULJLsjRm5u8K_F4VFwQwhxAs,2668
180
- zrb/runner/web_util.py,sha256=FBMnS7qMp31ogm0pCZBObNjrlopIwzYM7UuZjCX1n8Q,428
176
+ zrb/runner/web_controller/static/login/event.js,sha256=1-NxaUwU-X7Tu2RAwVkzU7gngS0OdooH7Ple4_KDrh4,1135
177
+ zrb/runner/web_controller/static/logout/event.js,sha256=MfZxrTa2yL49Lbh7cCZDdqsIcf9e1q3W8-WjmZXV5pA,692
178
+ zrb/runner/web_controller/static/pico.min.css,sha256=_Esfkjs_U_igYn-tXBUaK3AEKb7d4l9DlmaOiw9bXfI,82214
179
+ zrb/runner/web_controller/static/session/common-util.js,sha256=t7_s5DXgMyZlT8L8LYZTkzOT6vWVeZvmCKjt-bflQY0,2117
180
+ zrb/runner/web_controller/static/session/current-session.js,sha256=oA1OFWeRYJzowL8-5mMpy32m9hv-_T6MwAuVruP7XDw,6515
181
+ zrb/runner/web_controller/static/session/event.js,sha256=NpFPV2kejUu_WSqfZgW57Un791L4NbmATujavcoIhrM,4217
182
+ zrb/runner/web_controller/static/session/past-session.js,sha256=LP0ABMTm7Ap9t9G-JF4b_pRm7BCbh96D_IFb5p91FgA,5325
183
+ zrb/runner/web_util.py,sha256=4t6DQ1Avb-aPaLCPB_Q3qaDOZssZ1oNsMBIW5MDqCIU,2262
181
184
  zrb/session/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
182
185
  zrb/session/any_session.py,sha256=x57mS15E-AfUjdVxwOWEzCBjW32zjer7WoeBw0guoDc,5266
183
186
  zrb/session/session.py,sha256=b89UdwPs0U9XXmTHNhCXFmcYXxuRVhNr94Dp_bVO3n4,9827
@@ -234,7 +237,7 @@ zrb/util/string/name.py,sha256=8picJfUBXNpdh64GNaHv3om23QHhUZux7DguFLrXHp8,1163
234
237
  zrb/util/todo.py,sha256=1nDdwPc22oFoK_1ZTXyf3638Bg6sqE2yp_U4_-frHoc,16015
235
238
  zrb/xcom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
236
239
  zrb/xcom/xcom.py,sha256=o79rxR9wphnShrcIushA0Qt71d_p3ZTxjNf7x9hJB78,1571
237
- zrb-1.0.0a18.dist-info/METADATA,sha256=h5C5cSwSpHtTmH3KEzwbjus-gdtA9liScrhbnhx4UhY,4106
238
- zrb-1.0.0a18.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
239
- zrb-1.0.0a18.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
240
- zrb-1.0.0a18.dist-info/RECORD,,
240
+ zrb-1.0.0a20.dist-info/METADATA,sha256=u-FbzxbG3e53o9Q9_YN93QeDzSKbsF6jq82fJB7EHhQ,4164
241
+ zrb-1.0.0a20.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
242
+ zrb-1.0.0a20.dist-info/entry_points.txt,sha256=-Pg3ElWPfnaSM-XvXqCxEAa-wfVI6BEgcs386s8C8v8,46
243
+ zrb-1.0.0a20.dist-info/RECORD,,
@@ -1,83 +0,0 @@
1
- import os
2
-
3
- from zrb.group.any_group import AnyGroup
4
- from zrb.util.file import read_file
5
- from zrb.util.group import get_non_empty_subgroups, get_subtasks
6
- from zrb.util.string.format import fstring_format
7
-
8
- _DIR = os.path.dirname(__file__)
9
-
10
- _VIEW_TEMPLATE = read_file(os.path.join(_DIR, "view.html"))
11
- _GROUP_INFO_TEMPLATE = read_file(os.path.join(_DIR, "partial", "group_info.html"))
12
- _GROUP_LI_TEMPLATE = read_file(os.path.join(_DIR, "partial", "group_li.html"))
13
- _TASK_INFO_TEMPLATE = read_file(os.path.join(_DIR, "partial", "task_info.html"))
14
- _TASK_LI_TEMPLATE = read_file(os.path.join(_DIR, "partial", "task_li.html"))
15
-
16
-
17
- def handle_group_info_ui(root_group: AnyGroup, group: AnyGroup, url: str):
18
- from fastapi.responses import HTMLResponse
19
-
20
- url_parts = url.split("/")
21
- parent_url_parts = url_parts[:-2] + [""]
22
- parent_url = "/".join(parent_url_parts)
23
- subgroups = get_non_empty_subgroups(group, web_only=True)
24
- group_info = (
25
- ""
26
- if len(subgroups) == 0
27
- else fstring_format(
28
- _GROUP_INFO_TEMPLATE,
29
- {
30
- "group_li": "\n".join(
31
- [
32
- fstring_format(
33
- _GROUP_LI_TEMPLATE,
34
- {
35
- "caption": name,
36
- "url": url,
37
- "description": group.description,
38
- },
39
- )
40
- for name, group in subgroups.items()
41
- ]
42
- )
43
- },
44
- )
45
- )
46
- subtasks = get_subtasks(group, web_only=True)
47
- task_info = (
48
- ""
49
- if len(subtasks) == 0
50
- else fstring_format(
51
- _TASK_INFO_TEMPLATE,
52
- {
53
- "task_li": "\n".join(
54
- [
55
- fstring_format(
56
- _TASK_LI_TEMPLATE,
57
- {
58
- "caption": name,
59
- "url": url,
60
- "description": task.description,
61
- },
62
- )
63
- for name, task in subtasks.items()
64
- ]
65
- )
66
- },
67
- )
68
- )
69
- return HTMLResponse(
70
- fstring_format(
71
- _VIEW_TEMPLATE,
72
- {
73
- "group_info": group_info,
74
- "task_info": task_info,
75
- "name": group.name,
76
- "description": group.description,
77
- "root_name": root_group.name,
78
- "root_description": root_group.description,
79
- "url": url,
80
- "parent_url": parent_url,
81
- },
82
- )
83
- )
@@ -1,2 +0,0 @@
1
- <h5>Groups</h5>
2
- <ul>{group_li}</ul>
@@ -1 +0,0 @@
1
- <li><a href="{url}{caption}">{caption}</a> {description}</li>
@@ -1,2 +0,0 @@
1
- <h5>Tasks</h5>
2
- <ul>{task_li}</ul>
@@ -1 +0,0 @@
1
- <li><a href="{url}{caption}">{caption}</a> {description}</li>
@@ -1,31 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
- <meta name="color-scheme" content="light dark">
7
- <link rel="stylesheet" href="/static/pico.min.css">
8
- <link rel="icon" href="/static/favicon-32x32.png" sizes="32x32" type="image/png">
9
- <title>Zrb</title>
10
- </head>
11
- <body>
12
- <header class="container">
13
- <hgroup>
14
- <h1>{root_name}</h1>
15
- <p>{root_description}</p>
16
- <nav>
17
- <ul>
18
- <li><a href="/">🏠 Home</a></li>
19
- <li><a href="{parent_url}">🔙 Parent</a></li>
20
- </ul>
21
- </nav>
22
- </hgroup>
23
- </header>
24
- <main class="container">
25
- <h3>{name}</h3>
26
- <p>{description}</p>
27
- {group_info}
28
- {task_info}
29
- </main>
30
- </body>
31
- </html>
@@ -1,2 +0,0 @@
1
- <h5>Groups</h5>
2
- <ul>{group_li}</ul>
@@ -1 +0,0 @@
1
- <li><a href="/ui/{caption}">{caption}</a> {description}</li>
@@ -1,2 +0,0 @@
1
- <h5>Tasks</h5>
2
- <ul>{task_li}</ul>
@@ -1 +0,0 @@
1
- <li><a href="/ui/{caption}">{caption}</a> {description}</li>
File without changes