feat: audit logs UI (#6803)

* feat: init auditlogs ui

* chore: add api

* fix: action

* chore: add action,username,time

* feat: add pagination support

* chore: format time

* chore: refactor

* chore: refactor auditlogs api response

* chore: update icon

* chore: rubocop fixes

* Fixes the way meta is handled in store

* Fixes meta not appearing issue

---------

Co-authored-by: Sojan Jose <sojan@pepalo.com>
Co-authored-by: Nithin David Thomas <1277421+nithindavid@users.noreply.github.com>
This commit is contained in:
Vishnu Narayanan
2023-04-17 19:11:05 +05:30
committed by GitHub
parent 80dcd17f6e
commit 9e2f991484
15 changed files with 314 additions and 7 deletions

View File

@@ -0,0 +1,107 @@
<template>
<div class="column content-box">
<!-- List Audit Logs -->
<div class="row">
<div class="small-8 columns with-right-space ">
<p
v-if="!uiFlags.fetchingList && !records.length"
class="no-items-error-message"
>
{{ $t('AUDIT_LOGS.LIST.404') }}
</p>
<woot-loading-state
v-if="uiFlags.fetchingList"
:message="$t('AUDIT_LOGS.LOADING')"
/>
<table
v-if="!uiFlags.fetchingList && records.length"
class="woot-table"
>
<thead>
<!-- Header -->
<th
v-for="thHeader in $t('AUDIT_LOGS.LIST.TABLE_HEADER')"
:key="thHeader"
>
{{ thHeader }}
</th>
</thead>
<tbody>
<tr v-for="auditLogItem in records" :key="auditLogItem.id">
<td class="wrap-break-words">{{ auditLogItem.username }}</td>
<td class="wrap-break-words">
{{ auditLogItem.auditable_type }}.{{ auditLogItem.action }}
</td>
<td class="remote-address">
{{ auditLogItem.remote_address }}
</td>
<td class="wrap-break-words">
{{ dynamicTime(auditLogItem.created_at) }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
<table-footer
:current-page="Number(meta.currentPage)"
:total-count="meta.totalEntries"
:page-size="meta.perPage"
@page-change="onPageChange"
/>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import TableFooter from 'dashboard/components/widgets/TableFooter';
import timeMixin from 'dashboard/mixins/time';
import alertMixin from 'shared/mixins/alertMixin';
export default {
components: {
TableFooter,
},
mixins: [alertMixin, timeMixin],
data() {
return {
loading: {},
auditLogsAPI: {
message: '',
},
};
},
computed: {
...mapGetters({
records: 'auditlogs/getAuditLogs',
uiFlags: 'auditlogs/getUIFlags',
meta: 'auditlogs/getMeta',
}),
},
mounted() {
// Fetch API Call
this.$store.dispatch('auditlogs/fetch', { page: 1 });
},
methods: {
onPageChange(page) {
window.history.pushState({}, null, `${this.$route.path}?page=${page}`);
try {
this.$store.dispatch('auditlogs/fetch', { page });
} catch (error) {
const errorMessage =
error?.message || this.$t('AUDIT_LOGS.API.ERROR_MESSAGE');
this.showAlert(errorMessage);
}
},
},
};
</script>
<style scoped>
.remote-address {
width: 14rem;
}
.wrap-break-words {
word-break: break-all;
white-space: normal;
}
</style>

View File

@@ -0,0 +1,30 @@
import SettingsContent from '../Wrapper';
import AuditLogsHome from './Index';
import { frontendURL } from '../../../../helper/URLHelper';
export default {
routes: [
{
path: frontendURL('accounts/:accountId/settings/audit-log'),
component: SettingsContent,
props: {
headerTitle: 'AUDIT_LOGS.HEADER',
icon: 'key',
showNewButton: false,
},
children: [
{
path: '',
name: 'auditlogs_wrapper',
redirect: 'list',
},
{
path: 'list',
name: 'auditlogs_list',
roles: ['administrator'],
component: AuditLogsHome,
},
],
},
],
};

View File

@@ -4,6 +4,7 @@ import agent from './agents/agent.routes';
import agentBot from './agentBots/agentBot.routes';
import attributes from './attributes/attributes.routes';
import automation from './automation/automation.routes';
import auditlogs from './auditlogs/audit.routes';
import billing from './billing/billing.routes';
import campaigns from './campaigns/campaigns.routes';
import canned from './canned/canned.routes';
@@ -35,6 +36,7 @@ export default {
...agentBot.routes,
...attributes.routes,
...automation.routes,
...auditlogs.routes,
...billing.routes,
...campaigns.routes,
...canned.routes,