commit b6f0e019114a435badbd4255c2abbec026057f3a
Author: Matej Zeman <zeman339@gmail.com>
Date:   Wed Apr 20 11:57:54 2022 +0200

    re #9575 Filtering Over logs and devices.

diff --git a/server/sql_app/api/devices.py b/server/sql_app/api/devices.py
index cd0051d..e42ee85 100644
--- a/server/sql_app/api/devices.py
+++ b/server/sql_app/api/devices.py
@@ -4,13 +4,8 @@ from fastapi import Depends, FastAPI, HTTPException, APIRouter
 from sqlalchemy.orm import Session
 from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
-from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse
-from fastapi.staticfiles import StaticFiles
-from fastapi.templating import Jinja2Templates
 
 models.Base.metadata.create_all(bind=engine)
-templates = Jinja2Templates(directory="templates/devices")
 
 device = APIRouter(prefix="/api/v1")
 
@@ -23,12 +18,6 @@ def get_db():
         db.close()
 
 
-@device.get("/devices-web", response_class=HTMLResponse)
-async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
-    devices = crud.get_devices(db, skip=skip, limit=limit)
-    return templates.TemplateResponse("devices.html", {"request": request, "devs": devices})
-
-
 @device.post("/device", response_model=schemas.Device)
 def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)):
     print(crud.create_device(db=db, device=device))
diff --git a/server/sql_app/api/devices_web.py b/server/sql_app/api/devices_web.py
new file mode 100644
index 0000000..1f8510f
--- /dev/null
+++ b/server/sql_app/api/devices_web.py
@@ -0,0 +1,45 @@
+from typing import List
+
+from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
+from sqlalchemy.orm import Session
+from sql_app import crud, models, schemas
+from datetime import datetime
+from ..database import SessionLocal, engine
+from fastapi import FastAPI, Request
+from fastapi.responses import HTMLResponse
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
+
+models.Base.metadata.create_all(bind=engine)
+templates = Jinja2Templates(directory="../templates/devices")
+
+device_web = APIRouter(prefix="/api/v1")
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@device_web.get("/devices-web", response_class=HTMLResponse)
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+    devices = crud.get_devices(db, skip=skip, limit=limit)
+    return templates.TemplateResponse("devices.html", {"request": request, "devs": devices})
+
+
+@device_web.post("/devices-web", response_class=HTMLResponse)
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form("all"),
+                         db: Session = Depends(get_db)):
+    devices = crud.get_devices(db, skip=skip, limit=limit)
+    def_devices = []
+    for dev in devices:
+        for l in dev.licenses:
+            if dev not in def_devices and l.licenses.name == lic:
+                def_devices.append(dev)
+    if lic == "all":
+        def_devices = devices
+    return templates.TemplateResponse("devices.html", {"request": request, "devs": def_devices})
diff --git a/server/sql_app/api/licenses.py b/server/sql_app/api/licenses.py
index 32e791f..b79c7b9 100644
--- a/server/sql_app/api/licenses.py
+++ b/server/sql_app/api/licenses.py
@@ -2,16 +2,11 @@ from typing import List
 
 from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
 from sqlalchemy.orm import Session
-from datetime import date
+from datetime import datetime
 from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
-from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse
-from fastapi.staticfiles import StaticFiles
-from fastapi.templating import Jinja2Templates
 
 models.Base.metadata.create_all(bind=engine)
-templates = Jinja2Templates(directory="templates/licenses")
 
 licenses = APIRouter(prefix="/api/v1")
 
@@ -25,27 +20,6 @@ def get_db():
         db.close()
 
 
