@hedhog/admin 0.0.104 → 0.0.105

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. package/README.md +141 -141
  2. package/dist/admin.module.js +7 -7
  3. package/dist/admin.module.js.map +1 -1
  4. package/dist/auth/auth.service.d.ts +1 -1
  5. package/dist/auth/auth.service.d.ts.map +1 -1
  6. package/dist/auth/auth.service.js +8 -8
  7. package/dist/auth/auth.service.js.map +1 -1
  8. package/dist/auth/auth.service.spec.js +16 -16
  9. package/dist/auth/auth.service.spec.js.map +1 -1
  10. package/dist/dto/with-locale.dto.d.ts +4 -0
  11. package/dist/dto/with-locale.dto.d.ts.map +1 -0
  12. package/dist/dto/{with-locales.dto.js → with-locale.dto.js} +5 -5
  13. package/dist/dto/with-locale.dto.js.map +1 -0
  14. package/dist/index.d.ts +2 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/locale/locale.controller.js +1 -1
  19. package/dist/locale/locale.controller.js.map +1 -1
  20. package/dist/locale/locale.middleware.d.ts +1 -1
  21. package/dist/locale/locale.middleware.d.ts.map +1 -1
  22. package/dist/locale/locale.middleware.js +2 -2
  23. package/dist/locale/locale.middleware.js.map +1 -1
  24. package/dist/locale/locale.service.d.ts +6 -6
  25. package/dist/locale/locale.service.d.ts.map +1 -1
  26. package/dist/locale/locale.service.js +40 -40
  27. package/dist/locale/locale.service.js.map +1 -1
  28. package/dist/locale/locale.service.spec.js +14 -14
  29. package/dist/locale/locale.service.spec.js.map +1 -1
  30. package/dist/menu/menu.controller.js +3 -3
  31. package/dist/menu/menu.controller.js.map +1 -1
  32. package/dist/menu/menu.service.d.ts +3 -3
  33. package/dist/menu/menu.service.d.ts.map +1 -1
  34. package/dist/menu/menu.service.js +35 -35
  35. package/dist/menu/menu.service.js.map +1 -1
  36. package/dist/menu/menu.service.spec.js +33 -37
  37. package/dist/menu/menu.service.spec.js.map +1 -1
  38. package/dist/role/dto/create.dto.d.ts +2 -2
  39. package/dist/role/dto/create.dto.d.ts.map +1 -1
  40. package/dist/role/dto/create.dto.js +2 -2
  41. package/dist/role/dto/create.dto.js.map +1 -1
  42. package/dist/role/guards/role.guard.js +4 -4
  43. package/dist/role/guards/role.guard.js.map +1 -1
  44. package/dist/role/role.controller.js +7 -7
  45. package/dist/role/role.controller.js.map +1 -1
  46. package/dist/role/role.service.d.ts +2 -2
  47. package/dist/role/role.service.d.ts.map +1 -1
  48. package/dist/role/role.service.js +35 -35
  49. package/dist/role/role.service.js.map +1 -1
  50. package/dist/role/role.service.spec.d.ts +0 -1
  51. package/dist/role/role.service.spec.js +400 -340
  52. package/dist/role/role.service.spec.js.map +1 -1
  53. package/dist/route/route.controller.js +3 -3
  54. package/dist/route/route.controller.js.map +1 -1
  55. package/dist/route/route.service.d.ts +2 -2
  56. package/dist/route/route.service.d.ts.map +1 -1
  57. package/dist/route/route.service.js +18 -18
  58. package/dist/route/route.service.js.map +1 -1
  59. package/dist/route/route.service.spec.js +27 -27
  60. package/dist/route/route.service.spec.js.map +1 -1
  61. package/dist/screen/screen.controller.js +4 -4
  62. package/dist/screen/screen.controller.js.map +1 -1
  63. package/dist/screen/screen.service.d.ts +2 -2
  64. package/dist/screen/screen.service.d.ts.map +1 -1
  65. package/dist/screen/screen.service.js +16 -16
  66. package/dist/screen/screen.service.js.map +1 -1
  67. package/dist/screen/screen.service.spec.js +16 -16
  68. package/dist/screen/screen.service.spec.js.map +1 -1
  69. package/dist/setting/dto/setting.dto.d.ts +9 -0
  70. package/dist/setting/dto/setting.dto.d.ts.map +1 -0
  71. package/dist/setting/dto/{settings.dto.js → setting.dto.js} +6 -6
  72. package/dist/setting/dto/setting.dto.js.map +1 -0
  73. package/dist/setting/{settings.controller.d.ts → setting.controller.d.ts} +6 -6
  74. package/dist/setting/setting.controller.d.ts.map +1 -0
  75. package/dist/setting/{settings.controller.js → setting.controller.js} +20 -20
  76. package/dist/setting/setting.controller.js.map +1 -0
  77. package/dist/setting/setting.module.d.ts +3 -0
  78. package/dist/setting/setting.module.d.ts.map +1 -0
  79. package/dist/setting/{settings.module.js → setting.module.js} +6 -6
  80. package/dist/setting/setting.module.js.map +1 -0
  81. package/dist/setting/{settings.service.d.ts → setting.service.d.ts} +4 -4
  82. package/dist/setting/setting.service.d.ts.map +1 -0
  83. package/dist/setting/{settings.service.js → setting.service.js} +42 -42
  84. package/dist/setting/setting.service.js.map +1 -0
  85. package/dist/setting/setting.service.spec.d.ts +2 -0
  86. package/dist/setting/setting.service.spec.d.ts.map +1 -0
  87. package/dist/setting/{settings.service.spec.js → setting.service.spec.js} +17 -17
  88. package/dist/setting/setting.service.spec.js.map +1 -0
  89. package/dist/user/user.controller.js +3 -3
  90. package/dist/user/user.controller.js.map +1 -1
  91. package/dist/user/user.service.d.ts +2 -2
  92. package/dist/user/user.service.d.ts.map +1 -1
  93. package/dist/user/user.service.js +9 -9
  94. package/dist/user/user.service.js.map +1 -1
  95. package/dist/user/user.service.spec.js +24 -24
  96. package/dist/user/user.service.spec.js.map +1 -1
  97. package/package.json +2 -2
  98. package/src/admin.module.ts +36 -0
  99. package/src/auth/auth.controller.ts +48 -0
  100. package/src/auth/auth.module.ts +39 -0
  101. package/src/auth/auth.service.spec.ts +196 -0
  102. package/src/auth/auth.service.ts +175 -0
  103. package/src/auth/decorators/public.decorator.ts +4 -0
  104. package/src/auth/decorators/user.decorator.ts +17 -0
  105. package/src/auth/dto/forget.dto.ts +6 -0
  106. package/src/auth/dto/login.dto.ts +15 -0
  107. package/src/auth/dto/otp.dto.ts +11 -0
  108. package/src/auth/enums/multifactor-type.enum.ts +4 -0
  109. package/src/auth/guards/auth.guard.ts +50 -0
  110. package/src/auth/types/user.type.ts +8 -0
  111. package/src/dto/delete.dto.ts +8 -0
  112. package/src/dto/update-ids.dto.ts +9 -0
  113. package/src/dto/with-locale.dto.ts +8 -0
  114. package/src/index.ts +34 -0
  115. package/src/locale/dto/create.dto.ts +12 -0
  116. package/src/locale/dto/delete.dto.ts +8 -0
  117. package/src/locale/dto/set-enabled.dto.ts +9 -0
  118. package/src/locale/dto/update.dto.ts +15 -0
  119. package/src/locale/index.ts +4 -0
  120. package/src/locale/locale.controller.ts +79 -0
  121. package/src/locale/locale.decorator.ts +8 -0
  122. package/src/locale/locale.middleware.ts +34 -0
  123. package/src/locale/locale.module.ts +23 -0
  124. package/src/locale/locale.service.spec.ts +193 -0
  125. package/src/locale/locale.service.ts +366 -0
  126. package/src/menu/dto/create.dto.ts +25 -0
  127. package/src/menu/dto/order.dto.ts +8 -0
  128. package/src/menu/dto/update.dto.ts +19 -0
  129. package/src/menu/menu.controller.ts +106 -0
  130. package/src/menu/menu.module.ts +18 -0
  131. package/src/menu/menu.service.spec.ts +247 -0
  132. package/src/menu/menu.service.ts +263 -0
  133. package/src/role/decorators/role.decorator.ts +4 -0
  134. package/src/role/dto/create.dto.ts +7 -0
  135. package/src/role/dto/update.dto.ts +4 -0
  136. package/src/role/guards/role.guard.ts +122 -0
  137. package/src/role/role.controller.ts +126 -0
  138. package/src/role/role.module.ts +28 -0
  139. package/src/role/role.service.spec.ts +417 -0
  140. package/src/role/role.service.ts +302 -0
  141. package/src/route/dto/create.dto.ts +13 -0
  142. package/src/route/dto/update.dto.ts +15 -0
  143. package/src/route/route.controller.ts +91 -0
  144. package/src/route/route.module.ts +18 -0
  145. package/src/route/route.service.spec.ts +299 -0
  146. package/src/route/route.service.ts +164 -0
  147. package/src/screen/dto/create.dto.ts +19 -0
  148. package/src/screen/dto/update.dto.ts +19 -0
  149. package/src/screen/screen.controller.ts +93 -0
  150. package/src/screen/screen.module.ts +18 -0
  151. package/src/screen/screen.service.spec.ts +298 -0
  152. package/src/screen/screen.service.ts +181 -0
  153. package/src/setting/dto/create.dto.ts +1 -0
  154. package/src/setting/dto/setting-user.dto.ts +6 -0
  155. package/src/setting/dto/setting.dto.ts +17 -0
  156. package/src/setting/dto/update.dto.ts +3 -0
  157. package/src/setting/setting.controller.ts +100 -0
  158. package/src/setting/setting.module.ts +18 -0
  159. package/src/setting/setting.service.spec.ts +183 -0
  160. package/src/setting/setting.service.ts +346 -0
  161. package/src/types/http-method.ts +8 -0
  162. package/src/user/constants/user.constants.ts +1 -0
  163. package/src/user/dto/create.dto.ts +24 -0
  164. package/src/user/dto/update.dto.ts +41 -0
  165. package/src/user/user.controller.ts +75 -0
  166. package/src/user/user.module.ts +18 -0
  167. package/src/user/user.service.spec.ts +294 -0
  168. package/src/user/user.service.ts +129 -0
  169. package/tsconfig.lib.json +9 -0
  170. package/tsconfig.production.json +20 -0
  171. package/dist/dto/with-locales.dto.d.ts +0 -4
  172. package/dist/dto/with-locales.dto.d.ts.map +0 -1
  173. package/dist/dto/with-locales.dto.js.map +0 -1
  174. package/dist/setting/dto/settings.dto.d.ts +0 -9
  175. package/dist/setting/dto/settings.dto.d.ts.map +0 -1
  176. package/dist/setting/dto/settings.dto.js.map +0 -1
  177. package/dist/setting/settings.controller.d.ts.map +0 -1
  178. package/dist/setting/settings.controller.js.map +0 -1
  179. package/dist/setting/settings.module.d.ts +0 -3
  180. package/dist/setting/settings.module.d.ts.map +0 -1
  181. package/dist/setting/settings.module.js.map +0 -1
  182. package/dist/setting/settings.service.d.ts.map +0 -1
  183. package/dist/setting/settings.service.js.map +0 -1
  184. package/dist/setting/settings.service.spec.d.ts +0 -2
  185. package/dist/setting/settings.service.spec.d.ts.map +0 -1
  186. package/dist/setting/settings.service.spec.js.map +0 -1
