Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions backend/testjam/routers/bugs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from datetime import datetime, timezone

from fastapi import APIRouter, BackgroundTasks, Depends, File, HTTPException, UploadFile, status
from sqlalchemy import func, select
from sqlalchemy import case, func, select
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session, selectinload

Expand Down Expand Up @@ -176,6 +176,17 @@ def _latest_active_version_id(db: Session, project_id: int) -> int | None:
return row[0] if row else None


SEVERITY_ORDER = {"critical": 0, "high": 1, "medium": 2, "low": 3}


def _bug_sort_clause(sort_by: str | None):
if sort_by == "severity":
return case(SEVERITY_ORDER, value=Bug.severity, else_=99)
if sort_by == "created_at":
return Bug.created_at.desc()
return Bug.number.desc()


@projects_router.get("/{id}/bugs", response_model=list[BugOut])
def list_bugs(
id: int,
Expand All @@ -188,6 +199,7 @@ def list_bugs(
search: str | None = None,
cf_key: str | None = None,
cf_value: str | None = None,
sort_by: str | None = None,
skip: int = 0,
limit: int = 50,
db: Session = Depends(get_db),
Expand Down Expand Up @@ -218,7 +230,8 @@ def list_bugs(
if search:
like = f"%{search.lower()}%"
query = query.filter(func.lower(Bug.title).like(like))
rows = query.order_by(Bug.number.desc()).all()
order = _bug_sort_clause(sort_by)
rows = query.order_by(order).all()
if tag:
rows = [bug for bug in rows if bug.tags and tag in bug.tags]
if cf_key:
Expand Down
14 changes: 10 additions & 4 deletions frontend/src/components/bug/NewBugDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import { Input } from "../ui/input"
import { Label } from "../ui/label"
import { Textarea } from "../ui/textarea"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select"
import { Badge } from "../ui/badge"
import { EnvironmentPicker } from "../environment/EnvironmentPicker"
import { CustomFieldsForm } from "../customField/CustomFieldInput"
import { SEVERITIES, SEVERITY_VARIANT } from "../../lib/bugConfig"

const VERSION_NONE = "__none__"

const SEVERITIES = ["critical", "high", "medium", "low"]

export function NewBugDialog({ projectId, trigger, prefill = {}, onCreated }) {
const { t } = useTranslation("bugs")
const [open, setOpen] = useState(false)
Expand Down Expand Up @@ -91,10 +91,16 @@ export function NewBugDialog({ projectId, trigger, prefill = {}, onCreated }) {
<div className="space-y-1">
<Label>{t("fields.severity")}</Label>
<Select value={severity} onValueChange={setSeverity}>
<SelectTrigger><SelectValue /></SelectTrigger>
<SelectTrigger>
<Badge variant={SEVERITY_VARIANT[severity] ?? "secondary"}>
{t(`severity.${severity}`)}
</Badge>
</SelectTrigger>
<SelectContent>
{SEVERITIES.map(value => (
<SelectItem key={value} value={value}>{t(`severity.${value}`)}</SelectItem>
<SelectItem key={value} value={value}>
<Badge variant={SEVERITY_VARIANT[value] ?? "secondary"}>{t(`severity.${value}`)}</Badge>
</SelectItem>
))}
</SelectContent>
</Select>
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/components/share/PublicReportDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export function PublicReportDialog({

const handleCreate = async (event) => {
event.preventDefault()
if (expiresAt && new Date(expiresAt) <= new Date()) {
toast.error(t("expiredDateError"))
return
}
try {
const payload = {
kind: defaultKind,
Expand Down Expand Up @@ -133,6 +137,7 @@ export function PublicReportDialog({
<Input
type="datetime-local"
value={expiresAt}
min={new Date().toISOString().slice(0, 16)}
onChange={event => setExpiresAt(event.target.value)}
/>
<p className="text-xs text-gray-500">{t("expiresHelp")}</p>
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/components/ui/context-panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,12 @@ function ContextSection({ section }) {
function ContextRow({ row }) {
const Icon = row.icon
return (
<div className="flex items-start gap-2 text-xs">
{Icon && <Icon size={11} className="text-gray-400 dark:text-gray-500 mt-0.5 shrink-0" />}
<span className="text-gray-500 dark:text-gray-400 w-20 shrink-0">{row.label}</span>
<span className="flex-1 min-w-0 text-gray-800 dark:text-gray-100 break-words">{row.value}</span>
<div className="flex items-center gap-2 text-xs">
<div className="w-3 shrink-0 flex items-center justify-center">
{Icon && <Icon size={11} className="text-gray-400 dark:text-gray-500" />}
</div>
<div className="text-gray-500 dark:text-gray-400 w-20 shrink-0">{row.label}</div>
<div className="flex-1 min-w-0 text-gray-800 dark:text-gray-100 break-words">{row.value}</div>
</div>
)
}
22 changes: 17 additions & 5 deletions frontend/src/i18n/locales/ca/bugs.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
"version": "Versió",
"assignee": "Assignat",
"tag": "Etiqueta",
"any": "Qualsevol"
"any": "Qualsevol",
"sortLabel": "Sort by",
"sortNewest": "Newest first",
"sortSeverity": "Severity",
"sortCreated": "Creation date"
},
"severity": {
"critical": "Crítica",
Expand All @@ -48,7 +52,8 @@
"version": "Versió",
"environment": "Entorn",
"assignee": "Assignat",
"externalUrl": "URL del tiquet extern"
"externalUrl": "URL del tiquet extern",
"notSet": "Not set"
},
"actions": {
"save": "Desa",
Expand All @@ -57,7 +62,8 @@
"changeStatus": "Canvia estat",
"addComment": "Afegeix comentari",
"edit": "Edita",
"cancel": "Cancel·la"
"cancel": "Cancel·la",
"editTitle": "Click to edit title"
},
"tabs": {
"description": "Descripció",
Expand Down Expand Up @@ -166,7 +172,8 @@
"version": "Versió",
"externalTicket": "Tiquet extern",
"tags": "Etiquetes",
"noTags": "Sense etiquetes"
"noTags": "Sense etiquetes",
"affectedVersion": "Affected version"
},
"links": {
"add": "Afegeix vincle",
Expand Down Expand Up @@ -205,11 +212,16 @@
"updateFailed": "No s'han pogut desar els canvis",
"commentFailed": "No s'ha pogut afegir el comentari",
"commentEditFailed": "No s'ha pogut desar el comentari",
"commentDeleteFailed": "No s'ha pogut eliminar el comentari"
"commentDeleteFailed": "No s'ha pogut eliminar el comentari",
"severityChanged": "Severity updated",
"severityFailed": "Could not change severity"
},
"report": {
"dialogTitle": "Reporta bug",
"fromResult": "Des del resultat {{result}}",
"logHint": "L'extracte del log s'adjunta automàticament a la descripció."
},
"list": {
"updated": "updated"
}
}
3 changes: 2 additions & 1 deletion frontend/src/i18n/locales/ca/publicReports.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
"revoked": "Enllaç revocat",
"revokeFailed": "No s'ha pogut revocar l'enllaç",
"created": "Enllaç públic generat",
"createFailed": "No s'ha pogut crear l'enllaç"
"createFailed": "No s'ha pogut crear l'enllaç",
"expiredDateError": "Expiration date must be in the future"
}
22 changes: 17 additions & 5 deletions frontend/src/i18n/locales/en/bugs.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@
"versionLabel": "Filter by version",
"anyStatus": "Any status",
"anySeverity": "Any severity",
"anyVersion": "Any version"
"anyVersion": "Any version",
"sortLabel": "Sort by",
"sortNewest": "Newest first",
"sortSeverity": "Severity",
"sortCreated": "Creation date"
},
"severity": {
"critical": "Critical",
Expand Down Expand Up @@ -66,7 +70,8 @@
"fixedInVersionNone": "Not set",
"affectedVersion": "Affected version",
"affectedVersionPlaceholder": "Pick a version…",
"affectedVersionNone": "Not set"
"affectedVersionNone": "Not set",
"notSet": "Not set"
},
"actions": {
"save": "Save",
Expand All @@ -75,7 +80,8 @@
"changeStatus": "Change status",
"addComment": "Add comment",
"edit": "Edit",
"cancel": "Cancel"
"cancel": "Cancel",
"editTitle": "Click to edit title"
},
"tabs": {
"description": "Description",
Expand Down Expand Up @@ -188,7 +194,8 @@
"version": "Version",
"externalTicket": "External ticket",
"tags": "Tags",
"noTags": "No tags"
"noTags": "No tags",
"affectedVersion": "Affected version"
},
"links": {
"add": "Add link",
Expand Down Expand Up @@ -227,11 +234,16 @@
"updateFailed": "Could not save changes",
"commentFailed": "Could not add comment",
"commentEditFailed": "Could not save comment",
"commentDeleteFailed": "Could not delete comment"
"commentDeleteFailed": "Could not delete comment",
"severityChanged": "Severity updated",
"severityFailed": "Could not change severity"
},
"report": {
"dialogTitle": "Report bug",
"fromResult": "From result {{result}}",
"logHint": "Log excerpt attached to the description automatically."
},
"list": {
"updated": "updated"
}
}
3 changes: 2 additions & 1 deletion frontend/src/i18n/locales/en/publicReports.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
"revoked": "Link revoked",
"revokeFailed": "Could not revoke link",
"created": "Public link generated",
"createFailed": "Could not create link"
"createFailed": "Could not create link",
"expiredDateError": "Expiration date must be in the future"
}
22 changes: 17 additions & 5 deletions frontend/src/i18n/locales/es/bugs.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@
"versionLabel": "Filtrar por versión",
"anyStatus": "Cualquier estado",
"anySeverity": "Cualquier severidad",
"anyVersion": "Cualquier versión"
"anyVersion": "Cualquier versión",
"sortLabel": "Ordenar por",
"sortNewest": "Más recientes",
"sortSeverity": "Severidad",
"sortCreated": "Fecha de creación"
},
"severity": {
"critical": "Crítica",
Expand Down Expand Up @@ -66,7 +70,8 @@
"fixedInVersionNone": "Sin establecer",
"affectedVersion": "Versión afectada",
"affectedVersionPlaceholder": "Elige una versión…",
"affectedVersionNone": "Sin establecer"
"affectedVersionNone": "Sin establecer",
"notSet": "Sin asignar"
},
"actions": {
"save": "Guardar",
Expand All @@ -75,7 +80,8 @@
"changeStatus": "Cambiar estado",
"addComment": "Añadir comentario",
"edit": "Editar",
"cancel": "Cancelar"
"cancel": "Cancelar",
"editTitle": "Clic para editar el título"
},
"tabs": {
"description": "Descripción",
Expand Down Expand Up @@ -188,7 +194,8 @@
"version": "Versión",
"externalTicket": "Ticket externo",
"tags": "Etiquetas",
"noTags": "Sin etiquetas"
"noTags": "Sin etiquetas",
"affectedVersion": "Versión afectada"
},
"links": {
"add": "Añadir vínculo",
Expand Down Expand Up @@ -227,11 +234,16 @@
"updateFailed": "No se pudieron guardar los cambios",
"commentFailed": "No se pudo añadir el comentario",
"commentEditFailed": "No se pudo guardar el comentario",
"commentDeleteFailed": "No se pudo eliminar el comentario"
"commentDeleteFailed": "No se pudo eliminar el comentario",
"severityChanged": "Severidad actualizada",
"severityFailed": "No se pudo cambiar la severidad"
},
"report": {
"dialogTitle": "Reportar bug",
"fromResult": "Desde el resultado {{result}}",
"logHint": "El extracto de log se adjunta automáticamente a la descripción."
},
"list": {
"updated": "actualizado"
}
}
3 changes: 2 additions & 1 deletion frontend/src/i18n/locales/es/publicReports.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
"revoked": "Enlace revocado",
"revokeFailed": "No se pudo revocar el enlace",
"created": "Enlace público generado",
"createFailed": "No se pudo crear el enlace"
"createFailed": "No se pudo crear el enlace",
"expiredDateError": "La fecha de expiración debe ser futura"
}
22 changes: 17 additions & 5 deletions frontend/src/i18n/locales/eu/bugs.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
"version": "Bertsioa",
"assignee": "Esleitua",
"tag": "Etiketa",
"any": "Edozein"
"any": "Edozein",
"sortLabel": "Sort by",
"sortNewest": "Newest first",
"sortSeverity": "Severity",
"sortCreated": "Creation date"
},
"severity": {
"critical": "Kritikoa",
Expand All @@ -48,7 +52,8 @@
"version": "Bertsioa",
"environment": "Ingurunea",
"assignee": "Esleitua",
"externalUrl": "Kanpoko txartelaren URLa"
"externalUrl": "Kanpoko txartelaren URLa",
"notSet": "Not set"
},
"actions": {
"save": "Gorde",
Expand All @@ -57,7 +62,8 @@
"changeStatus": "Aldatu egoera",
"addComment": "Gehitu iruzkina",
"edit": "Editatu",
"cancel": "Utzi"
"cancel": "Utzi",
"editTitle": "Click to edit title"
},
"tabs": {
"description": "Deskribapena",
Expand Down Expand Up @@ -166,7 +172,8 @@
"version": "Bertsioa",
"externalTicket": "Kanpoko txartela",
"tags": "Etiketak",
"noTags": "Etiketarik ez"
"noTags": "Etiketarik ez",
"affectedVersion": "Affected version"
},
"links": {
"add": "Gehitu lotura",
Expand Down Expand Up @@ -205,11 +212,16 @@
"updateFailed": "Ezin izan dira aldaketak gorde",
"commentFailed": "Ezin izan da iruzkina gehitu",
"commentEditFailed": "Ezin izan da iruzkina gorde",
"commentDeleteFailed": "Ezin izan da iruzkina ezabatu"
"commentDeleteFailed": "Ezin izan da iruzkina ezabatu",
"severityChanged": "Severity updated",
"severityFailed": "Could not change severity"
},
"report": {
"dialogTitle": "Eman akatsaren berri",
"fromResult": "Emaitzatik {{result}}",
"logHint": "Logaren laburpena automatikoki gehitzen zaio deskribapenari."
},
"list": {
"updated": "updated"
}
}
3 changes: 2 additions & 1 deletion frontend/src/i18n/locales/eu/publicReports.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
"revoked": "Esteka baliogabetuta",
"revokeFailed": "Ezin izan da esteka baliogabetu",
"created": "Esteka publikoa sortu da",
"createFailed": "Ezin izan da esteka sortu"
"createFailed": "Ezin izan da esteka sortu",
"expiredDateError": "Expiration date must be in the future"
}
Loading
Loading