feat: track authenticated user activity
This commit is contained in:
@@ -455,12 +455,6 @@
|
||||
<span class="text-sm text-gray-500 dark:text-dark-400">{{ formatDateTime(value) }}</span>
|
||||
</template>
|
||||
|
||||
<template #cell-last_login_at="{ value }">
|
||||
<span class="text-sm text-gray-500 dark:text-dark-400">
|
||||
{{ value ? formatDateTime(value) : '-' }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<template #cell-last_used_at="{ value }">
|
||||
<span class="text-sm text-gray-500 dark:text-dark-400">
|
||||
{{ value ? formatDateTime(value) : '-' }}
|
||||
@@ -718,7 +712,6 @@ const allColumns = computed<Column[]>(() => [
|
||||
{ key: 'usage', label: t('admin.users.columns.usage'), sortable: false },
|
||||
{ key: 'concurrency', label: t('admin.users.columns.concurrency'), sortable: true },
|
||||
{ key: 'status', label: t('admin.users.columns.status'), sortable: true },
|
||||
{ key: 'last_login_at', label: t('admin.users.columns.lastLogin'), sortable: true },
|
||||
{ key: 'last_used_at', label: t('admin.users.columns.lastUsed'), sortable: true },
|
||||
{ key: 'last_active_at', label: t('admin.users.columns.lastActive'), sortable: true },
|
||||
{ key: 'created_at', label: t('admin.users.columns.created'), sortable: true },
|
||||
@@ -735,7 +728,9 @@ const toggleableColumns = computed(() =>
|
||||
const hiddenColumns = reactive<Set<string>>(new Set())
|
||||
|
||||
// Default hidden columns (columns hidden by default on first load)
|
||||
const DEFAULT_HIDDEN_COLUMNS = ['notes', 'groups', 'subscriptions', 'usage', 'concurrency', 'last_login_at', 'last_active_at']
|
||||
const DEFAULT_HIDDEN_COLUMNS = ['notes', 'groups', 'subscriptions', 'usage', 'concurrency']
|
||||
const REMOVED_COLUMNS = new Set(['last_login_at'])
|
||||
const FORCED_VISIBLE_COLUMNS = new Set(['last_active_at'])
|
||||
|
||||
// localStorage key for column settings
|
||||
const HIDDEN_COLUMNS_KEY = 'user-hidden-columns'
|
||||
@@ -746,7 +741,9 @@ const loadSavedColumns = () => {
|
||||
const saved = localStorage.getItem(HIDDEN_COLUMNS_KEY)
|
||||
if (saved) {
|
||||
const parsed = JSON.parse(saved) as string[]
|
||||
parsed.forEach(key => hiddenColumns.add(key))
|
||||
parsed
|
||||
.filter(key => !REMOVED_COLUMNS.has(key) && !FORCED_VISIBLE_COLUMNS.has(key))
|
||||
.forEach(key => hiddenColumns.add(key))
|
||||
} else {
|
||||
// Use default hidden columns on first load
|
||||
DEFAULT_HIDDEN_COLUMNS.forEach(key => hiddenColumns.add(key))
|
||||
@@ -808,7 +805,7 @@ const searchQuery = ref('')
|
||||
const USER_SORT_STORAGE_KEY = 'admin-users-table-sort'
|
||||
const loadInitialSortState = (): { sort_by: string; sort_order: 'asc' | 'desc' } => {
|
||||
const fallback = { sort_by: 'created_at', sort_order: 'desc' as 'asc' | 'desc' }
|
||||
const sortable = new Set(['email', 'id', 'username', 'role', 'balance', 'concurrency', 'status', 'last_login_at', 'last_used_at', 'last_active_at', 'created_at'])
|
||||
const sortable = new Set(['email', 'id', 'username', 'role', 'balance', 'concurrency', 'status', 'last_used_at', 'last_active_at', 'created_at'])
|
||||
try {
|
||||
const raw = localStorage.getItem(USER_SORT_STORAGE_KEY)
|
||||
if (!raw) return fallback
|
||||
|
||||
@@ -113,7 +113,7 @@ describe('admin UsersView', () => {
|
||||
getBatchUserAttributes.mockResolvedValue({ values: {} })
|
||||
})
|
||||
|
||||
it('shows last_used_at column and requests last_used_at sort', async () => {
|
||||
it('shows active and used activity columns, hides last_login_at, and requests last_used_at sort', async () => {
|
||||
const wrapper = mount(UsersView, {
|
||||
global: {
|
||||
stubs: {
|
||||
@@ -144,7 +144,10 @@ describe('admin UsersView', () => {
|
||||
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.get('[data-test="columns"]').text()).toContain('last_used_at')
|
||||
const columns = wrapper.get('[data-test="columns"]').text()
|
||||
expect(columns).toContain('last_used_at')
|
||||
expect(columns).toContain('last_active_at')
|
||||
expect(columns).not.toContain('last_login_at')
|
||||
|
||||
await wrapper.get('[data-test="sort-last-used"]').trigger('click')
|
||||
await flushPromises()
|
||||
|
||||
Reference in New Issue
Block a user