Adding objects dashboard.

This commit is contained in:
Michael Woods
2025-12-26 14:04:44 -05:00
parent 522bd9e70e
commit 1f455f47ed
4 changed files with 133 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
from fastapi import APIRouter, Depends, Request, Form, File, UploadFile
from fastapi.responses import HTMLResponse, RedirectResponse
from packetserver.http.dependencies import get_current_http_user
from packetserver.http.auth import HttpUser
from packetserver.http.server import templates
from packetserver.http.routers.objects import router as api_router # to call internal endpoints
from packetserver.http.database import DbDependency
router = APIRouter(tags=["objects_html"])
# Internal reference to the list function (assuming it's list_my_objects)
from packetserver.http.routers.objects import list_my_objects as api_list_objects
@router.get("/objects", response_class=HTMLResponse)
async def objects_page(
db: DbDependency,
request: Request,
current_user: HttpUser = Depends(get_current_http_user)
):
# Call the API list endpoint internally
objects_resp = await api_list_objects(db, current_user=current_user) # db injected via dependency
objects = objects_resp # it's already the list
return templates.TemplateResponse(
"objects.html",
{
"request": request,
"current_user": current_user.username,
"objects": objects
}
)

View File

@@ -43,6 +43,7 @@ from .routers import dashboard, bulletins
from .routers.message_detail import router as message_detail_router
from .routers.messages import html_router
from .routers.objects import router as objects_router
from .routers import objects_html
# initialize database
init_db()
@@ -58,5 +59,6 @@ app.include_router(bulletins.html_router)
app.include_router(message_detail_router)
app.include_router(html_router)
app.include_router(objects_router)
app.include_router(objects_html.router)

View File

@@ -19,6 +19,7 @@
<a href="{{ url_for('profile_page') }}" class="btn btn-outline-light btn-sm me-2">Profile</a>
<a href="/messages" class="btn btn-outline-light btn-sm me-2">Messages</a>
<a href="/bulletins" class="btn btn-outline-light btn-sm me-2">Bulletins</a>
<a href="/objects" class="btn btn-outline-light btn-sm me-2">Objects</a>
</div>
</nav>

View File

@@ -0,0 +1,99 @@
{% extends "base.html" %}
{% block title %}My Objects - {{ current_user }}{% endblock %}
{% block content %}
<h2 class="mb-4">My Objects</h2>
<!-- Simple File Upload Form -->
<div class="card mb-4">
<div class="card-body">
<h5>Upload File</h5>
<form action="/api/v1/objects" method="post" enctype="multipart/form-data">
<div class="mb-3">
<input type="file" name="file" class="form-control" required>
</div>
<div class="mb-3">
<input type="text" name="name" class="form-control" placeholder="Optional name">
</div>
<div class="form-check mb-3">
<input type="checkbox" name="private" class="form-check-input" checked>
<label class="form-check-label">Private</label>
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</div>
<!-- Quick Text Object -->
<div class="card mb-4">
<div class="card-body">
<h5>Create Text Object</h5>
<form action="/api/v1/objects/text" method="post">
<div class="mb-3">
<textarea name="text" class="form-control" rows="4" placeholder="Enter text content..." required></textarea>
</div>
<div class="mb-3">
<input type="text" name="name" class="form-control" placeholder="Optional name (e.g. note.txt)">
</div>
<div class="form-check mb-3">
<input type="checkbox" name="private" class="form-check-input" checked>
<label class="form-check-label">Private</label>
</div>
<button type="submit" class="btn btn-success">Create</button>
</form>
</div>
</div>
<!-- Objects Table -->
{% if objects %}
<table class="table table-striped table-hover">
<thead class="table-dark">
<tr>
<th>Name</th>
<th>Size</th>
<th>Type</th>
<th>Uploaded</th>
<th>Visibility</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for obj in objects %}
<tr>
<td><strong>{{ obj.name }}</strong></td>
<td>{{ "%0.1f KB" | format(obj.size / 1024) if obj.size > 1024 else obj.size ~ " bytes" }}</td>
<td>
{% if obj.binary %}
<span class="badge bg-secondary">Binary</span>
{% else %}
<span class="badge bg-info">Text</span>
{% endif %}
</td>
<td>{{ obj.created_at[:10] }}</td>
<td>
{% if obj.private %}
<span class="badge bg-warning">Private</span>
{% else %}
<span class="badge bg-success">Public</span>
{% endif %}
</td>
<td>
{% if not obj.binary %}
<a href="/api/v1/objects/{{ obj.uuid }}/text" class="btn btn-sm btn-outline-info" target="_blank">View Text</a>
{% endif %}
<a href="/api/v1/objects/{{ obj.uuid }}/download" class="btn btn-sm btn-primary">Download</a>
<form action="/api/v1/objects/{{ obj.uuid }}" method="post" style="display:inline;">
<input type="hidden" name="_method" value="DELETE">
<button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Delete {{ obj.name }}?')">Delete</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No objects uploaded yet.</p>
{% endif %}
{% endblock %}