@hedhog/admin 0.48.15 → 0.48.17
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/frontend/dashboard/components/database-stats.tsx.ejs +126 -0
- package/frontend/dashboard/components/module-installed.tsx.ejs +113 -0
- package/frontend/dashboard/components/system-info.tsx.ejs +144 -0
- package/frontend/dashboard/components/user-summary.tsx.ejs +151 -0
- package/hedhog.yaml +56 -6
- package/package.json +2 -2
@@ -0,0 +1,126 @@
|
|
1
|
+
import { Database } from 'lucide-react'
|
2
|
+
import { useEffect, useState } from 'react'
|
3
|
+
|
4
|
+
import {
|
5
|
+
Card,
|
6
|
+
CardContent,
|
7
|
+
CardDescription,
|
8
|
+
CardHeader,
|
9
|
+
CardTitle,
|
10
|
+
} from '@/components/ui/card'
|
11
|
+
import { useApp } from '@/hooks/use-app'
|
12
|
+
import { bytesToHuman } from '@/lib/bytes-to-human'
|
13
|
+
import { DashboardDefaultData } from '@/types'
|
14
|
+
|
15
|
+
const DatabaseStats = () => {
|
16
|
+
const { request } = useApp()
|
17
|
+
const [isRefreshing, setIsRefreshing] = useState(false)
|
18
|
+
const [data, setData] = useState<DashboardDefaultData>({
|
19
|
+
os: {
|
20
|
+
name: '',
|
21
|
+
platform: '',
|
22
|
+
version: '',
|
23
|
+
architecture: '',
|
24
|
+
uptime: 0,
|
25
|
+
cpu: {
|
26
|
+
model: '',
|
27
|
+
speed: 0,
|
28
|
+
physicalCores: 0,
|
29
|
+
virtualCores: 0,
|
30
|
+
},
|
31
|
+
memory: {
|
32
|
+
total: 0,
|
33
|
+
free: 0,
|
34
|
+
},
|
35
|
+
disk: [],
|
36
|
+
},
|
37
|
+
modules: [],
|
38
|
+
users: {
|
39
|
+
total: 0,
|
40
|
+
admin: 0,
|
41
|
+
active: 0,
|
42
|
+
activities: [],
|
43
|
+
},
|
44
|
+
database: {
|
45
|
+
connections: 0,
|
46
|
+
size: 0,
|
47
|
+
queriesPerSecond: 0,
|
48
|
+
},
|
49
|
+
} as DashboardDefaultData)
|
50
|
+
|
51
|
+
const load = async () => {
|
52
|
+
setIsRefreshing(true)
|
53
|
+
const { data } = await request<DashboardDefaultData>({
|
54
|
+
url: '/core',
|
55
|
+
})
|
56
|
+
|
57
|
+
setData(data)
|
58
|
+
|
59
|
+
setIsRefreshing(false)
|
60
|
+
}
|
61
|
+
|
62
|
+
useEffect(() => {
|
63
|
+
load()
|
64
|
+
}, [])
|
65
|
+
|
66
|
+
return (
|
67
|
+
<Card>
|
68
|
+
<CardHeader>
|
69
|
+
<CardTitle className='flex items-center'>
|
70
|
+
<Database className='mr-2 h-5 w-5 text-primary' />
|
71
|
+
Estatísticas do Banco de Dados
|
72
|
+
</CardTitle>
|
73
|
+
<CardDescription>
|
74
|
+
Informações sobre o banco de dados do sistema
|
75
|
+
</CardDescription>
|
76
|
+
</CardHeader>
|
77
|
+
<CardContent>
|
78
|
+
{isRefreshing ? (
|
79
|
+
<div className='grid grid-cols-1 gap-4 md:grid-cols-3'>
|
80
|
+
<div className='animate-pulse rounded-lg border p-4'>
|
81
|
+
<div className='h-4 w-1/3 rounded bg-muted-foreground/20'></div>
|
82
|
+
<div className='mt-2 h-6 w-2/3 rounded bg-muted-foreground/20'></div>
|
83
|
+
</div>
|
84
|
+
<div className='animate-pulse rounded-lg border p-4'>
|
85
|
+
<div className='h-4 w-1/3 rounded bg-muted-foreground/20'></div>
|
86
|
+
<div className='mt-2 h-6 w-2/3 rounded bg-muted-foreground/20'></div>
|
87
|
+
</div>
|
88
|
+
<div className='animate-pulse rounded-lg border p-4'>
|
89
|
+
<div className='h-4 w-1/3 rounded bg-muted-foreground/20'></div>
|
90
|
+
<div className='mt-2 h-6 w-2/3 rounded bg-muted-foreground/20'></div>
|
91
|
+
</div>
|
92
|
+
</div>
|
93
|
+
) : (
|
94
|
+
<div className='grid grid-cols-1 gap-4 md:grid-cols-3'>
|
95
|
+
<div className='rounded-lg border p-4'>
|
96
|
+
<div className='text-sm font-medium text-muted-foreground'>
|
97
|
+
Conexões
|
98
|
+
</div>
|
99
|
+
<div className='mt-1 text-2xl font-bold'>
|
100
|
+
{data.database.connections}
|
101
|
+
</div>
|
102
|
+
</div>
|
103
|
+
<div className='rounded-lg border p-4'>
|
104
|
+
<div className='text-sm font-medium text-muted-foreground'>
|
105
|
+
Tamanho
|
106
|
+
</div>
|
107
|
+
<div className='mt-1 text-2xl font-bold'>
|
108
|
+
{bytesToHuman(data.database.size)}
|
109
|
+
</div>
|
110
|
+
</div>
|
111
|
+
<div className='rounded-lg border p-4'>
|
112
|
+
<div className='text-sm font-medium text-muted-foreground'>
|
113
|
+
Consultas/min
|
114
|
+
</div>
|
115
|
+
<div className='mt-1 text-2xl font-bold'>
|
116
|
+
{data.database.queriesPerSecond}
|
117
|
+
</div>
|
118
|
+
</div>
|
119
|
+
</div>
|
120
|
+
)}
|
121
|
+
</CardContent>
|
122
|
+
</Card>
|
123
|
+
)
|
124
|
+
}
|
125
|
+
|
126
|
+
export default DatabaseStats
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import { Package } from 'lucide-react'
|
2
|
+
import { useEffect, useState } from 'react'
|
3
|
+
|
4
|
+
import { Badge } from '@/components/ui/badge'
|
5
|
+
import {
|
6
|
+
Card,
|
7
|
+
CardContent,
|
8
|
+
CardDescription,
|
9
|
+
CardHeader,
|
10
|
+
CardTitle,
|
11
|
+
} from '@/components/ui/card'
|
12
|
+
import { useApp } from '@/hooks/use-app'
|
13
|
+
import { DashboardDefaultData } from '@/types'
|
14
|
+
|
15
|
+
const ModuleInstalled = () => {
|
16
|
+
const { request } = useApp()
|
17
|
+
const [isRefreshing, setIsRefreshing] = useState(false)
|
18
|
+
const [data, setData] = useState<DashboardDefaultData>({
|
19
|
+
os: {
|
20
|
+
name: '',
|
21
|
+
platform: '',
|
22
|
+
version: '',
|
23
|
+
architecture: '',
|
24
|
+
uptime: 0,
|
25
|
+
cpu: {
|
26
|
+
model: '',
|
27
|
+
speed: 0,
|
28
|
+
physicalCores: 0,
|
29
|
+
virtualCores: 0,
|
30
|
+
},
|
31
|
+
memory: {
|
32
|
+
total: 0,
|
33
|
+
free: 0,
|
34
|
+
},
|
35
|
+
disk: [],
|
36
|
+
},
|
37
|
+
modules: [],
|
38
|
+
users: {
|
39
|
+
total: 0,
|
40
|
+
admin: 0,
|
41
|
+
active: 0,
|
42
|
+
activities: [],
|
43
|
+
},
|
44
|
+
database: {
|
45
|
+
connections: 0,
|
46
|
+
size: 0,
|
47
|
+
queriesPerSecond: 0,
|
48
|
+
},
|
49
|
+
} as DashboardDefaultData)
|
50
|
+
|
51
|
+
const load = async () => {
|
52
|
+
setIsRefreshing(true)
|
53
|
+
const { data } = await request<DashboardDefaultData>({
|
54
|
+
url: '/core',
|
55
|
+
})
|
56
|
+
|
57
|
+
setData(data)
|
58
|
+
|
59
|
+
setIsRefreshing(false)
|
60
|
+
}
|
61
|
+
|
62
|
+
useEffect(() => {
|
63
|
+
load()
|
64
|
+
}, [])
|
65
|
+
|
66
|
+
return (
|
67
|
+
<Card>
|
68
|
+
<CardHeader className='pb-2'>
|
69
|
+
<CardTitle className='flex items-center'>
|
70
|
+
<Package className='mr-2 h-5 w-5 text-primary' />
|
71
|
+
Módulos Instalados
|
72
|
+
</CardTitle>
|
73
|
+
<CardDescription>Módulos e suas versões</CardDescription>
|
74
|
+
</CardHeader>
|
75
|
+
<CardContent>
|
76
|
+
{isRefreshing ? (
|
77
|
+
<div className='space-y-4'>
|
78
|
+
{Array.from({ length: 5 }).map((_, index) => (
|
79
|
+
<div
|
80
|
+
key={index}
|
81
|
+
className='flex animate-pulse items-center justify-between'
|
82
|
+
>
|
83
|
+
<div>
|
84
|
+
<div className='h-4 w-24 rounded bg-muted'></div>
|
85
|
+
<div className='mt-1 h-3 w-16 rounded bg-muted'></div>
|
86
|
+
</div>
|
87
|
+
<div className='h-6 w-20 rounded bg-muted'></div>
|
88
|
+
</div>
|
89
|
+
))}
|
90
|
+
</div>
|
91
|
+
) : (
|
92
|
+
<div className='space-y-4'>
|
93
|
+
{data.modules.map((module, index) => (
|
94
|
+
<div key={index} className='flex items-center justify-between'>
|
95
|
+
<div>
|
96
|
+
<div className='font-medium'>{module.name}</div>
|
97
|
+
<div className='text-sm text-muted-foreground'>
|
98
|
+
v{String(module.version).replace(/\^/g, '')}
|
99
|
+
</div>
|
100
|
+
</div>
|
101
|
+
<Badge variant={module.upToDate ? 'outline' : 'secondary'}>
|
102
|
+
{module.upToDate ? 'Atualizado' : 'Atualização disponível'}
|
103
|
+
</Badge>
|
104
|
+
</div>
|
105
|
+
))}
|
106
|
+
</div>
|
107
|
+
)}
|
108
|
+
</CardContent>
|
109
|
+
</Card>
|
110
|
+
)
|
111
|
+
}
|
112
|
+
|
113
|
+
export default ModuleInstalled
|
@@ -0,0 +1,144 @@
|
|
1
|
+
import { Cpu, HardDrive, Server } from 'lucide-react'
|
2
|
+
import { useEffect, useState } from 'react'
|
3
|
+
|
4
|
+
import {
|
5
|
+
Card,
|
6
|
+
CardContent,
|
7
|
+
CardDescription,
|
8
|
+
CardHeader,
|
9
|
+
CardTitle,
|
10
|
+
} from '@/components/ui/card'
|
11
|
+
import { Separator } from '@/components/ui/separator'
|
12
|
+
import { useApp } from '@/hooks/use-app'
|
13
|
+
import { bytesToHuman } from '@/lib/bytes-to-human'
|
14
|
+
import { secondsToHuman } from '@/lib/seconds-to-human'
|
15
|
+
import { DashboardDefaultData } from '@/types'
|
16
|
+
|
17
|
+
const SystemInfo = () => {
|
18
|
+
const { request } = useApp()
|
19
|
+
const [isRefreshing, setIsRefreshing] = useState(false)
|
20
|
+
const [data, setData] = useState<DashboardDefaultData>({
|
21
|
+
os: {
|
22
|
+
name: '',
|
23
|
+
platform: '',
|
24
|
+
version: '',
|
25
|
+
architecture: '',
|
26
|
+
uptime: 0,
|
27
|
+
cpu: {
|
28
|
+
model: '',
|
29
|
+
speed: 0,
|
30
|
+
physicalCores: 0,
|
31
|
+
virtualCores: 0,
|
32
|
+
},
|
33
|
+
memory: {
|
34
|
+
total: 0,
|
35
|
+
free: 0,
|
36
|
+
},
|
37
|
+
disk: [],
|
38
|
+
},
|
39
|
+
modules: [],
|
40
|
+
users: {
|
41
|
+
total: 0,
|
42
|
+
admin: 0,
|
43
|
+
active: 0,
|
44
|
+
activities: [],
|
45
|
+
},
|
46
|
+
database: {
|
47
|
+
connections: 0,
|
48
|
+
size: 0,
|
49
|
+
queriesPerSecond: 0,
|
50
|
+
},
|
51
|
+
} as DashboardDefaultData)
|
52
|
+
|
53
|
+
const load = async () => {
|
54
|
+
setIsRefreshing(true)
|
55
|
+
const { data } = await request<DashboardDefaultData>({
|
56
|
+
url: '/core',
|
57
|
+
})
|
58
|
+
|
59
|
+
setData(data)
|
60
|
+
|
61
|
+
setIsRefreshing(false)
|
62
|
+
}
|
63
|
+
|
64
|
+
useEffect(() => {
|
65
|
+
load()
|
66
|
+
}, [])
|
67
|
+
|
68
|
+
return (
|
69
|
+
<Card>
|
70
|
+
<CardHeader className='pb-2'>
|
71
|
+
<CardTitle className='flex items-center'>
|
72
|
+
<Server className='mr-2 h-5 w-5 text-primary' />
|
73
|
+
Informações do Sistema
|
74
|
+
</CardTitle>
|
75
|
+
<CardDescription>
|
76
|
+
Detalhes do sistema operacional e hardware
|
77
|
+
</CardDescription>
|
78
|
+
</CardHeader>
|
79
|
+
<CardContent>
|
80
|
+
{isRefreshing ? (
|
81
|
+
<div className='space-y-4'>
|
82
|
+
<div className='animate-pulse'>
|
83
|
+
<div className='mb-2 h-4 w-3/4 rounded bg-gray-200'></div>
|
84
|
+
<div className='mb-2 h-4 w-1/2 rounded bg-gray-200'></div>
|
85
|
+
<div className='mb-2 h-4 w-1/4 rounded bg-gray-200'></div>
|
86
|
+
<div className='mb-2 h-4 w-2/3 rounded bg-gray-200'></div>
|
87
|
+
</div>
|
88
|
+
<Separator />
|
89
|
+
<div className='animate-pulse'>
|
90
|
+
<div className='mb-2 h-4 w-3/4 rounded bg-gray-200'></div>
|
91
|
+
<div className='mb-2 h-4 w-1/2 rounded bg-gray-200'></div>
|
92
|
+
<div className='mb-2 h-4 w-1/4 rounded bg-gray-200'></div>
|
93
|
+
<div className='mb-2 h-4 w-2/3 rounded bg-gray-200'></div>
|
94
|
+
</div>
|
95
|
+
</div>
|
96
|
+
) : (
|
97
|
+
<div className='space-y-4'>
|
98
|
+
<div>
|
99
|
+
<h3 className='flex items-center text-sm font-medium'>
|
100
|
+
<HardDrive className='mr-2 h-4 w-4 text-muted-foreground' />
|
101
|
+
Sistema Operacional
|
102
|
+
</h3>
|
103
|
+
<div className='mt-1 grid grid-cols-2 gap-1 text-sm'>
|
104
|
+
<div className='text-muted-foreground'>Nome:</div>
|
105
|
+
<div>{data.os.name}</div>
|
106
|
+
<div className='text-muted-foreground'>Versão:</div>
|
107
|
+
<div>{data.os.version}</div>
|
108
|
+
<div className='text-muted-foreground'>Arquitetura:</div>
|
109
|
+
<div>{data.os.architecture}</div>
|
110
|
+
<div className='text-muted-foreground'>Tempo ativo:</div>
|
111
|
+
<div>{secondsToHuman(data.os.uptime, true)}</div>
|
112
|
+
</div>
|
113
|
+
</div>
|
114
|
+
<Separator />
|
115
|
+
<div>
|
116
|
+
<h3 className='flex items-center text-sm font-medium'>
|
117
|
+
<Cpu className='mr-2 h-4 w-4 text-muted-foreground' />
|
118
|
+
Hardware
|
119
|
+
</h3>
|
120
|
+
<div className='mt-1 grid grid-cols-2 gap-1 text-sm'>
|
121
|
+
<div className='text-muted-foreground'>CPU:</div>
|
122
|
+
<div>{data.os.cpu.model}</div>
|
123
|
+
<div className='text-muted-foreground'>Memória:</div>
|
124
|
+
<div>{bytesToHuman(data.os.memory.total)}</div>
|
125
|
+
{data.os.disk.map((disk) => (
|
126
|
+
<>
|
127
|
+
<div className='text-muted-foreground'>
|
128
|
+
Disco {disk.filesystem}:
|
129
|
+
</div>
|
130
|
+
<div>
|
131
|
+
{bytesToHuman(disk.size)} ({bytesToHuman(disk.free)} free)
|
132
|
+
</div>
|
133
|
+
</>
|
134
|
+
))}
|
135
|
+
</div>
|
136
|
+
</div>
|
137
|
+
</div>
|
138
|
+
)}
|
139
|
+
</CardContent>
|
140
|
+
</Card>
|
141
|
+
)
|
142
|
+
}
|
143
|
+
|
144
|
+
export default SystemInfo
|
@@ -0,0 +1,151 @@
|
|
1
|
+
import { User, Users } from 'lucide-react'
|
2
|
+
import { useEffect, useState } from 'react'
|
3
|
+
|
4
|
+
import { Button } from '@/components/ui/button'
|
5
|
+
import {
|
6
|
+
Card,
|
7
|
+
CardContent,
|
8
|
+
CardDescription,
|
9
|
+
CardFooter,
|
10
|
+
CardHeader,
|
11
|
+
CardTitle,
|
12
|
+
} from '@/components/ui/card'
|
13
|
+
import { useApp } from '@/hooks/use-app'
|
14
|
+
import { DashboardDefaultData } from '@/types'
|
15
|
+
import { useNavigate } from 'react-router-dom'
|
16
|
+
|
17
|
+
const UserSummary = () => {
|
18
|
+
const navigate = useNavigate()
|
19
|
+
const { request } = useApp()
|
20
|
+
const [isRefreshing, setIsRefreshing] = useState(false)
|
21
|
+
const [data, setData] = useState<DashboardDefaultData>({
|
22
|
+
os: {
|
23
|
+
name: '',
|
24
|
+
platform: '',
|
25
|
+
version: '',
|
26
|
+
architecture: '',
|
27
|
+
uptime: 0,
|
28
|
+
cpu: {
|
29
|
+
model: '',
|
30
|
+
speed: 0,
|
31
|
+
physicalCores: 0,
|
32
|
+
virtualCores: 0,
|
33
|
+
},
|
34
|
+
memory: {
|
35
|
+
total: 0,
|
36
|
+
free: 0,
|
37
|
+
},
|
38
|
+
disk: [],
|
39
|
+
},
|
40
|
+
modules: [],
|
41
|
+
users: {
|
42
|
+
total: 0,
|
43
|
+
admin: 0,
|
44
|
+
active: 0,
|
45
|
+
activities: [],
|
46
|
+
},
|
47
|
+
database: {
|
48
|
+
connections: 0,
|
49
|
+
size: 0,
|
50
|
+
queriesPerSecond: 0,
|
51
|
+
},
|
52
|
+
} as DashboardDefaultData)
|
53
|
+
|
54
|
+
const load = async () => {
|
55
|
+
setIsRefreshing(true)
|
56
|
+
const { data } = await request<DashboardDefaultData>({
|
57
|
+
url: '/core',
|
58
|
+
})
|
59
|
+
|
60
|
+
setData(data)
|
61
|
+
|
62
|
+
setIsRefreshing(false)
|
63
|
+
}
|
64
|
+
|
65
|
+
useEffect(() => {
|
66
|
+
load()
|
67
|
+
}, [])
|
68
|
+
|
69
|
+
return (
|
70
|
+
<Card>
|
71
|
+
<CardHeader className='pb-2'>
|
72
|
+
<CardTitle className='flex items-center'>
|
73
|
+
<Users className='mr-2 h-5 w-5 text-primary' />
|
74
|
+
Resumo de Usuários
|
75
|
+
</CardTitle>
|
76
|
+
<CardDescription>Visão geral dos usuários do sistema</CardDescription>
|
77
|
+
</CardHeader>
|
78
|
+
<CardContent>
|
79
|
+
<div className='space-y-4'>
|
80
|
+
{isRefreshing ? (
|
81
|
+
<div className='grid grid-cols-3 gap-4'>
|
82
|
+
{Array.from({ length: 3 }).map((_, index) => (
|
83
|
+
<div
|
84
|
+
key={index}
|
85
|
+
className='flex animate-pulse flex-col items-center justify-center rounded-lg bg-primary/10 p-3'
|
86
|
+
>
|
87
|
+
<div className='h-6 w-12 rounded bg-muted'></div>
|
88
|
+
<div className='mt-2 h-4 w-16 rounded bg-muted'></div>
|
89
|
+
</div>
|
90
|
+
))}
|
91
|
+
</div>
|
92
|
+
) : (
|
93
|
+
<>
|
94
|
+
<div className='grid grid-cols-3 gap-4'>
|
95
|
+
<div className='flex flex-col items-center justify-center rounded-lg bg-primary/10 p-3'>
|
96
|
+
<div className='text-2xl font-bold'>{data.users.total}</div>
|
97
|
+
<div className='text-xs text-muted-foreground'>Total</div>
|
98
|
+
</div>
|
99
|
+
<div className='flex flex-col items-center justify-center rounded-lg bg-primary/10 p-3'>
|
100
|
+
<div className='text-2xl font-bold'>{data.users.admin}</div>
|
101
|
+
<div className='text-xs text-muted-foreground'>Admins</div>
|
102
|
+
</div>
|
103
|
+
<div className='flex flex-col items-center justify-center rounded-lg bg-primary/10 p-3'>
|
104
|
+
<div className='text-2xl font-bold'>{data.users.active}</div>
|
105
|
+
<div className='text-xs text-muted-foreground'>Ativos</div>
|
106
|
+
</div>
|
107
|
+
</div>
|
108
|
+
{data.users.activities.length > 0 && (
|
109
|
+
<div>
|
110
|
+
<h3 className='mb-2 text-sm font-medium'>
|
111
|
+
Atividade Recente
|
112
|
+
</h3>
|
113
|
+
|
114
|
+
<div className='space-y-2'>
|
115
|
+
{data.users.activities.map((activity, index) => (
|
116
|
+
<div
|
117
|
+
key={index}
|
118
|
+
className='flex items-center justify-between text-sm'
|
119
|
+
>
|
120
|
+
<div className='flex items-center'>
|
121
|
+
<User className='mr-2 h-4 w-4 text-muted-foreground' />
|
122
|
+
<span>{activity.user.name}</span>
|
123
|
+
</div>
|
124
|
+
<div className='text-muted-foreground'>
|
125
|
+
{activity.created_at}
|
126
|
+
</div>
|
127
|
+
</div>
|
128
|
+
))}
|
129
|
+
</div>
|
130
|
+
</div>
|
131
|
+
)}
|
132
|
+
</>
|
133
|
+
)}
|
134
|
+
</div>
|
135
|
+
</CardContent>
|
136
|
+
<CardFooter>
|
137
|
+
<Button
|
138
|
+
variant='outline'
|
139
|
+
size='sm'
|
140
|
+
className='w-full'
|
141
|
+
onClick={() => navigate('/users')}
|
142
|
+
>
|
143
|
+
<User className='mr-2 h-4 w-4' />
|
144
|
+
Ver Todos Usuários
|
145
|
+
</Button>
|
146
|
+
</CardFooter>
|
147
|
+
</Card>
|
148
|
+
)
|
149
|
+
}
|
150
|
+
|
151
|
+
export default UserSummary
|
package/hedhog.yaml
CHANGED
@@ -812,12 +812,33 @@ data:
|
|
812
812
|
- slug: default
|
813
813
|
dashboard_component:
|
814
814
|
- slug: system-info
|
815
|
-
path:
|
816
|
-
width:
|
817
|
-
height:
|
815
|
+
path: SystemInfo
|
816
|
+
width: 4
|
817
|
+
height: 14
|
818
818
|
name:
|
819
819
|
en: System Info
|
820
820
|
pt: Informações do Sistema
|
821
|
+
- slug: module-installed
|
822
|
+
path: ModuleInstalled
|
823
|
+
width: 4
|
824
|
+
height: 14
|
825
|
+
name:
|
826
|
+
en: Modules Installed
|
827
|
+
pt: Módulos Instalados
|
828
|
+
- slug: user-summary
|
829
|
+
path: UserSummary
|
830
|
+
width: 4
|
831
|
+
height: 14
|
832
|
+
name:
|
833
|
+
en: Users Summary
|
834
|
+
pt: Resumo de Usuários
|
835
|
+
- slug: database-stats
|
836
|
+
path: DatabaseStats
|
837
|
+
width: 12
|
838
|
+
height: 4
|
839
|
+
name:
|
840
|
+
en: Database Stats
|
841
|
+
pt: Estatísticas do Banco de Dados
|
821
842
|
dashboard_item:
|
822
843
|
- component_id:
|
823
844
|
where:
|
@@ -825,11 +846,40 @@ data:
|
|
825
846
|
dashboard_id:
|
826
847
|
where:
|
827
848
|
slug: default
|
828
|
-
width:
|
829
|
-
height:
|
849
|
+
width: 4
|
850
|
+
height: 14
|
830
851
|
x_axis: 0
|
831
852
|
y_axis: 0
|
832
|
-
|
853
|
+
- component_id:
|
854
|
+
where:
|
855
|
+
slug: module-installed
|
856
|
+
dashboard_id:
|
857
|
+
where:
|
858
|
+
slug: default
|
859
|
+
width: 4
|
860
|
+
height: 14
|
861
|
+
x_axis: 4
|
862
|
+
y_axis: 0
|
863
|
+
- component_id:
|
864
|
+
where:
|
865
|
+
slug: user-summary
|
866
|
+
dashboard_id:
|
867
|
+
where:
|
868
|
+
slug: default
|
869
|
+
width: 4
|
870
|
+
height: 14
|
871
|
+
x_axis: 8
|
872
|
+
y_axis: 0
|
873
|
+
- component_id:
|
874
|
+
where:
|
875
|
+
slug: database-stats
|
876
|
+
dashboard_id:
|
877
|
+
where:
|
878
|
+
slug: default
|
879
|
+
width: 12
|
880
|
+
height: 4
|
881
|
+
x_axis: 0
|
882
|
+
y_axis: 14
|
833
883
|
screens:
|
834
884
|
dashboard:
|
835
885
|
title:
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@hedhog/admin",
|
3
|
-
"version": "0.48.
|
3
|
+
"version": "0.48.17",
|
4
4
|
"private": false,
|
5
5
|
"main": "dist/index.js",
|
6
6
|
"scripts": {
|
@@ -25,7 +25,7 @@
|
|
25
25
|
"license": "MIT",
|
26
26
|
"description": "",
|
27
27
|
"devDependencies": {
|
28
|
-
"@hedhog/locale": "^0.48.
|
28
|
+
"@hedhog/locale": "^0.48.4",
|
29
29
|
"@hedhog/mail": "^0.48.1",
|
30
30
|
"@hedhog/pagination": "^0.46.1",
|
31
31
|
"@hedhog/prisma": "^0.46.1",
|