@@ -0,0 +1,193 @@
1
+ import { PaginationService } from '@hedhog/pagination';
2
+ import { PrismaService } from '@hedhog/prisma';
3
+ import { BadRequestException } from '@nestjs/common';
4
+ import { Test, TestingModule } from '@nestjs/testing';
5
+ import { CreateDTO } from './dto/create.dto';
6
+ import { DeleteDTO } from './dto/delete.dto';
7
+ import { UpdateDTO } from './dto/update.dto';
8
+ import { LocaleService } from './locale.service';
9
+
10
+ describe('LocaleService', () => {
11
+ let service: LocaleService;
12
+ let prismaService: PrismaService;
13
+ let paginationService: PaginationService;
14
+
15
+ beforeEach(async () => {
16
+ const module: TestingModule = await Test.createTestingModule({
17
+ providers: [
18
+ LocaleService,
19
+ {
20
+ provide: PrismaService,
21
+ useValue: {
22
+ translation: {
23
+ findMany: jest.fn(),
24
+ },
25
+ locale: {
26
+ findUnique: jest.fn(),
27
+ create: jest.fn(),
28
+ update: jest.fn(),
29
+ deleteMany: jest.fn(),
30
+ },
31
+ },
32
+ },
33
+ {
34
+ provide: PaginationService,
35
+ useValue: {
36
+ paginate: jest.fn(),
37
+ },
38
+ },
39
+ ],
40
+ }).compile();
41
+
42
+ service = module.get<LocaleService>(LocaleService);
43
+ prismaService = module.get<PrismaService>(PrismaService);
44
+ paginationService = module.get<PaginationService>(PaginationService);
45
+ });
46
+
47
+ it('should be defined', () => {
48
+ expect(service).toBeDefined();
49
+ });
50
+
51
+ describe('getTranslations', () => {
52
+ it('should throw BadRequestException when localeCode is not provided', async () => {
53
+ await expect(service.getTranslations('', 'namespace')).rejects.toThrow(
54
+ BadRequestException,
55
+ );
56
+ });
57
+
58
+ it('should return translation for a given localeCode and namespace', async () => {
59
+ const mockTranslations = [
60
+ {
61
+ id: 1,
62
+ locale_id: 1,
63
+ namespace_id: 1,
64
+ name: 'hello',
65
+ value: 'Hello',
66
+ created_at: new Date(),
67
+ updated_at: new Date(),
68
+ },
69
+ ];
70
+ jest
71
+ .spyOn(prismaService.translation, 'findMany')
72
+ .mockResolvedValue(mockTranslations);
73
+
74
+ const result = await service.getTranslations('en-US', 'namespace');
75
+ expect(result).toEqual({ hello: 'Hello' });
76
+ });
77
+ });
78
+ /*
79
+ describe('get', () => {
80
+ it('should paginate locale', async () => {
81
+ const mockPaginationResult = {
82
+ data: [],
83
+ total: 10,
84
+ lastPage: 1,
85
+ page: 1,
86
+ prev: 0,
87
+ next: 2,
88
+ pageSize: 10,
89
+ };
90
+ jest
91
+ .spyOn(paginationService, 'paginate')
92
+ .mockResolvedValue(mockPaginationResult);
93
+
94
+ const paginationParams: PaginationDTO = {
95
+ page: 1,
96
+ pageSize: 20,
97
+ sortField: '',
98
+ sortOrder: PageOrderDirection.Asc,
99
+ fields: '',
100
+ search: '',
101
+ };
102
+ const result = await service.get(paginationParams );
103
+
104
+ expect(paginationService.paginate).toHaveBeenCalledWith(
105
+ prismaService.locale,
106
+ paginationParams,
107
+ expect.anything(),
108
+ );
109
+ expect(result).toBe(mockPaginationResult);
110
+ });
111
+ });
112
+ */
113
+ describe('getById', () => {
114
+ it('should return a locale by ID', async () => {
115
+ const mockLocale = {
116
+ id: 1,
117
+ name: 'English',
118
+ code: 'en',
119
+ region: 'us',
120
+ created_at: new Date(),
121
+ updated_at: new Date(),
122
+ };
123
+ jest
124
+ .spyOn(prismaService.locale, 'findUnique')
125
+ .mockResolvedValue(mockLocale);
126
+
127
+ const result = await service.getById(1);
128
+ expect(result).toBe(mockLocale);
129
+ });
130
+ });
131
+
132
+ describe('create', () => {
133
+ it('should create a new locale', async () => {
134
+ const mockCreateDTO: CreateDTO = {
135
+ name: 'English',
136
+ code: 'en',
137
+ region: 'us',
138
+ };
139
+ const mockLocale = {
140
+ id: 1,
141
+ name: 'English',
142
+ code: 'en',
143
+ region: 'us',
144
+ created_at: new Date(),
145
+ updated_at: new Date(),
146
+ };
147
+ jest.spyOn(prismaService.locale, 'create').mockResolvedValue(mockLocale);
148
+
149
+ const result = await service.create(mockCreateDTO);
150
+ expect(result).toBe(mockLocale);
151
+ });
152
+ });
153
+
154
+ describe('update', () => {
155
+ it('should update a locale', async () => {
156
+ const mockUpdateDTO: UpdateDTO = {
157
+ name: 'English Updated',
158
+ code: 'en',
159
+ region: 'us',
160
+ };
161
+ const mockLocale = {
162
+ id: 1,
163
+ name: 'English Updated',
164
+ code: 'en',
165
+ region: 'us',
166
+ created_at: new Date(),
167
+ updated_at: new Date(),
168
+ };
169
+ jest.spyOn(prismaService.locale, 'update').mockResolvedValue(mockLocale);
170
+
171
+ const result = await service.update({ id: 1, data: mockUpdateDTO });
172
+ expect(result).toBe(mockLocale);
173
+ });
174
+ });
175
+
176
+ describe('delete', () => {
177
+ it('should throw BadRequestException if no IDs are provided', async () => {
178
+ await expect(service.delete({ ids: null })).rejects.toThrow(
179
+ BadRequestException,
180
+ );
181
+ });
182
+
183
+ it('should delete locale by IDs', async () => {
184
+ const mockDeleteDTO: DeleteDTO = { ids: [1, 2, 3] };
185
+ jest
186
+ .spyOn(prismaService.locale, 'deleteMany')
187
+ .mockResolvedValue({ count: 3 });
188
+
189
+ const result = await service.delete(mockDeleteDTO);
190
+ expect(result.count).toBe(3);
191
+ });
192
+ });
193
+ });
@@ -0,0 +1,366 @@
1
+ import { PaginationDTO, PaginationService } from '@hedhog/pagination';
2
+ import { PrismaService } from '@hedhog/prisma';
3
+ import {
4
+ BadRequestException,
5
+ Inject,
6
+ Injectable,
7
+ forwardRef,
8
+ } from '@nestjs/common';
9
+ import { CreateDTO } from './dto/create.dto';
10
+ import { DeleteDTO } from './dto/delete.dto';
11
+ import { UpdateDTO } from './dto/update.dto';
12
+
13
+ @Injectable()
14
+ export class LocaleService {
15
+ private codes: any = {};
16
+
17
+ constructor(
18
+ @Inject(forwardRef(() => PrismaService))
19
+ private readonly prismaService: PrismaService,
20
+ @Inject(forwardRef(() => PaginationService))
21
+ private readonly paginationService: PaginationService,
22
+ ) {}
23
+
24
+ async setEnabled(codes: string[]) {
25
+ if (!codes || codes.length < 1) {
26
+ throw new BadRequestException('You must select at least one item code.');
27
+ }
28
+
29
+ await this.prismaService.locale.updateMany({
30
+ where: {
31
+ enabled: true,
32
+ },
33
+ data: {
34
+ enabled: false,
35
+ },
36
+ });
37
+
38
+ return this.prismaService.locale.updateMany({
39
+ where: {
40
+ code: {
41
+ in: codes,
42
+ },
43
+ },
44
+ data: {
45
+ enabled: true,
46
+ },
47
+ });
48
+ }
49
+
50
+ async getEnables(currentLocale: string, paginationParams: PaginationDTO) {
51
+ const fields = ['code', 'region'];
52
+ const OR: any[] = this.prismaService.createInsensitiveSearch(
53
+ fields,
54
+ paginationParams,
55
+ );
56
+
57
+ const result = await this.paginationService.paginate(
58
+ this.prismaService.locale,
59
+ paginationParams,
60
+ {
61
+ where: {
62
+ AND: [
63
+ {
64
+ enabled: true,
65
+ },
66
+ {
67
+ OR,
68
+ },
69
+ ],
70
+ },
71
+ },
72
+ );
73
+
74
+ const codes = [];
75
+
76
+ for (const item of result.data) {
77
+ codes.push((item as any).code);
78
+ }
79
+
80
+ const { code, region, locale } = this.parseLocale(currentLocale);
81
+
82
+ const where: any = {
83
+ locale: {
84
+ code,
85
+ },
86
+ translation_namespaces: {
87
+ name: 'translation',
88
+ },
89
+ };
90
+
91
+ if (locale.length > 1) {
92
+ where.locale.region = region;
93
+ }
94
+
95
+ const values = await this.prismaService.translation.findMany({
96
+ where,
97
+ select: {
98
+ name: true,
99
+ value: true,
100
+ },
101
+ });
102
+
103
+ for (let i = 0; i < result.data.length; i++) {
104
+ for (const value of values) {
105
+ if (value.name === (result.data[i] as any).code) {
106
+ (result.data[i] as any).name = value.value;
107
+ break;
108
+ }
109
+ }
110
+ }
111
+
112
+ return result;
113
+ }
114
+
115
+ parseLocale(locale: string) {
116
+ const localeCodes = locale.toLowerCase().split('-');
117
+ const code = localeCodes[0];
118
+ const region = localeCodes[1];
119
+ return {
120
+ code,
121
+ region,
122
+ locale: localeCodes,
123
+ };
124
+ }
125
+
126
+ async getTranslations(localeCode: string, namespace: string) {
127
+ if (!localeCode) {
128
+ throw new BadRequestException('Locale code is required.');
129
+ }
130
+
131
+ if (!namespace) {
132
+ namespace = 'translation';
133
+ }
134
+
135
+ const { code, region, locale } = this.parseLocale(localeCode);
136
+ const where: any = {
137
+ locale: {
138
+ code,
139
+ },
140
+ translation_namespaces: {
141
+ name: namespace,
142
+ },
143
+ };
144
+
145
+ if (locale.length > 1) {
146
+ where.locale.region = region;
147
+ }
148
+
149
+ const values = await this.prismaService.translation.findMany({
150
+ where,
151
+ select: {
152
+ name: true,
153
+ value: true,
154
+ },
155
+ });
156
+
157
+ const translation = {};
158
+
159
+ for (const value of values) {
160
+ translation[value.name] = value.value;
161
+ }
162
+
163
+ return translation;
164
+ }
165
+
166
+ async get(currentLocale: string, paginationParams: PaginationDTO) {
167
+ const fields = ['code', 'region'];
168
+ const OR: any[] = this.prismaService.createInsensitiveSearch(
169
+ fields,
170
+ paginationParams,
171
+ );
172
+
173
+ const result = await this.paginationService.paginate(
174
+ this.prismaService.locale,
175
+ paginationParams,
176
+ {
177
+ where: {
178
+ OR,
179
+ },
180
+ },
181
+ );
182
+
183
+ const codes = [];
184
+
185
+ for (const item of result.data) {
186
+ codes.push((item as any).code);
187
+ }
188
+
189
+ const { code, region, locale } = this.parseLocale(currentLocale);
190
+
191
+ const where: any = {
192
+ locale: {
193
+ code,
194
+ },
195
+ translation_namespaces: {
196
+ name: 'translation',
197
+ },
198
+ };
199
+
200
+ if (locale.length > 1) {
201
+ where.locale.region = region;
202
+ }
203
+
204
+ const values = await this.prismaService.translation.findMany({
205
+ where,
206
+ select: {
207
+ name: true,
208
+ value: true,
209
+ },
210
+ });
211
+
212
+ for (let i = 0; i < result.data.length; i++) {
213
+ for (const value of values) {
214
+ if (value.name === (result.data[i] as any).code) {
215
+ (result.data[i] as any).name = value.value;
216
+ break;
217
+ }
218
+ }
219
+ }
220
+
221
+ return result;
222
+ }
223
+
224
+ async getByCode(code: string) {
225
+ if (this.codes[code]) {
226
+ return this.codes[code];
227
+ }
228
+ return (this.codes[code] = await this.prismaService.locale.findFirst({
229
+ where: { code },
230
+ }));
231
+ }
232
+
233
+ async getById(localeId: number) {
234
+ return this.prismaService.locale.findUnique({
235
+ where: { id: localeId },
236
+ });
237
+ }
238
+
239
+ async create(data: CreateDTO) {
240
+ return this.prismaService.locale.create({
241
+ data,
242
+ });
243
+ }
244
+
245
+ async update({ id, data }: { id: number; data: UpdateDTO }) {
246
+ return this.prismaService.locale.update({
247
+ where: { id },
248
+ data,
249
+ });
250
+ }
251
+
252
+ async delete({ ids }: DeleteDTO) {
253
+ if (ids == undefined || ids == null) {
254
+ throw new BadRequestException(
255
+ 'You must select at least one item to delete.',
256
+ );
257
+ }
258
+
259
+ return this.prismaService.locale.deleteMany({
260
+ where: {
261
+ id: {
262
+ in: ids,
263
+ },
264
+ },
265
+ });
266
+ }
267
+
268
+ private getTableNameTranslations(modelName: string) {
269
+ const modelNames = modelName.split('_');
270
+ modelNames.push('locale');
271
+ return modelNames.join('_');
272
+ }
273
+
274
+ async createModelWithLocale<T>(
275
+ modelName: string,
276
+ foreginKeyName: string,
277
+ data: T,
278
+ locale: Record<string, string>,
279
+ ) {
280
+ const model = await this.prismaService[modelName].create({
281
+ data,
282
+ });
283
+
284
+ for (const localeCode of Object.keys(locale)) {
285
+ const locale = await this.getByCode(localeCode);
286
+
287
+ const data: any = {};
288
+
289
+ for (const key of Object.keys(locale[localeCode])) {
290
+ data[key] = locale[localeCode][key];
291
+ }
292
+
293
+ await this.prismaService[this.getTableNameTranslations(modelName)].create(
294
+ {
295
+ data: {
296
+ [foreginKeyName]: model.id,
297
+ locale_id: locale.id,
298
+ ...data,
299
+ },
300
+ },
301
+ );
302
+ }
303
+
304
+ return this.prismaService[modelName].findUnique({
305
+ where: { id: model.id },
306
+ include: {
307
+ [this.getTableNameTranslations(modelName)]: {
308
+ where: {
309
+ locale: {
310
+ enabled: true,
311
+ },
312
+ },
313
+ include: {
314
+ locale: {
315
+ select: {
316
+ code: true,
317
+ },
318
+ },
319
+ },
320
+ },
321
+ },
322
+ });
323
+ }
324
+
325
+ async updateModelWithLocale<T extends any>(
326
+ modelName: string,
327
+ foreginKeyName: string,
328
+ id: number,
329
+ data: T,
330
+ locale: Record<string, string>,
331
+ ) {
332
+ for (const localeCode of Object.keys(locale)) {
333
+ const locale = await this.getByCode(localeCode);
334
+
335
+ const data: any = {};
336
+
337
+ for (const key of Object.keys(locale[localeCode])) {
338
+ data[key] = locale[localeCode][key];
339
+ }
340
+
341
+ await this.prismaService[this.getTableNameTranslations(modelName)].upsert(
342
+ {
343
+ where: {
344
+ [`${foreginKeyName}_locale_id`]: {
345
+ [foreginKeyName]: id,
346
+ locale_id: locale.id,
347
+ },
348
+ },
349
+ create: {
350
+ [foreginKeyName]: id,
351
+ locale_id: locale.id,
352
+ ...data,
353
+ },
354
+ update: {
355
+ ...data,
356
+ },
357
+ },
358
+ );
359
+ }
360
+
361
+ return this.prismaService[modelName].update({
362
+ where: { id },
363
+ data,
364
+ });
365
+ }
366
+ }
@@ -0,0 +1,25 @@
1
+ import { IsInt, IsNotEmpty, IsOptional, IsString, Min } from 'class-validator';
2
+
3
+ export class CreateDTO {
4
+ @IsString({ message: 'O nome deve ser uma string' })
5
+ @IsNotEmpty({ message: 'O nome é obrigatório.' })
6
+ name: string;
7
+
8
+ @IsString({ message: 'A url deve ser uma string' })
9
+ @IsNotEmpty({ message: 'A url é obrigatório.' })
10
+ url: string;
11
+
12
+ @IsInt({ message: 'Order deve ser um número.' })
13
+ @Min(1)
14
+ @IsOptional()
15
+ order?: number;
16
+
17
+ @IsString({ message: 'O ícone deve ser uma string' })
18
+ @IsOptional()
19
+ icon?: string;
20
+
21
+ @IsInt({ message: 'MenuID deve ser um número.' })
22
+ @Min(1)
23
+ @IsOptional()
24
+ menuId?: number;
25
+ }
@@ -0,0 +1,8 @@
1
+ import { ArrayMinSize, IsArray, IsInt } from 'class-validator';
2
+
3
+ export class OrderDTO {
4
+ @IsArray()
5
+ @ArrayMinSize(1)
6
+ @IsInt({ each: true })
7
+ ids: number[];
8
+ }
@@ -0,0 +1,19 @@
1
+ import { IsInt, IsOptional, IsString } from 'class-validator';
2
+
3
+ export class UpdateDTO {
4
+ @IsString({ message: 'O nome deve ser uma string' })
5
+ @IsOptional()
6
+ name?: string;
7
+
8
+ @IsString({ message: 'A url deve ser uma string' })
9
+ @IsOptional()
10
+ url?: string;
11
+
12
+ @IsInt({ message: 'Order deve ser um número.' })
13
+ @IsOptional()
14
+ order?: number;
15
+
16
+ @IsString({ message: 'O ícone deve ser uma string' })
17
+ @IsOptional()
18
+ icon?: string;
19
+ }
@@ -0,0 +1,106 @@
1
+ import { Pagination } from '@hedhog/pagination';
2
+ import {
3
+ Body,
4
+ Controller,
5
+ Delete,
6
+ Get,
7
+ Inject,
8
+ Param,
9
+ ParseIntPipe,
10
+ Patch,
11
+ Post,
12
+ forwardRef,
13
+ } from '@nestjs/common';
14
+ import { User } from '../auth/decorators/user.decorator';
15
+ import { DeleteDTO } from '../dto/delete.dto';
16
+ import { UpdateIdsDTO } from '../dto/update-ids.dto';
17
+ import { Locale } from '../locale';
18
+ import { Role } from '../role/decorators/role.decorator';
19
+ import { CreateDTO } from './dto/create.dto';
20
+ import { OrderDTO } from './dto/order.dto';
21
+ import { UpdateDTO } from './dto/update.dto';
22
+ import { MenuService } from './menu.service';
23
+
24
+ @Role()
25
+ @Controller('menu')
26
+ export class MenuController {
27
+ constructor(
28
+ @Inject(forwardRef(() => MenuService))
29
+ private readonly menuService: MenuService,
30
+ ) {}
31
+
32
+ @Get('system')
33
+ async getSystemMenu(@User() { id }, @Locale() locale) {
34
+ return this.menuService.getSystemMenu(locale, id);
35
+ }
36
+
37
+ @Get()
38
+ async getMenu(@Pagination() paginationParams, @Locale() locale) {
39
+ return this.menuService.getMenu(locale, paginationParams);
40
+ }
41
+
42
+ @Get(':menuId/role')
43
+ async listRoles(
44
+ @Param('menuId', ParseIntPipe) menuId: number,
45
+ @Pagination() paginationParams,
46
+ @Locale() locale,
47
+ ) {
48
+ return this.menuService.listRoles(locale, menuId, paginationParams);
49
+ }
50
+
51
+ @Get(':menuId/screens')
52
+ async listScreens(
53
+ @Param('menuId', ParseIntPipe) menuId: number,
54
+ @Pagination() paginationParams,
55
+ @Locale() locale,
56
+ ) {
57
+ return this.menuService.listScreens(locale, menuId, paginationParams);
58
+ }
59
+
60
+ @Patch(':menuId/role')
61
+ async updateRoles(
62
+ @Param('menuId', ParseIntPipe) menuId: number,
63
+ @Body() data: UpdateIdsDTO,
64
+ ) {
65
+ return this.menuService.updateRoles(menuId, data);
66
+ }
67
+
68
+ @Patch(':menuId/screens')
69
+ async updateScreens(
70
+ @Param('menuId', ParseIntPipe) menuId: number,
71
+ @Body() data: UpdateIdsDTO,
72
+ ) {
73
+ return this.menuService.updateScreens(menuId, data);
74
+ }
75
+
76
+ @Get(':menuId')
77
+ async show(@Param('menuId', ParseIntPipe) menuId: number) {
78
+ return this.menuService.get(menuId);
79
+ }
80
+
81
+ @Post()
82
+ async create(@Body() data: CreateDTO) {
83
+ return this.menuService.create(data);
84
+ }
85
+
86
+ @Patch(':menuId')
87
+ async update(
88
+ @Param('menuId', ParseIntPipe) menuId: number,
89
+ @Body() data: UpdateDTO,
90
+ ) {
91
+ return this.menuService.update({
92
+ id: menuId,
93
+ data,
94
+ });
95
+ }
96
+
97
+ @Delete()
98
+ async delete(@Body() data: DeleteDTO) {
99
+ return this.menuService.delete(data);
100
+ }
101
+
102
+ @Patch('order')
103
+ async updateOrder(@Body() data: OrderDTO): Promise<void> {
104
+ return this.menuService.updateOrder(data);
105
+ }
106
+ }