@drax/identity-vue 0.35.0 → 0.37.0

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 CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.35.0",
6
+ "version": "0.37.0",
7
7
  "type": "module",
8
8
  "main": "./src/index.ts",
9
9
  "module": "./src/index.ts",
@@ -24,12 +24,12 @@
24
24
  "format": "prettier --write src/"
25
25
  },
26
26
  "dependencies": {
27
- "@drax/common-front": "^0.35.0",
28
- "@drax/common-vue": "^0.35.0",
29
- "@drax/crud-front": "^0.35.0",
30
- "@drax/crud-share": "^0.35.0",
31
- "@drax/crud-vue": "^0.35.0",
32
- "@drax/identity-share": "^0.35.0"
27
+ "@drax/common-front": "^0.37.0",
28
+ "@drax/common-vue": "^0.37.0",
29
+ "@drax/crud-front": "^0.37.0",
30
+ "@drax/crud-share": "^0.37.0",
31
+ "@drax/crud-vue": "^0.37.0",
32
+ "@drax/identity-share": "^0.37.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "pinia": "^2.2.2",
@@ -66,5 +66,5 @@
66
66
  "vue-tsc": "^2.1.6",
67
67
  "vuetify": "^3.7.1"
68
68
  },
69
- "gitHead": "d8e9ad20ff3a5bd9e9d4383ef0926b79eac335d8"
69
+ "gitHead": "0bca48d4b686fd9536a78d84f5befe6801238000"
70
70
  }
