Ticket jde uzavrit, komentare jsou videt, zakaznik bez soudu, Dashboard misto Portalu

Karta Resitel ma tlacitko Uzavrit ticket a Znovu otevrit; meni jen priznak
closed, text stavu zustava a meni se v poli Stav nezavisle.

Komentar je vlastni druh radku logu (kind comment) s autorem; detail ma
sekci Komentare se seznamem (jmeno, cas, text) a formularem, log ho ukazuje
s autorem. Test tests/data/comments.test.ts.

Sekce Zakaznik jen popisuje: pryc odznak "nedohledan", varovne zbarveni,
text o CRM a garantovi i zvyrazneni v tabulce a na karte; ID v CRM jen
kdyz existuje.

Uzivatelske texty: Portal a Prehled -> Dashboard (zalozka Prehled v Lidech
je Souhrn), v auditu "odepreni" -> "zamitnute pokusy".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
JiriUhlir
2026-09-10 07:56:55 +02:00
co-authored by Claude Fable 5.1
parent 5d41600578
commit 0ae9dab1d4
29 changed files with 296 additions and 136 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ export interface ModuleDefinition {
* Nova zalozka = zaznam tady plus cesta na klientovi.
*/
export const moduleCatalog: ModuleDefinition[] = [
{ key: 'overview', label: 'Přehled', permissions: [], required: true },
{ key: 'overview', label: 'Dashboard', permissions: [], required: true },
{ key: 'tickets', label: 'Tickety', permissions: ['ticket.view'] },
/*
* Helpdesk je pohled **zadavatele**, ne resitele: firma tu vidi pozadavky,
+3 -1
View File
@@ -398,7 +398,9 @@ export function addComment(
markResponded(ticket);
touch(ticket);
appendTrace(id, [{ kind: 'note', label: `${author}: ${text}`, status: 'info' }]);
// Vlastni druh radku: detail z nej sklada sekci Komentare, log ho ukazuje
// s autorem. Driv byl komentar poznamka "autor: text" a v detailu nebyl videt.
appendTrace(id, [{ kind: 'comment', label: text, author, status: 'info' }]);
publish('ticket.updated', `Nový komentář u ticketu ${ticket.id}`, { ticketId: ticket.id, ticket: toTicket(ticket) }, ticket.tenantId);
return toTicket(ticket);
+3
View File
@@ -15,6 +15,8 @@ import { nextTraceId, ticketsById, traces } from './state.js';
export interface TraceInput {
kind: TraceKind;
label: string;
/** Autor komentare, jen u `kind: 'comment'`. */
author?: string;
status: TraceStatus;
serviceId?: string | null;
operationId?: string | null;
@@ -42,6 +44,7 @@ export function flattenTrace(
serviceId: input.serviceId ?? null,
operationId: input.operationId ?? null,
label: input.label,
...(input.author !== undefined ? { author: input.author } : {}),
status: input.status,
response: input.response ?? null,
durationMs: input.durationMs ?? null,
+1 -1
View File
@@ -544,7 +544,7 @@ builtinAction({
text: z.string().trim().min(2, 'Komentář musí mít alespoň 2 znaky.'),
}),
apply: (ticket, input, tenantIds, req) =>
addComment(ticket.id, req.user?.name ?? 'Portál', input.text, tenantIds),
addComment(ticket.id, req.user?.name ?? 'Dashboard', input.text, tenantIds),
});
/**
+8 -1
View File
@@ -36,7 +36,12 @@ export interface TicketAssignee {
}
export type TraceStatus = 'ok' | 'error' | 'skipped' | 'info';
export type TraceKind = 'trigger' | 'action' | 'condition' | 'note';
/**
* `comment` je komentar cloveka: ma autora a text, kresli se ve vlastni
* sekci detailu i v logu. `note` je poznamka systemu (prirazeni, zmena
* stavu), bez autora.
*/
export type TraceKind = 'trigger' | 'action' | 'condition' | 'note' | 'comment';
/** Jeden radek v logu ticketu. Strom se sklada pres `parentId`. */
export interface TicketTraceEntry {
@@ -48,6 +53,8 @@ export interface TicketTraceEntry {
serviceId: string | null;
operationId: string | null;
label: string;
/** Kdo komentar napsal. Jen u `kind: 'comment'`, jinde chybi. */
author?: string;
status: TraceStatus;
/** Co sluzba vratila. Tohle je duvod, proc log existuje. */
response: string | null;