Compare commits
2 Commits
7a4f574a38
...
b79e99246e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b79e99246e | ||
|
|
a92298daf2 |
@ -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,11 +132,6 @@ 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;
|
||||
}
|
||||
@ -194,26 +189,26 @@ onMounted(load);
|
||||
>
|
||||
Событий не найдено.
|
||||
</div>
|
||||
<div v-else class="space-y-8">
|
||||
<div
|
||||
<div v-else class="space-y-6">
|
||||
<section
|
||||
v-for="group in grouped"
|
||||
:key="group.day"
|
||||
class="space-y-3"
|
||||
class="space-y-2"
|
||||
>
|
||||
<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>
|
||||
<h2
|
||||
class="text-[10px] font-semibold uppercase tracking-[0.18em] text-gray-400 px-1"
|
||||
>
|
||||
{{ group.day }}
|
||||
</h2>
|
||||
|
||||
<div class="card divide-y divide-gray-100">
|
||||
<div
|
||||
v-for="e in group.items"
|
||||
:key="e.id"
|
||||
class="flex items-center gap-4 px-4 py-3 hover:bg-gray-50/70 transition"
|
||||
class="flex items-center gap-3 px-4 py-3 hover:bg-gray-50/70 transition"
|
||||
>
|
||||
<div
|
||||
class="w-9 h-9 rounded-full flex items-center justify-center text-base ring-1 shrink-0"
|
||||
class="w-8 h-8 rounded-full flex items-center justify-center text-sm font-semibold ring-1 shrink-0 leading-none"
|
||||
:class="[
|
||||
TONE_CLASSES[actionMeta(e.action).tone].bg,
|
||||
TONE_CLASSES[actionMeta(e.action).tone].ring,
|
||||
@ -224,39 +219,37 @@ onMounted(load);
|
||||
{{ actionMeta(e.action).icon }}
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<button
|
||||
v-if="e.entity === 'lead'"
|
||||
type="button"
|
||||
class="font-mono text-sky-600 hover:underline"
|
||||
class="ml-1.5 font-mono text-xs text-sky-600 hover:underline align-middle"
|
||||
@click="gotoEntity(e)"
|
||||
>
|
||||
{{ shortId(e.entity_id) }}
|
||||
</button>
|
||||
<span v-else class="font-mono text-gray-600">{{ e.entity_id }}</span>
|
||||
</div>
|
||||
<span
|
||||
v-else
|
||||
class="ml-1.5 font-mono text-xs text-gray-500 align-middle"
|
||||
>
|
||||
{{ e.entity_id }}
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div
|
||||
class="text-xs text-gray-400 tabular-nums shrink-0"
|
||||
<time
|
||||
class="text-[11px] text-gray-400 tabular-nums shrink-0 leading-none"
|
||||
:title="fmtFullTime(e.created_at)"
|
||||
>
|
||||
{{ relativeTime(e.created_at) }}
|
||||
</div>
|
||||
</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user