Compare commits

..

No commits in common. "b79e99246eaf4ba10d0ccf8e6bda64c056be98f5" and "7a4f574a38733144e527c4f0b470000720090653" have entirely different histories.

View File

@ -17,9 +17,9 @@ const entries = ref<AuditEntry[]>([]);
const loading = ref(false);
const ENTITY_LABELS: Record<string, string> = {
lead: 'Лида',
user: 'Пользователя',
system: 'Систему',
lead: 'лида',
user: 'пользователя',
system: 'систему',
};
interface ActionMeta {
@ -29,12 +29,12 @@ interface ActionMeta {
}
const ACTIONS: Record<string, ActionMeta> = {
create: { label: 'создал', tone: 'success', icon: '+' },
delete: { label: 'удалил', tone: 'danger', icon: '×' },
create: { label: 'создал', tone: 'success', icon: '+' },
delete: { label: 'удалил', tone: 'danger', icon: '🗑' },
reassign: { label: 'переназначил', tone: 'warning', icon: '↻' },
reset_password: { label: 'сменил пароль', tone: 'warning', icon: '⚿' },
change_role: { label: 'изменил роль', tone: 'warning', icon: '⚙' },
recalc: { label: 'пересчитал score', tone: 'neutral', icon: '∑' },
reset_password: { label: 'сменил пароль', tone: 'warning', icon: '🔑' },
change_role: { label: 'изменил роль', tone: 'warning', icon: '👤' },
recalc: { label: 'пересчитал score', tone: 'neutral', icon: '⟳' },
};
function actionMeta(a: string): ActionMeta {
@ -132,6 +132,11 @@ const grouped = computed(() => {
return groups;
});
function initials(name: string): string {
const parts = name.split(/[\s._-]+/).filter(Boolean).slice(0, 2);
return parts.map((p) => p[0]?.toUpperCase() ?? '').join('') || name[0]?.toUpperCase() || '?';
}
function shortId(id: string): string {
return id.length > 10 ? id.slice(0, 8) + '…' : id;
}
@ -189,26 +194,26 @@ onMounted(load);
>
Событий не найдено.
</div>
<div v-else class="space-y-6">
<section
<div v-else class="space-y-8">
<div
v-for="group in grouped"
:key="group.day"
class="space-y-2"
class="space-y-3"
>
<h2
class="text-[10px] font-semibold uppercase tracking-[0.18em] text-gray-400 px-1"
>
{{ group.day }}
</h2>
<div class="sticky top-16 z-10 bg-gradient-to-b from-white via-white to-white/0 pb-1">
<div class="text-[11px] font-semibold uppercase tracking-widest text-gray-400">
{{ group.day }}
</div>
</div>
<div class="card divide-y divide-gray-100">
<div
v-for="e in group.items"
:key="e.id"
class="flex items-center gap-3 px-4 py-3 hover:bg-gray-50/70 transition"
class="flex items-center gap-4 px-4 py-3 hover:bg-gray-50/70 transition"
>
<div
class="w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold ring-1 shrink-0 leading-none"
class="w-9 h-9 rounded-full flex items-center justify-center text-base ring-1 shrink-0"
:class="[
TONE_CLASSES[actionMeta(e.action).tone].bg,
TONE_CLASSES[actionMeta(e.action).tone].ring,
@ -219,37 +224,39 @@ onMounted(load);
{{ actionMeta(e.action).icon }}
</div>
<p
class="flex-1 min-w-0 text-sm text-gray-700 leading-snug truncate"
>
<span class="font-semibold text-gray-900">{{ e.actor }}</span>
<span class="mx-1.5">{{ actionMeta(e.action).label }}</span>
<span class="text-gray-500">{{ ENTITY_LABELS[e.entity] ?? e.entity }}</span>
<div class="flex items-center gap-2 shrink-0">
<div
class="w-7 h-7 rounded-full bg-gray-100 text-gray-700 flex items-center justify-center text-[11px] font-semibold"
:title="e.actor"
>
{{ initials(e.actor) }}
</div>
<span class="text-sm font-medium text-gray-900">{{ e.actor }}</span>
</div>
<div class="flex-1 min-w-0 text-sm text-gray-700 truncate">
<span>{{ actionMeta(e.action).label }}</span>
<span class="text-gray-500"> {{ ENTITY_LABELS[e.entity] ?? e.entity }} </span>
<button
v-if="e.entity === 'lead'"
type="button"
class="ml-1.5 font-mono text-xs text-sky-600 hover:underline align-middle"
class="font-mono text-sky-600 hover:underline"
@click="gotoEntity(e)"
>
{{ shortId(e.entity_id) }}
</button>
<span
v-else
class="ml-1.5 font-mono text-xs text-gray-500 align-middle"
>
{{ e.entity_id }}
</span>
</p>
<span v-else class="font-mono text-gray-600">{{ e.entity_id }}</span>
</div>
<time
class="text-[11px] text-gray-400 tabular-nums shrink-0 leading-none"
<div
class="text-xs text-gray-400 tabular-nums shrink-0"
:title="fmtFullTime(e.created_at)"
>
{{ relativeTime(e.created_at) }}
</time>
</div>
</div>
</div>
</section>
</div>
</div>
</div>
</template>