-@licenses.get("/license-create", response_class=HTMLResponse)
-async def licenses_create_web(request: Request):
-    return templates.TemplateResponse("license_create.html", {"request": request})
-
-
-@licenses.get("/licenses-web", response_class=HTMLResponse)
-async def licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
-    licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses})
-
-
-@licenses.post("/licenses-web", response_class=HTMLResponse)
-def create_license(request: Request, name: str = Form(...), expdate: date = Form(...), skip: int = 0, limit: int = 100,
-                   db: Session = Depends(get_db)):
-    db_license = crud.create_license(db, name, expdate)
-    if db_license is None:
-        print("something went wrong")
-    licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses})
-
-
 @licenses.get("/licenses", response_model=List[schemas.License])
 def read_licenses(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
@@ -54,4 +28,5 @@ def read_licenses(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)
 
 @licenses.post("/device-license", response_model=schemas.DeviceLicense)
 def create_device_license(device_license: schemas.DeviceLicenseCreate, db: Session = Depends(get_db)):
-    print(crud.create_device_license(db=db, device_license=device_license))
+    print(crud.create_device_license(db=db, device=device_license.device_id, license=device_license.license_id,
+                                     time=datetime.now()))
diff --git a/server/sql_app/api/licenses_web.py b/server/sql_app/api/licenses_web.py
new file mode 100644
index 0000000..ee50239
--- /dev/null
+++ b/server/sql_app/api/licenses_web.py
@@ -0,0 +1,46 @@
+from typing import List
+
+from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
+from sqlalchemy.orm import Session
+from datetime import date
+from sql_app import crud, models, schemas
+from ..database import SessionLocal, engine
+from fastapi import FastAPI, Request
+from fastapi.responses import HTMLResponse
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
+
+models.Base.metadata.create_all(bind=engine)
+templates = Jinja2Templates(directory="../templates/licenses")
+
+licenses_web = APIRouter(prefix="/api/v1")
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@licenses_web.get("/license-create", response_class=HTMLResponse)
+async def licenses_create_web(request: Request):
+    return templates.TemplateResponse("license_create.html", {"request": request})
+
+
+@licenses_web.get("/licenses-web", response_class=HTMLResponse)
+async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses})
+
+
+@licenses_web.post("/licenses-web", response_class=HTMLResponse)
+def create_license(request: Request, name: str = Form(...), expdate: date = Form(...), skip: int = 0, limit: int = 100,
+                   db: Session = Depends(get_db)):
+    db_license = crud.create_license(db, name, expdate)
+    if db_license is None:
+        print("something went wrong")
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    return templates.TemplateResponse("licenses.html", {"request": request, "licenses": licenses})
\ No newline at end of file
diff --git a/server/sql_app/api/pcs.py b/server/sql_app/api/pcs.py
index f7bb4eb..ba78f06 100644
--- a/server/sql_app/api/pcs.py
+++ b/server/sql_app/api/pcs.py
@@ -3,13 +3,8 @@ from fastapi import Depends, FastAPI, HTTPException, APIRouter
 from sqlalchemy.orm import Session
 from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
-from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse
-from fastapi.staticfiles import StaticFiles
-from fastapi.templating import Jinja2Templates
 
 models.Base.metadata.create_all(bind=engine)
-templates = Jinja2Templates(directory="templates/pcs")
 
 pcs = APIRouter(prefix="/api/v1")
 
@@ -23,12 +18,6 @@ def get_db():
         db.close()
 
 
-@pcs.get("/pcs-web", response_class=HTMLResponse)
-async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
-    pcs = crud.get_pcs(db, skip=skip, limit=limit)
-    return templates.TemplateResponse("pcs.html", {"request": request, "pcs": pcs})
-
-
 @pcs.post("/pc", response_model=schemas.PC)
 def create_pc(pc: schemas.PCCreate, db: Session = Depends(get_db)):
     print(crud.create_pc(db=db, user=pc.username, host=pc.hostname))
@@ -45,4 +34,4 @@ def read_pc(pc_id: int, db: Session = Depends(get_db)):
     db_pc = crud.get_pc(db, pc_id=pc_id)
     if db_pc is None:
         raise HTTPException(status_code=404, detail="Device not found")
-    return db_pc
+    return db_pc
\ No newline at end of file
diff --git a/server/sql_app/api/pcs_web.py b/server/sql_app/api/pcs_web.py
new file mode 100644
index 0000000..11f3e2c
--- /dev/null
+++ b/server/sql_app/api/pcs_web.py
@@ -0,0 +1,29 @@
+from typing import List
+from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
+from sqlalchemy.orm import Session
+from sql_app import crud, models, schemas
+from ..database import SessionLocal, engine
+from fastapi import FastAPI, Request
+from fastapi.responses import HTMLResponse
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
+
+models.Base.metadata.create_all(bind=engine)
+templates = Jinja2Templates(directory="../templates/pcs")
+
+pcs_web = APIRouter(prefix="/api/v1")
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@pcs_web.get("/pcs-web", response_class=HTMLResponse)
+async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+    pcs = crud.get_pcs(db, skip=skip, limit=limit)
+    return templates.TemplateResponse("pcs.html", {"request": request, "pcs": pcs})
diff --git a/server/sql_app/api/teams.py b/server/sql_app/api/teams.py
index 3fb3366..b685b28 100644
--- a/server/sql_app/api/teams.py
+++ b/server/sql_app/api/teams.py
@@ -4,13 +4,8 @@ from fastapi import Depends, FastAPI, HTTPException, APIRouter
 from sqlalchemy.orm import Session
 from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
