fix(requests): confirm destructive actions and align surfaces
This commit is contained in:
parent
b7b09740cb
commit
1552bbe84b
@ -514,7 +514,7 @@ class RequestViewSet(viewsets.ModelViewSet):
|
||||
req_obj = self.get_object()
|
||||
|
||||
# Получаем чат для этой заявки
|
||||
chat = comments_helpers.get_or_create_comments_chat(req_obj)[0]
|
||||
chat = comments_helpers.get_or_create_comments_chat(req_obj)
|
||||
|
||||
# Находим комментарий
|
||||
try:
|
||||
|
||||
@ -386,6 +386,32 @@ def test_comments_allowed_for_admin_and_manager(
|
||||
assert post_r.status_code == 201, "Получатель должен уметь создавать комментарий"
|
||||
|
||||
|
||||
def test_comment_author_can_delete_own_comment(
|
||||
auth_client,
|
||||
regular_user: models.Model,
|
||||
make_request,
|
||||
) -> None:
|
||||
"""Автор комментария может удалить свой комментарий без 500."""
|
||||
req = make_request(employee=regular_user)
|
||||
client = auth_client(regular_user)
|
||||
|
||||
post_resp = client.post(
|
||||
f"{API_BASE}{req.id}/comments/",
|
||||
data={"text": "удаляемый комментарий"},
|
||||
format="json",
|
||||
)
|
||||
assert post_resp.status_code == 201
|
||||
comment_id = post_resp.json()["id"]
|
||||
|
||||
delete_resp = client.delete(f"{API_BASE}{req.id}/comments/{comment_id}/")
|
||||
assert delete_resp.status_code == 204
|
||||
|
||||
list_resp = client.get(f"{API_BASE}{req.id}/comments/")
|
||||
assert list_resp.status_code == 200
|
||||
ids = {item["id"] for item in _results(list_resp.json())}
|
||||
assert comment_id not in ids
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# 8) ФИЛЬТРЫ
|
||||
# ------------------------------------------------------------------------------
|
||||
@ -434,4 +460,4 @@ def test_invalid_filter_does_not_crash(auth_client, admin_user: models.Model) ->
|
||||
"""Странные значения фильтров не приводят к 500."""
|
||||
client = auth_client(admin_user)
|
||||
resp = client.get(f"{API_BASE}?type=__sql__' OR 1=1 --&status=")
|
||||
assert resp.status_code == 200
|
||||
assert resp.status_code == 200
|
||||
|
||||
@ -235,7 +235,7 @@ function RequestsPageContent() {
|
||||
const summary = item.comment || item.description;
|
||||
|
||||
return (
|
||||
<article key={item.id} className="app-surface overflow-hidden rounded-xl transition hover:border-[var(--border-strong)]">
|
||||
<article key={item.id} className="app-surface-muted overflow-hidden rounded-xl transition hover:border-[var(--border-strong)]">
|
||||
<div className="p-4">
|
||||
<div className="flex items-start gap-3">
|
||||
<button type="button" onClick={() => h.toggleRow(item.id)} className="app-action-secondary mt-0.5 inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg transition"><ChevronDown size={15} className={`transition ${rowOpen ? "rotate-180" : ""}`} /></button>
|
||||
@ -271,7 +271,7 @@ function RequestsPageContent() {
|
||||
</div>
|
||||
|
||||
{(rowOpen || commentsOpen) && (
|
||||
<div className="app-surface-muted mt-4 rounded-xl p-4">
|
||||
<div className="app-surface-elevated mt-4 rounded-xl p-4">
|
||||
{rowOpen && (
|
||||
<div className="space-y-3 text-xs">
|
||||
<div className="grid grid-cols-1 gap-x-4 gap-y-2 sm:grid-cols-2">
|
||||
|
||||
@ -320,6 +320,9 @@ export function useRequestsPage(_userId: number | null | undefined) {
|
||||
};
|
||||
|
||||
const handleDelete = async (id: number) => {
|
||||
if (!window.confirm("Удалить заявление? Это действие нельзя отменить.")) {
|
||||
return;
|
||||
}
|
||||
try { setBusyKey(`delete-${id}`); setActionError(null); await apiClient.deleteRequest(id); setRequests((p) => p.filter((r) => r.id !== id)); }
|
||||
catch (e: unknown) { setActionError(String((e as Error)?.message || "Не удалось удалить")); }
|
||||
finally { setBusyKey(null); }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user