@hed-hog/core 0.0.278 → 0.0.279

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.
Files changed (36) hide show
  1. package/README.md +60 -0
  2. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +12 -0
  3. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts.map +1 -1
  4. package/dist/dashboard/dashboard-core/dashboard-core.controller.js +9 -0
  5. package/dist/dashboard/dashboard-core/dashboard-core.controller.js.map +1 -1
  6. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +12 -0
  7. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts.map +1 -1
  8. package/dist/dashboard/dashboard-core/dashboard-core.service.js +25 -0
  9. package/dist/dashboard/dashboard-core/dashboard-core.service.js.map +1 -1
  10. package/hedhog/data/dashboard_component.yaml +95 -77
  11. package/hedhog/data/dashboard_component_role.yaml +91 -79
  12. package/hedhog/data/dashboard_item.yaml +121 -101
  13. package/hedhog/data/route.yaml +8 -0
  14. package/hedhog/frontend/app/ai_agent/page.tsx.ejs +17 -17
  15. package/hedhog/frontend/app/dashboard/[slug]/dashboard-content.tsx.ejs +23 -12
  16. package/hedhog/frontend/app/dashboard/components/draggable-grid.tsx.ejs +80 -5
  17. package/hedhog/frontend/app/dashboard/components/widgets/account-security.tsx.ejs +33 -29
  18. package/hedhog/frontend/app/dashboard/components/widgets/activity-timeline.tsx.ejs +18 -14
  19. package/hedhog/frontend/app/dashboard/components/widgets/email-notifications.tsx.ejs +39 -32
  20. package/hedhog/frontend/app/dashboard/components/widgets/login-history-chart.tsx.ejs +22 -19
  21. package/hedhog/frontend/app/dashboard/components/widgets/menus-card.tsx.ejs +58 -0
  22. package/hedhog/frontend/app/dashboard/components/widgets/routes-card.tsx.ejs +58 -0
  23. package/hedhog/frontend/app/dashboard/components/widgets/stat-access-level.tsx.ejs +18 -18
  24. package/hedhog/frontend/app/dashboard/components/widgets/stat-actions-today.tsx.ejs +18 -18
  25. package/hedhog/frontend/app/dashboard/components/widgets/stat-consecutive-days.tsx.ejs +18 -18
  26. package/hedhog/frontend/app/dashboard/components/widgets/stat-online-time.tsx.ejs +18 -18
  27. package/hedhog/frontend/app/dashboard/components/widgets/user-roles.tsx.ejs +15 -11
  28. package/hedhog/frontend/app/dashboard/components/widgets/user-sessions.tsx.ejs +39 -37
  29. package/hedhog/frontend/app/dashboard/dashboard.css.ejs +20 -4
  30. package/hedhog/frontend/app/mail/log/page.tsx.ejs +5 -11
  31. package/hedhog/frontend/app/users/page.tsx.ejs +9 -9
  32. package/hedhog/frontend/messages/en.json +10 -2
  33. package/hedhog/frontend/messages/pt.json +10 -2
  34. package/package.json +3 -3
  35. package/src/dashboard/dashboard-core/dashboard-core.controller.ts +5 -0
  36. package/src/dashboard/dashboard-core/dashboard-core.service.ts +34 -0
