@drax/audit-vue 0.39.1 → 0.42.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/components/AuditDashboard.vue +43 -0
- package/src/components/AuditView.vue +24 -17
- package/src/cruds/AuditCrud.ts +1 -0
- package/src/dashboards/AuditDashboard.ts +73 -0
- package/src/pages/crud/AuditCrudDashboardPage.vue +73 -0
- package/src/pages/crud/AuditCrudPage.vue +24 -1
- package/src/routes/AuditCrudRoute.ts +10 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.42.2",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "./src/index.ts",
|
|
9
9
|
"module": "./src/index.ts",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"format": "prettier --write src/"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@drax/crud-front": "^0.
|
|
28
|
-
"@drax/crud-share": "^0.
|
|
27
|
+
"@drax/crud-front": "^0.42.2",
|
|
28
|
+
"@drax/crud-share": "^0.42.2"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"pinia": "^2.2.2",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"vue-tsc": "^2.0.11",
|
|
63
63
|
"vuetify": "^3.7.1"
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "6b4f9f50a8e3f0fbdaff7ec913356834a4e2c0b5"
|
|
66
66
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {DashboardView} from "@drax/dashboard-vue"
|
|
3
|
+
import {auditDashboard} from "../dashboards/AuditDashboard"
|
|
4
|
+
import {ref} from "vue"
|
|
5
|
+
import { VDateInput } from 'vuetify/labs/VDateInput'
|
|
6
|
+
import type {IDashboardBase, IDashboardCard} from "@drax/dashboard-share";
|
|
7
|
+
|
|
8
|
+
const today = new Date()
|
|
9
|
+
today.setHours(23, 59, 59, 999)
|
|
10
|
+
const firstDayOfCurrentMonth = new Date(today.getFullYear(), today.getMonth(), 1)
|
|
11
|
+
const filters = ref([
|
|
12
|
+
{field: "createdAt", operator:"gte", value: firstDayOfCurrentMonth},
|
|
13
|
+
{field: "createdAt", operator:"lte", value: today},
|
|
14
|
+
]
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
const ad = ref<IDashboardBase>(auditDashboard)
|
|
18
|
+
|
|
19
|
+
ad.value.cards?.forEach((card:IDashboardCard) => {
|
|
20
|
+
card.filters = filters.value
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<v-container>
|
|
27
|
+
<v-row>
|
|
28
|
+
<v-col cols="6">
|
|
29
|
+
<v-date-input v-model="filters[0].value" label="From"></v-date-input>
|
|
30
|
+
</v-col>
|
|
31
|
+
<v-col cols="6">
|
|
32
|
+
<v-date-input v-model="filters[1].value" label="To"></v-date-input>
|
|
33
|
+
</v-col>
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
</v-row>
|
|
37
|
+
<dashboard-view :dashboard="ad"></dashboard-view>
|
|
38
|
+
</v-container>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<style scoped>
|
|
42
|
+
|
|
43
|
+
</style>
|
|
@@ -3,14 +3,32 @@
|
|
|
3
3
|
<!-- BLOQUE DE ATRIBUTOS EN COLUMNA -->
|
|
4
4
|
<div class="text-body-2 mt-3">
|
|
5
5
|
|
|
6
|
+
<div
|
|
7
|
+
v-if="audit.createdAt"
|
|
8
|
+
class="mb-1 audit-row"
|
|
9
|
+
>
|
|
10
|
+
<strong class="audit-label">{{ t('audit.field.createdAt') }}:</strong>
|
|
11
|
+
<span>{{ formatDateTime(audit.createdAt) }}</span>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
6
14
|
<div class="mb-1 audit-row">
|
|
7
|
-
<strong class="audit-label">{{ t('audit.field.
|
|
8
|
-
<span>{{ audit.
|
|
15
|
+
<strong class="audit-label">{{ t('audit.field.user') }}:</strong>
|
|
16
|
+
<span>{{ audit.user.username }}</span> <span v-if="audit.user.rolName"><{{ audit.user.rolName }}></span> <span>(ID {{
|
|
17
|
+
audit.user.id
|
|
18
|
+
}})</span>
|
|
9
19
|
</div>
|
|
10
20
|
|
|
11
21
|
<div class="mb-1 audit-row">
|
|
12
22
|
<strong class="audit-label">{{ t('audit.field.entity') }}:</strong>
|
|
13
|
-
<span>{{ audit.entity }}</span>
|
|
23
|
+
<span>{{ te(audit?.entity?.toLowerCase() + '.entity') ? t(audit?.entity.toLowerCase() + '.entity') : audit?.entity }}</span>
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<div class="mb-1 audit-row">
|
|
27
|
+
<strong class="audit-label">{{ t('audit.field.action') }}:</strong>
|
|
28
|
+
<span>
|
|
29
|
+
|
|
30
|
+
{{ te('audit.action.'+audit.action) ? t('audit.action.'+audit.action) : audit.action }}
|
|
31
|
+
</span>
|
|
14
32
|
</div>
|
|
15
33
|
|
|
16
34
|
<div class="mb-1 audit-row">
|
|
@@ -19,12 +37,7 @@
|
|
|
19
37
|
</div>
|
|
20
38
|
|
|
21
39
|
|
|
22
|
-
|
|
23
|
-
<strong class="audit-label">{{ t('audit.field.user') }}:</strong>
|
|
24
|
-
<span>{{ audit.user.username }}</span> <span v-if="audit.user.rolName"><{{ audit.user.rolName }}></span> <span>(ID {{
|
|
25
|
-
audit.user.id
|
|
26
|
-
}})</span>
|
|
27
|
-
</div>
|
|
40
|
+
|
|
28
41
|
|
|
29
42
|
<div
|
|
30
43
|
v-if="audit.apiKey?.id"
|
|
@@ -70,13 +83,7 @@
|
|
|
70
83
|
<span>{{ audit.requestId }}</span>
|
|
71
84
|
</div>
|
|
72
85
|
|
|
73
|
-
|
|
74
|
-
v-if="audit.createdAt"
|
|
75
|
-
class="mb-1 audit-row"
|
|
76
|
-
>
|
|
77
|
-
<strong class="audit-label">{{ t('audit.field.createdAt') }}:</strong>
|
|
78
|
-
<span>{{ formatDateTime(audit.createdAt) }}</span>
|
|
79
|
-
</div>
|
|
86
|
+
|
|
80
87
|
|
|
81
88
|
|
|
82
89
|
</div>
|
|
@@ -173,7 +180,7 @@ interface IAudit {
|
|
|
173
180
|
updatedAt?: string
|
|
174
181
|
}
|
|
175
182
|
|
|
176
|
-
const {t} = useI18n()
|
|
183
|
+
const {t, te} = useI18n()
|
|
177
184
|
|
|
178
185
|
defineProps<{
|
|
179
186
|
audit: IAudit
|
package/src/cruds/AuditCrud.ts
CHANGED
|
@@ -105,6 +105,7 @@ class AuditCrud extends EntityCrud implements IEntityCrud {
|
|
|
105
105
|
name: 'user',
|
|
106
106
|
type: 'object',
|
|
107
107
|
label: 'user',
|
|
108
|
+
refDisplay:'username',
|
|
108
109
|
default: {"id": "''", "username": "''", "rolName": "''"},
|
|
109
110
|
objectFields: [{name: 'id', type: 'string', label: 'id', default: ''},
|
|
110
111
|
{name: 'username', type: 'string', label: 'username', default: ''},
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type {IDashboardBase} from "@drax/dashboard-share";
|
|
2
|
+
import AuditCrud from "../cruds/AuditCrud";
|
|
3
|
+
|
|
4
|
+
const auditDashboard: IDashboardBase = {
|
|
5
|
+
identifier: "audit",
|
|
6
|
+
title: "Audit Dashboard",
|
|
7
|
+
cards: [
|
|
8
|
+
{
|
|
9
|
+
entity: 'Audit',
|
|
10
|
+
type: "groupBy",
|
|
11
|
+
entityInstance: AuditCrud.instance,
|
|
12
|
+
title: "User Entity Action",
|
|
13
|
+
filters: [],
|
|
14
|
+
layout:{
|
|
15
|
+
cols: 12, sm: 12, md: 12, lg: 12, cardVariant: "outlined", height: 400
|
|
16
|
+
},
|
|
17
|
+
groupBy: {
|
|
18
|
+
fields: ["user", "entity", "action"],
|
|
19
|
+
dateFormat: "day",
|
|
20
|
+
render: "table"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
entity: 'Audit',
|
|
25
|
+
type: "groupBy",
|
|
26
|
+
entityInstance: AuditCrud.instance,
|
|
27
|
+
title: "User Audits",
|
|
28
|
+
filters: [],
|
|
29
|
+
layout:{
|
|
30
|
+
cols: 12, sm: 12, md: 4, lg: 4, cardVariant: "outlined", height: 400
|
|
31
|
+
},
|
|
32
|
+
groupBy: {
|
|
33
|
+
fields: ["user"],
|
|
34
|
+
dateFormat: "day",
|
|
35
|
+
render: "pie"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
entity: 'Audit',
|
|
40
|
+
type: "groupBy",
|
|
41
|
+
entityInstance: AuditCrud.instance,
|
|
42
|
+
title: "Entity Audits",
|
|
43
|
+
filters: [],
|
|
44
|
+
layout:{
|
|
45
|
+
cols: 12, sm: 12, md: 4, lg: 4, cardVariant: "outlined", height: 400
|
|
46
|
+
},
|
|
47
|
+
groupBy: {
|
|
48
|
+
fields: ["entity"],
|
|
49
|
+
dateFormat: "day",
|
|
50
|
+
render: "pie"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
entity: 'Audit',
|
|
55
|
+
type: "groupBy",
|
|
56
|
+
entityInstance: AuditCrud.instance,
|
|
57
|
+
title: "Action Audits",
|
|
58
|
+
filters: [],
|
|
59
|
+
layout:{
|
|
60
|
+
cols: 12, sm: 12, md: 4, lg: 4, cardVariant: "outlined", height: 400
|
|
61
|
+
},
|
|
62
|
+
groupBy: {
|
|
63
|
+
fields: ["action"],
|
|
64
|
+
dateFormat: "day",
|
|
65
|
+
render: "pie"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export {auditDashboard}
|
|
73
|
+
export default auditDashboard;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
<script setup lang="ts">
|
|
3
|
+
import AuditCrud from '../../cruds/AuditCrud'
|
|
4
|
+
import {Crud, useCrudStore} from "@drax/crud-vue";
|
|
5
|
+
import {formatDateTime} from "@drax/common-front"
|
|
6
|
+
import AuditView from "../../components/AuditView.vue";
|
|
7
|
+
import {ref} from "vue";
|
|
8
|
+
import AuditDashboard from "../../components/AuditDashboard.vue";
|
|
9
|
+
import {useI18n} from "vue-i18n";
|
|
10
|
+
|
|
11
|
+
const {t, te} = useI18n();
|
|
12
|
+
const store = useCrudStore();
|
|
13
|
+
const tabSelected = ref('crud');
|
|
14
|
+
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<v-tabs v-model="tabSelected">
|
|
19
|
+
<v-tab value="crud">
|
|
20
|
+
{{ t('audit.crud') }}
|
|
21
|
+
</v-tab>
|
|
22
|
+
<v-tab value="dashboard">
|
|
23
|
+
{{ t('audit.dashboard') }}
|
|
24
|
+
</v-tab>
|
|
25
|
+
</v-tabs>
|
|
26
|
+
|
|
27
|
+
<v-tabs-window v-model="tabSelected">
|
|
28
|
+
<v-tabs-window-item value="crud">
|
|
29
|
+
<crud :entity="AuditCrud.instance">
|
|
30
|
+
|
|
31
|
+
<template v-slot:item.createdAt="{value}">
|
|
32
|
+
{{ formatDateTime(value) }}
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<template v-slot:item.user="{value}">
|
|
36
|
+
{{ value.username }} ({{value.rolName}})
|
|
37
|
+
</template>
|
|
38
|
+
|
|
39
|
+
<template v-slot:item.tenant="{value}">
|
|
40
|
+
{{ value?.name }}
|
|
41
|
+
</template>
|
|
42
|
+
|
|
43
|
+
<template v-slot:item.action="{value}">
|
|
44
|
+
{{ te('audit.action.'+value) ? t('audit.action.'+value) : value }}
|
|
45
|
+
</template>
|
|
46
|
+
|
|
47
|
+
<template v-slot:item.changes="{value}">
|
|
48
|
+
<div v-if="value && value.length > 0" class="changes-container">
|
|
49
|
+
<div v-for="(change, index) in value" :key="index" class="change-item">
|
|
50
|
+
<span class="field-name">{{ change.field }}:</span>
|
|
51
|
+
<span class="old-value">{{ change.old }}</span>
|
|
52
|
+
<span class="arrow">→</span>
|
|
53
|
+
<span class="new-value">{{ change.new }}</span>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
<span v-else class="no-changes">Sin cambios</span>
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
|
+
<template v-slot:form>
|
|
60
|
+
<audit-view :audit="store.form"></audit-view>
|
|
61
|
+
</template>
|
|
62
|
+
</crud>
|
|
63
|
+
</v-tabs-window-item>
|
|
64
|
+
|
|
65
|
+
<v-tabs-window-item value="dashboard">
|
|
66
|
+
<audit-dashboard></audit-dashboard>
|
|
67
|
+
</v-tabs-window-item>
|
|
68
|
+
</v-tabs-window>
|
|
69
|
+
</template>
|
|
70
|
+
|
|
71
|
+
<style scoped>
|
|
72
|
+
|
|
73
|
+
</style>
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
import AuditCrud from '../../cruds/AuditCrud'
|
|
4
4
|
import {Crud, useCrudStore} from "@drax/crud-vue";
|
|
5
5
|
import {formatDateTime} from "@drax/common-front"
|
|
6
|
+
import {EntityCombobox} from "@drax/crud-vue"
|
|
6
7
|
import AuditView from "../../components/AuditView.vue";
|
|
8
|
+
import {useI18n} from "vue-i18n";
|
|
7
9
|
|
|
10
|
+
const {t, te} = useI18n();
|
|
8
11
|
const store = useCrudStore();
|
|
9
12
|
|
|
10
13
|
</script>
|
|
@@ -12,18 +15,38 @@ const store = useCrudStore();
|
|
|
12
15
|
<template>
|
|
13
16
|
<crud :entity="AuditCrud.instance">
|
|
14
17
|
|
|
18
|
+
<template v-slot:filter.entity="{filterIndex}">
|
|
19
|
+
<entity-combobox
|
|
20
|
+
v-model="store.filters[filterIndex].value"
|
|
21
|
+
:clearable="true"
|
|
22
|
+
density="compact"
|
|
23
|
+
variant="outlined"
|
|
24
|
+
hide-details
|
|
25
|
+
disable-rules
|
|
26
|
+
prepend-inner-icon="mdi-equal"
|
|
27
|
+
/>
|
|
28
|
+
</template>
|
|
29
|
+
|
|
15
30
|
<template v-slot:item.createdAt="{value}">
|
|
16
31
|
{{ formatDateTime(value) }}
|
|
17
32
|
</template>
|
|
18
33
|
|
|
19
34
|
<template v-slot:item.user="{value}">
|
|
20
|
-
|
|
35
|
+
{{ value.username }} ({{value.rolName}})
|
|
21
36
|
</template>
|
|
22
37
|
|
|
23
38
|
<template v-slot:item.tenant="{value}">
|
|
24
39
|
{{ value?.name }}
|
|
25
40
|
</template>
|
|
26
41
|
|
|
42
|
+
<template v-slot:item.action="{value}">
|
|
43
|
+
{{ te('audit.action.'+value) ? t('audit.action.'+value) : value }}
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<template v-slot:item.entity="{value}">
|
|
47
|
+
{{ te(value?.toLowerCase() + '.entity') ? t(value.toLowerCase() + '.entity') : value }}
|
|
48
|
+
</template>
|
|
49
|
+
|
|
27
50
|
<template v-slot:item.changes="{value}">
|
|
28
51
|
<div v-if="value && value.length > 0" class="changes-container">
|
|
29
52
|
<div v-for="(change, index) in value" :key="index" class="change-item">
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import AuditCrudPage from "../pages/crud/AuditCrudPage.vue";
|
|
3
|
+
import AuditCrudDashboardPage from "../pages/crud/AuditCrudDashboardPage.vue";
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
const AuditCrudRoute = [
|
|
@@ -12,6 +13,15 @@ const AuditCrudRoute = [
|
|
|
12
13
|
permission: 'audit:manage',
|
|
13
14
|
}
|
|
14
15
|
},
|
|
16
|
+
{
|
|
17
|
+
name: 'AuditCrudDashboardPage',
|
|
18
|
+
path: '/crud/audit-ds',
|
|
19
|
+
component: AuditCrudDashboardPage,
|
|
20
|
+
meta: {
|
|
21
|
+
auth: true,
|
|
22
|
+
permission: 'audit:manage',
|
|
23
|
+
}
|
|
24
|
+
},
|
|
15
25
|
]
|
|
16
26
|
|
|
17
27
|
export default AuditCrudRoute
|