@hed-hog/core 0.0.297 → 0.0.299

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 (183) hide show
  1. package/dist/auth/auth.controller.d.ts +10 -10
  2. package/dist/auth/auth.service.d.ts +10 -10
  3. package/dist/dashboard/dashboard/dashboard.controller.d.ts +3 -0
  4. package/dist/dashboard/dashboard/dashboard.controller.d.ts.map +1 -1
  5. package/dist/dashboard/dashboard/dashboard.service.d.ts +3 -0
  6. package/dist/dashboard/dashboard/dashboard.service.d.ts.map +1 -1
  7. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +12 -0
  8. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts.map +1 -1
  9. package/dist/dashboard/dashboard-component/dashboard-component.controller.js +22 -0
  10. package/dist/dashboard/dashboard-component/dashboard-component.controller.js.map +1 -1
  11. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +15 -0
  12. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts.map +1 -1
  13. package/dist/dashboard/dashboard-component/dashboard-component.service.js +110 -3
  14. package/dist/dashboard/dashboard-component/dashboard-component.service.js.map +1 -1
  15. package/dist/dashboard/dashboard-component/dto/create.dto.d.ts +1 -0
  16. package/dist/dashboard/dashboard-component/dto/create.dto.d.ts.map +1 -1
  17. package/dist/dashboard/dashboard-component/dto/create.dto.js +5 -0
  18. package/dist/dashboard/dashboard-component/dto/create.dto.js.map +1 -1
  19. package/dist/dashboard/dashboard-component/dto/update.dto.d.ts +1 -0
  20. package/dist/dashboard/dashboard-component/dto/update.dto.d.ts.map +1 -1
  21. package/dist/dashboard/dashboard-component/dto/update.dto.js +5 -0
  22. package/dist/dashboard/dashboard-component/dto/update.dto.js.map +1 -1
  23. package/dist/dashboard/dashboard-component-role/dashboard-component-role.controller.d.ts +1 -0
  24. package/dist/dashboard/dashboard-component-role/dashboard-component-role.controller.d.ts.map +1 -1
  25. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts +1 -0
  26. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts.map +1 -1
  27. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +21 -1
  28. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts.map +1 -1
  29. package/dist/dashboard/dashboard-core/dashboard-core.controller.js +9 -0
  30. package/dist/dashboard/dashboard-core/dashboard-core.controller.js.map +1 -1
  31. package/dist/dashboard/dashboard-core/dashboard-core.module.d.ts.map +1 -1
  32. package/dist/dashboard/dashboard-core/dashboard-core.module.js +6 -1
  33. package/dist/dashboard/dashboard-core/dashboard-core.module.js.map +1 -1
  34. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +180 -2
  35. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts.map +1 -1
  36. package/dist/dashboard/dashboard-core/dashboard-core.service.js +619 -9
  37. package/dist/dashboard/dashboard-core/dashboard-core.service.js.map +1 -1
  38. package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts +1 -0
  39. package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts.map +1 -1
  40. package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts +1 -0
  41. package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts.map +1 -1
  42. package/dist/file/file.controller.d.ts.map +1 -1
  43. package/dist/file/file.controller.js +16 -0
  44. package/dist/file/file.controller.js.map +1 -1
  45. package/dist/file/file.service.d.ts +7 -1
  46. package/dist/file/file.service.d.ts.map +1 -1
  47. package/dist/file/file.service.js +38 -1
  48. package/dist/file/file.service.js.map +1 -1
  49. package/dist/file/provider/s3.provider.d.ts +1 -0
  50. package/dist/file/provider/s3.provider.d.ts.map +1 -1
  51. package/dist/file/provider/s3.provider.js +38 -29
  52. package/dist/file/provider/s3.provider.js.map +1 -1
  53. package/dist/oauth/oauth.service.d.ts.map +1 -1
  54. package/dist/oauth/oauth.service.js +2 -1
  55. package/dist/oauth/oauth.service.js.map +1 -1
  56. package/dist/user/constants/user.constants.d.ts +1 -0
  57. package/dist/user/constants/user.constants.d.ts.map +1 -1
  58. package/dist/user/constants/user.constants.js +2 -1
  59. package/dist/user/constants/user.constants.js.map +1 -1
  60. package/dist/user/user.controller.d.ts +10 -10
  61. package/dist/user/user.service.d.ts +30 -30
  62. package/dist/user/user.service.d.ts.map +1 -1
  63. package/dist/user/user.service.js +2 -1
  64. package/dist/user/user.service.js.map +1 -1
  65. package/hedhog/data/dashboard_item.yaml +10 -10
  66. package/hedhog/data/route.yaml +20 -0
  67. package/hedhog/frontend/app/dashboard/[slug]/dashboard-content.tsx.ejs +212 -34
  68. package/hedhog/frontend/app/dashboard/[slug]/types.ts.ejs +3 -0
  69. package/hedhog/frontend/app/dashboard/[slug]/widget-renderer.tsx.ejs +136 -23
  70. package/hedhog/frontend/app/dashboard/components/add-widget-selector-dialog.tsx.ejs +266 -85
  71. package/hedhog/frontend/app/dashboard/components/widgets/core..gitkeep.ejs +11 -0
  72. package/hedhog/frontend/app/dashboard/components/widgets/core.account-security.tsx.ejs +192 -0
  73. package/hedhog/frontend/app/dashboard/components/widgets/core.email-notifications.tsx.ejs +226 -0
  74. package/hedhog/frontend/app/dashboard/components/widgets/core.locale-config.tsx.ejs +168 -0
  75. package/hedhog/frontend/app/dashboard/components/widgets/core.mail-config.tsx.ejs +199 -0
  76. package/hedhog/frontend/app/dashboard/components/widgets/core.oauth-config.tsx.ejs +175 -0
  77. package/hedhog/frontend/app/dashboard/components/widgets/core.profile-card.tsx.ejs +186 -0
  78. package/hedhog/frontend/app/dashboard/components/widgets/core.storage-config.tsx.ejs +196 -0
  79. package/hedhog/frontend/app/dashboard/components/widgets/core.theme-config.tsx.ejs +213 -0
  80. package/hedhog/frontend/app/dashboard/components/widgets/core.user-roles.tsx.ejs +132 -0
  81. package/hedhog/frontend/app/dashboard/components/widgets/core.user-sessions.tsx.ejs +236 -0
  82. package/hedhog/frontend/app/dashboard/components/widgets/finance.alerts.tsx.ejs +108 -0
  83. package/hedhog/frontend/app/dashboard/components/widgets/finance.cash-balance-kpi.tsx.ejs +66 -0
  84. package/hedhog/frontend/app/dashboard/components/widgets/finance.cash-flow-chart.tsx.ejs +122 -0
  85. package/hedhog/frontend/app/dashboard/components/widgets/finance.default-kpi.tsx.ejs +63 -0
  86. package/hedhog/frontend/app/dashboard/components/widgets/finance.payable-30d-kpi.tsx.ejs +73 -0
  87. package/hedhog/frontend/app/dashboard/components/widgets/finance.receivable-30d-kpi.tsx.ejs +73 -0
  88. package/hedhog/frontend/app/dashboard/components/widgets/finance.upcoming-payable.tsx.ejs +123 -0
  89. package/hedhog/frontend/app/dashboard/components/widgets/finance.upcoming-receivable.tsx.ejs +118 -0
  90. package/hedhog/frontend/messages/en.json +93 -0
  91. package/hedhog/frontend/messages/pt.json +93 -0
  92. package/hedhog/frontend/public/dashboard-previews/.gitkeep +12 -0
  93. package/hedhog/frontend/public/dashboard-previews/account-security.png +0 -0
  94. package/hedhog/frontend/public/dashboard-previews/active-users-card.png +0 -0
  95. package/hedhog/frontend/public/dashboard-previews/activity-timeline.png +0 -0
  96. package/hedhog/frontend/public/dashboard-previews/cash-balance-kpi.png +0 -0
  97. package/hedhog/frontend/public/dashboard-previews/cash-flow-chart.png +0 -0
  98. package/hedhog/frontend/public/dashboard-previews/default-kpi.png +0 -0
  99. package/hedhog/frontend/public/dashboard-previews/email-notifications.png +0 -0
  100. package/hedhog/frontend/public/dashboard-previews/financial-alerts.png +0 -0
  101. package/hedhog/frontend/public/dashboard-previews/login-history-chart.png +0 -0
  102. package/hedhog/frontend/public/dashboard-previews/mail-sent-card.png +0 -0
  103. package/hedhog/frontend/public/dashboard-previews/mail-sent-chart.png +0 -0
  104. package/hedhog/frontend/public/dashboard-previews/menus-card.png +0 -0
  105. package/hedhog/frontend/public/dashboard-previews/payable-30d-kpi.png +0 -0
  106. package/hedhog/frontend/public/dashboard-previews/permissions-card.png +0 -0
  107. package/hedhog/frontend/public/dashboard-previews/permissions-chart.png +0 -0
  108. package/hedhog/frontend/public/dashboard-previews/profile-card.png +0 -0
  109. package/hedhog/frontend/public/dashboard-previews/receivable-30d-kpi.png +0 -0
  110. package/hedhog/frontend/public/dashboard-previews/routes-card.png +0 -0
  111. package/hedhog/frontend/public/dashboard-previews/session-activity-chart.png +0 -0
  112. package/hedhog/frontend/public/dashboard-previews/sessions-today-card.png +0 -0
  113. package/hedhog/frontend/public/dashboard-previews/stat-access-level.png +0 -0
  114. package/hedhog/frontend/public/dashboard-previews/stat-actions-today.png +0 -0
  115. package/hedhog/frontend/public/dashboard-previews/stat-consecutive-days.png +0 -0
  116. package/hedhog/frontend/public/dashboard-previews/stat-online-time.png +0 -0
  117. package/hedhog/frontend/public/dashboard-previews/upcoming-payable.png +0 -0
  118. package/hedhog/frontend/public/dashboard-previews/upcoming-receivable.png +0 -0
  119. package/hedhog/frontend/public/dashboard-previews/user-growth-chart.png +0 -0
  120. package/hedhog/frontend/public/dashboard-previews/user-roles.png +0 -0
  121. package/hedhog/frontend/{app/dashboard/components/widgets → widgets}/account-security.tsx.ejs +33 -29
  122. package/hedhog/frontend/widgets/active-users-card.tsx.ejs +58 -0
  123. package/hedhog/frontend/widgets/activity-timeline.tsx.ejs +223 -0
  124. package/hedhog/frontend/{app/dashboard/components/widgets → widgets}/email-notifications.tsx.ejs +85 -61
  125. package/hedhog/frontend/widgets/locale-config.tsx.ejs +168 -0
  126. package/hedhog/frontend/widgets/login-history-chart.tsx.ejs +115 -0
  127. package/hedhog/frontend/widgets/mail-config.tsx.ejs +199 -0
  128. package/hedhog/frontend/widgets/mail-sent-card.tsx.ejs +58 -0
  129. package/hedhog/frontend/widgets/mail-sent-chart.tsx.ejs +149 -0
  130. package/hedhog/frontend/widgets/menus-card.tsx.ejs +58 -0
  131. package/hedhog/frontend/widgets/oauth-config.tsx.ejs +175 -0
  132. package/hedhog/frontend/widgets/permissions-card.tsx.ejs +61 -0
  133. package/hedhog/frontend/widgets/permissions-chart.tsx.ejs +156 -0
  134. package/hedhog/frontend/{app/dashboard/components/widgets → widgets}/profile-card.tsx.ejs +3 -3
  135. package/hedhog/frontend/widgets/routes-card.tsx.ejs +58 -0
  136. package/hedhog/frontend/widgets/session-activity-chart.tsx.ejs +183 -0
  137. package/hedhog/frontend/widgets/sessions-today-card.tsx.ejs +62 -0
  138. package/hedhog/frontend/widgets/stat-access-level.tsx.ejs +57 -0
  139. package/hedhog/frontend/widgets/stat-actions-today.tsx.ejs +57 -0
  140. package/hedhog/frontend/widgets/stat-consecutive-days.tsx.ejs +57 -0
  141. package/hedhog/frontend/widgets/stat-online-time.tsx.ejs +57 -0
  142. package/hedhog/frontend/widgets/storage-config.tsx.ejs +196 -0
  143. package/hedhog/frontend/widgets/theme-config.tsx.ejs +213 -0
  144. package/hedhog/frontend/widgets/user-growth-chart.tsx.ejs +210 -0
  145. package/hedhog/frontend/{app/dashboard/components/widgets → widgets}/user-roles.tsx.ejs +12 -14
  146. package/hedhog/frontend/{app/dashboard/components/widgets → widgets}/user-sessions.tsx.ejs +1 -1
  147. package/hedhog/table/dashboard_component.yaml +7 -0
  148. package/hedhog/table/mail_sent_user.yaml +75 -0
  149. package/package.json +4 -4
  150. package/src/dashboard/dashboard-component/dashboard-component.controller.ts +36 -12
  151. package/src/dashboard/dashboard-component/dashboard-component.service.ts +150 -3
  152. package/src/dashboard/dashboard-component/dto/create.dto.ts +4 -0
  153. package/src/dashboard/dashboard-component/dto/update.dto.ts +4 -0
  154. package/src/dashboard/dashboard-core/dashboard-core.controller.ts +5 -0
  155. package/src/dashboard/dashboard-core/dashboard-core.module.ts +6 -1
  156. package/src/dashboard/dashboard-core/dashboard-core.service.ts +874 -8
  157. package/src/file/file.controller.ts +37 -13
  158. package/src/file/file.service.ts +47 -5
  159. package/src/file/provider/s3.provider.ts +39 -29
  160. package/src/oauth/oauth.service.ts +8 -7
  161. package/src/user/constants/user.constants.ts +1 -0
  162. package/src/user/user.service.ts +2 -1
  163. package/hedhog/frontend/app/dashboard/components/widgets/locale-config.tsx.ejs +0 -309
  164. package/hedhog/frontend/app/dashboard/components/widgets/mail-config.tsx.ejs +0 -445
  165. package/hedhog/frontend/app/dashboard/components/widgets/oauth-config.tsx.ejs +0 -296
  166. package/hedhog/frontend/app/dashboard/components/widgets/storage-config.tsx.ejs +0 -340
  167. package/hedhog/frontend/app/dashboard/components/widgets/theme-config.tsx.ejs +0 -275
  168. /package/hedhog/frontend/app/dashboard/components/widgets/{active-users-card.tsx.ejs → core.active-users-card.tsx.ejs} +0 -0
  169. /package/hedhog/frontend/app/dashboard/components/widgets/{activity-timeline.tsx.ejs → core.activity-timeline.tsx.ejs} +0 -0
  170. /package/hedhog/frontend/app/dashboard/components/widgets/{login-history-chart.tsx.ejs → core.login-history-chart.tsx.ejs} +0 -0
  171. /package/hedhog/frontend/app/dashboard/components/widgets/{mail-sent-card.tsx.ejs → core.mail-sent-card.tsx.ejs} +0 -0
  172. /package/hedhog/frontend/app/dashboard/components/widgets/{mail-sent-chart.tsx.ejs → core.mail-sent-chart.tsx.ejs} +0 -0
  173. /package/hedhog/frontend/app/dashboard/components/widgets/{menus-card.tsx.ejs → core.menus-card.tsx.ejs} +0 -0
  174. /package/hedhog/frontend/app/dashboard/components/widgets/{permissions-card.tsx.ejs → core.permissions-card.tsx.ejs} +0 -0
  175. /package/hedhog/frontend/app/dashboard/components/widgets/{permissions-chart.tsx.ejs → core.permissions-chart.tsx.ejs} +0 -0
  176. /package/hedhog/frontend/app/dashboard/components/widgets/{routes-card.tsx.ejs → core.routes-card.tsx.ejs} +0 -0
  177. /package/hedhog/frontend/app/dashboard/components/widgets/{session-activity-chart.tsx.ejs → core.session-activity-chart.tsx.ejs} +0 -0
  178. /package/hedhog/frontend/app/dashboard/components/widgets/{sessions-today-card.tsx.ejs → core.sessions-today-card.tsx.ejs} +0 -0
  179. /package/hedhog/frontend/app/dashboard/components/widgets/{stat-access-level.tsx.ejs → core.stat-access-level.tsx.ejs} +0 -0
  180. /package/hedhog/frontend/app/dashboard/components/widgets/{stat-actions-today.tsx.ejs → core.stat-actions-today.tsx.ejs} +0 -0
  181. /package/hedhog/frontend/app/dashboard/components/widgets/{stat-consecutive-days.tsx.ejs → core.stat-consecutive-days.tsx.ejs} +0 -0
  182. /package/hedhog/frontend/app/dashboard/components/widgets/{stat-online-time.tsx.ejs → core.stat-online-time.tsx.ejs} +0 -0
  183. /package/hedhog/frontend/app/dashboard/components/widgets/{user-growth-chart.tsx.ejs → core.user-growth-chart.tsx.ejs} +0 -0
