дальше колупаю htmx

This commit is contained in:
sergey 2024-07-14 21:37:00 +03:00
parent a4c7c00254
commit a4268180cd
19 changed files with 5323 additions and 91 deletions

View File

@ -0,0 +1,36 @@
"""create isp_connection table
Revision ID: f073180e963c
Revises: 85fef76b3dcd
Create Date: 2024-07-13 16:15:44.004704
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = "f073180e963c"
down_revision: Union[str, None] = "85fef76b3dcd"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("isp_connections", "isp_name")
# ### end Alembic commands ###
def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"isp_connections",
sa.Column(
"isp_name", sa.VARCHAR(), autoincrement=False, nullable=False
),
)
# ### end Alembic commands ###

View File

@ -3,13 +3,18 @@ from typing import Sequence
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload, selectinload
from models import Isp
from schemas.isp import IspCreate
from schemas.isp import IspCreate, IspRead
async def get_all_isp(session: AsyncSession) -> Sequence[Isp]:
stmt = select(Isp).order_by(Isp.id)
async def get_all_isp(
session: AsyncSession,
) -> Sequence[Isp]:
stmt = select(Isp).options(selectinload(Isp.isp_connections)).order_by(Isp.id)
result = await session.scalars(stmt)
return result.all()

View File

@ -1,6 +1,11 @@
from typing import TYPE_CHECKING
from pydantic import BaseModel
from .isp_connections import IspConnectionBase
class IspBase(BaseModel):
name: str
manager_name: str
@ -9,6 +14,7 @@ class IspBase(BaseModel):
tech_support_phone: str
tesh_support_email: str
comment: str
isp_connections: list["IspConnectionBase"] | None
class IspCreate(IspBase):

View File

@ -22,9 +22,10 @@ class ApiPrefix(BaseModel):
class WebPrefix(BaseModel):
start: str = "/web"
isp: str = "/web/isp"
settings: str = "/web/settings"
isp_connections: str = "/web/isp_connections"
start: str = "/web"
class DatabaseConfig(BaseModel):

View File

@ -4,6 +4,7 @@ from settings import settings
from .web import router as web_router
from .isp import router as isp_router
from .setting import router as settings_router
router = APIRouter()
@ -15,3 +16,7 @@ router.include_router(
isp_router,
prefix=settings.web.isp,
)
router.include_router(
settings_router,
prefix=settings.web.settings,
)

View File

@ -1,23 +1,39 @@
from fastapi import APIRouter
from starlette.requests import Request
from starlette.responses import HTMLResponse
from starlette.templating import Jinja2Templates
from settings import settings
from typing import Annotated
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from models import db_helper
from crud import isp as isp_crud
from fastapi.encoders import jsonable_encoder
router = APIRouter(
tags=["Web_Isp"],
tags=["Web"],
)
templates = Jinja2Templates(directory="views/templates")
@router.get("/", response_class=HTMLResponse)
async def read_item(request: Request):
print("sadf")
@router.get("/get_all", response_class=HTMLResponse)
async def get_all_isp(
request: Request,
session: Annotated[AsyncSession, Depends(db_helper.session_getter)],
):
isps = jsonable_encoder(
await isp_crud.get_all_isp(
session=session,
)
)
print(isps)
return templates.TemplateResponse(
"index.html",
"body-isp.html",
{
"request": request,
"isps": isps,
},
)

25
sipi-app/views/setting.py Normal file
View File

@ -0,0 +1,25 @@
from starlette.requests import Request
from starlette.responses import HTMLResponse
from starlette.templating import Jinja2Templates
from fastapi import APIRouter, Depends
router = APIRouter(
tags=["Web"],
)
templates = Jinja2Templates(directory="views/templates")
@router.get("/", response_class=HTMLResponse)
async def get_all_settings(
request: Request,
):
return templates.TemplateResponse(
"body-settings.html",
{
"request": request,
},
)

View File

@ -0,0 +1,32 @@
header {
background-color: green;
position: relative;
top: 0;
left: 0;
width: 100%;
margin-bottom: 10px;
}
div.header-button{
#background-color: red;
display: inline-block;
float: right;
}
div.body{
position: relative;
}
footer {
background-color: red;
position:fixed;
left: 0;
bottom:0;
width:100%;
text-align: right;
}

View File

@ -1,35 +0,0 @@
h1 {
color: green;
}
button {
background-color: gray;
width: 250px;
color: white;
text-align: left;
}
ping.button.button {
background-color: green;
width: 250px;
color: white;
text-align: left;
}
td {
word-wrap:break-word;
border: 1px solid grey;
}
table {
display: inline;
}
.htmx-indicator{
display:none;
}
.htmx-request .htmx-indicator{
display:inline;
}
.htmx-request.htmx-indicator{
display:inline;
}

File diff suppressed because it is too large Load Diff

1
sipi-app/views/static/js/htmx.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,15 @@
<!DOCTYPE HTML>
<html>
<head>
<title>SiPi-web</title>
<link href="/static/css/base.css" rel="stylesheet" type="text/css" />
<link rel="icon" href="data:;base64,=">
<script src="/static/js/htmx.js"></script>
</head>
{% include 'header.html' %}
{% include 'body.html' %}
{% include 'footer.html' %}
</html>

View File

@ -0,0 +1,13 @@
<div id="body">
{% for isp in isps %}
{{isp.name}}
{% for connection in isp.isp_connections %}
{{connection.contract_num}}
{% endfor %}
<br>
{% endfor %}
</div>

View File

@ -0,0 +1,3 @@
<div id="body">
Настройки
</div>

View File

@ -0,0 +1,3 @@
<div id="body">
</div>

View File

@ -0,0 +1,3 @@
<footer class="footer">
Сирожа корпорейтед &#169;
</footer>

View File

@ -0,0 +1,13 @@
<header>
<label>SiPi-web</label>
<div class="header-button">
<button hx-get="/web/isp/get_all" hx-target='#body'>Подключения провайдеров</button>
<button hx-get="/web/settings" hx-target='#body'>Настройки</button>
<!--
<button hx-get="/web/isp/get_all" hx-target='#body' hx-swap="outerHTML" hx-trigger="click">Площадки</button>
<button hx-get="/web/isp/get_all" hx-target='#body'>Внешние адреса</button>
<button hx-get="/web/isp/get_all" hx-target='#body'>Внутренние подсети</button>
<button hx-get="/web/isp/get_all" hx-target='#body'>Сетевое оборудование</button>
-->
</div>
</header>

View File

@ -1,31 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<title>SiPi-web</title>
<link href="/static/css/isp.css" rel="stylesheet" type="text/css" />
<link rel="icon" href="data:;base64,=">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="/static/js/htmx.js"></script>
</head>
<div id="tabs" hx-target="#tab-contents" role="tablist" _="on htmx:afterOnLoad set @aria-selected of <[aria-selected=true]/> to false tell the target take .selected set @aria-selected to true">
<button role="tab" aria-controls="tab-content" aria-selected="true" hx-get="/tab1" class="selected">Площадки</button>
<button role="tab" aria-controls="tab-content" aria-selected="false" hx-get="/tab2">Провайдеры</button>
<button role="tab" aria-controls="tab-content" aria-selected="false" hx-get="/tab3">Подключения</button>
<button role="tab" aria-controls="tab-content" aria-selected="false" hx-get="/tab5">Оборудование</button>
<button role="tab" aria-controls="tab-content" aria-selected="false" hx-get="/tab5">Подсети</button>
</div>
<div id="tab-contents" role="tabpanel" hx-get="/tab1" hx-trigger="load">
<h1>Провайдеры</h1>
</div>
<div id="tab-contents" role="tabpanel" hx-get="/tab2" hx-trigger="load">
<h1>Провайдеры</h1>
</div>
<body>
</body>
</html>

View File

@ -3,29 +3,18 @@ from starlette.requests import Request
from starlette.responses import HTMLResponse
from starlette.templating import Jinja2Templates
from settings import settings
router = APIRouter(
tags=["Web_Start"],
tags=["Web"],
)
templates = Jinja2Templates(directory="views/templates")
@router.get("/", response_class=HTMLResponse)
async def read_item(request: Request):
async def start_page(request: Request):
return templates.TemplateResponse(
"index.html",
{
"request": request,
},
)
@router.get("/", response_class=HTMLResponse)
async def read_item(request: Request):
return templates.TemplateResponse(
"index.html",
"base.html",
{
"request": request,
},