@@ -1,51 +1,63 @@
1
- - component_id:
2
- where:
3
- slug: active-users-card
4
- role_id:
5
- where:
6
- slug: admin-access
7
- - component_id:
8
- where:
9
- slug: mail-sent-card
10
- role_id:
11
- where:
12
- slug: admin-access
13
- - component_id:
14
- where:
15
- slug: mail-sent-chart
16
- role_id:
17
- where:
18
- slug: admin-access
19
- - component_id:
20
- where:
21
- slug: permissions-card
22
- role_id:
23
- where:
24
- slug: admin-access
25
- - component_id:
26
- where:
27
- slug: permissions-chart
28
- role_id:
29
- where:
30
- slug: admin-access
31
- - component_id:
32
- where:
33
- slug: session-activity-chart
34
- role_id:
35
- where:
36
- slug: admin-access
37
- - component_id:
38
- where:
39
- slug: sessions-today-card
40
- role_id:
41
- where:
42
- slug: admin-access
43
- - component_id:
44
- where:
45
- slug: user-growth-chart
46
- role_id:
47
- where:
48
- slug: admin-access
1
+ - component_id:
2
+ where:
3
+ slug: active-users-card
4
+ role_id:
5
+ where:
6
+ slug: admin-access
7
+ - component_id:
8
+ where:
9
+ slug: mail-sent-card
10
+ role_id:
11
+ where:
12
+ slug: admin-access
13
+ - component_id:
14
+ where:
15
+ slug: mail-sent-chart
16
+ role_id:
17
+ where:
18
+ slug: admin-access
19
+ - component_id:
20
+ where:
21
+ slug: permissions-card
22
+ role_id:
23
+ where:
24
+ slug: admin-access
25
+ - component_id:
26
+ where:
27
+ slug: permissions-chart
28
+ role_id:
29
+ where:
30
+ slug: admin-access
31
+ - component_id:
32
+ where:
33
+ slug: session-activity-chart
34
+ role_id:
35
+ where:
36
+ slug: admin-access
37
+ - component_id:
38
+ where:
39
+ slug: sessions-today-card
40
+ role_id:
41
+ where:
42
+ slug: admin-access
43
+ - component_id:
44
+ where:
45
+ slug: menus-card
46
+ role_id:
47
+ where:
48
+ slug: admin-access
49
+ - component_id:
50
+ where:
51
+ slug: routes-card
52
+ role_id:
53
+ where:
54
+ slug: admin-access
55
+ - component_id:
56
+ where:
57
+ slug: user-growth-chart
58
+ role_id:
59
+ where:
60
+ slug: admin-access
49
61
  - component_id:
50
62
  where:
51
63
  slug: account-security
@@ -178,34 +190,34 @@
178
190
  role_id:
179
191
  where:
180
192
  slug: admin-access
181
-
182
- - component_id:
183
- where:
184
- slug: mail-config
185
- role_id:
186
- where:
187
- slug: admin
188
- - component_id:
189
- where:
190
- slug: locale-config
191
- role_id:
192
- where:
193
- slug: admin
194
- - component_id:
195
- where:
196
- slug: oauth-config
197
- role_id:
198
- where:
199
- slug: admin
200
- - component_id:
201
- where:
202
- slug: storage-config
203
- role_id:
204
- where:
205
- slug: admin
206
- - component_id:
207
- where:
208
- slug: theme-config
209
- role_id:
210
- where:
211
- slug: admin
193
+
194
+ - component_id:
195
+ where:
196
+ slug: mail-config
197
+ role_id:
198
+ where:
199
+ slug: admin
200
+ - component_id:
201
+ where:
202
+ slug: locale-config
203
+ role_id:
204
+ where:
205
+ slug: admin
206
+ - component_id:
207
+ where:
208
+ slug: oauth-config
209
+ role_id:
210
+ where:
211
+ slug: admin
212
+ - component_id:
213
+ where:
214
+ slug: storage-config
215
+ role_id:
216
+ where:
217
+ slug: admin
218
+ - component_id:
219
+ where:
220
+ slug: theme-config
221
+ role_id:
222
+ where:
223
+ slug: admin
@@ -68,6 +68,26 @@
68
68
  height: 2
69
69
  x_axis: 2
70
70
  y_axis: 0
71
+ - component_id:
72
+ where:
73
+ slug: menus-card
74
+ dashboard_id:
75
+ where:
76
+ slug: default
77
+ width: 2
78
+ height: 2
79
+ x_axis: 8
80
+ y_axis: 0
81
+ - component_id:
82
+ where:
83
+ slug: routes-card
84
+ dashboard_id:
85
+ where:
86
+ slug: default
87
+ width: 2
88
+ height: 2
89
+ x_axis: 10
90
+ y_axis: 0
71
91
  - component_id:
72
92
  where:
73
93
  slug: user-growth-chart
@@ -86,109 +106,109 @@
86
106
  where:
87
107
  slug: user
88
108
  width: 12
89
- height: 2
109
+ height: 3
90
110
  x_axis: 0
91
111
  y_axis: 0