@@ -8,14 +8,427 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
+ var DashboardCoreService_1;
11
12
  Object.defineProperty(exports, "__esModule", { value: true });
12
13
  exports.DashboardCoreService = void 0;
13
14
  const api_locale_1 = require("@hed-hog/api-locale");
14
15
  const api_prisma_1 = require("@hed-hog/api-prisma");
15
16
  const common_1 = require("@nestjs/common");
16
- let DashboardCoreService = class DashboardCoreService {
17
- constructor(prismaService) {
17
+ const setting_service_1 = require("../../setting/setting.service");
18
+ const MAIL_PROVIDER_REQUIREMENTS = {
19
+ SMTP: ['mail-from', 'mail-smtp-host', 'mail-smtp-port', 'mail-client-secret'],
20
+ GMAIL: [
21
+ 'mail-from',
22
+ 'mail-gmail-client-id',
23
+ 'mail-gmail-client-secret',
24
+ 'mail-gmail-refresh-token',
25
+ ],
26
+ SES: [
27
+ 'mail-from',
28
+ 'mail-aws-access-key-id',
29
+ 'mail-aws-secret-access-key',
30
+ 'mail-aws-region',
31
+ ],
32
+ };
33
+ const MAIL_PROVIDER_LABELS = {
34
+ SMTP: 'SMTP',
35
+ GMAIL: 'Gmail',
36
+ SES: 'Amazon SES',
37
+ };
38
+ const OAUTH_PROVIDER_DEFINITIONS = [
39
+ {
40
+ id: 'google',
41
+ label: 'Google',
42
+ requiredKeys: ['google_client_id', 'google_client_secret', 'url'],
43
+ scopeKey: 'google_scopes',
44
+ },
45
+ {
46
+ id: 'facebook',
47
+ label: 'Facebook',
48
+ requiredKeys: ['facebook_client_id', 'facebook_client_secret', 'url'],
49
+ scopeKey: 'facebook_scopes',
50
+ },
51
+ {
52
+ id: 'github',
53
+ label: 'GitHub',
54
+ requiredKeys: ['github_client_id', 'github_client_secret', 'api-url'],
55
+ scopeKey: 'github_scopes',
56
+ },
57
+ {
58
+ id: 'microsoft',
59
+ label: 'Microsoft',
60
+ requiredKeys: ['microsoft_client_id', 'microsoft_client_secret', 'url'],
61
+ scopeKey: 'microsoft_scopes',
62
+ },
63
+ {
64
+ id: 'microsoft_entra_id',
65
+ label: 'Microsoft Entra ID',
66
+ requiredKeys: [
67
+ 'microsoft_entra_id_client_id',
68
+ 'microsoft_entra_id_client_secret',
69
+ 'microsoft_entra_id_tenant_id',
70
+ 'url',
71
+ ],
72
+ scopeKey: 'microsoft_entra_id_scopes',
73
+ },
74
+ ];
75
+ const LOCALE_SETTING_KEYS = ['date-format', 'time-format', 'timezone'];
76
+ const MAIL_SETTING_KEYS = [
77
+ 'mail-provider',
78
+ 'mail-from',
79
+ 'mail-gmail-client-id',
80
+ 'mail-gmail-client-secret',
81
+ 'mail-gmail-refresh-token',
82
+ 'mail-smtp-host',
83
+ 'mail-smtp-port',
84
+ 'mail-smtp-secure',
85
+ 'mail-client-secret',
86
+ 'mail-aws-access-key-id',
87
+ 'mail-aws-secret-access-key',
88
+ 'mail-aws-region',
89
+ ];
90
+ const OAUTH_SETTING_KEYS = [
91
+ 'providers',
92
+ 'url',
93
+ 'api-url',
94
+ 'google_client_id',
95
+ 'google_client_secret',
96
+ 'google_scopes',
97
+ 'facebook_client_id',
98
+ 'facebook_client_secret',
99
+ 'facebook_scopes',
100
+ 'github_client_id',
101
+ 'github_client_secret',
102
+ 'github_scopes',
103
+ 'microsoft_client_id',
104
+ 'microsoft_client_secret',
105
+ 'microsoft_scopes',
106
+ 'microsoft_entra_id_client_id',
107
+ 'microsoft_entra_id_client_secret',
108
+ 'microsoft_entra_id_tenant_id',
109
+ 'microsoft_entra_id_scopes',
110
+ ];
111
+ const THEME_SETTING_KEYS = [
112
+ 'system-name',
113
+ 'system-slogan',
114
+ 'icon-url',
115
+ 'image-url',
116
+ 'theme-mode',
117
+ 'theme-font',
118
+ 'theme-text-size',
119
+ 'theme-radius',
120
+ 'theme-primary-light',
121
+ 'theme-primary-foreground-light',
122
+ 'theme-secondary-light',
123
+ 'theme-secondary-foreground-light',
124
+ 'theme-accent-light',
125
+ 'theme-accent-foreground-light',
126
+ 'theme-muted-light',
127
+ 'theme-muted-foreground-light',
128
+ 'theme-background-light',
129
+ 'theme-background-foreground-light',
130
+ 'theme-card-light',
131
+ 'theme-card-foreground-light',
132
+ 'theme-primary-dark',
133
+ 'theme-primary-foreground-dark',
134
+ 'theme-secondary-dark',
135
+ 'theme-secondary-foreground-dark',
136
+ 'theme-accent-dark',
137
+ 'theme-accent-foreground-dark',
138
+ 'theme-muted-dark',
139
+ 'theme-muted-foreground-dark',
140
+ 'theme-background-dark',
141
+ 'theme-background-foreground-dark',
142
+ 'theme-card-dark',
143
+ 'theme-card-foreground-dark',
144
+ ];
145
+ let DashboardCoreService = DashboardCoreService_1 = class DashboardCoreService {
146
+ constructor(prismaService, settingService) {
18
147
  this.prismaService = prismaService;
148
+ this.settingService = settingService;
149
+ this.logger = new common_1.Logger(DashboardCoreService_1.name);
150
+ }
151
+ async getConfigOverview() {
152
+ const [localeConfig, mailConfig, oauthConfig, storageConfig, themeConfig] = await Promise.all([
153
+ this.getLocaleConfigOverview(),
154
+ this.getMailConfigOverview(),
155
+ this.getOAuthConfigOverview(),
156
+ this.getStorageConfigOverview(),
157
+ this.getThemeConfigOverview(),
158
+ ]);
159
+ return {
160
+ localeConfig,
161
+ mailConfig,
162
+ oauthConfig,
163
+ storageConfig,
164
+ themeConfig,
165
+ };
166
+ }
167
+ async getLocaleConfigOverview() {
168
+ const [settings, locales] = await Promise.all([
169
+ this.settingService.getSettingValues([...LOCALE_SETTING_KEYS]),
170
+ this.prismaService.locale.findMany({
171
+ orderBy: [{ enabled: 'desc' }, { code: 'asc' }],
172
+ select: {
173
+ id: true,
174
+ code: true,
175
+ region: true,
176
+ name: true,
177
+ enabled: true,
178
+ },
179
+ }),
180
+ ]);
181
+ const enabledLocaleCount = locales.filter((locale) => locale.enabled).length;
182
+ const disabledLocaleCount = locales.length - enabledLocaleCount;
183
+ return {
184
+ status: {
185
+ isConfigured: enabledLocaleCount > 0 &&
186
+ this.hasConfigValue(settings['date-format']) &&
187
+ this.hasConfigValue(settings['time-format']) &&
188
+ this.hasConfigValue(settings['timezone']),
189
+ enabledLocaleCount,
190
+ disabledLocaleCount,
191
+ },
192
+ settings: {
193
+ dateFormat: this.toNullableString(settings['date-format']),
194
+ timeFormat: this.toNullableString(settings['time-format']),
195
+ timezone: this.toNullableString(settings['timezone']),
196
+ },
197
+ locales,
198
+ };
199
+ }
200
+ async getMailConfigOverview() {
201
+ var _a;
202
+ const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
203
+ const [settings, templateCount, sentCount, sentLast30Days] = await Promise.all([
204
+ this.settingService.getSettingValues([...MAIL_SETTING_KEYS]),
205
+ this.prismaService.mail.count(),
206
+ this.prismaService.mail_sent.count(),
207
+ this.prismaService.mail_sent.count({
208
+ where: {
209
+ created_at: {
210
+ gte: thirtyDaysAgo,
211
+ },
212
+ },
213
+ }),
214
+ ]);
215
+ const selectedProvider = this.toNullableUppercaseString(settings['mail-provider']);
216
+ const providers = Object.entries(MAIL_PROVIDER_REQUIREMENTS).map(([providerId, requiredKeys]) => {
217
+ var _a;
218
+ const missingKeys = this.getMissingSettingKeys(settings, requiredKeys);
219
+ return {
220
+ id: providerId,
221
+ label: (_a = MAIL_PROVIDER_LABELS[providerId]) !== null && _a !== void 0 ? _a : providerId,
222
+ selected: providerId === selectedProvider,
223
+ configured: missingKeys.length === 0,
224
+ missingKeys,
225
+ };
226
+ });
227
+ const configuredProvider = providers.find((provider) => provider.id === selectedProvider && provider.configured);
228
+ return {
229
+ status: {
230
+ isConfigured: configuredProvider !== undefined,
231
+ selectedProvider,
232
+ configuredProvider: (_a = configuredProvider === null || configuredProvider === void 0 ? void 0 : configuredProvider.id) !== null && _a !== void 0 ? _a : null,
233
+ },
234
+ sender: {
235
+ from: this.toNullableString(settings['mail-from']),
236
+ },
237
+ metrics: {
238
+ templateCount,
239
+ sentCount,
240
+ sentLast30Days,
241
+ },
242
+ providers,
243
+ };
244
+ }
245
+ async getOAuthConfigOverview() {
246
+ const [settings, connectedAccounts] = await Promise.all([
247
+ this.settingService.getSettingValues([...OAUTH_SETTING_KEYS]),
248
+ this.prismaService.user_account.groupBy({
249
+ by: ['provider'],
250
+ _count: {
251
+ _all: true,
252
+ },
253
+ }),
254
+ ]);
255
+ const enabledProviders = this.normalizeProviderList(settings['providers']);
256
+ const connectedAccountsByProvider = new Map(connectedAccounts.map((entry) => [String(entry.provider), entry._count._all]));
257
+ const providers = OAUTH_PROVIDER_DEFINITIONS.map((provider) => {
258
+ var _a;
259
+ const missingKeys = this.getMissingSettingKeys(settings, provider.requiredKeys);
260
+ const scopes = Array.isArray(settings[provider.scopeKey])
261
+ ? settings[provider.scopeKey]
262
+ : [];
263
+ return {
264
+ id: provider.id,
265
+ label: provider.label,
266
+ enabled: enabledProviders.includes(provider.id),
267
+ configured: missingKeys.length === 0,
268
+ missingKeys,
269
+ scopesCount: scopes.length,
270
+ connectedUsers: (_a = connectedAccountsByProvider.get(provider.id)) !== null && _a !== void 0 ? _a : 0,
271
+ };
272
+ });
273
+ return {
274
+ status: {
275
+ isConfigured: providers.some((provider) => provider.enabled && provider.configured),
276
+ enabledProviderCount: providers.filter((provider) => provider.enabled).length,
277
+ configuredProviderCount: providers.filter((provider) => provider.configured).length,
278
+ connectedAccountCount: providers.reduce((total, provider) => total + provider.connectedUsers, 0),
279
+ },
280
+ providers,
281
+ };
282
+ }
283
+ async getStorageConfigOverview() {
284
+ var _a, _b;
285
+ const profiles = await this.prismaService.storage_profile.findMany({
286
+ where: {
287
+ deleted_at: null,
288
+ },
289
+ orderBy: [{ is_default: 'desc' }, { is_active: 'desc' }, { name: 'asc' }],
290
+ select: {
291
+ id: true,
292
+ name: true,
293
+ provider_type: true,
294
+ bucket_name: true,
295
+ region: true,
296
+ endpoint_url: true,
297
+ base_path: true,
298
+ path_template: true,
299
+ force_path_style: true,
300
+ is_default: true,
301
+ is_active: true,
302
+ test_status: true,
303
+ last_tested_at: true,
304
+ updated_at: true,
305
+ },
306
+ });
307
+ const providerMap = new Map();
308
+ profiles.forEach((profile) => {
309
+ var _a;
310
+ const providerType = String(profile.provider_type);
311
+ const current = (_a = providerMap.get(providerType)) !== null && _a !== void 0 ? _a : {
312
+ providerType,
313
+ total: 0,
314
+ active: 0,
315
+ defaults: 0,
316
+ };
317
+ current.total += 1;
318
+ current.active += profile.is_active ? 1 : 0;
319
+ current.defaults += profile.is_default ? 1 : 0;
320
+ providerMap.set(providerType, current);
321
+ });
322
+ const activeProfiles = profiles.filter((profile) => profile.is_active).length;
323
+ const defaultProfile = (_a = profiles.find((profile) => profile.is_default)) !== null && _a !== void 0 ? _a : null;
324
+ return {
325
+ status: {
326
+ isConfigured: activeProfiles > 0,
327
+ totalProfiles: profiles.length,
328
+ activeProfiles,
329
+ defaultProfileId: (_b = defaultProfile === null || defaultProfile === void 0 ? void 0 : defaultProfile.id) !== null && _b !== void 0 ? _b : null,
330
+ },
331
+ providers: Array.from(providerMap.values()),
332
+ profiles: profiles.map((profile) => ({
333
+ id: profile.id,
334
+ name: profile.name,
335
+ providerType: String(profile.provider_type),
336
+ bucketName: profile.bucket_name,
337
+ region: profile.region,
338
+ endpointUrl: profile.endpoint_url,
339
+ basePath: profile.base_path,
340
+ pathTemplate: profile.path_template,
341
+ forcePathStyle: profile.force_path_style,
342
+ isDefault: profile.is_default,
343
+ isActive: profile.is_active,
344
+ testStatus: String(profile.test_status),
345
+ lastTestedAt: profile.last_tested_at,
346
+ updatedAt: profile.updated_at,
347
+ })),
348
+ };
349
+ }
350
+ async getThemeConfigOverview() {
351
+ const settings = await this.settingService.getSettingValues([...THEME_SETTING_KEYS]);
352
+ const configuredTokenCount = THEME_SETTING_KEYS.filter((key) => this.hasConfigValue(settings[key])).length;
353
+ return {
354
+ status: {
355
+ isConfigured: this.hasConfigValue(settings['system-name']) ||
356
+ this.hasConfigValue(settings['theme-primary-light']) ||
357
+ this.hasConfigValue(settings['theme-primary-dark']),
358
+ configuredTokenCount,
359
+ },
360
+ branding: {
361
+ systemName: this.toNullableString(settings['system-name']),
362
+ systemSlogan: this.toNullableString(settings['system-slogan']),
363
+ iconUrl: this.toNullableString(settings['icon-url']),
364
+ imageUrl: this.toNullableString(settings['image-url']),
365
+ },
366
+ presentation: {
367
+ mode: this.toNullableString(settings['theme-mode']),
368
+ font: this.toNullableString(settings['theme-font']),
369
+ textSize: this.toNullableString(settings['theme-text-size']),
370
+ radius: this.toNullableString(settings['theme-radius']),
371
+ },
372
+ palette: {
373
+ light: {
374
+ primary: this.toNullableString(settings['theme-primary-light']),
375
+ primaryForeground: this.toNullableString(settings['theme-primary-foreground-light']),
376
+ secondary: this.toNullableString(settings['theme-secondary-light']),
377
+ secondaryForeground: this.toNullableString(settings['theme-secondary-foreground-light']),
378
+ accent: this.toNullableString(settings['theme-accent-light']),
379
+ accentForeground: this.toNullableString(settings['theme-accent-foreground-light']),
380
+ muted: this.toNullableString(settings['theme-muted-light']),
381
+ mutedForeground: this.toNullableString(settings['theme-muted-foreground-light']),
382
+ background: this.toNullableString(settings['theme-background-light']),
383
+ backgroundForeground: this.toNullableString(settings['theme-background-foreground-light']),
384
+ card: this.toNullableString(settings['theme-card-light']),
385
+ cardForeground: this.toNullableString(settings['theme-card-foreground-light']),
386
+ },
387
+ dark: {
388
+ primary: this.toNullableString(settings['theme-primary-dark']),
389
+ primaryForeground: this.toNullableString(settings['theme-primary-foreground-dark']),
390
+ secondary: this.toNullableString(settings['theme-secondary-dark']),
391
+ secondaryForeground: this.toNullableString(settings['theme-secondary-foreground-dark']),
392
+ accent: this.toNullableString(settings['theme-accent-dark']),
393
+ accentForeground: this.toNullableString(settings['theme-accent-foreground-dark']),
394
+ muted: this.toNullableString(settings['theme-muted-dark']),
395
+ mutedForeground: this.toNullableString(settings['theme-muted-foreground-dark']),
396
+ background: this.toNullableString(settings['theme-background-dark']),
397
+ backgroundForeground: this.toNullableString(settings['theme-background-foreground-dark']),
398
+ card: this.toNullableString(settings['theme-card-dark']),
399
+ cardForeground: this.toNullableString(settings['theme-card-foreground-dark']),
400
+ },
401
+ },
402
+ };
403
+ }
404
+ getMissingSettingKeys(settings, requiredKeys) {
405
+ return requiredKeys.filter((key) => !this.hasConfigValue(settings[key]));
406
+ }
407
+ hasConfigValue(value) {
408
+ if (Array.isArray(value)) {
409
+ return value.length > 0;
410
+ }
411
+ if (typeof value === 'string') {
412
+ return value.trim().length > 0;
413
+ }
414
+ return value !== null && value !== undefined;
415
+ }
416
+ toNullableString(value) {
417
+ if (typeof value !== 'string') {
418
+ return value === null || value === undefined ? null : String(value);
419
+ }
420
+ const normalized = value.trim();
421
+ return normalized.length > 0 ? normalized : null;
422
+ }
423
+ toNullableUppercaseString(value) {
424
+ const normalized = this.toNullableString(value);
425
+ return normalized ? normalized.toUpperCase() : null;
426
+ }
427
+ normalizeProviderList(value) {
428
+ if (!Array.isArray(value)) {
429
+ return [];
430
+ }
431
+ return value.map((provider) => String(provider).toLowerCase());
19
432
  }
20
433
  async getHome(userId, locale) {
21
434
  const user = await this.prismaService.user.findUnique({
@@ -326,6 +739,7 @@ let DashboardCoreService = class DashboardCoreService {
326
739
  i: `widget-${item.id}`,
327
740
  component_id: item.component_id,
328
741
  slug: component.slug,
742
+ library_slug: component.library_slug,
329
743
  name: (locale === null || locale === void 0 ? void 0 : locale.name) || component.slug,
330
744
  description: (locale === null || locale === void 0 ? void 0 : locale.description) || '',
331
745
  x: item.x_axis,
@@ -398,8 +812,44 @@ let DashboardCoreService = class DashboardCoreService {
398
812
  if (!canAccess) {
399
813
  throw new common_1.ForbiddenException('Access denied to this dashboard');
400
814
  }
815
+ const userRoles = await this.prismaService.role_user.findMany({
816
+ where: { user_id: userId },
817
+ select: { role_id: true },
818
+ });
819
+ const userRoleIds = userRoles.map((item) => item.role_id);
820
+ if (userRoleIds.length === 0) {
821
+ throw new common_1.ForbiddenException('Access denied to this component');
822
+ }
823
+ const slugParts = componentSlug.split('.').filter(Boolean);
824
+ const requestedSlug = slugParts.length > 0 ? slugParts[slugParts.length - 1] : componentSlug;
825
+ const requestedLibrarySlug = slugParts.length > 1 ? slugParts[0] : undefined;
401
826
  const component = await this.prismaService.dashboard_component.findFirst({
402
- where: { slug: componentSlug },
827
+ where: {
828
+ AND: [
829
+ requestedLibrarySlug
830
+ ? {
831
+ OR: [
832
+ { slug: componentSlug },
833
+ {
834
+ slug: requestedSlug,
835
+ library_slug: requestedLibrarySlug,
836
+ },
837
+ ],
838
+ }
839
+ : {
840
+ OR: [{ slug: componentSlug }, { slug: requestedSlug }],
841
+ },
842
+ {
843
+ dashboard_component_role: {
844
+ some: {
845
+ role_id: {
846
+ in: userRoleIds,
847
+ },
848
+ },
849
+ },
850
+ },
851
+ ],
852
+ },
403
853
  include: {
404
854
  dashboard_component_locale: {
405
855
  where: {
@@ -411,7 +861,7 @@ let DashboardCoreService = class DashboardCoreService {
411
861
  },
412
862
  });
413
863
  if (!component) {
414
- throw new Error(`Component with slug '${componentSlug}' not found`);
864
+ throw new common_1.ForbiddenException('Access denied to this component');
415
865
  }
416
866
  let dashboardItem = await this.prismaService.dashboard_item.findFirst({
417
867
  where: {
@@ -420,6 +870,16 @@ let DashboardCoreService = class DashboardCoreService {
420
870
  },
421
871
  });
422
872
  if (!dashboardItem) {
873
+ const dashboardItems = await this.prismaService.dashboard_item.findMany({
874
+ where: {
875
+ dashboard_id: dashboard.id,
876
+ },
877
+ select: {
878
+ y_axis: true,
879
+ height: true,
880
+ },
881
+ });
882
+ const nextAvailableY = dashboardItems.reduce((maxY, item) => Math.max(maxY, item.y_axis + item.height), 0);
423
883
  dashboardItem = await this.prismaService.dashboard_item.create({
424
884
  data: {
425
885
  dashboard_id: dashboard.id,
@@ -427,7 +887,7 @@ let DashboardCoreService = class DashboardCoreService {
427
887
  width: component.width,
428
888
  height: component.height,
429
889
  x_axis: 0,
430
- y_axis: 0,
890
+ y_axis: nextAvailableY,
431
891
  },
432
892
  });
433
893
  }
@@ -436,6 +896,7 @@ let DashboardCoreService = class DashboardCoreService {
436
896
  i: `widget-${dashboardItem.id}`,
437
897
  component_id: component.id,
438
898
  slug: component.slug,
899
+ library_slug: component.library_slug,
439
900
  name: (locale === null || locale === void 0 ? void 0 : locale.name) || component.slug,
440
901
  description: (locale === null || locale === void 0 ? void 0 : locale.description) || '',
441
902
  x: dashboardItem.x_axis,
@@ -450,7 +911,43 @@ let DashboardCoreService = class DashboardCoreService {
450
911
  };
451
912
  }
452
913
  async removeWidgetFromUserDashboard(userId, slug, widgetId) {
453
- throw new Error('Not implemented yet');
914
+ const dashboard = await this.prismaService.dashboard.findFirst({
915
+ where: { slug },
916
+ });
917
+ if (!dashboard) {
918
+ throw new Error(`Dashboard with slug '${slug}' not found`);
919
+ }
920
+ const canAccess = await this.prismaService.dashboard_user.findFirst({
921
+ where: {
922
+ dashboard_id: dashboard.id,
923
+ user_id: userId,
924
+ },
925
+ select: { id: true },
926
+ });
927
+ if (!canAccess) {
928
+ throw new common_1.ForbiddenException('Access denied to this dashboard');
929
+ }
930
+ const parsedWidgetId = Number(widgetId.replace(/^widget-/, ''));
931
+ if (!Number.isInteger(parsedWidgetId) || parsedWidgetId <= 0) {
932
+ throw new common_1.BadRequestException('Invalid widget id');
933
+ }
934
+ const dashboardItem = await this.prismaService.dashboard_item.findFirst({
935
+ where: {
936
+ id: parsedWidgetId,
937
+ dashboard_id: dashboard.id,
938
+ },
939
+ select: { id: true },
940
+ });
941
+ if (!dashboardItem) {
942
+ throw new common_1.BadRequestException('Widget not found in this dashboard');
943
+ }
944
+ await this.prismaService.dashboard_item.delete({
945
+ where: { id: dashboardItem.id },
946
+ });
947
+ return {
948
+ success: true,
949
+ removedWidgetId: `widget-${dashboardItem.id}`,
950
+ };
454
951
  }
455
952
  async checkDashboardAccess(userId, slug, locale) {
456
953
  var _a;
@@ -739,10 +1236,121 @@ let DashboardCoreService = class DashboardCoreService {
739
1236
  });
740
1237
  });
741
1238
  }
1239
+ async getEmailNotificationStats(userId) {
1240
+ var _a, _b;
1241
+ const now = new Date();
1242
+ const periodStart = new Date(now);
1243
+ periodStart.setHours(0, 0, 0, 0);
1244
+ periodStart.setDate(periodStart.getDate() - 13);
1245
+ const periodEnd = new Date(now);
1246
+ periodEnd.setHours(23, 59, 59, 999);
1247
+ const toDateKey = (date) => {
1248
+ const year = date.getFullYear();
1249
+ const month = String(date.getMonth() + 1).padStart(2, '0');
1250
+ const day = String(date.getDate()).padStart(2, '0');
1251
+ return `${year}-${month}-${day}`;
1252
+ };
1253
+ try {
1254
+ const [cardsRows, chartRows] = await Promise.all([
1255
+ this.prismaService.$queryRaw `
1256
+ SELECT
1257
+ COUNT(*) FILTER (WHERE "status" IN ('received', 'read'))::bigint as received,
1258
+ COUNT(*) FILTER (WHERE "status" = 'read')::bigint as read,
1259
+ COUNT(*) FILTER (WHERE "status" = 'received' AND "read_at" IS NULL)::bigint as unread,
1260
+ COUNT(*) FILTER (WHERE "status" = 'error')::bigint as error
1261
+ FROM "mail_sent_user"
1262
+ WHERE "user_id" = ${userId}
1263
+ AND "created_at" >= ${periodStart}
1264
+ AND "created_at" <= ${periodEnd}
1265
+ `,
1266
+ this.prismaService.$queryRaw `
1267
+ SELECT
1268
+ DATE("created_at") as date,
1269
+ COUNT(*) FILTER (WHERE "status" IN ('received', 'read'))::bigint as received,
1270
+ COUNT(*) FILTER (WHERE "status" = 'read')::bigint as read
1271
+ FROM "mail_sent_user"
1272
+ WHERE "user_id" = ${userId}
1273
+ AND "created_at" >= ${periodStart}
1274
+ AND "created_at" <= ${periodEnd}
1275
+ GROUP BY DATE("created_at")
1276
+ ORDER BY date ASC
1277
+ `,
1278
+ ]);
1279
+ const cards = (_a = cardsRows[0]) !== null && _a !== void 0 ? _a : {
1280
+ received: BigInt(0),
1281
+ read: BigInt(0),
1282
+ unread: BigInt(0),
1283
+ error: BigInt(0),
1284
+ };
1285
+ const chartMap = new Map();
1286
+ for (const row of chartRows) {
1287
+ const rowDate = new Date(row.date);
1288
+ rowDate.setHours(0, 0, 0, 0);
1289
+ const key = toDateKey(rowDate);
1290
+ chartMap.set(key, {
1291
+ received: Number(row.received),
1292
+ read: Number(row.read),
1293
+ });
1294
+ }
1295
+ const dateFormatter = new Intl.DateTimeFormat('pt-BR', {
1296
+ day: '2-digit',
1297
+ month: '2-digit',
1298
+ });
1299
+ const chart = [];
1300
+ for (let i = 13; i >= 0; i--) {
1301
+ const day = new Date(now);
1302
+ day.setDate(day.getDate() - i);
1303
+ day.setHours(0, 0, 0, 0);
1304
+ const key = toDateKey(day);
1305
+ const values = (_b = chartMap.get(key)) !== null && _b !== void 0 ? _b : { received: 0, read: 0 };
1306
+ chart.push({
1307
+ date: dateFormatter.format(day),
1308
+ received: values.received,
1309
+ read: values.read,
1310
+ });
1311
+ }
1312
+ return {
1313
+ cards: {
1314
+ received: Number(cards.received),
1315
+ read: Number(cards.read),
1316
+ unread: Number(cards.unread),
1317
+ error: Number(cards.error),
1318
+ },
1319
+ chart,
1320
+ };
1321
+ }
1322
+ catch (error) {
1323
+ this.logger.error('Error loading email notification stats:', error);
1324
+ const dateFormatter = new Intl.DateTimeFormat('pt-BR', {
1325
+ day: '2-digit',
1326
+ month: '2-digit',
1327
+ });
1328
+ const chart = [];
1329
+ for (let i = 13; i >= 0; i--) {
1330
+ const day = new Date(now);
1331
+ day.setDate(day.getDate() - i);
1332
+ chart.push({
1333
+ date: dateFormatter.format(day),
1334
+ received: 0,
1335
+ read: 0,
1336
+ });
1337
+ }
1338
+ return {
1339
+ cards: {
1340
+ received: 0,
1341
+ read: 0,
1342
+ unread: 0,
1343
+ error: 0,
1344
+ },
1345
+ chart,
1346
+ };
1347
+ }
1348
+ }
742
1349
  async getWidgetsData(userId, locale) {
743
- const [accountSecurity, activityTimeline, loginHistory, profile, quickStats, userRoles, userSessions] = await Promise.all([
1350
+ const [accountSecurity, activityTimeline, emailNotifications, loginHistory, profile, quickStats, userRoles, userSessions] = await Promise.all([
744
1351
  this.getAccountSecurity(userId),
745
1352
  this.getActivityTimeline(userId),
1353
+ this.getEmailNotificationStats(userId),
746
1354
  this.getLoginHistory(userId),
747
1355
  this.getProfile(userId),
748
1356
  this.getQuickStats(userId),
@@ -752,6 +1360,7 @@ let DashboardCoreService = class DashboardCoreService {
752
1360
  return {
753
1361
  accountSecurity,
754
1362
  activityTimeline,
1363
+ emailNotifications,
755
1364
  loginHistory,
756
1365
  profile,
757
1366
  quickStats,
@@ -780,8 +1389,9 @@ let DashboardCoreService = class DashboardCoreService {
780
1389
  }
781
1390
  };
782
1391
  exports.DashboardCoreService = DashboardCoreService;
783
- exports.DashboardCoreService = DashboardCoreService = __decorate([
1392
+ exports.DashboardCoreService = DashboardCoreService = DashboardCoreService_1 = __decorate([
784
1393
  (0, common_1.Injectable)(),
785
- __metadata("design:paramtypes", [api_prisma_1.PrismaService])
1394
+ __metadata("design:paramtypes", [api_prisma_1.PrismaService,
1395
+ setting_service_1.SettingService])
786
1396
  ], DashboardCoreService);
787
1397
  //# sourceMappingURL=dashboard-core.service.js.map