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,40 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from zrb.group.any_group import AnyGroup
|
4
|
+
from zrb.runner.web_config import User
|
5
|
+
from zrb.runner.web_util import (
|
6
|
+
get_html_auth_link,
|
7
|
+
get_html_subgroup_info,
|
8
|
+
get_html_subtask_info,
|
9
|
+
)
|
10
|
+
from zrb.util.file import read_file
|
11
|
+
from zrb.util.string.format import fstring_format
|
12
|
+
|
13
|
+
|
14
|
+
def show_group_info_page(user: User, root_group: AnyGroup, group: AnyGroup, url: str):
|
15
|
+
from fastapi.responses import HTMLResponse
|
16
|
+
|
17
|
+
_DIR = os.path.dirname(__file__)
|
18
|
+
_VIEW_TEMPLATE = read_file(os.path.join(_DIR, "view.html"))
|
19
|
+
url_parts = url.split("/")
|
20
|
+
parent_url_parts = url_parts[:-2] + [""]
|
21
|
+
parent_url = "/".join(parent_url_parts)
|
22
|
+
group_info = get_html_subgroup_info(user, url, group)
|
23
|
+
task_info = get_html_subtask_info(user, url, group)
|
24
|
+
auth_link = get_html_auth_link(user)
|
25
|
+
return HTMLResponse(
|
26
|
+
fstring_format(
|
27
|
+
_VIEW_TEMPLATE,
|
28
|
+
{
|
29
|
+
"group_info": group_info,
|
30
|
+
"task_info": task_info,
|
31
|
+
"name": group.name,
|
32
|
+
"description": group.description,
|
33
|
+
"auth_link": auth_link,
|
34
|
+
"root_name": root_group.name,
|
35
|
+
"root_description": root_group.description,
|
36
|
+
"url": url,
|
37
|
+
"parent_url": parent_url,
|
38
|
+
},
|
39
|
+
)
|
40
|
+
)
|
@@ -0,0 +1,36 @@
|
|
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
|
+
<link rel="stylesheet" href="/static/common.css">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<header class="container">
|
14
|
+
<hgroup>
|
15
|
+
<h1>{root_name}</h1>
|
16
|
+
<p>{root_description}</p>
|
17
|
+
<nav>
|
18
|
+
<ul>
|
19
|
+
<li><a href="/">🏠 Home</a></li>
|
20
|
+
<li><a href="{parent_url}">🔙 Parent</a></li>
|
21
|
+
<li><a href="/docs">💻 API Documentation</a></li>
|
22
|
+
</ul>
|
23
|
+
<ul>
|
24
|
+
<li>{auth_link}</li>
|
25
|
+
</ul>
|
26
|
+
</nav>
|
27
|
+
</hgroup>
|
28
|
+
</header>
|
29
|
+
<main class="container">
|
30
|
+
<h3>{name}</h3>
|
31
|
+
<p>{description}</p>
|
32
|
+
{group_info}
|
33
|
+
{task_info}
|
34
|
+
</main>
|
35
|
+
</body>
|
36
|
+
</html>
|
@@ -1,60 +1,24 @@
|
|
1
1
|
import os
|
2
2
|
|
3
3
|
from zrb.group.any_group import AnyGroup
|
4
|
+
from zrb.runner.web_config import User
|
5
|
+
from zrb.runner.web_util import (
|
6
|
+
get_html_auth_link,
|
7
|
+
get_html_subgroup_info,
|
8
|
+
get_html_subtask_info,
|
9
|
+
)
|
4
10
|
from zrb.util.file import read_file
|
5
|
-
from zrb.util.group import get_non_empty_subgroups, get_subtasks
|
6
11
|
from zrb.util.string.format import fstring_format
|
7
12
|
|
8
|
-
_DIR = os.path.dirname(__file__)
|
9
13
|
|
10
|
-
|
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_home_page(root_group: AnyGroup):
|
14
|
+
def show_home_page(user: User, root_group: AnyGroup):
|
18
15
|
from fastapi.responses import HTMLResponse
|
19
16
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
_GROUP_INFO_TEMPLATE,
|
26
|
-
{
|
27
|
-
"group_li": "\n".join(
|
28
|
-
[
|
29
|
-
fstring_format(
|
30
|
-
_GROUP_LI_TEMPLATE,
|
31
|
-
{"caption": name, "description": group.description},
|
32
|
-
)
|
33
|
-
for name, group in subgroups.items()
|
34
|
-
]
|
35
|
-
)
|
36
|
-
},
|
37
|
-
)
|
38
|
-
)
|
39
|
-
subtasks = get_subtasks(root_group, web_only=True)
|
40
|
-
task_info = (
|
41
|
-
""
|
42
|
-
if len(subtasks) == 0
|
43
|
-
else fstring_format(
|
44
|
-
_TASK_INFO_TEMPLATE,
|
45
|
-
{
|
46
|
-
"task_li": "\n".join(
|
47
|
-
[
|
48
|
-
fstring_format(
|
49
|
-
_TASK_LI_TEMPLATE,
|
50
|
-
{"caption": name, "description": task.description},
|
51
|
-
)
|
52
|
-
for name, task in subtasks.items()
|
53
|
-
]
|
54
|
-
)
|
55
|
-
},
|
56
|
-
)
|
57
|
-
)
|
17
|
+
_DIR = os.path.dirname(__file__)
|
18
|
+
_VIEW_TEMPLATE = read_file(os.path.join(_DIR, "view.html"))
|
19
|
+
group_info = get_html_subgroup_info(user, "/ui/", root_group)
|
20
|
+
task_info = get_html_subtask_info(user, "/ui/", root_group)
|
21
|
+
auth_link = get_html_auth_link(user)
|
58
22
|
return HTMLResponse(
|
59
23
|
fstring_format(
|
60
24
|
_VIEW_TEMPLATE,
|
@@ -63,6 +27,7 @@ def handle_home_page(root_group: AnyGroup):
|
|
63
27
|
"task_info": task_info,
|
64
28
|
"name": root_group.name,
|
65
29
|
"description": root_group.description,
|
30
|
+
"auth_link": auth_link,
|
66
31
|
},
|
67
32
|
)
|
68
33
|
)
|
@@ -1,23 +1,32 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<html lang="en">
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
<
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
+
<link rel="stylesheet" href="/static/common.css">
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<header class="container">
|
14
|
+
<hgroup>
|
15
|
+
<h1>{name}</h1>
|
16
|
+
<p>{description}</p>
|
17
|
+
<nav>
|
18
|
+
<ul>
|
19
|
+
<li><a href="/docs">💻 API Documentation</a></li>
|
20
|
+
</ul>
|
21
|
+
<ul>
|
22
|
+
<li>{auth_link}</li>
|
23
|
+
</ul>
|
24
|
+
</nav>
|
25
|
+
</hgroup>
|
26
|
+
</header>
|
27
|
+
<main class="container">
|
28
|
+
{group_info}
|
29
|
+
{task_info}
|
30
|
+
</main>
|
31
|
+
</body>
|
23
32
|
</html>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from zrb.group.any_group import AnyGroup
|
4
|
+
from zrb.runner.web_config import User
|
5
|
+
from zrb.runner.web_util import get_html_auth_link
|
6
|
+
from zrb.util.file import read_file
|
7
|
+
from zrb.util.string.format import fstring_format
|
8
|
+
|
9
|
+
|
10
|
+
def show_login_page(user: User, root_group: AnyGroup):
|
11
|
+
from fastapi.responses import HTMLResponse
|
12
|
+
|
13
|
+
_DIR = os.path.dirname(__file__)
|
14
|
+
_VIEW_TEMPLATE = read_file(os.path.join(_DIR, "view.html"))
|
15
|
+
auth_link = get_html_auth_link(user)
|
16
|
+
return HTMLResponse(
|
17
|
+
fstring_format(
|
18
|
+
_VIEW_TEMPLATE,
|
19
|
+
{
|
20
|
+
"name": root_group.name,
|
21
|
+
"description": root_group.description,
|
22
|
+
"auth_link": auth_link,
|
23
|
+
},
|
24
|
+
)
|
25
|
+
)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta charset="utf-8">
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
7
|
+
<meta name="color-scheme" content="light dark">
|
8
|
+
<link rel="stylesheet" href="/static/pico.min.css">
|
9
|
+
<link rel="icon" href="/static/favicon-32x32.png" sizes="32x32" type="image/png">
|
10
|
+
<title>Zrb</title>
|
11
|
+
<link rel="stylesheet" href="/static/common.css">
|
12
|
+
</head>
|
13
|
+
|
14
|
+
<body>
|
15
|
+
<header class="container">
|
16
|
+
<hgroup>
|
17
|
+
<h1>{name}</h1>
|
18
|
+
<p>{description}</p>
|
19
|
+
<nav>
|
20
|
+
<ul>
|
21
|
+
<li><a href="/">🏠 Home</a></li>
|
22
|
+
<li><a href="/docs">💻 API Documentation</a></li>
|
23
|
+
</ul>
|
24
|
+
</nav>
|
25
|
+
</hgroup>
|
26
|
+
</header>
|
27
|
+
<main class="container">
|
28
|
+
<article>
|
29
|
+
<h1>Login</h1>
|
30
|
+
<form id="login-form" onsubmit="login(event)">
|
31
|
+
<label for="username">
|
32
|
+
Username
|
33
|
+
<input type="text" id="username" name="username" placeholder="Enter your username" required />
|
34
|
+
</label>
|
35
|
+
<label for="password">
|
36
|
+
Password
|
37
|
+
<input type="password" id="password" name="password" placeholder="Enter your password" required />
|
38
|
+
</label>
|
39
|
+
<div class="button-group">
|
40
|
+
<button class="primary">🔑 Login</button>
|
41
|
+
<button class="secondary" onclick="window.history.back()">🔙 Cancel</button>
|
42
|
+
</div>
|
43
|
+
</form>
|
44
|
+
<p id="error-message"></p>
|
45
|
+
</article>
|
46
|
+
</main>
|
47
|
+
<script src="/static/login/event.js"></script>
|
48
|
+
</body>
|
49
|
+
|
50
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from zrb.group.any_group import AnyGroup
|
4
|
+
from zrb.runner.web_config import User
|
5
|
+
from zrb.runner.web_util import get_html_auth_link
|
6
|
+
from zrb.util.file import read_file
|
7
|
+
from zrb.util.string.format import fstring_format
|
8
|
+
|
9
|
+
|
10
|
+
def show_logout_page(user: User, root_group: AnyGroup):
|
11
|
+
from fastapi.responses import HTMLResponse
|
12
|
+
|
13
|
+
_DIR = os.path.dirname(__file__)
|
14
|
+
_VIEW_TEMPLATE = read_file(os.path.join(_DIR, "view.html"))
|
15
|
+
auth_link = get_html_auth_link(user)
|
16
|
+
return HTMLResponse(
|
17
|
+
fstring_format(
|
18
|
+
_VIEW_TEMPLATE,
|
19
|
+
{
|
20
|
+
"name": root_group.name,
|
21
|
+
"description": root_group.description,
|
22
|
+
"auth_link": auth_link,
|
23
|
+
"user": user,
|
24
|
+
},
|
25
|
+
)
|
26
|
+
)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<html lang="en">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta charset="utf-8">
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
7
|
+
<meta name="color-scheme" content="light dark">
|
8
|
+
<link rel="stylesheet" href="/static/pico.min.css">
|
9
|
+
<link rel="icon" href="/static/favicon-32x32.png" sizes="32x32" type="image/png">
|
10
|
+
<title>Zrb</title>
|
11
|
+
<link rel="stylesheet" href="/static/common.css">
|
12
|
+
</head>
|
13
|
+
|
14
|
+
<body>
|
15
|
+
<header class="container">
|
16
|
+
<hgroup>
|
17
|
+
<h1>{name}</h1>
|
18
|
+
<p>{description}</p>
|
19
|
+
<nav>
|
20
|
+
<ul>
|
21
|
+
<li><a href="/">🏠 Home</a></li>
|
22
|
+
<li><a href="/docs">💻 API Documentation</a></li>
|
23
|
+
</ul>
|
24
|
+
</nav>
|
25
|
+
</hgroup>
|
26
|
+
</header>
|
27
|
+
<main class="container">
|
28
|
+
<article>
|
29
|
+
<h2>Ready to log out?</h2>
|
30
|
+
<p>You are currently logged in as <strong>{user.username}</strong>.</p>
|
31
|
+
<div class="button-group">
|
32
|
+
<button class="primary" onclick="logout()">🚪 Logout</button>
|
33
|
+
<button class="secondary" onclick="window.history.back()">🔙 Cancel</button>
|
34
|
+
</div>
|
35
|
+
</article>
|
36
|
+
</main>
|
37
|
+
<script src="/static/logout/event.js"></script>
|
38
|
+
</body>
|
39
|
+
|
40
|
+
</html>
|
@@ -1,42 +1,46 @@
|
|
1
|
+
import json
|
1
2
|
import os
|
2
3
|
|
3
4
|
from zrb.group.any_group import AnyGroup
|
5
|
+
from zrb.runner.web_config import User
|
6
|
+
from zrb.runner.web_util import get_html_auth_link
|
4
7
|
from zrb.session.any_session import AnySession
|
5
8
|
from zrb.task.any_task import AnyTask
|
6
9
|
from zrb.util.file import read_file
|
7
10
|
from zrb.util.string.format import fstring_format
|
8
11
|
|
9
|
-
_DIR = os.path.dirname(__file__)
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
os.path.join(_DIR, "partial", "visualize-history.js")
|
19
|
-
)
|
20
|
-
_COMMON_UTIL_SCRIPT = read_file(os.path.join(_DIR, "partial", "common-util.js"))
|
21
|
-
|
22
|
-
|
23
|
-
def handle_task_ui(
|
24
|
-
root_group: AnyGroup, task: AnyTask, session: AnySession, url: str, args: list[str]
|
13
|
+
def show_session_page(
|
14
|
+
user: User,
|
15
|
+
root_group: AnyGroup,
|
16
|
+
task: AnyTask,
|
17
|
+
session: AnySession,
|
18
|
+
url: str,
|
19
|
+
args: list[str],
|
25
20
|
):
|
26
21
|
from fastapi.responses import HTMLResponse
|
27
22
|
|
23
|
+
_DIR = os.path.dirname(__file__)
|
24
|
+
_VIEW_TEMPLATE = read_file(os.path.join(_DIR, "view.html"))
|
25
|
+
_TASK_INPUT_TEMPLATE = read_file(os.path.join(_DIR, "partial", "input.html"))
|
26
|
+
auth_link = get_html_auth_link(user)
|
27
|
+
|
28
28
|
session.register_task(task)
|
29
29
|
ctx = task.get_ctx(session)
|
30
30
|
url_parts = url.split("/")
|
31
31
|
# Assemble parent url
|
32
32
|
parent_url_parts = url_parts[:-2] + [""]
|
33
33
|
parent_url = "/".join(parent_url_parts)
|
34
|
-
# Assemble api url
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
# Assemble session api url
|
35
|
+
session_url_parts = list(url_parts)
|
36
|
+
session_url_parts[1] = "api/sessions"
|
37
|
+
session_api_url = "/".join(session_url_parts)
|
38
|
+
# Assemble input api url
|
39
|
+
input_url_parts = list(url_parts)
|
40
|
+
input_url_parts[1] = "api/inputs"
|
41
|
+
input_api_url = "/".join(input_url_parts)
|
38
42
|
# Assemble ui url
|
39
|
-
ui_url_parts = list(
|
43
|
+
ui_url_parts = list(url_parts)
|
40
44
|
ui_url_parts[1] = "ui"
|
41
45
|
ui_url = "/".join(ui_url_parts)
|
42
46
|
# Assemble task inputs
|
@@ -53,18 +57,23 @@ def handle_task_ui(
|
|
53
57
|
{
|
54
58
|
"name": task.name,
|
55
59
|
"description": task.description,
|
60
|
+
"auth_link": auth_link,
|
56
61
|
"root_name": root_group.name,
|
57
62
|
"root_description": root_group.description,
|
58
63
|
"url": url,
|
59
64
|
"parent_url": parent_url,
|
60
65
|
"task_inputs": "\n".join(input_html_list),
|
61
|
-
"api_url": api_url,
|
62
66
|
"ui_url": ui_url,
|
63
|
-
"
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
67
|
+
"json_cfg": json.dumps(
|
68
|
+
{
|
69
|
+
"CURRENT_URL": url,
|
70
|
+
"SESSION_API_URL": session_api_url,
|
71
|
+
"INPUT_API_URL": input_api_url,
|
72
|
+
"UI_URL": ui_url,
|
73
|
+
"SESSION_NAME": session_name,
|
74
|
+
"PAGE": 0,
|
75
|
+
}
|
76
|
+
),
|
68
77
|
},
|
69
78
|
)
|
70
79
|
)
|
@@ -0,0 +1,91 @@
|
|
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
|
+
|
13
|
+
<header class="container">
|
14
|
+
<hgroup>
|
15
|
+
<h1>{root_name}</h1>
|
16
|
+
<p>{root_description}</p>
|
17
|
+
<nav>
|
18
|
+
<ul>
|
19
|
+
<li><a href="/">🏠 Home</a></li>
|
20
|
+
<li><a href="{parent_url}">🔙 Parent</a></li>
|
21
|
+
<li><a href="/docs">💻 API Documentation</a></li>
|
22
|
+
<li><a href="{ui_url}">🆕 New Session</a></li>
|
23
|
+
<li><a href="#" onclick="openPastSessionDialog(event)">📂 Existing Session</a></li>
|
24
|
+
</ul>
|
25
|
+
<ul>
|
26
|
+
<li>{auth_link}</li>
|
27
|
+
</ul>
|
28
|
+
</nav>
|
29
|
+
</hgroup>
|
30
|
+
</header>
|
31
|
+
|
32
|
+
<dialog id="past-session-dialog">
|
33
|
+
<article>
|
34
|
+
<header>
|
35
|
+
<button aria-label="Close" rel="prev" onclick="closePastSessionDialog(event)"></button>
|
36
|
+
<p>
|
37
|
+
<strong>📂 Existing Session</strong>
|
38
|
+
</p>
|
39
|
+
</header>
|
40
|
+
<main>
|
41
|
+
<form>
|
42
|
+
<fieldset class="grid">
|
43
|
+
<input type="datetime-local" id="min-start-at-input" placeholder="Minimum Start Time" aria-label="Minimum Start Time" />
|
44
|
+
<input type="datetime-local" id="max-start-at-input" placeholder="Maximum Start Time" aria-label="Maximum Start Time" />
|
45
|
+
</fieldset>
|
46
|
+
</form>
|
47
|
+
<ul id="past-session-ul" style="font-family:monospace;"></ul>
|
48
|
+
</main>
|
49
|
+
<footer>
|
50
|
+
<nav>
|
51
|
+
<ul id="past-session-pagination-ul"></ul>
|
52
|
+
</nav>
|
53
|
+
</footer>
|
54
|
+
</article>
|
55
|
+
</dialog>
|
56
|
+
|
57
|
+
<main class="container">
|
58
|
+
<article>
|
59
|
+
<h2>{name}</h2>
|
60
|
+
<p>{description}</p>
|
61
|
+
<canvas id="history-canvas" height="0" width="1000" style="width: 100%;"></canvas>
|
62
|
+
</article>
|
63
|
+
<article>
|
64
|
+
<form id="submit-task-form" onsubmit="submitNewSessionForm(event)">
|
65
|
+
{task_inputs}
|
66
|
+
<button>🚀 Run</button>
|
67
|
+
</form>
|
68
|
+
</article>
|
69
|
+
<article>
|
70
|
+
<label>
|
71
|
+
Result
|
72
|
+
<textarea id="result-textarea" rows="1" readonly style="font-family:monospace;">
|
73
|
+
</textarea>
|
74
|
+
</label>
|
75
|
+
<label>
|
76
|
+
Log
|
77
|
+
<textarea id="log-textarea" rows="5" readonly style="font-family:monospace;">
|
78
|
+
</textarea>
|
79
|
+
</label>
|
80
|
+
</article>
|
81
|
+
</main>
|
82
|
+
|
83
|
+
</body>
|
84
|
+
<script>
|
85
|
+
const cfg = {json_cfg};
|
86
|
+
</script>
|
87
|
+
<script src="/static/session/common-util.js"></script>
|
88
|
+
<script src="/static/session/past-session.js"></script>
|
89
|
+
<script src="/static/session/current-session.js"></script>
|
90
|
+
<script src="/static/session/event.js"></script>
|
91
|
+
</html>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
async function login(event) {
|
2
|
+
event.preventDefault();
|
3
|
+
|
4
|
+
const username = document.getElementById('username').value;
|
5
|
+
const password = document.getElementById('password').value;
|
6
|
+
const errorMessage = document.getElementById('error-message');
|
7
|
+
|
8
|
+
try {
|
9
|
+
const response = await fetch('/api/v1/login', {
|
10
|
+
method: 'POST',
|
11
|
+
headers: {
|
12
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
13
|
+
},
|
14
|
+
body: new URLSearchParams({
|
15
|
+
'username': username,
|
16
|
+
'password': password,
|
17
|
+
}),
|
18
|
+
});
|
19
|
+
|
20
|
+
if (response.ok) {
|
21
|
+
const data = await response.json();
|
22
|
+
console.log('Login successful', data);
|
23
|
+
// Redirect to home page or dashboard
|
24
|
+
window.location.href = '/';
|
25
|
+
} else {
|
26
|
+
const errorData = await response.json();
|
27
|
+
errorMessage.textContent = errorData.detail || 'Login failed. Please try again.';
|
28
|
+
}
|
29
|
+
} catch (error) {
|
30
|
+
console.error('Error:', error);
|
31
|
+
errorMessage.textContent = 'An error occurred. Please try again.';
|
32
|
+
}
|
33
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
async function logout() {
|
2
|
+
try {
|
3
|
+
const response = await fetch('/api/v1/logout', {
|
4
|
+
method: 'GET',
|
5
|
+
credentials: 'same-origin' // This is important for including cookies in the request
|
6
|
+
});
|
7
|
+
|
8
|
+
if (response.ok) {
|
9
|
+
// If logout was successful, redirect to the home page
|
10
|
+
window.location.href = '/';
|
11
|
+
} else {
|
12
|
+
// If there was an error, log it and alert the user
|
13
|
+
console.error('Logout failed');
|
14
|
+
alert('Logout failed. Please try again.');
|
15
|
+
}
|
16
|
+
} catch (error) {
|
17
|
+
console.error('Error:', error);
|
18
|
+
alert('An error occurred during logout. Please try again.');
|
19
|
+
}
|
20
|
+
}
|