-from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse
-from fastapi.staticfiles import StaticFiles
-from fastapi.templating import Jinja2Templates
 
 models.Base.metadata.create_all(bind=engine)
-templates = Jinja2Templates(directory="templates/teams")
 
 teams = APIRouter(prefix="/api/v1")
 
@@ -23,12 +18,6 @@ def get_db():
         db.close()
 
 
-@teams.get("/teams-web", response_class=HTMLResponse)
-async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
-    teams = crud.get_teams(db, skip=skip, limit=limit)
-    return templates.TemplateResponse("teams.html", {"request": request, "teams": teams})
-
-
 @teams.post("/team", response_model=schemas.Team)
 def create_device(team: schemas.TeamCreate, db: Session = Depends(get_db)):
     print(crud.create_team(db=db, name=team.name))
diff --git a/server/sql_app/api/teams_web.py b/server/sql_app/api/teams_web.py
new file mode 100644
index 0000000..9ee6bdc
--- /dev/null
+++ b/server/sql_app/api/teams_web.py
@@ -0,0 +1,30 @@
+from typing import List
+
+from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
+from sqlalchemy.orm import Session
+from sql_app import crud, models, schemas
+from ..database import SessionLocal, engine
+from fastapi import FastAPI, Request
+from fastapi.responses import HTMLResponse
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
+
+models.Base.metadata.create_all(bind=engine)
+templates = Jinja2Templates(directory="../templates/teams")
+
+teams_web = APIRouter(prefix="/api/v1")
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@teams_web.get("/teams-web", response_class=HTMLResponse)
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    return templates.TemplateResponse("teams.html", {"request": request, "teams": teams})
diff --git a/server/sql_app/api/usb_logs.py b/server/sql_app/api/usb_logs.py
index 3d6e630..7eace95 100644
--- a/server/sql_app/api/usb_logs.py
+++ b/server/sql_app/api/usb_logs.py
@@ -4,13 +4,8 @@ from datetime import datetime
 from sqlalchemy.orm import Session
 from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
-from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse
-from fastapi.staticfiles import StaticFiles
-from fastapi.templating import Jinja2Templates
 
 models.Base.metadata.create_all(bind=engine)
-templates = Jinja2Templates(directory="templates/usb-logs")
 
 usblogs = APIRouter(prefix="/api/v1")
 
@@ -24,35 +19,6 @@ def get_db():
         db.close()
 
 
-@usblogs.get("/logs-web", response_class=HTMLResponse)
-async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
-    logs = crud.get_logs(db, skip=skip, limit=limit)
-    pcs = []
-    for log in logs:
-        if log.pc_id not in pcs:
-            pcs.append(log.pc_id)
-    pc_obj = crud.find_pcs(db, pcs)
-    return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj})
-
-
-@usblogs.post("/logs-web", response_class=HTMLResponse)
-async def filter_logs(request: Request, pc: str = Form(...), skip: int = 0, limit: int = 100,
-                      db: Session = Depends(get_db)):
-    logs_temp = crud.get_logs(db, skip=skip, limit=limit)
-    pcs = []
-    logs = []
-    for log in logs_temp:
-        if log.pc_id not in pcs:
-            pcs.append(log.pc_id)
-        if pc != "all":
-            if log.pc_id == int(pc):
-                logs.append(log)
-    if pc == "all":
-        logs = logs_temp
-    pc_obj = crud.find_pcs(db, pcs)
-    return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj})
-
-
 @usblogs.post("/usb-logs", response_model=schemas.USBLog)
 def create_device_logs(log: schemas.USBTempBase, db: Session = Depends(get_db)):
     dev = crud.find_device(db, log.device)
