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.
- zrb/__init__.py +5 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/api_client.py +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +1 -1
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase.py +1 -5
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_usecase_factory.py +6 -0
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/route.py +3 -9
- zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +44 -0
- zrb/config.py +17 -0
- zrb/input/any_input.py +4 -0
- zrb/input/base_input.py +4 -4
- zrb/input/bool_input.py +1 -1
- zrb/input/float_input.py +2 -2
- zrb/input/int_input.py +1 -1
- zrb/input/option_input.py +2 -2
- zrb/input/password_input.py +2 -2
- zrb/input/text_input.py +2 -2
- zrb/runner/cli.py +9 -34
- zrb/runner/common_util.py +31 -0
- zrb/runner/web_app.py +164 -44
- zrb/runner/web_config.py +288 -0
- zrb/runner/web_controller/error_page/controller.py +27 -0
- zrb/runner/web_controller/error_page/view.html +33 -0
- zrb/runner/web_controller/group_info_page/controller.py +40 -0
- zrb/runner/web_controller/group_info_page/view.html +36 -0
- zrb/runner/web_controller/home_page/controller.py +13 -48
- zrb/runner/web_controller/home_page/view.html +29 -20
- zrb/runner/web_controller/login_page/controller.py +25 -0
- zrb/runner/web_controller/login_page/view.html +50 -0
- zrb/runner/web_controller/logout_page/controller.py +26 -0
- zrb/runner/web_controller/logout_page/view.html +40 -0
- zrb/runner/web_controller/{task_ui → session_page}/controller.py +35 -26
- zrb/runner/web_controller/{task_ui → session_page}/partial/input.html +1 -1
- zrb/runner/web_controller/session_page/view.html +91 -0
- zrb/runner/web_controller/static/common.css +11 -0
- zrb/runner/web_controller/static/login/event.js +33 -0
- zrb/runner/web_controller/static/logout/event.js +20 -0
- zrb/runner/web_controller/static/pico.min.css +1 -1
- zrb/runner/web_controller/static/session/common-util.js +63 -0
- zrb/runner/web_controller/static/session/current-session.js +164 -0
- zrb/runner/web_controller/static/session/event.js +120 -0
- zrb/runner/web_controller/static/session/past-session.js +138 -0
- zrb/runner/web_util.py +53 -0
- {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/METADATA +2 -1
- {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/RECORD +50 -47
- zrb/runner/web_controller/group_info_ui/controller.py +0 -83
- zrb/runner/web_controller/group_info_ui/partial/group_info.html +0 -2
- zrb/runner/web_controller/group_info_ui/partial/group_li.html +0 -1
- zrb/runner/web_controller/group_info_ui/partial/task_info.html +0 -2
- zrb/runner/web_controller/group_info_ui/partial/task_li.html +0 -1
- zrb/runner/web_controller/group_info_ui/view.html +0 -31
- zrb/runner/web_controller/home_page/partial/group_info.html +0 -2
- zrb/runner/web_controller/home_page/partial/group_li.html +0 -1
- zrb/runner/web_controller/home_page/partial/task_info.html +0 -2
- zrb/runner/web_controller/home_page/partial/task_li.html +0 -1
- zrb/runner/web_controller/task_ui/__init__.py +0 -0
- zrb/runner/web_controller/task_ui/partial/common-util.js +0 -37
- zrb/runner/web_controller/task_ui/partial/main.js +0 -195
- zrb/runner/web_controller/task_ui/partial/show-existing-session.js +0 -97
- zrb/runner/web_controller/task_ui/partial/visualize-history.js +0 -104
- zrb/runner/web_controller/task_ui/view.html +0 -87
- /zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/{factory.py → user_repository_factory.py} +0 -0
- /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
- /zrb/runner/web_controller/{group_info_ui → session_page}/__init__.py +0 -0
- {zrb-1.0.0a18.dist-info → zrb-1.0.0a20.dist-info}/WHEEL +0 -0
- {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.
|
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=
|
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=
|
68
|
-
zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/direct_client.py,sha256=
|
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=
|
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/
|
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=
|
90
|
-
zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py,sha256=
|
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=
|
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=
|
144
|
-
zrb/input/base_input.py,sha256=
|
145
|
-
zrb/input/bool_input.py,sha256=
|
146
|
-
zrb/input/float_input.py,sha256=
|
147
|
-
zrb/input/int_input.py,sha256=
|
148
|
-
zrb/input/option_input.py,sha256=
|
149
|
-
zrb/input/password_input.py,sha256=
|
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=
|
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
|
154
|
-
zrb/runner/
|
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/
|
157
|
-
zrb/runner/web_controller/
|
158
|
-
zrb/runner/web_controller/
|
159
|
-
zrb/runner/web_controller/
|
160
|
-
zrb/runner/web_controller/
|
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=
|
165
|
-
zrb/runner/web_controller/home_page/
|
166
|
-
zrb/runner/web_controller/
|
167
|
-
zrb/runner/web_controller/
|
168
|
-
zrb/runner/web_controller/
|
169
|
-
zrb/runner/web_controller/
|
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/
|
172
|
-
zrb/runner/web_controller/
|
173
|
-
zrb/runner/web_controller/
|
174
|
-
zrb/runner/web_controller/
|
175
|
-
zrb/runner/web_controller/
|
176
|
-
zrb/runner/web_controller/
|
177
|
-
zrb/runner/web_controller/
|
178
|
-
zrb/runner/
|
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.
|
238
|
-
zrb-1.0.
|
239
|
-
zrb-1.0.
|
240
|
-
zrb-1.0.
|
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 +0,0 @@
|
|
1
|
-
<li><a href="{url}{caption}">{caption}</a> {description}</li>
|
@@ -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 +0,0 @@
|
|
1
|
-
<li><a href="/ui/{caption}">{caption}</a> {description}</li>
|
@@ -1 +0,0 @@
|
|
1
|
-
<li><a href="/ui/{caption}">{caption}</a> {description}</li>
|
File without changes
|