v1.5.1
Co nowego: - Kolumny kolejki operatora: dwie nowe (ID, e-mail) obok istniejących, oraz możliwość zmiany kolejności widocznych kolumn strzałkami ↑/↓ w picker „Kolumny” — nie tylko włączanie/wyłączanie. Kolejność zapamiętywana jest per operator tak samo jak dotąd widoczność. - Wybór sprzętu klienta (Snipe-IT): druga lista dozwolonych kategorii obok istniejącej listy podkategorii — pozwala objąć od razu wszystkie podkategorie danej kategorii jednym zaznaczeniem. - Pulpit klienta i widok zgłoszenia operatora pamiętają teraz aktywną zakładkę, więc „Wróć do listy” wraca do tej samej, a nie zawsze do domyślnej. Poprawki: - Paginacja (kolejka operatora, pulpit klienta) używała domyślnego, szarego stylu Laravela reagującego na motyw systemu/przeglądarki, a nie przełącznik jasny/ciemny w aplikacji — stąd ciemne przyciski nawet w trybie jasnym. Podmieniony na własny widok zgodny z kolorami aplikacji (w tym własne tło/border każdego przycisku i wyśrodkowanie na telefonie). - Kolorystyka boksu z informacją o logowaniu nie zmienia już odcienia między trybem jasnym i ciemnym (wcześniej pochodziła z --color-accent) — teraz stałe, ciemne tło w obu trybach, więc kolory tekstu ustawione przez admina (np. biały) zostają czytelne niezależnie od motywu. Poszerzona karta logowania (380px → 480px). - Lista zgłoszeń klienta: etykiety priorytetu/statusu nie zawijają się już do osobnej linii przy długim temacie na wąskich ekranach — zostają przypięte do prawej, a temat zawija się we własnej kolumnie. - Liczniki czasu pracy (resumeTimer/stopTimer/...) nie dotykają już updated_at — samo otwarcie zgłoszenia nie liczy się jako aktualizacja. Kolejka operatora i pulpit klienta domyślnie sortują po dacie utworzenia z tego samego powodu. Zaktualizowana dokumentacja: README, CLAUDE.md, ARCHITECTURE.md, CHANGELOG.md, wiki/admin, wiki/client, wiki/operator. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -611,7 +611,7 @@ class Ticket extends Model
|
||||
public function flushTimer(): void
|
||||
{
|
||||
if ($this->timer_started_at) {
|
||||
$this->update([
|
||||
$this->updateTimerFields([
|
||||
'time_spent_seconds' => $this->time_spent_seconds + $this->secondsSinceTimerStarted(),
|
||||
'timer_started_at' => now(),
|
||||
]);
|
||||
@@ -621,7 +621,7 @@ class Ticket extends Model
|
||||
public function stopTimer(): void
|
||||
{
|
||||
if ($this->timer_started_at) {
|
||||
$this->update([
|
||||
$this->updateTimerFields([
|
||||
'time_spent_seconds' => $this->time_spent_seconds + $this->secondsSinceTimerStarted(),
|
||||
'timer_started_at' => null,
|
||||
]);
|
||||
@@ -640,13 +640,13 @@ class Ticket extends Model
|
||||
}
|
||||
|
||||
if (! $this->timer_started_at) {
|
||||
$this->update(['timer_started_at' => now()]);
|
||||
$this->updateTimerFields(['timer_started_at' => now()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function resetTimer(): void
|
||||
{
|
||||
$this->update(['time_spent_seconds' => 0, 'timer_started_at' => null]);
|
||||
$this->updateTimerFields(['time_spent_seconds' => 0, 'timer_started_at' => null]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -657,12 +657,27 @@ class Ticket extends Model
|
||||
*/
|
||||
public function setTimeSpent(int $seconds): void
|
||||
{
|
||||
$this->update([
|
||||
$this->updateTimerFields([
|
||||
'time_spent_seconds' => max(0, $seconds),
|
||||
'timer_started_at' => $this->timer_started_at ? now() : null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Timer bookkeeping alone is never a ticket "update" worth surfacing —
|
||||
* merely opening a ticket (resumeTimer on mount, stopTimer on leaving)
|
||||
* would otherwise bump `updated_at` on every single view, drowning out
|
||||
* genuinely stale tickets in queues/lists sorted by that column. Real
|
||||
* content changes (replies, status/priority/assignee edits, ...) go
|
||||
* through their own ->update() calls elsewhere and still touch it.
|
||||
*/
|
||||
private function updateTimerFields(array $attributes): void
|
||||
{
|
||||
$this->timestamps = false;
|
||||
$this->update($attributes);
|
||||
$this->timestamps = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom field values for this ticket's subcategory, in display order, skipping blanks.
|
||||
*
|
||||
|
||||
@@ -14,7 +14,7 @@ use Illuminate\Notifications\Notifiable;
|
||||
use LdapRecord\Laravel\Auth\AuthenticatesWithLdap;
|
||||
use LdapRecord\Laravel\Auth\LdapAuthenticatable;
|
||||
|
||||
#[Fillable(['name', 'email', 'password', 'roles', 'custom_field_values'])]
|
||||
#[Fillable(['name', 'email', 'password', 'roles', 'custom_field_values', 'operator_queue_columns'])]
|
||||
#[Hidden(['password'])]
|
||||
class User extends Authenticatable implements LdapAuthenticatable
|
||||
{
|
||||
@@ -109,6 +109,7 @@ class User extends Authenticatable implements LdapAuthenticatable
|
||||
{
|
||||
return [
|
||||
'password' => 'hashed',
|
||||
'operator_queue_columns' => 'array',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user