diff --git a/server/sql_app/api/usb_logs_web.py b/server/sql_app/api/usb_logs_web.py
new file mode 100644
index 0000000..f9e20d6
--- /dev/null
+++ b/server/sql_app/api/usb_logs_web.py
@@ -0,0 +1,55 @@
+from typing import List
+from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
+from datetime import datetime
+from sqlalchemy.orm import Session
+from sql_app import crud, models, schemas
+from ..database import SessionLocal, engine
+from fastapi import FastAPI, Request
+from fastapi.responses import HTMLResponse
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
+
+models.Base.metadata.create_all(bind=engine)
+templates = Jinja2Templates(directory="../templates/usb-logs")
+
+usblogs_web = APIRouter(prefix="/api/v1")
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@usblogs_web.get("/logs-web", response_class=HTMLResponse)
+async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+    logs = crud.get_logs(db, skip=skip, limit=limit)
+    pcs = []
+    for log in logs:
+        if log.pc_id not in pcs:
+            pcs.append(log.pc_id)
+    pc_obj = crud.find_pcs(db, pcs)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
+                                                    "licenses": licenses})
+
+
+@usblogs_web.post("/logs-web", response_class=HTMLResponse)
+async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form("all"), lic: str = Form("all"),
+                      skip: int = 0, limit: int = 100,
+                      db: Session = Depends(get_db)):
+    log = crud.get_filtered_logs(db, pc, team, lic)
+    logs_ids = []
+    for l in log:
+        logs_ids.append(l[0])
+    logs = crud.find_filtered_logs(db, logs_ids)
+    pc_obj = crud.get_pcs(db, skip=skip, limit=limit)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
+                                                    "licenses": licenses})
+
diff --git a/server/sql_app/crud.py b/server/sql_app/crud.py
index 834d615..3bd76df 100644
--- a/server/sql_app/crud.py
+++ b/server/sql_app/crud.py
@@ -1,7 +1,7 @@
 from datetime import datetime, date
 
 from sqlalchemy.orm import Session
-from sqlalchemy import and_
+from sqlalchemy import and_, desc
 from . import models, schemas
 
 
@@ -15,8 +15,8 @@ def get_devices(db: Session, skip: int = 0, limit: int = 100):
 
 def find_device(db: Session, device: schemas.DeviceBase):
     return db.query(models.Device).filter(and_(models.Device.product_id == device.product_id,
-                                          models.Device.vendor_id == device.vendor_id,
-                                          models.Device.serial_number == device.serial_number)).first()
+                                               models.Device.vendor_id == device.vendor_id,
+                                               models.Device.serial_number == device.serial_number)).first()
 
 
 def create_device(db: Session, device: schemas.DeviceBase):
@@ -36,6 +36,10 @@ def get_licenses(db: Session, skip: int = 0, limit: int = 100):
     return db.query(models.License).offset(skip).limit(limit).all()
 
 
+def find_license(db: Session, name: str):
+    return db.query(models.License).filter(models.License.name == name).first()
+
+
 def create_license(db: Session, name: str, expdate: date):
     db_license = models.License(name=name, expiration_date=expdate)
     db.add(db_license)
@@ -44,32 +48,64 @@ def create_license(db: Session, name: str, expdate: date):
     return db_license
 
 
-def create_device_license(db: Session, device_license: schemas.DeviceLicenseBase):
-    db_device_license = models.DeviceLicense(device_id=device_license.device_id, license_id=device_license.license_id,
-                                             assigned_datetime=device_license.assigned_datetime)
+def get_license_devices(db: Session, license_id: int):
+    return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id == license_id).all()
+
+
+def create_device_license(db: Session, device: int, license: int, time: datetime):
+    db_device_license = models.DeviceLicense(device_id=device, license_id=license,
+                                             assigned_datetime=time)
     db.add(db_device_license)
     db.commit()
     db.refresh(db_device_license)
     return db_device_license
 
 
+def find_pc_by_username(db: Session, name: str):
+    return db.query(models.PC).filter(models.PC.username == name).first()
+
+
 def get_pc(db: Session, pc_id: int):
     return db.query(models.PC).filter(models.PC.id == pc_id).first()
 
 
