@hed-hog/core 0.0.185 → 0.0.190
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/hedhog/frontend/app/account/2fa/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/accounts/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +356 -0
- package/hedhog/frontend/app/account/components/change-email-form.tsx.ejs +379 -0
- package/hedhog/frontend/app/account/components/change-password-form.tsx.ejs +184 -0
- package/hedhog/frontend/app/account/components/connected-accounts.tsx.ejs +144 -0
- package/hedhog/frontend/app/account/components/email-request-dialog.tsx.ejs +96 -0
- package/hedhog/frontend/app/account/components/mfa-add-buttons.tsx.ejs +43 -0
- package/hedhog/frontend/app/account/components/mfa-method-card.tsx.ejs +115 -0
- package/hedhog/frontend/app/account/components/mfa-setup-dialog.tsx.ejs +236 -0
- package/hedhog/frontend/app/account/components/profile-form.tsx.ejs +209 -0
- package/hedhog/frontend/app/account/components/recovery-codes-dialog.tsx.ejs +192 -0
- package/hedhog/frontend/app/account/components/regenerate-codes-dialog.tsx.ejs +372 -0
- package/hedhog/frontend/app/account/components/remove-mfa-dialog.tsx.ejs +337 -0
- package/hedhog/frontend/app/account/components/two-factor-auth.tsx.ejs +393 -0
- package/hedhog/frontend/app/account/components/verify-before-add-dialog.tsx.ejs +332 -0
- package/hedhog/frontend/app/account/email/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/hooks/use-mfa-methods.ts.ejs +27 -0
- package/hedhog/frontend/app/account/hooks/use-mfa-setup.ts.ejs +461 -0
- package/hedhog/frontend/app/account/layout.tsx.ejs +105 -0
- package/hedhog/frontend/app/account/lib/mfa-utils.tsx.ejs +37 -0
- package/hedhog/frontend/app/account/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/password/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/profile/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/sessions/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +490 -0
- package/hedhog/frontend/app/configurations/[slug]/page.tsx.ejs +62 -0
- package/hedhog/frontend/app/configurations/layout.tsx.ejs +316 -0
- package/hedhog/frontend/app/configurations/page.tsx.ejs +35 -0
- package/hedhog/frontend/app/dashboard/[slug]/dashboard-content.tsx.ejs +351 -0
- package/hedhog/frontend/app/dashboard/[slug]/page.tsx.ejs +11 -0
- package/hedhog/frontend/app/dashboard/[slug]/types.ts.ejs +62 -0
- package/hedhog/frontend/app/dashboard/[slug]/widget-renderer.tsx.ejs +45 -0
- package/hedhog/frontend/app/dashboard/dashboard.css.ejs +196 -0
- package/hedhog/frontend/app/dashboard/management/page.tsx.ejs +63 -0
- package/hedhog/frontend/app/dashboard/management/tabs/component-roles-tab.tsx.ejs +516 -0
- package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +753 -0
- package/hedhog/frontend/app/dashboard/management/tabs/dashboard-roles-tab.tsx.ejs +516 -0
- package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +489 -0
- package/hedhog/frontend/app/dashboard/management/tabs/items-tab.tsx.ejs +621 -0
- package/hedhog/frontend/app/dashboard/page.tsx.ejs +14 -0
- package/hedhog/frontend/app/mail/log/page.tsx.ejs +312 -0
- package/hedhog/frontend/app/mail/template/page.tsx.ejs +1177 -0
- package/hedhog/frontend/app/preferences/page.tsx.ejs +448 -0
- package/hedhog/frontend/app/roles/menus.tsx.ejs +504 -0
- package/hedhog/frontend/app/roles/page.tsx.ejs +814 -0
- package/hedhog/frontend/app/roles/routes.tsx.ejs +397 -0
- package/hedhog/frontend/app/roles/users.tsx.ejs +306 -0
- package/hedhog/frontend/app/users/active-session.tsx.ejs +159 -0
- package/hedhog/frontend/app/users/identifiers.tsx.ejs +279 -0
- package/hedhog/frontend/app/users/page.tsx.ejs +1257 -0
- package/hedhog/frontend/app/users/permissions.tsx.ejs +155 -0
- package/hedhog/frontend/messages/en.json +1080 -0
- package/hedhog/frontend/messages/pt.json +1135 -0
- package/package.json +4 -4
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useParams } from 'next/navigation';
|
|
4
|
+
import { DashboardContent } from './dashboard-content';
|
|
5
|
+
|
|
6
|
+
export default function DashboardPage() {
|
|
7
|
+
const params = useParams();
|
|
8
|
+
const dashboardSlug = params.slug as string;
|
|
9
|
+
|
|
10
|
+
return <DashboardContent dashboardSlug={dashboardSlug} />;
|
|
11
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export interface WidgetLayout {
|
|
2
|
+
i: string;
|
|
3
|
+
component_id: number;
|
|
4
|
+
slug: string;
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
w: number;
|
|
10
|
+
h: number;
|
|
11
|
+
minW?: number;
|
|
12
|
+
maxW?: number;
|
|
13
|
+
minH?: number;
|
|
14
|
+
maxH?: number;
|
|
15
|
+
isResizable: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface DashboardComponent {
|
|
19
|
+
id: number;
|
|
20
|
+
slug: string;
|
|
21
|
+
path: string;
|
|
22
|
+
min_width: number;
|
|
23
|
+
max_width?: number;
|
|
24
|
+
min_height: number;
|
|
25
|
+
max_height?: number;
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
is_resizable: boolean;
|
|
29
|
+
dashboard_component_locale?: Array<{
|
|
30
|
+
name: string;
|
|
31
|
+
locale: {
|
|
32
|
+
code: string;
|
|
33
|
+
};
|
|
34
|
+
}>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface DashboardAccessResponse {
|
|
38
|
+
hasAccess: boolean;
|
|
39
|
+
dashboard?: {
|
|
40
|
+
id: number;
|
|
41
|
+
slug: string;
|
|
42
|
+
name: string;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface LayoutItem {
|
|
47
|
+
i: string;
|
|
48
|
+
x: number;
|
|
49
|
+
y: number;
|
|
50
|
+
w: number;
|
|
51
|
+
h: number;
|
|
52
|
+
minW: number;
|
|
53
|
+
maxW: number;
|
|
54
|
+
minH: number;
|
|
55
|
+
maxH: number;
|
|
56
|
+
static: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface WidgetRendererProps {
|
|
60
|
+
widget: WidgetLayout;
|
|
61
|
+
onRemove: () => void;
|
|
62
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { DynamicWidget } from '@/components/dashboard';
|
|
4
|
+
import { Skeleton } from '@/components/ui/skeleton';
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
import { WidgetRendererProps } from './types';
|
|
7
|
+
|
|
8
|
+
export const WidgetRenderer = ({ widget, onRemove }: WidgetRendererProps) => {
|
|
9
|
+
const [Component, setComponent] = useState<any>(null);
|
|
10
|
+
const [useFallback, setUseFallback] = useState(false);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
import(`@/components/dashboard/widgets/${widget.slug}`)
|
|
14
|
+
.then((mod) => {
|
|
15
|
+
setComponent(() => mod.default);
|
|
16
|
+
})
|
|
17
|
+
.catch((error) => {
|
|
18
|
+
console.warn(
|
|
19
|
+
`Widget component not found for slug: ${widget.slug}`,
|
|
20
|
+
error
|
|
21
|
+
);
|
|
22
|
+
setUseFallback(true);
|
|
23
|
+
});
|
|
24
|
+
}, [widget.slug]);
|
|
25
|
+
|
|
26
|
+
if (useFallback) {
|
|
27
|
+
return (
|
|
28
|
+
<DynamicWidget
|
|
29
|
+
title={widget.name}
|
|
30
|
+
value={0}
|
|
31
|
+
description={widget.description || ''}
|
|
32
|
+
iconName="settings"
|
|
33
|
+
color="#000000"
|
|
34
|
+
draggable
|
|
35
|
+
onRemove={onRemove}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!Component) {
|
|
41
|
+
return <Skeleton className="h-full w-full" />;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return <Component widget={widget} onRemove={onRemove} />;
|
|
45
|
+
};
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
.react-grid-layout {
|
|
2
|
+
position: relative;
|
|
3
|
+
transition: height 200ms ease;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.react-grid-item {
|
|
7
|
+
transition: all 200ms ease;
|
|
8
|
+
transition-property: left, top, width, height;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.react-grid-item img {
|
|
12
|
+
pointer-events: none;
|
|
13
|
+
user-select: none;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.react-grid-item > .react-resizable-handle {
|
|
17
|
+
position: absolute;
|
|
18
|
+
width: 30px;
|
|
19
|
+
height: 30px;
|
|
20
|
+
z-index: 10;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.react-grid-item > .react-resizable-handle::after {
|
|
24
|
+
content: '';
|
|
25
|
+
position: absolute;
|
|
26
|
+
width: 12px;
|
|
27
|
+
height: 12px;
|
|
28
|
+
background-color: hsl(var(--primary));
|
|
29
|
+
border: 2px solid white;
|
|
30
|
+
border-radius: 2px;
|
|
31
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
32
|
+
opacity: 0.3;
|
|
33
|
+
transition:
|
|
34
|
+
opacity 0.2s ease,
|
|
35
|
+
transform 0.2s ease;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.react-grid-item:hover > .react-resizable-handle::after {
|
|
39
|
+
opacity: 1;
|
|
40
|
+
transform: scale(1.2);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.react-resizable-hide > .react-resizable-handle {
|
|
44
|
+
display: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-sw {
|
|
48
|
+
bottom: 0;
|
|
49
|
+
left: 0;
|
|
50
|
+
cursor: sw-resize;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-sw::after {
|
|
54
|
+
left: 2px;
|
|
55
|
+
bottom: 2px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-se {
|
|
59
|
+
bottom: 0;
|
|
60
|
+
right: 0;
|
|
61
|
+
cursor: se-resize;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-se::after {
|
|
65
|
+
right: 2px;
|
|
66
|
+
bottom: 2px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-nw {
|
|
70
|
+
top: 0;
|
|
71
|
+
left: 0;
|
|
72
|
+
cursor: nw-resize;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-nw::after {
|
|
76
|
+
left: 2px;
|
|
77
|
+
top: 2px;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-ne {
|
|
81
|
+
top: 0;
|
|
82
|
+
right: 0;
|
|
83
|
+
cursor: ne-resize;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-ne::after {
|
|
87
|
+
right: 2px;
|
|
88
|
+
top: 2px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-w {
|
|
92
|
+
left: 0;
|
|
93
|
+
top: 50%;
|
|
94
|
+
transform: translateY(-50%);
|
|
95
|
+
cursor: ew-resize;
|
|
96
|
+
width: 20px;
|
|
97
|
+
height: 60px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-w::after {
|
|
101
|
+
left: 2px;
|
|
102
|
+
top: 50%;
|
|
103
|
+
transform: translateY(-50%);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-e {
|
|
107
|
+
right: 0;
|
|
108
|
+
top: 50%;
|
|
109
|
+
transform: translateY(-50%);
|
|
110
|
+
cursor: ew-resize;
|
|
111
|
+
width: 20px;
|
|
112
|
+
height: 60px;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-e::after {
|
|
116
|
+
right: 2px;
|
|
117
|
+
top: 50%;
|
|
118
|
+
transform: translateY(-50%);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-n {
|
|
122
|
+
top: 0;
|
|
123
|
+
left: 50%;
|
|
124
|
+
transform: translateX(-50%);
|
|
125
|
+
cursor: ns-resize;
|
|
126
|
+
width: 60px;
|
|
127
|
+
height: 20px;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-n::after {
|
|
131
|
+
top: 2px;
|
|
132
|
+
left: 50%;
|
|
133
|
+
transform: translateX(-50%);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-s {
|
|
137
|
+
bottom: 0;
|
|
138
|
+
left: 50%;
|
|
139
|
+
transform: translateX(-50%);
|
|
140
|
+
cursor: ns-resize;
|
|
141
|
+
width: 60px;
|
|
142
|
+
height: 20px;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.react-grid-item > .react-resizable-handle.react-resizable-handle-s::after {
|
|
146
|
+
bottom: 2px;
|
|
147
|
+
left: 50%;
|
|
148
|
+
transform: translateX(-50%);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Drag handle styles */
|
|
152
|
+
.drag-handle {
|
|
153
|
+
cursor: grab !important;
|
|
154
|
+
user-select: none !important;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.drag-handle:active {
|
|
158
|
+
cursor: grabbing !important;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Prevent text selection during drag */
|
|
162
|
+
.react-grid-item.react-draggable-dragging {
|
|
163
|
+
transition: none;
|
|
164
|
+
z-index: 100;
|
|
165
|
+
will-change: transform;
|
|
166
|
+
opacity: 0.9;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.react-grid-item.resizing {
|
|
170
|
+
transition: none;
|
|
171
|
+
z-index: 100;
|
|
172
|
+
will-change: transform;
|
|
173
|
+
opacity: 0.9;
|
|
174
|
+
outline: 2px solid hsl(var(--primary));
|
|
175
|
+
outline-offset: 2px;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* Placeholder styling */
|
|
179
|
+
.react-grid-placeholder {
|
|
180
|
+
background: hsl(var(--primary) / 0.2);
|
|
181
|
+
opacity: 0.5;
|
|
182
|
+
transition-duration: 100ms;
|
|
183
|
+
z-index: 2;
|
|
184
|
+
border-radius: 0.5rem;
|
|
185
|
+
border: 2px dashed hsl(var(--primary));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.react-grid-item:hover {
|
|
189
|
+
outline: 1px solid hsl(var(--primary) / 0.2);
|
|
190
|
+
outline-offset: -1px;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.react-grid-item:hover > .react-resizable-handle::after {
|
|
194
|
+
opacity: 1;
|
|
195
|
+
transform: scale(1.1);
|
|
196
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { PageHeader } from '@/components/entity-list';
|
|
4
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|
5
|
+
import { useTranslations } from 'next-intl';
|
|
6
|
+
import { ComponentRolesTab } from './tabs/component-roles-tab';
|
|
7
|
+
import { ComponentsTab } from './tabs/components-tab';
|
|
8
|
+
import { DashboardRolesTab } from './tabs/dashboard-roles-tab';
|
|
9
|
+
import { DashboardsTab } from './tabs/dashboards-tab';
|
|
10
|
+
import { ItemsTab } from './tabs/items-tab';
|
|
11
|
+
|
|
12
|
+
export default function Page() {
|
|
13
|
+
const t = useTranslations('core.DashboardManagement');
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div className="flex flex-col h-screen px-4">
|
|
17
|
+
<PageHeader
|
|
18
|
+
breadcrumbs={[
|
|
19
|
+
{ label: 'Home', href: '/' },
|
|
20
|
+
{ label: t('description') },
|
|
21
|
+
]}
|
|
22
|
+
title={t('title')}
|
|
23
|
+
description={t('description')}
|
|
24
|
+
/>
|
|
25
|
+
|
|
26
|
+
<div className="flex flex-1 flex-col gap-4 overflow-auto pt-0">
|
|
27
|
+
<Tabs defaultValue="dashboards" className="w-full">
|
|
28
|
+
<TabsList className="grid w-full grid-cols-5">
|
|
29
|
+
<TabsTrigger value="dashboards">{t('dashboardsTab')}</TabsTrigger>
|
|
30
|
+
<TabsTrigger value="components">{t('componentsTab')}</TabsTrigger>
|
|
31
|
+
<TabsTrigger value="items">{t('itemsTab')}</TabsTrigger>
|
|
32
|
+
<TabsTrigger value="componentRoles">
|
|
33
|
+
{t('componentRolesTab')}
|
|
34
|
+
</TabsTrigger>
|
|
35
|
+
<TabsTrigger value="dashboardRoles">
|
|
36
|
+
{t('dashboardRolesTab')}
|
|
37
|
+
</TabsTrigger>
|
|
38
|
+
</TabsList>
|
|
39
|
+
|
|
40
|
+
<TabsContent value="dashboards" className="mt-6">
|
|
41
|
+
<DashboardsTab />
|
|
42
|
+
</TabsContent>
|
|
43
|
+
|
|
44
|
+
<TabsContent value="components" className="mt-6">
|
|
45
|
+
<ComponentsTab />
|
|
46
|
+
</TabsContent>
|
|
47
|
+
|
|
48
|
+
<TabsContent value="items" className="mt-6">
|
|
49
|
+
<ItemsTab />
|
|
50
|
+
</TabsContent>
|
|
51
|
+
|
|
52
|
+
<TabsContent value="componentRoles" className="mt-6">
|
|
53
|
+
<ComponentRolesTab />
|
|
54
|
+
</TabsContent>
|
|
55
|
+
|
|
56
|
+
<TabsContent value="dashboardRoles" className="mt-6">
|
|
57
|
+
<DashboardRolesTab />
|
|
58
|
+
</TabsContent>
|
|
59
|
+
</Tabs>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|