fix install diogram
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import base64
|
||||
import flet as ft
|
||||
import base64
|
||||
import designer as ds
|
||||
import api_client
|
||||
from radar_chart import RadarChart
|
||||
|
||||
|
||||
class PollPage(ft.Column):
|
||||
@@ -38,43 +37,64 @@ class PollPage(ft.Column):
|
||||
self.controls = [ds.CastomText(text="Тест не найден", size=16, color="#FF6B6B")]
|
||||
self.update()
|
||||
|
||||
def _build_choice_group(self, choices: list, qid: str) -> ft.Column:
|
||||
"""Кастомные кнопки выбора с переносом текста вместо ft.Radio."""
|
||||
containers: list[ft.Container] = []
|
||||
|
||||
def make_tile(choice_id: str, choice_text: str) -> ft.Container:
|
||||
return ft.Container(
|
||||
border_radius=8,
|
||||
padding=ft.padding.symmetric(horizontal=12, vertical=10),
|
||||
bgcolor=ds.clolors.laer3,
|
||||
border=ft.border.all(2, ds.clolors.laer3),
|
||||
content=ft.Row(
|
||||
spacing=10,
|
||||
vertical_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
controls=[
|
||||
ft.Icon(
|
||||
ft.Icons.RADIO_BUTTON_UNCHECKED,
|
||||
color=ds.clolors.ferst,
|
||||
size=20,
|
||||
),
|
||||
ft.Text(
|
||||
value=choice_text,
|
||||
color=ds.clolors.ferst,
|
||||
size=14,
|
||||
expand=True,
|
||||
no_wrap=False,
|
||||
),
|
||||
],
|
||||
),
|
||||
data=choice_id,
|
||||
)
|
||||
|
||||
def on_tile_click(e, _qid=qid, _containers=containers):
|
||||
selected_id = e.control.data
|
||||
self._answers[_qid] = selected_id
|
||||
for tile in _containers:
|
||||
is_selected = tile.data == selected_id
|
||||
tile.bgcolor = ds.clolors.laer1 if is_selected else ds.clolors.laer3
|
||||
tile.border = ft.border.all(2, ds.clolors.ferst if is_selected else ds.clolors.laer3)
|
||||
row = tile.content
|
||||
row.controls[0].name = ft.Icons.CHECK_CIRCLE if is_selected else ft.Icons.RADIO_BUTTON_UNCHECKED
|
||||
tile.update()
|
||||
|
||||
for c in choices:
|
||||
tile = make_tile(c["id"], c["text"])
|
||||
tile.on_click = on_tile_click
|
||||
tile.ink = True
|
||||
containers.append(tile)
|
||||
|
||||
return ft.Column(controls=containers, spacing=6)
|
||||
|
||||
def _render_poll(self, poll: dict):
|
||||
self._poll = poll
|
||||
question_cards = []
|
||||
|
||||
for q in poll.get("questions", []):
|
||||
choices = q.get("choices", [])
|
||||
q_type = q.get("type", "single")
|
||||
|
||||
if q_type == "single":
|
||||
radio_controls = [
|
||||
ft.Radio(
|
||||
value=c["id"],
|
||||
label=c["text"],
|
||||
fill_color=ds.clolors.laer1,
|
||||
label_style=ft.TextStyle(color=ds.clolors.ferst, size=14),
|
||||
)
|
||||
for c in choices
|
||||
]
|
||||
input_widget = ft.RadioGroup(
|
||||
content=ft.Column(controls=radio_controls, spacing=4),
|
||||
on_change=lambda e, qid=q["id"]: self._on_single_answer(qid, e.control.value),
|
||||
)
|
||||
else:
|
||||
# multiple / text — показываем как single если нет multiple в API
|
||||
radio_controls = [
|
||||
ft.Radio(
|
||||
value=c["id"],
|
||||
label=c["text"],
|
||||
fill_color=ds.clolors.laer1,
|
||||
label_style=ft.TextStyle(color=ds.clolors.ferst, size=14),
|
||||
)
|
||||
for c in choices
|
||||
]
|
||||
input_widget = ft.RadioGroup(
|
||||
content=ft.Column(controls=radio_controls, spacing=4),
|
||||
on_change=lambda e, qid=q["id"]: self._on_single_answer(qid, e.control.value),
|
||||
)
|
||||
input_widget = self._build_choice_group(choices, q["id"])
|
||||
|
||||
card = ft.Container(
|
||||
border_radius=12,
|
||||
@@ -122,9 +142,6 @@ class PollPage(ft.Column):
|
||||
]
|
||||
self._submit_btn.visible = True
|
||||
|
||||
def _on_single_answer(self, question_id: str, choice_id: str):
|
||||
self._answers[question_id] = choice_id
|
||||
|
||||
async def _submit(self, e):
|
||||
poll = getattr(self, "_poll", None)
|
||||
if not poll:
|
||||
@@ -170,49 +187,41 @@ class PollPage(ft.Column):
|
||||
self.update()
|
||||
|
||||
radar = await api_client.get_radar_result(response_id)
|
||||
svg_bytes = await api_client.get_radar_svg_bytes(response_id) if radar and radar.get("image_url") else None
|
||||
|
||||
success_controls: list[ft.Control] = [
|
||||
ft.Icon(ft.Icons.CHECK_CIRCLE_OUTLINE, size=48, color=ds.clolors.laer1),
|
||||
ds.CastomText(text="Тест пройден!", size=20, weight=ft.FontWeight.BOLD),
|
||||
]
|
||||
|
||||
if radar and radar.get("items"):
|
||||
items = sorted(
|
||||
radar["items"],
|
||||
key=lambda x: (
|
||||
x.get("dimension_position") is None,
|
||||
x.get("dimension_position", 0),
|
||||
),
|
||||
)
|
||||
actual_max = max((it["value"] for it in items), default=1.0)
|
||||
max_val = max(actual_max, 14.0)
|
||||
if svg_bytes and radar and radar.get("image_url"):
|
||||
b64 = base64.b64encode(svg_bytes).decode()
|
||||
data_uri = f"data:image/svg+xml;base64,{b64}"
|
||||
download_url = api_client.build_radar_download_url(self._page.url, response_id)
|
||||
|
||||
success_controls.append(
|
||||
ft.Row(
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
controls=[RadarChart(items, max_val)],
|
||||
ft.Container(
|
||||
expand=True,
|
||||
content=ft.Image(
|
||||
src=data_uri,
|
||||
expand=True,
|
||||
height=380,
|
||||
fit=ft.BoxFit.CONTAIN,
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
async def _download(_evt, _rid=response_id):
|
||||
svg_bytes = await api_client.get_radar_svg_bytes(_rid)
|
||||
if svg_bytes:
|
||||
b64 = base64.b64encode(svg_bytes).decode()
|
||||
uri = f"data:image/svg+xml;base64,{b64}"
|
||||
self._page.launch_url(uri, web_window_name="_blank")
|
||||
async def _download(_evt, _url=download_url):
|
||||
await self._page.launch_url(_url)
|
||||
|
||||
success_controls.append(
|
||||
ft.Row(
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
controls=[
|
||||
ft.ElevatedButton(
|
||||
ds.CastomIconButton(
|
||||
text="Сохранить диаграмму",
|
||||
icon=ft.Icons.DOWNLOAD,
|
||||
on_click=_download,
|
||||
style=ft.ButtonStyle(
|
||||
color=ds.clolors.ferst,
|
||||
bgcolor=ds.clolors.laer2,
|
||||
),
|
||||
)
|
||||
],
|
||||
)
|
||||
@@ -228,6 +237,9 @@ class PollPage(ft.Column):
|
||||
self.controls = [
|
||||
ft.Container(
|
||||
padding=20,
|
||||
bgcolor=ds.clolors.laer3,
|
||||
border_radius=16,
|
||||
expand=True,
|
||||
content=ft.Column(
|
||||
alignment=ft.MainAxisAlignment.CENTER,
|
||||
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
||||
|
||||
Reference in New Issue
Block a user