+def update_pc(db: Session, pc_id: int, team: str):
+    old_pc = get_pc(db, pc_id)
+    team = get_team(db, int(team))
+    new = {'id': old_pc.id, 'username': old_pc.username, 'hostname': old_pc.hostname, 'assigned': True,
+           'team_id': team.id}
+    for key, value in new.items():
+        setattr(old_pc, key, value)
+    db.commit()
+    db.refresh(old_pc)
+    return old_pc
+
+
 def get_pcs(db: Session, skip: int = 0, limit: int = 100):
     return db.query(models.PC).offset(skip).limit(limit).all()
 
 
 def find_pc(db: Session, username: str, hostname: str):
     return db.query(models.PC).filter(and_(models.PC.username == username,
-                                      models.PC.hostname == hostname)).first()
+                                           models.PC.hostname == hostname)).first()
+
+
+def find_pc_by_name(db: Session, username: str):
+    return db.query(models.PC).filter(models.PC.username == username).first()
+
+
+def find_pc_by_name_all(db: Session, username: str):
+    return db.query(models.PC).filter(models.PC.username == username).offset(0).limit(100).all()
 
 
 def find_pcs(db: Session, pcs: []):
     return db.query(models.PC).filter(models.PC.id.in_(pcs)).all()
 
 
+def get_pcs_by_team(db: Session, team_id: int):
+    return db.query(models.PC).filter(models.PC.team_id == team_id).all()
+
+
 def create_pc(db: Session, user: str, host: str):
     db_pc = models.PC(username=user, hostname=host, assigned=False)
     db.add(db_pc)
@@ -86,8 +122,12 @@ def get_teams(db: Session, skip: int = 0, limit: int = 100):
     return db.query(models.Team).offset(skip).limit(limit).all()
 
 
+def find_team(db: Session, name: str):
+    return db.query(models.Team).filter(models.Team.name == name).first()
+
+
 def create_team(db: Session, name: str):
-    db_team = models.PC(name=name)
+    db_team = models.Team(name=name)
     db.add(db_team)
     db.commit()
     db.refresh(db_team)
@@ -95,13 +135,49 @@ def create_team(db: Session, name: str):
 
 
 def get_logs(db: Session, skip: int = 0, limit: int = 100):
-    return db.query(models.USBLog).offset(skip).limit(limit).all()
+    return db.query(models.USBLog).order_by(desc(models.USBLog.timestamp)).offset(skip).limit(limit).all()
 
 
 def get_log(db: Session, device_id: int, skip: int = 0, limit: int = 100):
     return db.query(models.USBLog).filter(models.USBLog.device_id == device_id).offset(skip).limit(limit).all()
 
 
+def find_filtered_logs(db: Session, logs: []):
+    return db.query(models.USBLog).filter(models.USBLog.id.in_(logs)).order_by(desc(models.USBLog.timestamp)).all()
+
+
+def get_filtered_logs(db: Session, pc: str, tema: str, lic: str):
+    execute_string = "SELECT * FROM usb_logs AS logs"
+    if pc != "all":
+        pcs = find_pc_by_username(db, pc)
+        execute_string += "  WHERE logs.pc_id = " + str(pcs.id)
+    if tema != "all":
+        team = find_team(db, tema)
+        pcs = get_pcs_by_team(db, team.id)
+        pc_ids = "("
+        for p in pcs:
+            pc_ids += str(p.id) + ", "
+        def_pc_ids = pc_ids[:-2] + ")"
+        if pc != "all":
+            execute_string += " AND logs.pc_id IN " + def_pc_ids
+        else:
+            execute_string += " WHERE logs.pc_id IN " + def_pc_ids
+    if lic != "all":
+        license = find_license(db, lic)
+        device_licenses = get_license_devices(db, license.id)
+        dev_ids = "("
+        for dev in device_licenses:
+            dev_ids += str(dev.device_id) + ", "
+        defin_ids = dev_ids[:-2] + ")"
+        if pc != "all" or tema != "all":
+            execute_string += " AND logs.device_id IN " + defin_ids
+        else:
+            execute_string += " WHERE logs.device_id IN " + defin_ids
+
+    result = db.execute(execute_string)
+    return result
+
+
 def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_id: int, date: datetime):
     db_log = models.USBLog(pc_id=pc_id, timestamp=date, status=item.status, device_id=dev_id)
     db.add(db_log)
