Compare commits
2 Commits
7a4f574a38
...
b79e99246e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b79e99246e | ||
|
|
a92298daf2 |
@ -17,9 +17,9 @@ const entries = ref<AuditEntry[]>([]);
|
|||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
const ENTITY_LABELS: Record<string, string> = {
|
const ENTITY_LABELS: Record<string, string> = {
|
||||||
lead: 'лида',
|
lead: 'Лида',
|
||||||
user: 'пользователя',
|
user: 'Пользователя',
|
||||||
system: 'систему',
|
system: 'Систему',
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ActionMeta {
|
interface ActionMeta {
|
||||||
@ -29,12 +29,12 @@ interface ActionMeta {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ACTIONS: Record<string, ActionMeta> = {
|
const ACTIONS: Record<string, ActionMeta> = {
|
||||||
create: { label: 'создал', tone: 'success', icon: '+' },
|
create: { label: 'создал', tone: 'success', icon: '+' },
|
||||||
delete: { label: 'удалил', tone: 'danger', icon: '🗑' },
|
delete: { label: 'удалил', tone: 'danger', icon: '×' },
|
||||||
reassign: { label: 'переназначил', tone: 'warning', icon: '↻' },
|
reassign: { label: 'переназначил', tone: 'warning', icon: '↻' },
|
||||||
reset_password: { label: 'сменил пароль', tone: 'warning', icon: '🔑' },
|
reset_password: { label: 'сменил пароль', tone: 'warning', icon: '⚿' },
|
||||||
change_role: { label: 'изменил роль', tone: 'warning', icon: '👤' },
|
change_role: { label: 'изменил роль', tone: 'warning', icon: '⚙' },
|
||||||
recalc: { label: 'пересчитал score', tone: 'neutral', icon: '⟳' },
|
recalc: { label: 'пересчитал score', tone: 'neutral', icon: '∑' },
|
||||||
};
|
};
|
||||||
|
|
||||||
function actionMeta(a: string): ActionMeta {
|
function actionMeta(a: string): ActionMeta {
|
||||||
@ -132,11 +132,6 @@ const grouped = computed(() => {
|
|||||||
return groups;
|
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 {
|
function shortId(id: string): string {
|
||||||
return id.length > 10 ? id.slice(0, 8) + '…' : id;
|
return id.length > 10 ? id.slice(0, 8) + '…' : id;
|
||||||
}
|
}
|
||||||
@ -194,26 +189,26 @@ onMounted(load);
|
|||||||
>
|
>
|
||||||
Событий не найдено.
|
Событий не найдено.
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="space-y-8">
|
<div v-else class="space-y-6">
|
||||||
<div
|
<section
|
||||||
v-for="group in grouped"
|
v-for="group in grouped"
|
||||||
:key="group.day"
|
:key="group.day"
|
||||||
class="space-y-3"
|
class="space-y-2"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
class="text-[10px] font-semibold uppercase tracking-[0.18em] text-gray-400 px-1"
|
||||||
>
|
>
|
||||||
<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 }}
|
{{ group.day }}
|
||||||
</div>
|
</h2>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="card divide-y divide-gray-100">
|
<div class="card divide-y divide-gray-100">
|
||||||
<div
|
<div
|
||||||
v-for="e in group.items"
|
v-for="e in group.items"
|
||||||
:key="e.id"
|
: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
|
<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="[
|
:class="[
|
||||||
TONE_CLASSES[actionMeta(e.action).tone].bg,
|
TONE_CLASSES[actionMeta(e.action).tone].bg,
|
||||||
TONE_CLASSES[actionMeta(e.action).tone].ring,
|
TONE_CLASSES[actionMeta(e.action).tone].ring,
|
||||||
@ -224,39 +219,37 @@ onMounted(load);
|
|||||||
{{ actionMeta(e.action).icon }}
|
{{ actionMeta(e.action).icon }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center gap-2 shrink-0">
|
<p
|
||||||
<div
|
class="flex-1 min-w-0 text-sm text-gray-700 leading-snug truncate"
|
||||||
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) }}
|
<span class="font-semibold text-gray-900">{{ e.actor }}</span>
|
||||||
</div>
|
<span class="mx-1.5">{{ actionMeta(e.action).label }}</span>
|
||||||
<span class="text-sm font-medium text-gray-900">{{ e.actor }}</span>
|
<span class="text-gray-500">{{ ENTITY_LABELS[e.entity] ?? e.entity }}</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
|
<button
|
||||||
v-if="e.entity === 'lead'"
|
v-if="e.entity === 'lead'"
|
||||||
type="button"
|
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)"
|
@click="gotoEntity(e)"
|
||||||
>
|
>
|
||||||
{{ shortId(e.entity_id) }}
|
{{ shortId(e.entity_id) }}
|
||||||
</button>
|
</button>
|
||||||
<span v-else class="font-mono text-gray-600">{{ e.entity_id }}</span>
|
<span
|
||||||
</div>
|
v-else
|
||||||
|
class="ml-1.5 font-mono text-xs text-gray-500 align-middle"
|
||||||
|
>
|
||||||
|
{{ e.entity_id }}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
<div
|
<time
|
||||||
class="text-xs text-gray-400 tabular-nums shrink-0"
|
class="text-[11px] text-gray-400 tabular-nums shrink-0 leading-none"
|
||||||
:title="fmtFullTime(e.created_at)"
|
:title="fmtFullTime(e.created_at)"
|
||||||
>
|
>
|
||||||
{{ relativeTime(e.created_at) }}
|
{{ relativeTime(e.created_at) }}
|
||||||
|
</time>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user