1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""HTML fixtures shared by the browser-script tests."""
from __future__ import annotations
import json
from typing import Any
from pygitweb.static_tests.js_runtime import JsPage
MANIFEST: dict[str, list[dict[str, str]]] = {
"commits": [
{
"insert": "abcd",
"name": "subject",
"url": "/c/abcd",
"tags": "abcd subject",
"snippet": "subject",
"created": "2020-01-01",
},
{"insert": "eeee", "name": "other", "url": "/c/eeee", "tags": "eeee"},
],
"refs": [
{"insert": "main", "name": "main", "url": "/r/main", "tags": "main branch"},
{"insert": "task-1234", "name": "task", "url": "/r/task", "tags": "task"},
],
}
def card_html(
*,
ref: str = "",
status: str = "TODO",
points: str = "",
title: str = "",
description: str = "",
) -> str:
return (
f'<div class="card board-card" draggable="true" data-task-ref="{ref}" '
f'data-task-status="{status}" data-task-points="{points}">'
'<span class="board-card-icon" data-icon="cloud"></span>'
'<div class="board-card-title-line">'
'<span class="board-card-task-id"></span>'
f'<span class="board-card-title">{title}</span></div>'
'<div class="board-card-description-preview"></div>'
'<div class="board-card-meta">'
'<span class="badge">LOW</span>'
'<span class="board-card-points-badge d-none"></span>'
'<span class="board-card-assignee-compact">None</span>'
'<span class="ms-auto board-card-comments-count-meta">0 comments</span>'
"</div>"
'<div class="board-card-details d-none">'
'<div class="board-card-task-ref"></div>'
f'<div class="board-card-description-full">{description}</div>'
'<div class="board-card-due-date">None</div>'
'<div class="board-card-updated-at">None</div>'
'<div class="board-card-status">TODO</div>'
'<div class="board-card-priority">LOW</div>'
'<div class="board-card-points">–</div>'
'<div class="board-card-assignee">None</div>'
'<div class="board-card-tags"></div>'
'<select class="board-card-move-select"><option value="">Move to board…</option></select>'
'<button type="button" class="board-card-delete-btn">Delete</button>'
'<button type="button" class="board-card-archive-btn">Archive</button>'
'<form class="board-card-comment-form"><textarea class="board-card-comment-input"></textarea></form>'
'<div class="board-card-comment-signin-hint d-none"></div>'
'<div class="board-card-comments-list"></div>'
"</div></div>"
)
def column(status: str, cards: str = "") -> str:
return (
f'<div class="board-column dropzone" data-status="{status}">'
'<button type="button" class="board-column-add-card">'
'<span class="board-column-task-count">0</span></button>'
'<span class="board-column-points-total">0 pts</span>'
f'<div class="board-column-cards">{cards}</div></div>'
)
def board_shell(
*,
project: str = "demo",
board: str = "Tasks",
cards_todo: str = "",
cards_progress: str = "",
include_template: bool = True,
) -> str:
template = f'<template id="board-card-template">{card_html()}</template>' if include_template else ""
return (
template
+ f'<div class="board-columns" data-project="{project}" data-board="{board}">'
+ column("TODO", cards_todo)
+ column("IN_PROGRESS", cards_progress)
+ "</div>"
+ '<select id="board-board-select"></select>'
+ '<button type="button" id="board-new-board-btn">+ Board</button>'
+ '<button type="button" id="board-new-sprint-btn">+ Sprint</button>'
+ '<form id="board-new-form" class="d-none"><input id="board-new-name">'
+ '<span id="board-new-error" class="d-none"></span>'
+ '<button type="submit">Create</button></form>'
+ '<button type="button" id="board-new-cancel">Cancel</button>'
)
def requested(js: JsPage, fragment: str) -> bool:
return any(fragment in str(item["url"]) for item in js.requests())
def posted_json(js: JsPage, fragment: str) -> Any:
for item in reversed(js.requests()):
if fragment in str(item["url"]) and item.get("body"):
return json.loads(str(item["body"]))
return None