diff --git a/server/sql_app/main.py b/server/sql_app/main.py
index 29b1b83..c1cb701 100644
--- a/server/sql_app/main.py
+++ b/server/sql_app/main.py
@@ -1,9 +1,14 @@
 import uvicorn
 from sql_app.api.devices import device
+from sql_app.api.devices_web import device_web
 from sql_app.api.licenses import licenses
+from sql_app.api.licenses_web import licenses_web
 from sql_app.api.pcs import pcs
+from sql_app.api.pcs_web import pcs_web
 from sql_app.api.usb_logs import usblogs
+from sql_app.api.usb_logs_web import usblogs_web
 from sql_app.api.teams import teams
+from sql_app.api.teams_web import teams_web
 from fastapi import FastAPI
 
 
@@ -14,6 +19,12 @@ app.include_router(pcs)
 app.include_router(usblogs)
 app.include_router(teams)
 
+app.include_router(device_web)
+app.include_router(licenses_web)
+app.include_router(pcs_web)
+app.include_router(teams_web)
+app.include_router(usblogs_web)
+
 '''
 if __name__ == "__main__":
     uvicorn.run(app, host="192.168.0.22", port=8000)
diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html
index 18a50c0..10129d3 100644
--- a/server/templates/devices/devices.html
+++ b/server/templates/devices/devices.html
@@ -3,12 +3,34 @@
     <title>Devices Details</title>
 </head>
 <body>
+<form action="" method="get">
+  <label for="view">Choose view:</label>
+  <select id="view" name="view" onchange="this.form.action=this.value;">
+      <option value=""></option>
+      <option value="/api/v1/logs-web">Logs</option>
+      <option value="/api/v1/devices-web">Devices</option>
+      <option value="/api/v1/teams-web">Teams</option>
+      <option value="/api/v1/pcs-web">PCs</option>
+  </select>
+  <input type="submit" value="OK">
+</form>
+<form action="/api/v1/devices-web" method="post">
+    <label for="lic">License:</label>
+    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
+    <datalist id="licenses">
+        {% for license in licenses %}
+        <option value="{{license.name}}"></option>
+        {% endfor %}
+    </datalist>
+  <input type="submit" value="Filter">
+</form>
 <table>
     <TR>
         <TH>ID</TH>
         <TH>Vendor ID</TH>
         <TH>Product ID</TH>
         <TH>Serial Number</TH>
+        <TH>Licenses</TH>
     </TR>
     {% for device in devs %}
     <TR>
@@ -16,6 +38,11 @@
         <TD class="Vendor ID">{{device.vendor_id}}</TD>
         <TD class="Product ID">{{device.product_id}}</TD>
         <TD class="Serial Number">{{device.serial_number}}</TD>
+        <TD class="License">
+            {% for lic in device.licenses %}
+                {{lic.licenses.name}}<BR>
+            {% endfor %}
+        </TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/licenses/licenses.html b/server/templates/licenses/licenses.html
index 7b8c894..e456ab0 100644
--- a/server/templates/licenses/licenses.html
+++ b/server/templates/licenses/licenses.html
@@ -3,6 +3,17 @@
     <title>Licenses Details</title>
 </head>
 <body>
+<form action="" method="get">
+  <label for="view">Choose view:</label>
+  <select id="view" name="view" onchange="this.form.action=this.value;">
+      <option value=""></option>
+      <option value="/api/v1/logs-web">Logs</option>
+      <option value="/api/v1/devices-web">Devices</option>
+      <option value="/api/v1/teams-web">Teams</option>
+      <option value="/api/v1/pcs-web">PCs</option>
+  </select>
+  <input type="submit" value="OK">
+</form>
 <table>
     <TR>
         <TH>ID</TH>
diff --git a/server/templates/pcs/pcs.html b/server/templates/pcs/pcs.html
index 77bda14..44a042a 100644
--- a/server/templates/pcs/pcs.html
+++ b/server/templates/pcs/pcs.html
@@ -3,17 +3,34 @@
     <title>Pcs Details</title>
 </head>
 <body>
+<form action="" method="get">
+  <label for="view">Choose view:</label>
+  <select id="view" name="view" onchange="this.form.action=this.value;">
+      <option value=""></option>
+      <option value="/api/v1/logs-web">Logs</option>
+      <option value="/api/v1/devices-web">Devices</option>
+      <option value="/api/v1/teams-web">Teams</option>
+      <option value="/api/v1/pcs-web">PCs</option>
+  </select>
+  <input type="submit" value="OK">
+</form>
 <table>
     <TR>
         <TH>ID</TH>
         <TH>Username</TH>
         <TH>Hostname</TH>
+        <TH>Team</TH>
     </TR>
     {% for pc in pcs %}
     <TR>
         <TD class="ID">{{pc.id}}</TD>
         <TD class="Vendor ID">{{pc.username}}</TD>
         <TD class="Product ID">{{pc.hostname}}</TD>
+        {% if pc.team == None %}
+            <TD class="Team">NONE</TD>
+        {% else %}
+            <TD class="Team">{{pc.team.name}}</TD>
+        {% endif %}
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/teams/teams.html b/server/templates/teams/teams.html
index 8a8e385..09ec445 100644
--- a/server/templates/teams/teams.html
+++ b/server/templates/teams/teams.html
@@ -3,6 +3,17 @@
     <title>Teams Details</title>
 </head>
 <body>
+<form action="" method="get">
+  <label for="view">Choose view:</label>
+  <select id="view" name="view" onchange="this.form.action=this.value;">
+      <option value=""></option>
+      <option value="/api/v1/logs-web">Logs</option>
+      <option value="/api/v1/devices-web">Devices</option>
+      <option value="/api/v1/teams-web">Teams</option>
+      <option value="/api/v1/pcs-web">PCs</option>
+  </select>
+  <input type="submit" value="OK">
+</form>
 <table>
     <TR>
         <TH>ID</TH>
diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html
index aa8b496..722c811 100644
--- a/server/templates/usb-logs/logs.html
+++ b/server/templates/usb-logs/logs.html
@@ -3,14 +3,39 @@
     <title>Logs Details</title>
 </head>
 <body>
-<form action="/api/v1/logs-web/" method="post">
-  <label for="pc">PC:</label>
-  <select id="pc" name="pc">
-      <option value="all">all</option>
-      {% for pc in pcs %}
-    <option value={{pc.id}}>{{pc.username}}</option>
-      {% endfor %}
+<form action="" method="get">
+  <label for="view">Choose view:</label>
+  <select id="view" name="view" onchange="this.form.action=this.value;">
+      <option value=""></option>
+      <option value="/api/v1/logs-web">Logs</option>
+      <option value="/api/v1/devices-web">Devices</option>
+      <option value="/api/v1/teams-web">Teams</option>
+      <option value="/api/v1/pcs-web">PCs</option>
   </select>
+  <input type="submit" value="OK">
+</form>
+<form action="/api/v1/logs-web" method="post">
+  <label for="pc">PC:</label>
+  <input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all">
+    <datalist id="pcs">
+        {% for pc in pcs %}
+        <option value="{{pc.username}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="team">Team:</label>
+  <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <datalist id="teams">
+        {% for team in teams %}
+        <option value="{{team.name}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="lic">License:</label>
+    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
+    <datalist id="licenses">
+        {% for license in licenses %}
+        <option value="{{license.name}}"></option>
+        {% endfor %}
+    </datalist>
   <input type="submit" value="Filter">
 </form>
     <table>
@@ -18,6 +43,7 @@
         <TH>ID</TH>
         <TH>PC Username</TH>
         <TH>PC Hostname</TH>
+        <TH>Team</TH>
         <TH>Timestamp</TH>
         <TH>Status</TH>
         <TH>Device Product ID</TH>
@@ -28,6 +54,11 @@
         <TD class="ID">{{log.id}}</TD>
         <TD class="Username">{{log.pc.username}}</TD>
         <TD class="Hostname">{{log.pc.hostname}}</TD>
+        {% if log.pc.team == None %}
+            <TD class="Team">NONE</TD>
+        {% else %}
+            <TD class="Team">{{log.pc.team.name}}</TD>
+        {% endif %}
         <TD class="Timestamp">{{log.timestamp}}</TD>
         <TD class="Status">{{log.status}}</TD>
         <TD class="DeviceProductID">{{log.device.product_id}}</TD>
@@ -37,3 +68,4 @@
 </table>
 </body>
 </html>
+