92
- - component_id:
93
- where:
94
- slug: stat-online-time
95
- dashboard_id:
96
- where:
97
- slug: user
98
- width: 3
99
- height: 1
100
- x_axis: 0
101
- y_axis: 2
102
- - component_id:
103
- where:
104
- slug: stat-actions-today
105
- dashboard_id:
106
- where:
107
- slug: user
108
- width: 3
109
- height: 1
110
- x_axis: 3
111
- y_axis: 2
112
- - component_id:
113
- where:
114
- slug: stat-consecutive-days
115
- dashboard_id:
116
- where:
117
- slug: user
118
- width: 3
119
- height: 1
120
- x_axis: 6
121
- y_axis: 2
122
- - component_id:
123
- where:
124
- slug: stat-access-level
125
- dashboard_id:
126
- where:
127
- slug: user
128
- width: 3
129
- height: 1
130
- x_axis: 9
131
- y_axis: 2
132
- - component_id:
133
- where:
134
- slug: account-security
135
- dashboard_id:
136
- where:
137
- slug: user
138
- width: 5
139
- height: 5
140
- x_axis: 0
141
- y_axis: 7
142
- - component_id:
143
- where:
144
- slug: login-history-chart
145
- dashboard_id:
146
- where:
147
- slug: user
148
- width: 7
149
- height: 4
150
- x_axis: 0
151
- y_axis: 3
152
- - component_id:
153
- where:
154
- slug: email-notifications
155
- dashboard_id:
156
- where:
157
- slug: user
158
- width: 7
159
- height: 5
160
- x_axis: 5
161
- y_axis: 7
162
- - component_id:
163
- where:
164
- slug: activity-timeline
165
- dashboard_id:
166
- where:
167
- slug: user
168
- width: 5
169
- height: 3
170
- x_axis: 7
171
- y_axis: 12
172
- - component_id:
173
- where:
174
- slug: user-sessions
175
- dashboard_id:
176
- where:
177
- slug: user
178
- width: 5
179
- height: 4
180
- x_axis: 7
181
- y_axis: 3
182
- - component_id:
183
- where:
184
- slug: user-roles
185
- dashboard_id:
186
- where:
187
- slug: user
188
- width: 7
189
- height: 3
190
- x_axis: 0
191
- y_axis: 12
112
+ - component_id:
113
+ where:
114
+ slug: stat-online-time
115
+ dashboard_id:
116
+ where:
117
+ slug: user
118
+ width: 3
119
+ height: 1
120
+ x_axis: 0
121
+ y_axis: 3
122
+ - component_id:
123
+ where:
124
+ slug: stat-actions-today
125
+ dashboard_id:
126
+ where:
127
+ slug: user
128
+ width: 3
129
+ height: 1
130
+ x_axis: 3
131
+ y_axis: 3
132
+ - component_id:
133
+ where:
134
+ slug: stat-consecutive-days
135
+ dashboard_id:
136
+ where:
137
+ slug: user
138
+ width: 3
139
+ height: 1
140
+ x_axis: 6
141
+ y_axis: 3
142
+ - component_id:
143
+ where:
144
+ slug: stat-access-level
145
+ dashboard_id:
146
+ where:
147
+ slug: user
148
+ width: 3
149
+ height: 1
150
+ x_axis: 9
151
+ y_axis: 3
152
+ - component_id:
153
+ where:
154
+ slug: account-security
155
+ dashboard_id:
156
+ where:
157
+ slug: user
158
+ width: 5
159
+ height: 5
160
+ x_axis: 0
161
+ y_axis: 7
162
+ - component_id:
163
+ where:
164
+ slug: login-history-chart
165
+ dashboard_id:
166
+ where:
167
+ slug: user
168
+ width: 7
169
+ height: 4
170
+ x_axis: 0
171
+ y_axis: 3
172
+ - component_id:
173
+ where:
174
+ slug: email-notifications
175
+ dashboard_id:
176
+ where:
177
+ slug: user
178
+ width: 7
179
+ height: 5
180
+ x_axis: 5
181
+ y_axis: 7
182
+ - component_id:
183
+ where:
184
+ slug: activity-timeline
185
+ dashboard_id:
186
+ where:
187
+ slug: user
188
+ width: 5
189
+ height: 3
190
+ x_axis: 7
191
+ y_axis: 13
192
+ - component_id:
193
+ where:
194
+ slug: user-sessions
195
+ dashboard_id:
196
+ where:
197
+ slug: user
198
+ width: 5
199
+ height: 4
200
+ x_axis: 7
201
+ y_axis: 4
202
+ - component_id:
203
+ where:
204
+ slug: user-roles
205
+ dashboard_id:
206
+ where:
207
+ slug: user
208
+ width: 7
209
+ height: 3
210
+ x_axis: 0
211
+ y_axis: 13
192
212
 
