@hed-hog/core 0.0.279 → 0.0.285
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/dist/auth/auth.controller.d.ts +3 -3
- package/dist/auth/auth.service.d.ts +8 -8
- package/dist/file/file.controller.d.ts +2 -2
- package/dist/file/file.service.d.ts +4 -4
- package/dist/role/guards/role.guard.d.ts.map +1 -1
- package/dist/role/guards/role.guard.js +1 -1
- package/dist/role/guards/role.guard.js.map +1 -1
- package/dist/session/session.controller.d.ts +1 -1
- package/dist/session/session.service.d.ts +3 -3
- package/dist/user/user.controller.d.ts +2 -2
- package/dist/user/user.service.d.ts +6 -6
- package/hedhog/frontend/app/ai_agent/page.tsx.ejs +72 -65
- package/hedhog/frontend/app/mail/log/page.tsx.ejs +37 -42
- package/hedhog/frontend/app/mail/template/page.tsx.ejs +176 -126
- package/hedhog/frontend/app/menu/page.tsx.ejs +45 -39
- package/hedhog/frontend/app/roles/page.tsx.ejs +45 -46
- package/hedhog/frontend/app/users/page.tsx.ejs +61 -64
- package/hedhog/frontend/messages/en.json +5 -0
- package/hedhog/frontend/messages/pt.json +5 -0
- package/package.json +3 -3
- package/src/role/guards/role.guard.ts +9 -8
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import type React from 'react';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
EmptyState,
|
|
7
|
+
Page,
|
|
8
|
+
PageHeader,
|
|
9
|
+
PaginationFooter,
|
|
10
|
+
SearchBar,
|
|
11
|
+
} from '@/components/entity-list';
|
|
6
12
|
import { RichTextEditor } from '@/components/rich-text-editor';
|
|
7
13
|
import {
|
|
8
14
|
AlertDialog,
|
|
@@ -33,6 +39,13 @@ import {
|
|
|
33
39
|
SelectTrigger,
|
|
34
40
|
SelectValue,
|
|
35
41
|
} from '@/components/ui/select';
|
|
42
|
+
import {
|
|
43
|
+
Sheet,
|
|
44
|
+
SheetContent,
|
|
45
|
+
SheetDescription,
|
|
46
|
+
SheetHeader,
|
|
47
|
+
SheetTitle,
|
|
48
|
+
} from '@/components/ui/sheet';
|
|
36
49
|
import {
|
|
37
50
|
Table,
|
|
38
51
|
TableBody,
|
|
@@ -82,7 +95,17 @@ interface ImportResponse {
|
|
|
82
95
|
export default function EmailTemplatesPage() {
|
|
83
96
|
const { locales, request, currentLocaleCode, getSettingValue } = useApp();
|
|
84
97
|
const t = useTranslations('core.MailPage');
|
|
85
|
-
const {
|
|
98
|
+
const {
|
|
99
|
+
items,
|
|
100
|
+
refetch,
|
|
101
|
+
page,
|
|
102
|
+
setPage,
|
|
103
|
+
pageSize,
|
|
104
|
+
setPageSize,
|
|
105
|
+
totalItems,
|
|
106
|
+
search,
|
|
107
|
+
setSearch,
|
|
108
|
+
} = usePagination({ url: '/mail' });
|
|
86
109
|
const [templates, setTemplates] = useState<Mail[]>([]);
|
|
87
110
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
88
111
|
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
|
|
@@ -689,7 +712,7 @@ export default function EmailTemplatesPage() {
|
|
|
689
712
|
};
|
|
690
713
|
|
|
691
714
|
return (
|
|
692
|
-
<
|
|
715
|
+
<Page>
|
|
693
716
|
<PageHeader
|
|
694
717
|
breadcrumbs={[
|
|
695
718
|
{ label: t('breadcrumbHome'), href: '/' },
|
|
@@ -720,118 +743,154 @@ export default function EmailTemplatesPage() {
|
|
|
720
743
|
description={t('description')}
|
|
721
744
|
/>
|
|
722
745
|
|
|
723
|
-
<
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
<
|
|
743
|
-
|
|
744
|
-
<
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
<
|
|
765
|
-
{template.
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
{
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
</
|
|
796
|
-
<
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
>
|
|
804
|
-
<
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
746
|
+
<SearchBar
|
|
747
|
+
searchQuery={search}
|
|
748
|
+
onSearchChange={(value) => {
|
|
749
|
+
setSearch(value);
|
|
750
|
+
setPage(1);
|
|
751
|
+
}}
|
|
752
|
+
onSearch={() => setPage(1)}
|
|
753
|
+
placeholder={t('searchPlaceholder')}
|
|
754
|
+
/>
|
|
755
|
+
|
|
756
|
+
{templates.length === 0 ? (
|
|
757
|
+
<EmptyState
|
|
758
|
+
icon={<MailIcon className="h-12 w-12" />}
|
|
759
|
+
title={t('noTemplatesFound')}
|
|
760
|
+
description={t('noTemplatesHint')}
|
|
761
|
+
actionLabel={t('newTemplate')}
|
|
762
|
+
onAction={handleCreate}
|
|
763
|
+
/>
|
|
764
|
+
) : (
|
|
765
|
+
<div className="rounded-md border">
|
|
766
|
+
<Table>
|
|
767
|
+
<TableHeader>
|
|
768
|
+
<TableRow>
|
|
769
|
+
<TableHead className="w-12">
|
|
770
|
+
<Checkbox
|
|
771
|
+
checked={
|
|
772
|
+
selectedTemplates.size === templates.length &&
|
|
773
|
+
templates.length > 0
|
|
774
|
+
}
|
|
775
|
+
onCheckedChange={handleToggleAll}
|
|
776
|
+
/>
|
|
777
|
+
</TableHead>
|
|
778
|
+
<TableHead>{t('tableSlug')}</TableHead>
|
|
779
|
+
<TableHead>{t('tableSubject')}</TableHead>
|
|
780
|
+
<TableHead>{t('tableVariables')}</TableHead>
|
|
781
|
+
<TableHead>{t('tableUpdated')}</TableHead>
|
|
782
|
+
<TableHead className="text-right">{t('tableActions')}</TableHead>
|
|
783
|
+
</TableRow>
|
|
784
|
+
</TableHeader>
|
|
785
|
+
<TableBody>
|
|
786
|
+
{templates.map((template) => (
|
|
787
|
+
<TableRow
|
|
788
|
+
key={template.id}
|
|
789
|
+
onDoubleClick={() => handleEdit(template)}
|
|
790
|
+
className="cursor-pointer"
|
|
791
|
+
>
|
|
792
|
+
<TableCell onClick={(e) => e.stopPropagation()}>
|
|
793
|
+
<Checkbox
|
|
794
|
+
checked={selectedTemplates.has(
|
|
795
|
+
template.mail_id || template.id
|
|
796
|
+
)}
|
|
797
|
+
onCheckedChange={() =>
|
|
798
|
+
handleToggleTemplate(template.mail_id || template.id)
|
|
799
|
+
}
|
|
800
|
+
/>
|
|
801
|
+
</TableCell>
|
|
802
|
+
<TableCell className="font-mono text-sm">
|
|
803
|
+
{template.slug}
|
|
804
|
+
</TableCell>
|
|
805
|
+
<TableCell>{template.subject}</TableCell>
|
|
806
|
+
<TableCell>
|
|
807
|
+
<div className="flex flex-wrap gap-1">
|
|
808
|
+
{template.mail_var.map((v, index) => (
|
|
809
|
+
<Badge
|
|
810
|
+
key={`${template.id}-${v.id}-${index}`}
|
|
811
|
+
variant="secondary"
|
|
812
|
+
className="text-xs"
|
|
813
|
+
>
|
|
814
|
+
{v.name}
|
|
815
|
+
</Badge>
|
|
816
|
+
))}
|
|
817
|
+
</div>
|
|
818
|
+
</TableCell>
|
|
819
|
+
<TableCell className="text-muted-foreground">
|
|
820
|
+
{formatDate(
|
|
821
|
+
template.updated_at,
|
|
822
|
+
getSettingValue,
|
|
823
|
+
currentLocaleCode
|
|
824
|
+
)}
|
|
825
|
+
</TableCell>
|
|
826
|
+
<TableCell className="text-right">
|
|
827
|
+
<div className="flex justify-end gap-2">
|
|
828
|
+
<Button
|
|
829
|
+
variant="ghost"
|
|
830
|
+
size="icon"
|
|
831
|
+
onClick={(e) => {
|
|
832
|
+
e.stopPropagation();
|
|
833
|
+
handleDownloadHTML(template);
|
|
834
|
+
}}
|
|
835
|
+
title={t('downloadHTML')}
|
|
836
|
+
>
|
|
837
|
+
<FileDown className="h-4 w-4" />
|
|
838
|
+
</Button>
|
|
839
|
+
<Button
|
|
840
|
+
variant="ghost"
|
|
841
|
+
size="icon"
|
|
842
|
+
onClick={(e) => {
|
|
843
|
+
e.stopPropagation();
|
|
844
|
+
handleEdit(template);
|
|
845
|
+
}}
|
|
846
|
+
>
|
|
847
|
+
<Pencil className="h-4 w-4" />
|
|
848
|
+
</Button>
|
|
849
|
+
<Button
|
|
850
|
+
variant="ghost"
|
|
851
|
+
size="icon"
|
|
852
|
+
onClick={(e) => {
|
|
853
|
+
e.stopPropagation();
|
|
854
|
+
handleDelete(Number(template.mail_id || template.id));
|
|
855
|
+
}}
|
|
856
|
+
>
|
|
857
|
+
<Trash2 className="h-4 w-4 text-destructive" />
|
|
858
|
+
</Button>
|
|
859
|
+
</div>
|
|
860
|
+
</TableCell>
|
|
861
|
+
</TableRow>
|
|
862
|
+
))}
|
|
863
|
+
</TableBody>
|
|
864
|
+
</Table>
|
|
865
|
+
</div>
|
|
866
|
+
)}
|
|
867
|
+
|
|
868
|
+
<PaginationFooter
|
|
869
|
+
currentPage={page}
|
|
870
|
+
pageSize={pageSize}
|
|
871
|
+
totalItems={totalItems}
|
|
872
|
+
onPageChange={setPage}
|
|
873
|
+
onPageSizeChange={(newSize) => {
|
|
874
|
+
setPageSize(newSize);
|
|
875
|
+
setPage(1);
|
|
876
|
+
}}
|
|
877
|
+
/>
|
|
878
|
+
|
|
879
|
+
<Sheet open={isDialogOpen} onOpenChange={setIsDialogOpen}>
|
|
880
|
+
<SheetContent
|
|
881
|
+
side="right"
|
|
882
|
+
className="w-full max-w-[95vw] overflow-y-auto sm:max-w-6xl"
|
|
883
|
+
>
|
|
884
|
+
<SheetHeader>
|
|
885
|
+
<SheetTitle>
|
|
827
886
|
{editMode ? t('editTemplate') : t('newTemplateTitle')}
|
|
828
|
-
</
|
|
829
|
-
<
|
|
887
|
+
</SheetTitle>
|
|
888
|
+
<SheetDescription>
|
|
830
889
|
{editMode
|
|
831
890
|
? t('editTemplateDescription')
|
|
832
891
|
: t('newTemplateDescription')}
|
|
833
|
-
</
|
|
834
|
-
</
|
|
892
|
+
</SheetDescription>
|
|
893
|
+
</SheetHeader>
|
|
835
894
|
<form onSubmit={handleSubmit} className="space-y-6">
|
|
836
895
|
<div className="grid grid-cols-2 gap-6">
|
|
837
896
|
<div className="space-y-4 overflow-y-auto max-h-[calc(90vh-200px)] pr-4">
|
|
@@ -987,22 +1046,13 @@ export default function EmailTemplatesPage() {
|
|
|
987
1046
|
{t('sendTestEmail')}
|
|
988
1047
|
</Button>
|
|
989
1048
|
</div>
|
|
990
|
-
<
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
variant="outline"
|
|
994
|
-
onClick={() => setIsDialogOpen(false)}
|
|
995
|
-
>
|
|
996
|
-
{t('cancel')}
|
|
997
|
-
</Button>
|
|
998
|
-
<Button type="submit">
|
|
999
|
-
{editMode ? t('saveChanges') : t('createTemplate')}
|
|
1000
|
-
</Button>
|
|
1001
|
-
</div>
|
|
1049
|
+
<Button type="submit" className="min-w-40">
|
|
1050
|
+
{editMode ? t('saveChanges') : t('createTemplate')}
|
|
1051
|
+
</Button>
|
|
1002
1052
|
</div>
|
|
1003
1053
|
</form>
|
|
1004
|
-
</
|
|
1005
|
-
</
|
|
1054
|
+
</SheetContent>
|
|
1055
|
+
</Sheet>
|
|
1006
1056
|
|
|
1007
1057
|
<Dialog
|
|
1008
1058
|
open={isTestEmailDialogOpen}
|
|
@@ -1172,6 +1222,6 @@ export default function EmailTemplatesPage() {
|
|
|
1172
1222
|
</AlertDialogFooter>
|
|
1173
1223
|
</AlertDialogContent>
|
|
1174
1224
|
</AlertDialog>
|
|
1175
|
-
</
|
|
1225
|
+
</Page>
|
|
1176
1226
|
);
|
|
1177
1227
|
}
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
EmptyState,
|
|
5
|
+
icon={<Menu className="h-12 w-12" />}
|
|
4
6
|
PageHeader,
|
|
5
7
|
PaginationFooter,
|
|
6
8
|
SearchBar,
|
|
7
9
|
StatsCards,
|
|
8
10
|
} from '@/components/entity-list';
|
|
9
11
|
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
|
12
|
+
import {
|
|
13
|
+
AlertDialog,
|
|
14
|
+
AlertDialogAction,
|
|
15
|
+
AlertDialogCancel,
|
|
16
|
+
AlertDialogContent,
|
|
17
|
+
AlertDialogDescription,
|
|
18
|
+
AlertDialogFooter,
|
|
19
|
+
AlertDialogHeader,
|
|
20
|
+
AlertDialogTitle,
|
|
21
|
+
} from '@/components/ui/alert-dialog';
|
|
10
22
|
import { Badge } from '@/components/ui/badge';
|
|
11
23
|
import { Button } from '@/components/ui/button';
|
|
12
24
|
import {
|
|
@@ -885,7 +897,7 @@ export default function MenuPage() {
|
|
|
885
897
|
);
|
|
886
898
|
|
|
887
899
|
return (
|
|
888
|
-
<
|
|
900
|
+
<Page>
|
|
889
901
|
<PageHeader
|
|
890
902
|
breadcrumbs={[{ label: 'Home', href: '/' }, { label: t('menus') }]}
|
|
891
903
|
actions={[
|
|
@@ -947,7 +959,13 @@ export default function MenuPage() {
|
|
|
947
959
|
|
|
948
960
|
{!isLoading &&
|
|
949
961
|
(!menusResponse?.data || menusResponse.data.length === 0) ? (
|
|
950
|
-
<
|
|
962
|
+
<EmptyState
|
|
963
|
+
icon={Menu}
|
|
964
|
+
title={t('noMenusFound')}
|
|
965
|
+
description={t('description')}
|
|
966
|
+
actionLabel={t('buttonAddMenu')}
|
|
967
|
+
onAction={() => setIsDialogOpen(true)}
|
|
968
|
+
/>
|
|
951
969
|
) : (
|
|
952
970
|
<div className="grid gap-4 grid-cols-1 lg:grid-cols-2 xl:grid-cols-3">
|
|
953
971
|
{menusResponse?.data?.map((menu: MenuItem) => (
|
|
@@ -1022,19 +1040,18 @@ export default function MenuPage() {
|
|
|
1022
1040
|
/>
|
|
1023
1041
|
</div>
|
|
1024
1042
|
|
|
1025
|
-
<
|
|
1026
|
-
<
|
|
1027
|
-
<
|
|
1028
|
-
<
|
|
1029
|
-
<
|
|
1043
|
+
<Sheet open={isDialogOpen} onOpenChange={setIsDialogOpen}>
|
|
1044
|
+
<SheetContent className="w-full sm:max-w-lg overflow-y-auto gap-0">
|
|
1045
|
+
<SheetHeader>
|
|
1046
|
+
<SheetTitle>{t('dialogAddMenuTitle')}</SheetTitle>
|
|
1047
|
+
<SheetDescription>
|
|
1030
1048
|
{t('dialogAddMenuDescription')}
|
|
1031
|
-
</
|
|
1032
|
-
</
|
|
1033
|
-
<div className="w-full border-t pt-1 mt-1" />
|
|
1049
|
+
</SheetDescription>
|
|
1050
|
+
</SheetHeader>
|
|
1034
1051
|
<Form {...form}>
|
|
1035
1052
|
<form
|
|
1036
1053
|
onSubmit={form.handleSubmit(onSubmit)}
|
|
1037
|
-
className="space-y-4"
|
|
1054
|
+
className="space-y-4 px-4 pt-2"
|
|
1038
1055
|
>
|
|
1039
1056
|
<FormField
|
|
1040
1057
|
control={form.control}
|
|
@@ -1175,8 +1192,8 @@ export default function MenuPage() {
|
|
|
1175
1192
|
</Button>
|
|
1176
1193
|
</form>
|
|
1177
1194
|
</Form>
|
|
1178
|
-
</
|
|
1179
|
-
</
|
|
1195
|
+
</SheetContent>
|
|
1196
|
+
</Sheet>
|
|
1180
1197
|
|
|
1181
1198
|
{editingMenu && (
|
|
1182
1199
|
<Sheet open={!!editingMenu} onOpenChange={() => setEditingMenu(null)}>
|
|
@@ -1399,33 +1416,22 @@ export default function MenuPage() {
|
|
|
1399
1416
|
</Sheet>
|
|
1400
1417
|
)}
|
|
1401
1418
|
|
|
1402
|
-
<
|
|
1403
|
-
<
|
|
1404
|
-
<
|
|
1405
|
-
<
|
|
1406
|
-
<
|
|
1419
|
+
<AlertDialog open={openDeleteModal} onOpenChange={setOpenDeleteModal}>
|
|
1420
|
+
<AlertDialogContent>
|
|
1421
|
+
<AlertDialogHeader>
|
|
1422
|
+
<AlertDialogTitle>{t('dialogDeleteMenuTitle')}</AlertDialogTitle>
|
|
1423
|
+
<AlertDialogDescription>
|
|
1407
1424
|
{t('dialogDeleteMenuDescription')}
|
|
1408
|
-
</
|
|
1409
|
-
</
|
|
1410
|
-
<
|
|
1411
|
-
|
|
1412
|
-
<
|
|
1413
|
-
type="button"
|
|
1414
|
-
className="px-4 w-28 h-12 py-2 bg-gray-300 text-black hover:bg-gray-300 hover:text-black rounded-sm mr-2 text-md"
|
|
1415
|
-
onClick={() => setOpenDeleteModal(false)}
|
|
1416
|
-
>
|
|
1417
|
-
{t('deleteMenuCancel')}
|
|
1418
|
-
</Button>
|
|
1419
|
-
<Button
|
|
1420
|
-
onClick={onDelete}
|
|
1421
|
-
variant="destructive"
|
|
1422
|
-
className="px-4 w-32 h-12 py-2 text-white hover:text-white rounded-sm text-md cursor-pointer"
|
|
1423
|
-
>
|
|
1425
|
+
</AlertDialogDescription>
|
|
1426
|
+
</AlertDialogHeader>
|
|
1427
|
+
<AlertDialogFooter>
|
|
1428
|
+
<AlertDialogCancel>{t('deleteMenuCancel')}</AlertDialogCancel>
|
|
1429
|
+
<AlertDialogAction onClick={onDelete}>
|
|
1424
1430
|
{t('deleteMenuConfirm')}
|
|
1425
|
-
</
|
|
1426
|
-
</
|
|
1427
|
-
</
|
|
1428
|
-
</
|
|
1431
|
+
</AlertDialogAction>
|
|
1432
|
+
</AlertDialogFooter>
|
|
1433
|
+
</AlertDialogContent>
|
|
1434
|
+
</AlertDialog>
|
|
1429
1435
|
|
|
1430
1436
|
<MenuTreeDialog
|
|
1431
1437
|
open={isTreeOpen}
|
|
@@ -1436,6 +1442,6 @@ export default function MenuPage() {
|
|
|
1436
1442
|
}}
|
|
1437
1443
|
/>
|
|
1438
1444
|
</div>
|
|
1439
|
-
</
|
|
1445
|
+
</Page>
|
|
1440
1446
|
);
|
|
1441
1447
|
}
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
EmptyState,
|
|
5
|
+
icon={<ShieldCheck className="h-12 w-12" />}
|
|
4
6
|
PageHeader,
|
|
5
7
|
PaginationFooter,
|
|
6
8
|
SearchBar,
|
|
7
9
|
StatsCards,
|
|
8
10
|
} from '@/components/entity-list';
|
|
9
11
|
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
|
|
12
|
+
import {
|
|
13
|
+
AlertDialog,
|
|
14
|
+
AlertDialogAction,
|
|
15
|
+
AlertDialogCancel,
|
|
16
|
+
AlertDialogContent,
|
|
17
|
+
AlertDialogDescription,
|
|
18
|
+
AlertDialogFooter,
|
|
19
|
+
AlertDialogHeader,
|
|
20
|
+
AlertDialogTitle,
|
|
21
|
+
} from '@/components/ui/alert-dialog';
|
|
10
22
|
import { Button } from '@/components/ui/button';
|
|
11
23
|
import {
|
|
12
24
|
Card,
|
|
@@ -15,13 +27,6 @@ import {
|
|
|
15
27
|
CardHeader,
|
|
16
28
|
CardTitle,
|
|
17
29
|
} from '@/components/ui/card';
|
|
18
|
-
import {
|
|
19
|
-
Dialog,
|
|
20
|
-
DialogContent,
|
|
21
|
-
DialogDescription,
|
|
22
|
-
DialogHeader,
|
|
23
|
-
DialogTitle,
|
|
24
|
-
} from '@/components/ui/dialog';
|
|
25
30
|
import {
|
|
26
31
|
Form,
|
|
27
32
|
FormControl,
|
|
@@ -367,7 +372,7 @@ export default function RolePage() {
|
|
|
367
372
|
};
|
|
368
373
|
|
|
369
374
|
return (
|
|
370
|
-
<
|
|
375
|
+
<Page>
|
|
371
376
|
<PageHeader
|
|
372
377
|
breadcrumbs={[{ label: 'Home', href: '/' }, { label: t('roles') }]}
|
|
373
378
|
actions={[
|
|
@@ -423,7 +428,13 @@ export default function RolePage() {
|
|
|
423
428
|
|
|
424
429
|
{!isLoading &&
|
|
425
430
|
(!rolesResponse?.data || rolesResponse.data.length === 0) ? (
|
|
426
|
-
<
|
|
431
|
+
<EmptyState
|
|
432
|
+
icon={ShieldCheck}
|
|
433
|
+
title={t('noRolesFound')}
|
|
434
|
+
description={t('description')}
|
|
435
|
+
actionLabel={t('buttonAddRole')}
|
|
436
|
+
onAction={() => setIsDialogOpen(true)}
|
|
437
|
+
/>
|
|
427
438
|
) : (
|
|
428
439
|
<div className="grid gap-4 grid-cols-1 lg:grid-cols-2 xl:grid-cols-3">
|
|
429
440
|
{(rolesResponse?.data as (Role & { role_id: number })[])?.map(
|
|
@@ -504,19 +515,18 @@ export default function RolePage() {
|
|
|
504
515
|
/>
|
|
505
516
|
</div>
|
|
506
517
|
|
|
507
|
-
<
|
|
508
|
-
<
|
|
509
|
-
<
|
|
510
|
-
<
|
|
511
|
-
<
|
|
518
|
+
<Sheet open={isDialogOpen} onOpenChange={setIsDialogOpen}>
|
|
519
|
+
<SheetContent className="w-full sm:max-w-lg overflow-y-auto gap-0">
|
|
520
|
+
<SheetHeader>
|
|
521
|
+
<SheetTitle>{t('dialogAddRoleTitle')}</SheetTitle>
|
|
522
|
+
<SheetDescription>
|
|
512
523
|
{t('dialogAddRoleDescription')}
|
|
513
|
-
</
|
|
514
|
-
</
|
|
515
|
-
<div className="w-full border-t pt-1 mt-1" />
|
|
524
|
+
</SheetDescription>
|
|
525
|
+
</SheetHeader>
|
|
516
526
|
<Form {...form}>
|
|
517
527
|
<form
|
|
518
528
|
onSubmit={form.handleSubmit(onSubmit)}
|
|
519
|
-
className="space-y-4"
|
|
529
|
+
className="space-y-4 px-4 pt-2"
|
|
520
530
|
>
|
|
521
531
|
<FormField
|
|
522
532
|
control={form.control}
|
|
@@ -586,8 +596,8 @@ export default function RolePage() {
|
|
|
586
596
|
</Button>
|
|
587
597
|
</form>
|
|
588
598
|
</Form>
|
|
589
|
-
</
|
|
590
|
-
</
|
|
599
|
+
</SheetContent>
|
|
600
|
+
</Sheet>
|
|
591
601
|
|
|
592
602
|
{editingRole && (
|
|
593
603
|
<Sheet open={!!editingRole} onOpenChange={() => setEditingRole(null)}>
|
|
@@ -783,34 +793,23 @@ export default function RolePage() {
|
|
|
783
793
|
</Sheet>
|
|
784
794
|
)}
|
|
785
795
|
|
|
786
|
-
<
|
|
787
|
-
<
|
|
788
|
-
<
|
|
789
|
-
<
|
|
790
|
-
<
|
|
796
|
+
<AlertDialog open={openDeleteModal} onOpenChange={setOpenDeleteModal}>
|
|
797
|
+
<AlertDialogContent>
|
|
798
|
+
<AlertDialogHeader>
|
|
799
|
+
<AlertDialogTitle>{t('dialogDeleteRoleTitle')}</AlertDialogTitle>
|
|
800
|
+
<AlertDialogDescription>
|
|
791
801
|
{t('dialogDeleteRoleDescription')}
|
|
792
|
-
</
|
|
793
|
-
</
|
|
794
|
-
<
|
|
795
|
-
|
|
796
|
-
<
|
|
797
|
-
type="button"
|
|
798
|
-
className="px-4 w-28 h-12 py-2 bg-gray-300 text-black hover:bg-gray-300 hover:text-black rounded-sm mr-2 text-md"
|
|
799
|
-
onClick={() => setOpenDeleteModal(false)}
|
|
800
|
-
>
|
|
801
|
-
{t('deleteRoleCancel')}
|
|
802
|
-
</Button>
|
|
803
|
-
<Button
|
|
804
|
-
onClick={onDelete}
|
|
805
|
-
variant="destructive"
|
|
806
|
-
className="px-4 w-32 h-12 py-2 text-white hover:text-white rounded-sm text-md cursor-pointer"
|
|
807
|
-
>
|
|
802
|
+
</AlertDialogDescription>
|
|
803
|
+
</AlertDialogHeader>
|
|
804
|
+
<AlertDialogFooter>
|
|
805
|
+
<AlertDialogCancel>{t('deleteRoleCancel')}</AlertDialogCancel>
|
|
806
|
+
<AlertDialogAction onClick={onDelete}>
|
|
808
807
|
{t('deleteRoleConfirm')}
|
|
809
|
-
</
|
|
810
|
-
</
|
|
811
|
-
</
|
|
812
|
-
</
|
|
808
|
+
</AlertDialogAction>
|
|
809
|
+
</AlertDialogFooter>
|
|
810
|
+
</AlertDialogContent>
|
|
811
|
+
</AlertDialog>
|
|
813
812
|
</div>
|
|
814
|
-
</
|
|
813
|
+
</Page>
|
|
815
814
|
);
|
|
816
815
|
}
|