@@ -0,0 +1,132 @@
1
+ <script setup lang="ts">
2
+ import { ref, onMounted } from 'vue'
3
+ import { UserSystemFactory } from '@drax/identity-front'
4
+
5
+ interface RoleGroup {
6
+ _id: string
7
+ count: number
8
+ name?: string
9
+ icon?: string
10
+ color?: string
11
+ }
12
+
13
+ const userSystem = UserSystemFactory.getInstance()
14
+ const roleGroups = ref<RoleGroup[]>([])
15
+ const loading = ref(false)
16
+ const error = ref<string | null>(null)
17
+
18
+ const loadUsersByRole = async () => {
19
+ loading.value = true
20
+ error.value = null
21
+
22
+ try {
23
+ const result = await userSystem.groupBy({fields: ['role']})
24
+ roleGroups.value = result.map((group: any) => ({
25
+ _id: group._id,
26
+ count: group.count,
27
+ name: group?.role?.name || 'Sin rol',
28
+ icon: group?.role?.icon || 'mdi-account-group',
29
+ color: group?.role?.color || 'primary'
30
+ }))
31
+ } catch (e) {
32
+ console.error('Error loading users by role:', e)
33
+ error.value = 'Error al cargar los datos de usuarios'
34
+ } finally {
35
+ loading.value = false
36
+ }
37
+ }
38
+
39
+ onMounted(() => {
40
+ loadUsersByRole()
41
+ })
42
+ </script>
43
+
44
+ <template>
45
+ <v-card variant="text" class="rounded-xl ma-4">
46
+ <v-card-text class="pa-2">
47
+ <v-row v-if="loading" justify="center">
48
+ <v-col cols="12" class="text-center py-4">
49
+ <v-progress-circular
50
+ indeterminate
51
+ color="primary"
52
+ size="48"
53
+ ></v-progress-circular>
54
+ <p class="text-body-2 mt-2">Cargando...</p>
55
+ </v-col>
56
+ </v-row>
57
+
58
+ <v-row v-else-if="error" justify="center">
59
+ <v-col cols="12" md="6" class="py-2">
60
+ <v-alert
61
+ type="error"
62
+ variant="tonal"
63
+ density="compact"
64
+ closable
65
+ @click:close="error = null"
66
+ >
67
+ {{ error }}
68
+ </v-alert>
69
+ <div class="text-center mt-2">
70
+ <v-btn
71
+ color="primary"
72
+ variant="elevated"
73
+ size="small"
74
+ @click="loadUsersByRole"
75
+ >
76
+ Reintentar
77
+ </v-btn>
78
+ </div>
79
+ </v-col>
80
+ </v-row>
81
+
82
+ <v-row v-else dense>
83
+ <v-col
84
+ v-for="group in roleGroups"
85
+ :key="group._id"
86
+ cols="6"
87
+ sm="3"
88
+ md="3"
89
+ lg="2"
90
+ >
91
+ <v-card
92
+ elevation="1"
93
+ hover
94
+ class="role-card"
95
+ :class="`role-card--${group.color}`"
96
+ >
97
+ <v-card-text class="pa-3">
98
+ <div class="d-flex align-center mb-2">
99
+ <v-icon
100
+ :color="group.color"
101
+ size="28"
102
+ class="mr-2"
103
+ >
104
+ {{ group.icon }}
105
+ </v-icon>
106
+ <div :class="`text-subtitle-1 font-weight-bold text-truncate text-${group.color}`" :title="group.name">
107
+ {{ group.name }}
108
+ </div>
109
+ </div>
110
+ <div class="text-center">
111
+ <div :class="`text-h4 font-weight-bold ${group.color}--text`">
112
+ {{ group.count }}
113
+ </div>
114
+ </div>
115
+ </v-card-text>
116
+ </v-card>
117
+ </v-col>
118
+ </v-row>
119
+ </v-card-text>
120
+ </v-card>
121
+ </template>
122
+
123
+ <style scoped>
124
+ .role-card {
125
+ transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
126
+ }
127
+
128
+ .role-card:hover {
129
+ transform: translateY(-2px);
130
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12) !important;
131
+ }
132
+ </style>
@@ -0,0 +1,171 @@
1
+ import {EntityCrud} from "@drax/crud-vue";
2
+ import type {
3
+ IDraxCrudProvider,
4
+ IEntityCrud,
5
+ IEntityCrudField,
6
+ IEntityCrudFilter,
7
+ IEntityCrudHeader,
8
+ IEntityCrudPermissions,
9
+ IEntityCrudRefs,
10
+ IEntityCrudRules
11
+ } from "@drax/crud-share";
12
+ import {UserLoginFailSystemFactory} from "@drax/identity-front";
13
+
14
+ //Import EntityCrud Refs
15
+ import {UserCrud} from "@drax/identity-vue"
16
+
17
+ class UserLoginFailCrud extends EntityCrud implements IEntityCrud {
18
+
19
+ static singleton: UserLoginFailCrud
20
+
21
+ constructor() {
22
+ super();
23
+ this.name = 'UserLoginFail'
24
+ }
25
+
26
+ static get instance(): UserLoginFailCrud {
27
+ if (!UserLoginFailCrud.singleton) {
28
+ UserLoginFailCrud.singleton = new UserLoginFailCrud()
29
+ }
30
+ return UserLoginFailCrud.singleton
31
+ }
32
+
33
+ get permissions(): IEntityCrudPermissions {
34
+ return {
35
+ manage: 'userloginfail:manage',
36
+ view: 'userloginfail:view',
37
+ create: 'userloginfail:create',
38
+ update: 'userloginfail:update',
39
+ delete: 'userloginfail:delete'
40
+ }
41
+ }
42
+
43
+ get headers(): IEntityCrudHeader[] {
44
+ return [
45
+ {title: 'username', key: 'username', align: 'start'},
46
+ {title: 'userAgent', key: 'userAgent', align: 'start'},
47
+ {title: 'ip', key: 'ip', align: 'start'},
48
+ {title: 'createdAt', key: 'createdAt', align: 'start'}
49
+ ]
50
+ }
51
+
52
+ get selectedHeaders(): string[] {
53
+ return this.headers.map(header => header.key)
54
+ }
55
+
56
+ get actionHeaders(): IEntityCrudHeader[] {
57
+ return [
58
+ {
59
+ title: 'action.actions',
60
+ key: 'actions',
61
+ sortable: false,
62
+ align: 'center',
63
+ minWidth: '190px'
64
+ },
65
+ ]
66
+ }
67
+
68
+ get provider(): IDraxCrudProvider<any, any, any> {
69
+ return UserLoginFailSystemFactory.getInstance()
70
+ }
71
+
72
+ get refs(): IEntityCrudRefs {
73
+ return {
74
+ User: UserCrud.instance
75
+ }
76
+ }
77
+
78
+ get rules(): IEntityCrudRules {
79
+ return {
80
+ user: [(v: any) => !!v || 'validation.required'],
81
+ agent: [],
82
+ ip: [],
83
+ createdAt: []
84
+ }
85
+ }
86
+
87
+ get fields(): IEntityCrudField[] {
88
+ return [
89
+ {name: 'username', type: 'string', label: 'username', default: null},
90
+ {name: 'userAgent', type: 'string', label: 'userAgent', default: ''},
91
+ {name: 'ip', type: 'string', label: 'ip', default: ''},
92
+ {name: 'createdAt', type: 'date', label: 'createdAt', default: null}
93
+ ]
94
+ }
95
+
96
+ get filters(): IEntityCrudFilter[] {
97
+ return [
98
+ {name: 'createdAt', type: 'date', label: 'createdAt', default: '', operator: 'gte' },
99
+ {name: 'createdAt', type: 'date', label: 'createdAt', default: '', operator: 'lte' },
100
+ {name: 'username', type: 'string', label: 'username', default: '', operator: 'eq' },
101
+ {name: 'userAgent', type: 'string', label: 'userAgent', default: '', operator: 'eq' },
102
+ {name: 'ip', type: 'string', label: 'ip', default: '', operator: 'eq' },
103
+
104
+ ]
105
+ }
106
+
107
+ get searchEnable(){
108
+ return false
109
+ }
110
+
111
+ get isViewable() {
112
+ return true
113
+ }
114
+
115
+ get isEditable() {
116
+ return false
117
+ }
118
+
119
+ get isCreatable() {
120
+ return false
121
+ }
122
+
123
+ get isDeletable() {
124
+ return false
125
+ }
126
+
127
+ get isExportable() {
128
+ return true
129
+ }
130
+
131
+ get exportFormats() {
132
+ return ['CSV', 'JSON']
133
+ }
134
+
135
+ get exportHeaders() {
136
+ return ['_id','username','createdAt','userAgent','ip']
137
+ }
138
+
139
+ get isImportable() {
140
+ return false
141
+ }
142
+
143
+ get isColumnSelectable() {
144
+ return true
145
+ }
146
+
147
+ get isGroupable() {
148
+ return true
149
+ }
150
+
151
+ get importFormats() {
152
+ return ['CSV', 'JSON']
153
+ }
154
+
155
+ get dialogFullscreen() {
156
+ return false
157
+ }
158
+
159
+ get tabs() {
160
+ return []
161
+ }
162
+
163
+ get menus() {
164
+ return []
165
+ }
166
+
167
+
168
+ }
169
+
170
+ export default UserLoginFailCrud
171
+
@@ -0,0 +1,174 @@
1
+ import {EntityCrud} from "@drax/crud-vue";
2
+ import type {
3
+ IDraxCrudProvider,
4
+ IEntityCrud,
5
+ IEntityCrudField,
6
+ IEntityCrudFilter,
7
+ IEntityCrudHeader,
8
+ IEntityCrudPermissions,
9
+ IEntityCrudRefs,
10
+ IEntityCrudRules
11
+ } from "@drax/crud-share";
12
+ import {UserSessionSystemFactory} from "@drax/identity-front";
13
+
14
+ //Import EntityCrud Refs
15
+ import {UserCrud} from "@drax/identity-vue"
16
+
17
+ class UserSessionCrud extends EntityCrud implements IEntityCrud {
18
+
19
+ static singleton: UserSessionCrud
20
+
21
+ constructor() {
22
+ super();
23
+ this.name = 'UserSession'
24
+ }
25
+
26
+ static get instance(): UserSessionCrud {
27
+ if (!UserSessionCrud.singleton) {
28
+ UserSessionCrud.singleton = new UserSessionCrud()
29
+ }
30
+ return UserSessionCrud.singleton
31
+ }
32
+
33
+ get permissions(): IEntityCrudPermissions {
34
+ return {
35
+ manage: 'usersession:manage',
36
+ view: 'usersession:view',
37
+ create: 'usersession:create',
38
+ update: 'usersession:update',
39
+ delete: 'usersession:delete'
40
+ }
41
+ }
42
+
43
+ get headers(): IEntityCrudHeader[] {
44
+ return [
45
+ {title: 'uuid', key: 'uuid', align: 'start'},
46
+ {title: 'user', key: 'user', align: 'start'},
47
+ {title: 'agent', key: 'agent', align: 'start'},
48
+ {title: 'ip', key: 'ip', align: 'start'},
49
+ {title: 'createdAt', key: 'createdAt', align: 'start'}
50
+ ]
51
+ }
52
+
53
+ get selectedHeaders(): string[] {
54
+ return this.headers.map(header => header.key)
55
+ }
56
+
57
+ get actionHeaders(): IEntityCrudHeader[] {
58
+ return [
59
+ {
60
+ title: 'action.actions',
61
+ key: 'actions',
62
+ sortable: false,
63
+ align: 'center',
64
+ minWidth: '190px'
65
+ },
66
+ ]
67
+ }
68
+
69
+ get provider(): IDraxCrudProvider<any, any, any> {
70
+ return UserSessionSystemFactory.getInstance()
71
+ }
72
+
73
+ get refs(): IEntityCrudRefs {
74
+ return {
75
+ User: UserCrud.instance
76
+ }
77
+ }
78
+
79
+ get rules(): IEntityCrudRules {
80
+ return {
81
+ uuid: [(v: any) => !!v || 'validation.required'],
82
+ user: [(v: any) => !!v || 'validation.required'],
83
+ agent: [],
84
+ ip: [],
85
+ createdAt: []
86
+ }
87
+ }
88
+
89
+ get fields(): IEntityCrudField[] {
90
+ return [
91
+ {name: 'uuid', type: 'string', label: 'uuid', default: ''},
92
+ {name: 'user', type: 'ref', label: 'user', default: null, ref: 'User', refDisplay: 'username'},
93
+ {name: 'agent', type: 'string', label: 'agent', default: ''},
94
+ {name: 'ip', type: 'string', label: 'ip', default: ''},
95
+ {name: 'createdAt', type: 'date', label: 'createdAt', default: null}
96
+ ]
97
+ }
98
+
99
+ get filters(): IEntityCrudFilter[] {
100
+ return [
101
+ {name: 'createdAt', type: 'date', label: 'createdAt', default: '', operator: 'gte' },
102
+ {name: 'createdAt', type: 'date', label: 'createdAt', default: '', operator: 'lte' },
103
+ {name: 'user', type: 'ref', ref: 'User', refDisplay:"username", label: 'User', default: '', operator: 'eq' },
104
+ {name: 'userAgent', type: 'string', label: 'userAgent', default: '', operator: 'eq' },
105
+ {name: 'ip', type: 'string', label: 'ip', default: '', operator: 'eq' },
106
+
107
+ ]
108
+ }
109
+
110
+ get searchEnable(){
111
+ return false
112
+ }
113
+
114
+ get isViewable() {
115
+ return true
116
+ }
117
+
118
+ get isEditable() {
119
+ return false
120
+ }
121
+
122
+ get isCreatable() {
123
+ return false
124
+ }
125
+
126
+ get isDeletable() {
127
+ return false
128
+ }
129
+
130
+ get isExportable() {
131
+ return true
132
+ }
133
+
134
+ get exportFormats() {
135
+ return ['CSV', 'JSON']
136
+ }
137
+
138
+ get exportHeaders() {
139
+ return ['_id','user','createdAt','userAgent','ip']
140
+ }
141
+
142
+ get isImportable() {
143
+ return false
144
+ }
145
+
146
+ get isColumnSelectable() {
147
+ return true
148
+ }
149
+
150
+ get isGroupable() {
151
+ return true
152
+ }
153
+
154
+ get importFormats() {
155
+ return ['CSV', 'JSON']
156
+ }
157
+
158
+ get dialogFullscreen() {
159
+ return false
160
+ }
161
+
162
+ get tabs() {
163
+ return []
164
+ }
165
+
166
+ get menus() {
167
+ return []
168
+ }
169
+
170
+
171
+ }
172
+
173
+ export default UserSessionCrud
174
+
@@ -59,6 +59,8 @@ class RoleCrud extends EntityCrud implements IEntityCrud {
59
59
  get fields(): IEntityCrudField[]{
60
60
  return [
61
61
  {name: 'name', type: 'string', label: 'name', default:'', prependInnerIcon:'mdi-text-short' },
62
+ {name: 'icon', type: 'string', label: 'icon', default:'', prependInnerIcon:'mdi-simple-icons' },
63
+ {name: 'color', type: 'string', label: 'color', default:'', prependInnerIcon:'mdi-palette' },
62
64
  {name: 'childRoles', type: 'array.ref', ref:'Role', refDisplay: 'name', label: 'childRoles', default:[], prependInnerIcon:'mdi-text-short' },
63
65
  {name: 'permissions', type: 'array.string', label: 'childRoles', default:[], prependInnerIcon:'mdi-text-short' }
64
66
  ]
@@ -75,7 +77,7 @@ class RoleCrud extends EntityCrud implements IEntityCrud {
75
77
  }
76
78
 
77
79
  get exportHeaders(){
78
- return ['id', 'name','permissions','childRoles','readonly']
80
+ return ['id', 'name','icon','color','permissions','childRoles','readonly']
79
81
  }
80
82
 
81
83
  get isExportable(){
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import {useFormUtils, useCrudStore} from "@drax/crud-vue";
3
3
  import {computed, defineEmits, defineModel, ref} from "vue";
4
- import {useI18nValidation} from "@drax/common-vue";
4
+ import {useI18nValidation, IconCombobox, ColorCombobox} from "@drax/common-vue";
5
5
  import PermissionSelector from "../../components/PermissionSelector/PermissionSelector.vue";
6
6
  import RoleCombobox from "../../combobox/RoleCombobox.vue";
7
7
  import {useIdentityCrudStore} from "../../stores/IdentityCrudStore";
@@ -89,6 +89,10 @@ const {
89
89
  :clearable="false"
90
90
  ></v-text-field>
91
91
 
92
+
93
+ <icon-combobox v-model="valueModel.icon"></icon-combobox>
94
+ <color-combobox v-model="valueModel.color"></color-combobox>
95
+
92
96
  <RoleCombobox
93
97
  v-model="valueModel.childRoles"
94
98
  label="role.field.childRoles"
@@ -42,12 +42,14 @@ class UserCrud extends EntityCrud implements IEntityCrud {
42
42
  return import.meta.env.VITE_DRAX_TENANT === 'ENABLE'
43
43
  }
44
44
 
45
+
45
46
  get headers():IEntityCrudHeader[] {
46
47
  return [
48
+ { title: '', key: 'avatar', align: 'start', width:'50px' },
47
49
  { title: 'name', key: 'name', align: 'start' },
48
50
  { title: 'username', key: 'username', align: 'start' },
49
51
  { title: 'email', key: 'email', align: 'start' },
50
- { title: 'role', key: 'role.name', align: 'start' },
52
+ { title: 'role', key: 'role', align: 'start' },
51
53
  ...(this.isTenantEnabled ? [{ title: 'tenant', key: 'tenant.name', align: 'start' as const }] : []),
52
54
  { title: 'active', key: 'active', align: 'start' },
53
55
  ]
@@ -76,8 +78,8 @@ class UserCrud extends EntityCrud implements IEntityCrud {
76
78
  {name: 'username', type: 'string', label: 'username', default:'' },
77
79
  {name: 'email', type: 'string', label: 'email', default:'' },
78
80
  {name: 'phone', type: 'string', label: 'phone', default:'' },
79
- {name: 'role', type: 'ref', ref: 'role', label: 'role', default:null },
80
- {name: 'tenant', type: 'ref', ref: 'tenant', label: 'tenant', default:null, permission: 'tenant:manage' },
81
+ {name: 'role', type: 'ref', ref: 'role', refDisplay:'name', label: 'role', default:null },
82
+ {name: 'tenant', type: 'ref', ref: 'tenant', refDisplay:'name', label: 'tenant', default:null, permission: 'tenant:manage' },
81
83
  {name: 'active', type: 'boolean', label: 'active', default:true },
82
84
 
83
85
  ]
@@ -139,6 +141,9 @@ class UserCrud extends EntityCrud implements IEntityCrud {
139
141
  return false
140
142
  }
141
143
 
144
+ get containerFluid(): boolean{
145
+ return true
146
+ }
142
147
  }
143
148
 
144
149
  export default UserCrud
@@ -0,0 +1,46 @@
1
+
2
+ const messages = {
3
+ en: {
4
+
5
+ userloginfail: {
6
+ entity: 'UserLoginFail',
7
+ menu: 'UserLoginFail',
8
+ crud: 'Manage UserLoginFail',
9
+ field:{
10
+ user:'user',
11
+ agent:'agent',
12
+ ip:'ip',
13
+ createdAt:'createdAt'
14
+ }
15
+ },
16
+ permission: {
17
+ 'userloginfail:view': 'View UserLoginFail',
18
+ 'userloginfail:create': 'Create UserLoginFail',
19
+ 'userloginfail:update': 'Edit UserLoginFail',
20
+ 'userloginfail:delete': 'Delete UserLoginFail',
21
+ 'userloginfail:manage': 'Manage UserLoginFail',
22
+ }
23
+ },
24
+ es: {
25
+ userloginfail: {
26
+ entity: 'UserLoginFail',
27
+ menu: 'UserLoginFail',
28
+ crud: 'Gestionar UserLoginFail',
29
+ field:{
30
+ user:'user',
31
+ agent:'agent',
32
+ ip:'ip',
33
+ createdAt:'createdAt'
34
+ }
35
+ },
36
+ permission: {
37
+ 'userloginfail:view': 'Ver UserLoginFail',
38
+ 'userloginfail:create': 'Crear UserLoginFail',
39
+ 'userloginfail:update': 'Editar UserLoginFail',
40
+ 'userloginfail:delete': 'Eliminar UserLoginFail',
41
+ 'userloginfail:manage': 'Gestionar UserLoginFail',
42
+ }
43
+ }
44
+ }
45
+
46
+ export default messages;
@@ -0,0 +1,48 @@
1
+
2
+ const messages = {
3
+ en: {
4
+
5
+ usersession: {
6
+ entity: 'UserSession',
7
+ menu: 'UserSession',
8
+ crud: 'Manage UserSession',
9
+ field:{
10
+ uuid:'uuid',
11
+ user:'user',
12
+ agent:'agent',
13
+ ip:'ip',
14
+ createdAt:'createdAt'
15
+ }
16
+ },
17
+ permission: {
18
+ 'usersession:view': 'View UserSession',
19
+ 'usersession:create': 'Create UserSession',
20
+ 'usersession:update': 'Edit UserSession',
21
+ 'usersession:delete': 'Delete UserSession',
22
+ 'usersession:manage': 'Manage UserSession',
23
+ }
24
+ },
25
+ es: {
26
+ usersession: {
27
+ entity: 'UserSession',
28
+ menu: 'UserSession',
29
+ crud: 'Gestionar UserSession',
30
+ field:{
31
+ uuid:'uuid',
32
+ user:'user',
33
+ agent:'agent',
34
+ ip:'ip',
35
+ createdAt:'createdAt'
36
+ }
37
+ },
38
+ permission: {
39
+ 'usersession:view': 'Ver UserSession',
40
+ 'usersession:create': 'Crear UserSession',
41
+ 'usersession:update': 'Editar UserSession',
42
+ 'usersession:delete': 'Eliminar UserSession',
43
+ 'usersession:manage': 'Gestionar UserSession',
44
+ }
45
+ }
46
+ }
47
+
48
+ export default messages;
package/src/index.ts CHANGED
@@ -26,6 +26,10 @@ import UserApiKeyCreated from "./cruds/user-api-key-crud/UserApiKeyCreated.vue";
26
26
  import UserApiKeyView from "./views/UserApiKeyView.vue";
27
27
  import UserApiKeyCrudPage from "./pages/crud/UserApiKeyCrudPage.vue";
28
28
 
29
+
30
+ import UserLoginFailCrudPage from "./pages/crud/UserLoginFailCrudPage.vue";
31
+ import UserSessionCrudPage from "./pages/crud/UserSessionCrudPage.vue";
32
+
29
33
  import {useAuth} from "./composables/useAuth.js";
30
34
  import {useUser} from "./composables/useUser.js";
31
35
  import {useRole} from "./composables/useRole.js";
@@ -65,6 +69,9 @@ export {
65
69
  ProfilePage,
66
70
  PasswordPage,
67
71
 
72
+ UserLoginFailCrudPage,
73
+ UserSessionCrudPage,
74
+
68
75
  //User
69
76
  UserView,
70
77
  UserForm,
@@ -8,6 +8,7 @@ import PasswordUpdateButton from "../../cruds/user-crud/PasswordUpdateButton.vue
8
8
  import UserPasswordDialog from "../../cruds/user-crud/UserPasswordDialog.vue";
9
9
  import type {IUser} from "@drax/identity-share";
10
10
  import {useIdentityCrudStore} from "../../stores/IdentityCrudStore"
11
+ import IdentityUserGroupBy from "../../components/IdentityUserGroupBy/IdentityUserGroupBy.vue";
11
12
 
12
13
  const identityCrudStore = useIdentityCrudStore();
13
14
 
@@ -24,16 +25,20 @@ function onChangePassword(user:IUser){
24
25
  dialogPassword.value = true;
25
26
  }
26
27
 
28
+ const roleDashboard = import.meta.env.VITE_DRAX_USER_ROLE_DASHBOARD === 'ENABLE'
29
+
27
30
  </script>
28
31
 
29
32
  <template>
30
- <div>
33
+ <v-container fluid>
31
34
  <user-password-dialog
32
35
  v-if="dialogPassword && userSelected"
33
36
  v-model="dialogPassword"
34
37
  :user="userSelected"
35
38
  />
36
39
 
40
+ <identity-user-group-by v-if="roleDashboard"></identity-user-group-by>
41
+
37
42
  <crud :entity="identityCrudStore.userCrud">
38
43
 
39
44
  <template v-slot:form>
@@ -44,6 +49,17 @@ function onChangePassword(user:IUser){
44
49
  />
45
50
  </template>
46
51
 
52
+ <template v-slot:item.avatar="{ item }">
53
+ <v-avatar>
54
+ <v-img v-if="item.avatar" :src="item.avatar"></v-img>
55
+ <v-icon v-else size="50">mdi-account-circle</v-icon>
56
+ </v-avatar>
57
+ </template>
58
+
59
+ <template v-slot:item.role="{ item }">
60
+ <v-chip variant="outlined" :color="item.role.color"> <v-icon v-if="item.role.icon" start>{{item.role.icon}}</v-icon>{{item.role.name}}</v-chip>
61
+ </template>
62
+
47
63
 
48
64
 
49
65
  <template v-slot:item.actions="{ item }">
@@ -59,7 +75,7 @@ function onChangePassword(user:IUser){
59
75
  </v-chip>
60
76
  </template>
61
77
  </crud>
62
- </div>
78
+ </v-container>
63
79
 
64
80
  </template>
65
81
 
@@ -0,0 +1,19 @@
1
+
2
+ <script setup lang="ts">
3
+ import UserLoginFailCrud from '../../cruds/UserLoginFailCrud'
4
+ import {Crud} from "@drax/crud-vue";
5
+ import {formatDateTime} from "@drax/common-front"
6
+
7
+ </script>
8
+
9
+ <template>
10
+ <crud :entity="UserLoginFailCrud.instance">
11
+ <template v-slot:item.user="{value}">{{value?.username}}</template>
12
+ <template v-slot:item.createdAt="{value}">{{formatDateTime(value)}}</template>
13
+ </crud>
14
+ </template>
15
+
16
+ <style scoped>
17
+
18
+ </style>
19
+
@@ -0,0 +1,19 @@
1
+
2
+ <script setup lang="ts">
3
+ import UserSessionCrud from '../../cruds/UserSessionCrud'
4
+ import {Crud} from "@drax/crud-vue";
5
+ import {formatDateTime} from "@drax/common-front"
6
+
7
+ </script>
8
+
9
+ <template>
10
+ <crud :entity="UserSessionCrud.instance">
11
+ <template v-slot:item.user="{value}">{{value?.username}}</template>
12
+ <template v-slot:item.createdAt="{value}">{{formatDateTime(value)}}</template>
13
+ </crud>
14
+ </template>
15
+
16
+ <style scoped>
17
+
18
+ </style>
19
+
@@ -1,10 +1,14 @@
1
1
  import IdentityCrudRoutes from './IdentityCrudRoutes'
2
2
  import IdentityAuthRoutes from './IdentityAuthRoutes'
3
+ import UserLoginFailCrudRoute from './UserLoginFailCrudRoute'
4
+ import UserSessionCrudRoute from './UserSessionCrudRoute'
3
5
 
4
6
 
5
7
  const routes = [
6
8
  ...IdentityAuthRoutes,
7
9
  ...IdentityCrudRoutes,
10
+ ...UserLoginFailCrudRoute,
11
+ ...UserSessionCrudRoute
8
12
  ]
9
13
 
10
14
 
@@ -0,0 +1,18 @@
1
+
2
+ import UserLoginFailCrudPage from "../pages/crud/UserLoginFailCrudPage.vue";
3
+
4
+
5
+ const UserLoginFailCrudRoute = [
6
+ {
7
+ name: 'UserLoginFailCrudPage',
8
+ path: '/identity/user-login-fail',
9
+ component: UserLoginFailCrudPage,
10
+ meta: {
11
+ auth: true,
12
+ permission: 'userloginfail:manage',
13
+ }
14
+ },
15
+ ]
16
+
17
+ export default UserLoginFailCrudRoute
18
+ export { UserLoginFailCrudRoute }
@@ -0,0 +1,18 @@
1
+
2
+ import UserSessionCrudPage from "../pages/crud/UserSessionCrudPage.vue";
3
+
4
+
5
+ const UserSessionCrudRoute = [
6
+ {
7
+ name: 'UserSessionCrudPage',
8
+ path: '/identity/user-session',
9
+ component: UserSessionCrudPage,
10
+ meta: {
11
+ auth: true,
12
+ permission: 'usersession:manage',
13
+ }
14
+ },
15
+ ]
16
+
17
+ export default UserSessionCrudRoute
18
+ export { UserSessionCrudRoute }