193
213
  - component_id:
194
214
  where:
@@ -716,6 +716,14 @@
716
716
  role:
717
717
  - where:
718
718
  slug: admin-mail
719
+ - url: /dashboard-core/stats/overview/system
720
+ method: GET
721
+ relations:
722
+ role:
723
+ - where:
724
+ slug: admin
725
+ - where:
726
+ slug: admin-access
719
727
  - url: /dashboard-core/layout/:slug
720
728
  method: GET
721
729
  relations:
@@ -115,7 +115,7 @@ export default function AiAgentPage() {
115
115
  },
116
116
  });
117
117
 
118
- const { data, isLoading, refetch } = useQuery<PaginatedResponse<Agent>>({
118
+ const { data, isLoading, refetch } = useQuery<PaginatedResponse<Agent>>({
119
119
  queryKey: ['ai-agents', page, pageSize, debouncedSearch],
120
120
  queryFn: async () => {
121
121
  const params = new URLSearchParams();
@@ -130,14 +130,14 @@ export default function AiAgentPage() {
130
130
 
131
131
  return response.data;
132
132
  },
133
- initialData: {
134
- data: [],
135
- total: 0,
136
- page: 1,
137
- pageSize: 10,
138
- totalPages: 1,
139
- },
140
- });
133
+ });
134
+ const agentList = data ?? {
135
+ data: [],
136
+ total: 0,
137
+ page: 1,
138
+ pageSize: 10,
139
+ totalPages: 1,
140
+ };
141
141
 
142
142
  useEffect(() => {
143
143
  if (editingAgent) {
@@ -280,12 +280,12 @@ export default function AiAgentPage() {
280
280
  <TableRow>
281
281
  <TableCell colSpan={5}>{t('loading')}</TableCell>
282
282
  </TableRow>
283
- ) : data.data.length === 0 ? (
284
- <TableRow>
285
- <TableCell colSpan={5}>{t('empty')}</TableCell>
286
- </TableRow>
287
- ) : (
288
- data.data.map((agent) => (
283
+ ) : agentList.data.length === 0 ? (
284
+ <TableRow>
285
+ <TableCell colSpan={5}>{t('empty')}</TableCell>
286
+ </TableRow>
287
+ ) : (
288
+ agentList.data.map((agent) => (
289
289
  <TableRow key={agent.id}>
290
290
  <TableCell>{agent.slug}</TableCell>
291
291
  <TableCell className="uppercase">
@@ -322,8 +322,8 @@ export default function AiAgentPage() {
322
322
  <PaginationFooter
323
323
  currentPage={page}
324
324
  pageSize={pageSize}
325
- totalItems={data.total}
326
- onPageChange={setPage}
325
+ totalItems={agentList.total}
326
+ onPageChange={setPage}
327
327
  onPageSizeChange={(value) => {
328
328
  setPageSize(value);
329
329
  setPage(1);
@@ -12,6 +12,7 @@ import { Button } from '@/components/ui/button';
12
12
  import { Separator } from '@/components/ui/separator';
13
13
  import { SidebarTrigger } from '@/components/ui/sidebar';
14
14
  import { Skeleton } from '@/components/ui/skeleton';
15
+ import { useIsMobile } from '@/components/ui/use-mobile';
15
16
  import { useApp, useQuery } from '@hed-hog/next-app-provider';
16
17
  import { IconDeviceFloppy } from '@tabler/icons-react';
17
18
  import { useTranslations } from 'next-intl';
@@ -38,6 +39,7 @@ export const DashboardContent = ({ dashboardSlug }: DashboardContentProps) => {
38
39
  const t = useTranslations('core.DashboardPage');
39
40
  const { request } = useApp();
40
41
  const router = useRouter();
42
+ const isMobile = useIsMobile();
41
43
 
42
44
  const [layout, setLayout] = useState<LayoutItem[]>([]);
43
45
  const [widgets, setWidgets] = useState<WidgetLayout[]>([]);
@@ -106,7 +108,10 @@ export const DashboardContent = ({ dashboardSlug }: DashboardContentProps) => {
106
108
  x: item.x,
107
109
  y: item.y,
108
110
  w: item.w,
109
- h: item.h,
111
+ h:
112
+ dashboardSlug === 'user' && item.slug === 'profile-card'
113
+ ? Math.max(item.h, 3)
114
+ : item.h,
110
115
  minW: item.minW || 1,
111
116
  maxW: item.maxW || 12,
112
117
  minH: item.minH || 1,
@@ -277,37 +282,42 @@ export const DashboardContent = ({ dashboardSlug }: DashboardContentProps) => {
277
282
 
278
283
  return (
279
284
  <>
280
- <header className="flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12">
281
- <div className="flex w-full items-center justify-between gap-2 px-4">
282
- <div className="flex items-center gap-2">
285
+ <header className="flex min-h-16 shrink-0 items-center gap-2 py-2 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 sm:h-16 sm:py-0">
286
+ <div className="flex w-full flex-col gap-2 px-4 sm:flex-row sm:items-center sm:justify-between">
287
+ <div className="flex min-w-0 items-center gap-2">
283
288
  <SidebarTrigger className="-ml-1" />
284
289
  <Separator
285
290
  orientation="vertical"
286
291
  className="mr-2 data-[orientation=vertical]:h-4"
287
292
  />
288
- <Breadcrumb>
293
+ <Breadcrumb className="min-w-0">
289
294
  <BreadcrumbList>
290
295
  <BreadcrumbItem className="hidden md:block">
291
296
  <BreadcrumbLink href="#">{t('dashboard')}</BreadcrumbLink>
292
297
  </BreadcrumbItem>
293
298
  <BreadcrumbSeparator className="hidden md:block" />
294
299
  <BreadcrumbItem>
295
- <BreadcrumbPage>{dashboardName}</BreadcrumbPage>
300
+ <BreadcrumbPage className="truncate">
301
+ {dashboardName}
302
+ </BreadcrumbPage>
296
303
  </BreadcrumbItem>
297
304
  </BreadcrumbList>
298
305
  </Breadcrumb>
299
306
  </div>
300
- <div className="flex items-center gap-2">
307
+ <div className="flex w-full items-center justify-end gap-2 sm:w-auto">
301
308
  {hasChanges && (
302
309
  <Button
303
310
  size="sm"
304
311
  variant="default"
305
- className="gap-2"
312
+ className="gap-1 px-2 sm:gap-2 sm:px-3"
306
313
  onClick={handleSaveLayout}
307
314
  disabled={isSaving}
315
+ aria-label={isSaving ? t('saving') : t('saveLayout')}
308
316
  >
309
317
  <IconDeviceFloppy className="size-4" />
310
- {isSaving ? t('saving') : t('saveLayout')}
318
+ <span className="hidden sm:inline">
319
+ {isSaving ? t('saving') : t('saveLayout')}
320
+ </span>
311
321
  </Button>
312
322
  )}
313
323
  <AddWidgetSelectorDialog
@@ -321,15 +331,16 @@ export const DashboardContent = ({ dashboardSlug }: DashboardContentProps) => {
321
331
  </header>
322
332
  <div className="flex flex-1 flex-col gap-4 overflow-auto p-4 pt-0">
323
333
  {widgets.length > 0 ? (
324
- <div className="min-h-[600px]">
334
+ <div className="min-h-[420px] sm:min-h-[520px] lg:min-h-[600px]">
325
335
  <DraggableGrid
326
336
  className="dashboard-grid"
327
337
  layout={layout}
328
338
  onLayoutChange={handleLayoutChange}
329
339
  cols={12}
330
340
  rowHeight={80}
331
- isDraggable={true}
332
- isResizable={true}
341
+ preventCollision
342
+ isDraggable={!isMobile}
343
+ isResizable={!isMobile}
333
344
  resizeHandles={['se']}
334
345
  >
335
346
  {widgets.map((widget) => (