mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 03:57:52 +00:00
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:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -62,5 +62,8 @@ test/cypress/videos/*
|
|||||||
/config/*.enc
|
/config/*.enc
|
||||||
|
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
|
.vscode
|
||||||
|
|
||||||
# yalc for local testing
|
# yalc for local testing
|
||||||
.yalc
|
.yalc
|
||||||
|
yalc.lock
|
||||||
|
|||||||
16
app/javascript/dashboard/api/auditLogs.js
Normal file
16
app/javascript/dashboard/api/auditLogs.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/* global axios */
|
||||||
|
|
||||||
|
import ApiClient from './ApiClient';
|
||||||
|
|
||||||
|
class AuditLogs extends ApiClient {
|
||||||
|
constructor() {
|
||||||
|
super('audit_logs', { accountScoped: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
get({ page }) {
|
||||||
|
const url = page ? `${this.url}?page=${page}` : this.url;
|
||||||
|
return axios.get(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new AuditLogs();
|
||||||
@@ -8,6 +8,7 @@ const settings = accountId => ({
|
|||||||
'agent_list',
|
'agent_list',
|
||||||
'attributes_list',
|
'attributes_list',
|
||||||
'automation_list',
|
'automation_list',
|
||||||
|
'auditlogs_list',
|
||||||
'billing_settings_index',
|
'billing_settings_index',
|
||||||
'canned_list',
|
'canned_list',
|
||||||
'general_settings_index',
|
'general_settings_index',
|
||||||
@@ -150,6 +151,14 @@ const settings = accountId => ({
|
|||||||
toStateName: 'billing_settings_index',
|
toStateName: 'billing_settings_index',
|
||||||
showOnlyOnCloud: true,
|
showOnlyOnCloud: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
icon: 'key',
|
||||||
|
label: 'AUDIT_LOGS',
|
||||||
|
hasSubMenu: false,
|
||||||
|
toState: frontendURL(`accounts/${accountId}/settings/audit-log/list`),
|
||||||
|
toStateName: 'auditlogs_list',
|
||||||
|
beta: true,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
24
app/javascript/dashboard/i18n/locale/en/auditLogs.json
Normal file
24
app/javascript/dashboard/i18n/locale/en/auditLogs.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"AUDIT_LOGS": {
|
||||||
|
"HEADER": "Audit Logs",
|
||||||
|
"HEADER_BTN_TXT": "Add Audit Logs",
|
||||||
|
"LOADING": "Fetching Audit Logs",
|
||||||
|
"SEARCH_404": "There are no items matching this query",
|
||||||
|
"SIDEBAR_TXT": "<p><b>Audit Logs</b> </p><p> Audit Logs are trails for events and actions in a Chatwoot System. </p>",
|
||||||
|
"LIST": {
|
||||||
|
"404": "There are no Audit Logs available in this account.",
|
||||||
|
"TITLE": "Manage Audit Logs",
|
||||||
|
"DESC": "Audit Logs are trails for events and actions in a Chatwoot System.",
|
||||||
|
"TABLE_HEADER": [
|
||||||
|
"User",
|
||||||
|
"Action",
|
||||||
|
"IP Address",
|
||||||
|
"Time"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"API": {
|
||||||
|
"SUCCESS_MESSAGE": "AuditLogs retrieved successfully",
|
||||||
|
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import advancedFilters from './advancedFilters.json';
|
|||||||
import agentBots from './agentBots.json';
|
import agentBots from './agentBots.json';
|
||||||
import agentMgmt from './agentMgmt.json';
|
import agentMgmt from './agentMgmt.json';
|
||||||
import attributesMgmt from './attributesMgmt.json';
|
import attributesMgmt from './attributesMgmt.json';
|
||||||
|
import auditLogs from './auditLogs.json';
|
||||||
import automation from './automation.json';
|
import automation from './automation.json';
|
||||||
import bulkActions from './bulkActions.json';
|
import bulkActions from './bulkActions.json';
|
||||||
import campaign from './campaign.json';
|
import campaign from './campaign.json';
|
||||||
@@ -34,6 +35,7 @@ export default {
|
|||||||
...agentBots,
|
...agentBots,
|
||||||
...agentMgmt,
|
...agentMgmt,
|
||||||
...attributesMgmt,
|
...attributesMgmt,
|
||||||
|
...auditLogs,
|
||||||
...automation,
|
...automation,
|
||||||
...bulkActions,
|
...bulkActions,
|
||||||
...campaign,
|
...campaign,
|
||||||
|
|||||||
@@ -199,6 +199,7 @@
|
|||||||
"HOME": "Home",
|
"HOME": "Home",
|
||||||
"AGENTS": "Agents",
|
"AGENTS": "Agents",
|
||||||
"AGENT_BOTS": "Bots",
|
"AGENT_BOTS": "Bots",
|
||||||
|
"AUDIT_LOGS": "Audit Logs",
|
||||||
"INBOXES": "Inboxes",
|
"INBOXES": "Inboxes",
|
||||||
"NOTIFICATIONS": "Notifications",
|
"NOTIFICATIONS": "Notifications",
|
||||||
"CANNED_RESPONSES": "Canned Responses",
|
"CANNED_RESPONSES": "Canned Responses",
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -4,6 +4,7 @@ import agent from './agents/agent.routes';
|
|||||||
import agentBot from './agentBots/agentBot.routes';
|
import agentBot from './agentBots/agentBot.routes';
|
||||||
import attributes from './attributes/attributes.routes';
|
import attributes from './attributes/attributes.routes';
|
||||||
import automation from './automation/automation.routes';
|
import automation from './automation/automation.routes';
|
||||||
|
import auditlogs from './auditlogs/audit.routes';
|
||||||
import billing from './billing/billing.routes';
|
import billing from './billing/billing.routes';
|
||||||
import campaigns from './campaigns/campaigns.routes';
|
import campaigns from './campaigns/campaigns.routes';
|
||||||
import canned from './canned/canned.routes';
|
import canned from './canned/canned.routes';
|
||||||
@@ -35,6 +36,7 @@ export default {
|
|||||||
...agentBot.routes,
|
...agentBot.routes,
|
||||||
...attributes.routes,
|
...attributes.routes,
|
||||||
...automation.routes,
|
...automation.routes,
|
||||||
|
...auditlogs.routes,
|
||||||
...billing.routes,
|
...billing.routes,
|
||||||
...campaigns.routes,
|
...campaigns.routes,
|
||||||
...canned.routes,
|
...canned.routes,
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import agents from './modules/agents';
|
|||||||
import articles from './modules/helpCenterArticles';
|
import articles from './modules/helpCenterArticles';
|
||||||
import attributes from './modules/attributes';
|
import attributes from './modules/attributes';
|
||||||
import auth from './modules/auth';
|
import auth from './modules/auth';
|
||||||
|
import auditlogs from './modules/auditlogs';
|
||||||
import automations from './modules/automations';
|
import automations from './modules/automations';
|
||||||
import bulkActions from './modules/bulkActions';
|
import bulkActions from './modules/bulkActions';
|
||||||
import campaigns from './modules/campaigns';
|
import campaigns from './modules/campaigns';
|
||||||
@@ -71,6 +72,7 @@ export default new Vuex.Store({
|
|||||||
attributes,
|
attributes,
|
||||||
auth,
|
auth,
|
||||||
automations,
|
automations,
|
||||||
|
auditlogs,
|
||||||
bulkActions,
|
bulkActions,
|
||||||
campaigns,
|
campaigns,
|
||||||
cannedResponse,
|
cannedResponse,
|
||||||
|
|||||||
79
app/javascript/dashboard/store/modules/auditlogs.js
Normal file
79
app/javascript/dashboard/store/modules/auditlogs.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import * as MutationHelpers from 'shared/helpers/vuex/mutationHelpers';
|
||||||
|
import * as types from '../mutation-types';
|
||||||
|
import AuditLogsAPI from '../../api/auditLogs';
|
||||||
|
import { throwErrorMessage } from 'dashboard/store/utils/api';
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
records: [],
|
||||||
|
meta: {
|
||||||
|
currentPage: 1,
|
||||||
|
perPage: 15,
|
||||||
|
totalEntries: 0,
|
||||||
|
},
|
||||||
|
uiFlags: {
|
||||||
|
fetchingList: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const getters = {
|
||||||
|
getAuditLogs(_state) {
|
||||||
|
return _state.records;
|
||||||
|
},
|
||||||
|
getUIFlags(_state) {
|
||||||
|
return _state.uiFlags;
|
||||||
|
},
|
||||||
|
getMeta(_state) {
|
||||||
|
return _state.meta;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
async fetch({ commit }, { page } = {}) {
|
||||||
|
commit(types.default.SET_AUDIT_LOGS_UI_FLAG, { fetchingList: true });
|
||||||
|
try {
|
||||||
|
const response = await AuditLogsAPI.get({ page });
|
||||||
|
const { audit_logs: logs = [] } = response.data;
|
||||||
|
const {
|
||||||
|
total_entries: totalEntries,
|
||||||
|
per_page: perPage,
|
||||||
|
current_page: currentPage,
|
||||||
|
} = response.data;
|
||||||
|
commit(types.default.SET_AUDIT_LOGS, logs);
|
||||||
|
commit(types.default.SET_AUDIT_LOGS_META, {
|
||||||
|
totalEntries,
|
||||||
|
perPage,
|
||||||
|
currentPage,
|
||||||
|
});
|
||||||
|
commit(types.default.SET_AUDIT_LOGS_UI_FLAG, { fetchingList: false });
|
||||||
|
return logs;
|
||||||
|
} catch (error) {
|
||||||
|
commit(types.default.SET_AUDIT_LOGS_UI_FLAG, { fetchingList: false });
|
||||||
|
return throwErrorMessage(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
[types.default.SET_AUDIT_LOGS_UI_FLAG](_state, data) {
|
||||||
|
_state.uiFlags = {
|
||||||
|
..._state.uiFlags,
|
||||||
|
...data,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
[types.default.SET_AUDIT_LOGS]: MutationHelpers.set,
|
||||||
|
[types.default.SET_AUDIT_LOGS_META](_state, data) {
|
||||||
|
_state.meta = {
|
||||||
|
..._state.meta,
|
||||||
|
...data,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
getters,
|
||||||
|
actions,
|
||||||
|
mutations,
|
||||||
|
};
|
||||||
@@ -269,4 +269,9 @@ export default {
|
|||||||
SET_CONVERSATION_PARTICIPANTS_UI_FLAG:
|
SET_CONVERSATION_PARTICIPANTS_UI_FLAG:
|
||||||
'SET_CONVERSATION_PARTICIPANTS_UI_FLAG',
|
'SET_CONVERSATION_PARTICIPANTS_UI_FLAG',
|
||||||
SET_CONVERSATION_PARTICIPANTS: 'SET_CONVERSATION_PARTICIPANTS',
|
SET_CONVERSATION_PARTICIPANTS: 'SET_CONVERSATION_PARTICIPANTS',
|
||||||
|
|
||||||
|
// Audit Logs
|
||||||
|
SET_AUDIT_LOGS_UI_FLAG: 'SET_AUDIT_LOGS_UI_FLAG',
|
||||||
|
SET_AUDIT_LOGS: 'SET_AUDIT_LOGS',
|
||||||
|
SET_AUDIT_LOGS_META: 'SET_AUDIT_LOGS_META',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -107,6 +107,7 @@
|
|||||||
"headphones-sound-wave-outline": "M3.5 12a8.5 8.5 0 0 1 17 0v2h-2.25a.75.75 0 0 0-.75.75v6.5c0 .414.336.75.75.75H19a3 3 0 0 0 3-3v-7c0-5.523-4.477-10-10-10S2 6.477 2 12v7a3 3 0 0 0 3 3h.75a.75.75 0 0 0 .75-.75v-6.5a.75.75 0 0 0-.75-.75H3.5v-2Zm17 3.5V19a1.5 1.5 0 0 1-1.5 1.5v-5h1.5ZM3.5 19v-3.5H5v5A1.5 1.5 0 0 1 3.5 19Zm9.25-7.25a.75.75 0 0 0-1.5 0v10.5a.75.75 0 0 0 1.5 0v-10.5Zm-4 2.25a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-1.5 0v-4.5a.75.75 0 0 1 .75-.75Zm7.25.75a.75.75 0 0 0-1.5 0v4.5a.75.75 0 0 0 1.5 0v-4.5Z",
|
"headphones-sound-wave-outline": "M3.5 12a8.5 8.5 0 0 1 17 0v2h-2.25a.75.75 0 0 0-.75.75v6.5c0 .414.336.75.75.75H19a3 3 0 0 0 3-3v-7c0-5.523-4.477-10-10-10S2 6.477 2 12v7a3 3 0 0 0 3 3h.75a.75.75 0 0 0 .75-.75v-6.5a.75.75 0 0 0-.75-.75H3.5v-2Zm17 3.5V19a1.5 1.5 0 0 1-1.5 1.5v-5h1.5ZM3.5 19v-3.5H5v5A1.5 1.5 0 0 1 3.5 19Zm9.25-7.25a.75.75 0 0 0-1.5 0v10.5a.75.75 0 0 0 1.5 0v-10.5Zm-4 2.25a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-1.5 0v-4.5a.75.75 0 0 1 .75-.75Zm7.25.75a.75.75 0 0 0-1.5 0v4.5a.75.75 0 0 0 1.5 0v-4.5Z",
|
||||||
"image-outline": "M17.75 3A3.25 3.25 0 0 1 21 6.25v11.5A3.25 3.25 0 0 1 17.75 21H6.25A3.25 3.25 0 0 1 3 17.75V6.25A3.25 3.25 0 0 1 6.25 3h11.5Zm.58 16.401-5.805-5.686a.75.75 0 0 0-.966-.071l-.084.07-5.807 5.687c.182.064.378.099.582.099h11.5c.203 0 .399-.035.58-.099l-5.805-5.686L18.33 19.4ZM17.75 4.5H6.25A1.75 1.75 0 0 0 4.5 6.25v11.5c0 .208.036.408.103.594l5.823-5.701a2.25 2.25 0 0 1 3.02-.116l.128.116 5.822 5.702c.067-.186.104-.386.104-.595V6.25a1.75 1.75 0 0 0-1.75-1.75Zm-2.498 2a2.252 2.252 0 1 1 0 4.504 2.252 2.252 0 0 1 0-4.504Zm0 1.5a.752.752 0 1 0 0 1.504.752.752 0 0 0 0-1.504Z",
|
"image-outline": "M17.75 3A3.25 3.25 0 0 1 21 6.25v11.5A3.25 3.25 0 0 1 17.75 21H6.25A3.25 3.25 0 0 1 3 17.75V6.25A3.25 3.25 0 0 1 6.25 3h11.5Zm.58 16.401-5.805-5.686a.75.75 0 0 0-.966-.071l-.084.07-5.807 5.687c.182.064.378.099.582.099h11.5c.203 0 .399-.035.58-.099l-5.805-5.686L18.33 19.4ZM17.75 4.5H6.25A1.75 1.75 0 0 0 4.5 6.25v11.5c0 .208.036.408.103.594l5.823-5.701a2.25 2.25 0 0 1 3.02-.116l.128.116 5.822 5.702c.067-.186.104-.386.104-.595V6.25a1.75 1.75 0 0 0-1.75-1.75Zm-2.498 2a2.252 2.252 0 1 1 0 4.504 2.252 2.252 0 0 1 0-4.504Zm0 1.5a.752.752 0 1 0 0 1.504.752.752 0 0 0 0-1.504Z",
|
||||||
"info-outline": "M12 1.999c5.524 0 10.002 4.478 10.002 10.002 0 5.523-4.478 10.001-10.002 10.001-5.524 0-10.002-4.478-10.002-10.001C1.998 6.477 6.476 1.999 12 1.999Zm0 1.5a8.502 8.502 0 1 0 0 17.003A8.502 8.502 0 0 0 12 3.5Zm-.004 7a.75.75 0 0 1 .744.648l.007.102.003 5.502a.75.75 0 0 1-1.493.102l-.007-.101-.003-5.502a.75.75 0 0 1 .75-.75ZM12 7.003a.999.999 0 1 1 0 1.997.999.999 0 0 1 0-1.997Z",
|
"info-outline": "M12 1.999c5.524 0 10.002 4.478 10.002 10.002 0 5.523-4.478 10.001-10.002 10.001-5.524 0-10.002-4.478-10.002-10.001C1.998 6.477 6.476 1.999 12 1.999Zm0 1.5a8.502 8.502 0 1 0 0 17.003A8.502 8.502 0 0 0 12 3.5Zm-.004 7a.75.75 0 0 1 .744.648l.007.102.003 5.502a.75.75 0 0 1-1.493.102l-.007-.101-.003-5.502a.75.75 0 0 1 .75-.75ZM12 7.003a.999.999 0 1 1 0 1.997.999.999 0 0 1 0-1.997Z",
|
||||||
|
"key-outline": "M15 6a1 1 0 1 1-2 0a1 1 0 0 1 2 0Zm-2.5-4C9.424 2 7 4.424 7 7.5c0 .397.04.796.122 1.175c.058.27-.008.504-.142.638l-4.54 4.54A1.5 1.5 0 0 0 2 14.915V16.5A1.5 1.5 0 0 0 3.5 18h2A1.5 1.5 0 0 0 7 16.5V16h1a1 1 0 0 0 1-1v-1h1a1 1 0 0 0 1-1v-.18c.493.134 1.007.18 1.5.18c3.076 0 5.5-2.424 5.5-5.5S15.576 2 12.5 2ZM8 7.5C8 4.976 9.976 3 12.5 3S17 4.976 17 7.5S15.024 12 12.5 12c-.66 0-1.273-.095-1.776-.347A.5.5 0 0 0 10 12.1v.9H9a1 1 0 0 0-1 1v1H7a1 1 0 0 0-1 1v.5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-1.586a.5.5 0 0 1 .146-.353l4.541-4.541c.432-.432.522-1.044.412-1.556A4.619 4.619 0 0 1 8 7.5Z",
|
||||||
"keyboard-outline": "M19.745 5a2.25 2.25 0 0 1 2.25 2.25v9.505a2.25 2.25 0 0 1-2.25 2.25H4.25A2.25 2.25 0 0 1 2 16.755V7.25A2.25 2.25 0 0 1 4.25 5h15.495Zm0 1.5H4.25a.75.75 0 0 0-.75.75v9.505c0 .414.336.75.75.75h15.495a.75.75 0 0 0 .75-.75V7.25a.75.75 0 0 0-.75-.75Zm-12.995 8h10.5a.75.75 0 0 1 .102 1.493L17.25 16H6.75a.75.75 0 0 1-.102-1.493l.102-.007h10.5-10.5ZM16.5 11a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm-5.995 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm-3 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm6 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2ZM6 8a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm2.995 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm3 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm3 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm3 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z",
|
"keyboard-outline": "M19.745 5a2.25 2.25 0 0 1 2.25 2.25v9.505a2.25 2.25 0 0 1-2.25 2.25H4.25A2.25 2.25 0 0 1 2 16.755V7.25A2.25 2.25 0 0 1 4.25 5h15.495Zm0 1.5H4.25a.75.75 0 0 0-.75.75v9.505c0 .414.336.75.75.75h15.495a.75.75 0 0 0 .75-.75V7.25a.75.75 0 0 0-.75-.75Zm-12.995 8h10.5a.75.75 0 0 1 .102 1.493L17.25 16H6.75a.75.75 0 0 1-.102-1.493l.102-.007h10.5-10.5ZM16.5 11a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm-5.995 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm-3 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm6 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2ZM6 8a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm2.995 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm3 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm3 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Zm3 0a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z",
|
||||||
"library-outline": "M4 3h1c1.054 0 1.918.816 1.995 1.85L7 5v14a2.001 2.001 0 0 1-1.85 1.994L5 21H4a2.001 2.001 0 0 1-1.995-1.85L2 19V5c0-1.054.816-1.918 1.85-1.995L4 3h1-1Zm6 0h1c1.054 0 1.918.816 1.995 1.85L13 5v14a2.001 2.001 0 0 1-1.85 1.994L11 21h-1a2.001 2.001 0 0 1-1.995-1.85L8 19V5c0-1.054.816-1.918 1.85-1.995L10 3h1-1Zm6.974 2c.84 0 1.608.531 1.89 1.346l.047.157 3.015 11.745a2 2 0 0 1-1.296 2.392l-.144.043-.969.248a2.002 2.002 0 0 1-2.387-1.284l-.047-.155-3.016-11.745a2 2 0 0 1 1.298-2.392l.143-.043.968-.248c.166-.043.334-.064.498-.064ZM5 4.5H4a.501.501 0 0 0-.492.41L3.5 5v14c0 .244.177.45.41.492L4 19.5h1c.245 0 .45-.178.492-.41L5.5 19V5a.501.501 0 0 0-.41-.492L5 4.5Zm6 0h-1a.501.501 0 0 0-.492.41L9.5 5v14c0 .244.177.45.41.492l.09.008h1c.245 0 .45-.178.492-.41L11.5 19V5a.501.501 0 0 0-.41-.492L11 4.5Zm5.975 2-.063.004-.063.013-.968.247a.498.498 0 0 0-.376.51l.015.1 3.016 11.745a.5.5 0 0 0 .483.375l.063-.003.062-.012.97-.25a.5.5 0 0 0 .374-.519l-.015-.088-3.015-11.747a.501.501 0 0 0-.483-.375Z",
|
"library-outline": "M4 3h1c1.054 0 1.918.816 1.995 1.85L7 5v14a2.001 2.001 0 0 1-1.85 1.994L5 21H4a2.001 2.001 0 0 1-1.995-1.85L2 19V5c0-1.054.816-1.918 1.85-1.995L4 3h1-1Zm6 0h1c1.054 0 1.918.816 1.995 1.85L13 5v14a2.001 2.001 0 0 1-1.85 1.994L11 21h-1a2.001 2.001 0 0 1-1.995-1.85L8 19V5c0-1.054.816-1.918 1.85-1.995L10 3h1-1Zm6.974 2c.84 0 1.608.531 1.89 1.346l.047.157 3.015 11.745a2 2 0 0 1-1.296 2.392l-.144.043-.969.248a2.002 2.002 0 0 1-2.387-1.284l-.047-.155-3.016-11.745a2 2 0 0 1 1.298-2.392l.143-.043.968-.248c.166-.043.334-.064.498-.064ZM5 4.5H4a.501.501 0 0 0-.492.41L3.5 5v14c0 .244.177.45.41.492L4 19.5h1c.245 0 .45-.178.492-.41L5.5 19V5a.501.501 0 0 0-.41-.492L5 4.5Zm6 0h-1a.501.501 0 0 0-.492.41L9.5 5v14c0 .244.177.45.41.492l.09.008h1c.245 0 .45-.178.492-.41L11.5 19V5a.501.501 0 0 0-.41-.492L11 4.5Zm5.975 2-.063.004-.063.013-.968.247a.498.498 0 0 0-.376.51l.015.1 3.016 11.745a.5.5 0 0 0 .483.375l.063-.003.062-.012.97-.25a.5.5 0 0 0 .374-.519l-.015-.088-3.015-11.747a.501.501 0 0 0-.483-.375Z",
|
||||||
"link-outline": "M9.25 7a.75.75 0 0 1 .11 1.492l-.11.008H7a3.5 3.5 0 0 0-.206 6.994L7 15.5h2.25a.75.75 0 0 1 .11 1.492L9.25 17H7a5 5 0 0 1-.25-9.994L7 7h2.25ZM17 7a5 5 0 0 1 .25 9.994L17 17h-2.25a.75.75 0 0 1-.11-1.492l.11-.008H17a3.5 3.5 0 0 0 .206-6.994L17 8.5h-2.25a.75.75 0 0 1-.11-1.492L14.75 7H17ZM7 11.25h10a.75.75 0 0 1 .102 1.493L17 12.75H7a.75.75 0 0 1-.102-1.493L7 11.25h10H7Z",
|
"link-outline": "M9.25 7a.75.75 0 0 1 .11 1.492l-.11.008H7a3.5 3.5 0 0 0-.206 6.994L7 15.5h2.25a.75.75 0 0 1 .11 1.492L9.25 17H7a5 5 0 0 1-.25-9.994L7 7h2.25ZM17 7a5 5 0 0 1 .25 9.994L17 17h-2.25a.75.75 0 0 1-.11-1.492l.11-.008H17a3.5 3.5 0 0 0 .206-6.994L17 8.5h-2.25a.75.75 0 0 1-.11-1.492L14.75 7H17ZM7 11.25h10a.75.75 0 0 1 .102 1.493L17 12.75H7a.75.75 0 0 1-.102-1.493L7 11.25h10H7Z",
|
||||||
|
|||||||
@@ -2,22 +2,25 @@
|
|||||||
class Api::V1::Accounts::AuditLogsController < Api::V1::Accounts::BaseController
|
class Api::V1::Accounts::AuditLogsController < Api::V1::Accounts::BaseController
|
||||||
before_action :check_admin_authorization?
|
before_action :check_admin_authorization?
|
||||||
before_action :fetch_audit
|
before_action :fetch_audit
|
||||||
|
before_action :prepend_view_paths
|
||||||
|
|
||||||
RESULTS_PER_PAGE = 15
|
RESULTS_PER_PAGE = 15
|
||||||
|
|
||||||
|
# Prepend the view path to the enterprise/app/views won't be available by default
|
||||||
|
def prepend_view_paths
|
||||||
|
prepend_view_path 'enterprise/app/views/'
|
||||||
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@audit_logs = @audit_logs.page(params[:page]).per(RESULTS_PER_PAGE)
|
@audit_logs = @audit_logs.page(params[:page]).per(RESULTS_PER_PAGE)
|
||||||
render json: {
|
@current_page = @audit_logs.current_page
|
||||||
audit_logs: @audit_logs,
|
@total_entries = @audit_logs.total_count
|
||||||
current_page: @audit_logs.current_page,
|
@per_page = RESULTS_PER_PAGE
|
||||||
per_page: RESULTS_PER_PAGE,
|
|
||||||
total_entries: @audit_logs.total_count
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def fetch_audit
|
def fetch_audit
|
||||||
@audit_logs = Current.account.associated_audits
|
@audit_logs = Current.account.associated_audits.order(created_at: :desc)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
json.per_page @per_page
|
||||||
|
json.total_entries @total_entries
|
||||||
|
json.current_page @current_page
|
||||||
|
|
||||||
|
json.audit_logs do
|
||||||
|
json.array! @audit_logs do |audit_log|
|
||||||
|
json.id audit_log.id
|
||||||
|
json.auditable_id audit_log.auditable_id
|
||||||
|
json.auditable_type audit_log.auditable_type
|
||||||
|
json.associated_id audit_log.associated_id
|
||||||
|
json.associated_type audit_log.associated_type
|
||||||
|
json.user_id audit_log.user_id
|
||||||
|
json.user_type audit_log.user_type
|
||||||
|
json.username audit_log.username
|
||||||
|
json.action audit_log.action
|
||||||
|
json.audited_changes audit_log.audited_changes
|
||||||
|
json.version audit_log.version
|
||||||
|
json.comment audit_log.comment
|
||||||
|
json.request_uuid audit_log.request_uuid
|
||||||
|
json.created_at audit_log.created_at.to_i
|
||||||
|
json.remote_address audit_log.remote_address
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user