@solidstarters/solid-core 1.2.134 → 1.2.136

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 (300) hide show
  1. package/dist/controllers/ai-interaction.controller.d.ts +46 -0
  2. package/dist/controllers/ai-interaction.controller.d.ts.map +1 -0
  3. package/dist/controllers/ai-interaction.controller.js +204 -0
  4. package/dist/controllers/ai-interaction.controller.js.map +1 -0
  5. package/dist/controllers/dashboard-question-sql-dataset-config.controller.d.ts +43 -0
  6. package/dist/controllers/dashboard-question-sql-dataset-config.controller.d.ts.map +1 -0
  7. package/dist/controllers/dashboard-question-sql-dataset-config.controller.js +179 -0
  8. package/dist/controllers/dashboard-question-sql-dataset-config.controller.js.map +1 -0
  9. package/dist/controllers/dashboard-question.controller.d.ts +45 -0
  10. package/dist/controllers/dashboard-question.controller.d.ts.map +1 -0
  11. package/dist/controllers/dashboard-question.controller.js +194 -0
  12. package/dist/controllers/dashboard-question.controller.js.map +1 -0
  13. package/dist/controllers/dashboard-variable.controller.d.ts +43 -0
  14. package/dist/controllers/dashboard-variable.controller.d.ts.map +1 -0
  15. package/dist/controllers/dashboard-variable.controller.js +179 -0
  16. package/dist/controllers/dashboard-variable.controller.js.map +1 -0
  17. package/dist/controllers/dashboard.controller.d.ts +45 -0
  18. package/dist/controllers/dashboard.controller.d.ts.map +1 -0
  19. package/dist/controllers/dashboard.controller.js +192 -0
  20. package/dist/controllers/dashboard.controller.js.map +1 -0
  21. package/dist/controllers/test.controller.d.ts.map +1 -1
  22. package/dist/controllers/test.controller.js.map +1 -1
  23. package/dist/decorators/dashboard-question-data-provider.decorator.d.ts +3 -0
  24. package/dist/decorators/dashboard-question-data-provider.decorator.d.ts.map +1 -0
  25. package/dist/decorators/dashboard-question-data-provider.decorator.js +11 -0
  26. package/dist/decorators/dashboard-question-data-provider.decorator.js.map +1 -0
  27. package/dist/decorators/dashboard-selection-provider.decorator.d.ts +3 -0
  28. package/dist/decorators/dashboard-selection-provider.decorator.d.ts.map +1 -0
  29. package/dist/decorators/dashboard-selection-provider.decorator.js +11 -0
  30. package/dist/decorators/dashboard-selection-provider.decorator.js.map +1 -0
  31. package/dist/dtos/create-ai-interaction.dto.d.ts +14 -0
  32. package/dist/dtos/create-ai-interaction.dto.d.ts.map +1 -0
  33. package/dist/dtos/create-ai-interaction.dto.js +90 -0
  34. package/dist/dtos/create-ai-interaction.dto.js.map +1 -0
  35. package/dist/dtos/create-dashboard-question-sql-dataset-config.dto.d.ts +12 -0
  36. package/dist/dtos/create-dashboard-question-sql-dataset-config.dto.d.ts.map +1 -0
  37. package/dist/dtos/create-dashboard-question-sql-dataset-config.dto.js +77 -0
  38. package/dist/dtos/create-dashboard-question-sql-dataset-config.dto.js.map +1 -0
  39. package/dist/dtos/create-dashboard-question.dto.d.ts +17 -0
  40. package/dist/dtos/create-dashboard-question.dto.d.ts.map +1 -0
  41. package/dist/dtos/create-dashboard-question.dto.js +105 -0
  42. package/dist/dtos/create-dashboard-question.dto.js.map +1 -0
  43. package/dist/dtos/create-dashboard-variable.dto.d.ts +18 -0
  44. package/dist/dtos/create-dashboard-variable.dto.d.ts.map +1 -0
  45. package/dist/dtos/create-dashboard-variable.dto.js +97 -0
  46. package/dist/dtos/create-dashboard-variable.dto.js.map +1 -0
  47. package/dist/dtos/create-dashboard.dto.d.ts +15 -0
  48. package/dist/dtos/create-dashboard.dto.d.ts.map +1 -0
  49. package/dist/dtos/create-dashboard.dto.js +90 -0
  50. package/dist/dtos/create-dashboard.dto.js.map +1 -0
  51. package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.d.ts +8 -0
  52. package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.d.ts.map +1 -0
  53. package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.js +52 -0
  54. package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.js.map +1 -0
  55. package/dist/dtos/invoke-ai-prompt.dto.d.ts +4 -0
  56. package/dist/dtos/invoke-ai-prompt.dto.d.ts.map +1 -0
  57. package/dist/dtos/invoke-ai-prompt.dto.js +25 -0
  58. package/dist/dtos/invoke-ai-prompt.dto.js.map +1 -0
  59. package/dist/dtos/update-ai-interaction.dto.d.ts +15 -0
  60. package/dist/dtos/update-ai-interaction.dto.d.ts.map +1 -0
  61. package/dist/dtos/update-ai-interaction.dto.js +96 -0
  62. package/dist/dtos/update-ai-interaction.dto.js.map +1 -0
  63. package/dist/dtos/update-dashboard-question-sql-dataset-config.dto.d.ts +13 -0
  64. package/dist/dtos/update-dashboard-question-sql-dataset-config.dto.d.ts.map +1 -0
  65. package/dist/dtos/update-dashboard-question-sql-dataset-config.dto.js +86 -0
  66. package/dist/dtos/update-dashboard-question-sql-dataset-config.dto.js.map +1 -0
  67. package/dist/dtos/update-dashboard-question.dto.d.ts +18 -0
  68. package/dist/dtos/update-dashboard-question.dto.d.ts.map +1 -0
  69. package/dist/dtos/update-dashboard-question.dto.js +112 -0
  70. package/dist/dtos/update-dashboard-question.dto.js.map +1 -0
  71. package/dist/dtos/update-dashboard-variable.dto.d.ts +15 -0
  72. package/dist/dtos/update-dashboard-variable.dto.d.ts.map +1 -0
  73. package/dist/dtos/update-dashboard-variable.dto.js +95 -0
  74. package/dist/dtos/update-dashboard-variable.dto.js.map +1 -0
  75. package/dist/dtos/update-dashboard.dto.d.ts +16 -0
  76. package/dist/dtos/update-dashboard.dto.d.ts.map +1 -0
  77. package/dist/dtos/update-dashboard.dto.js +96 -0
  78. package/dist/dtos/update-dashboard.dto.js.map +1 -0
  79. package/dist/entities/ai-interaction.entity.d.ts +15 -0
  80. package/dist/entities/ai-interaction.entity.d.ts.map +1 -0
  81. package/dist/entities/ai-interaction.entity.js +70 -0
  82. package/dist/entities/ai-interaction.entity.js.map +1 -0
  83. package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts +13 -0
  84. package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts.map +1 -0
  85. package/dist/entities/dashboard-question-sql-dataset-config.entity.js +60 -0
  86. package/dist/entities/dashboard-question-sql-dataset-config.entity.js.map +1 -0
  87. package/dist/entities/dashboard-question.entity.d.ts +16 -0
  88. package/dist/entities/dashboard-question.entity.d.ts.map +1 -0
  89. package/dist/entities/dashboard-question.entity.js +71 -0
  90. package/dist/entities/dashboard-question.entity.js.map +1 -0
  91. package/dist/entities/dashboard-variable.entity.d.ts +15 -0
  92. package/dist/entities/dashboard-variable.entity.d.ts.map +1 -0
  93. package/dist/entities/dashboard-variable.entity.js +73 -0
  94. package/dist/entities/dashboard-variable.entity.js.map +1 -0
  95. package/dist/entities/dashboard.entity.d.ts +12 -0
  96. package/dist/entities/dashboard.entity.d.ts.map +1 -0
  97. package/dist/entities/dashboard.entity.js +50 -0
  98. package/dist/entities/dashboard.entity.js.map +1 -0
  99. package/dist/helpers/solid-registry.d.ts +9 -1
  100. package/dist/helpers/solid-registry.d.ts.map +1 -1
  101. package/dist/helpers/solid-registry.js +32 -0
  102. package/dist/helpers/solid-registry.js.map +1 -1
  103. package/dist/index.d.ts +10 -0
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +10 -0
  106. package/dist/index.js.map +1 -1
  107. package/dist/interfaces.d.ts +26 -1
  108. package/dist/interfaces.d.ts.map +1 -1
  109. package/dist/interfaces.js.map +1 -1
  110. package/dist/jobs/database/trigger-mcp-client-publisher-database.service.d.ts +11 -0
  111. package/dist/jobs/database/trigger-mcp-client-publisher-database.service.d.ts.map +1 -0
  112. package/dist/jobs/database/trigger-mcp-client-publisher-database.service.js +39 -0
  113. package/dist/jobs/database/trigger-mcp-client-publisher-database.service.js.map +1 -0
  114. package/dist/jobs/database/trigger-mcp-client-queue-options.d.ts +8 -0
  115. package/dist/jobs/database/trigger-mcp-client-queue-options.d.ts.map +1 -0
  116. package/dist/jobs/database/trigger-mcp-client-queue-options.js +10 -0
  117. package/dist/jobs/database/trigger-mcp-client-queue-options.js.map +1 -0
  118. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts +16 -0
  119. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts.map +1 -0
  120. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +71 -0
  121. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -0
  122. package/dist/mappers/dashboard-mapper.d.ts +6 -0
  123. package/dist/mappers/dashboard-mapper.d.ts.map +1 -0
  124. package/dist/mappers/dashboard-mapper.js +60 -0
  125. package/dist/mappers/dashboard-mapper.js.map +1 -0
  126. package/dist/repository/dashboard.repository.d.ts +9 -0
  127. package/dist/repository/dashboard.repository.d.ts.map +1 -0
  128. package/dist/repository/dashboard.repository.js +98 -0
  129. package/dist/repository/dashboard.repository.js.map +1 -0
  130. package/dist/seeders/module-metadata-seeder.service.d.ts +5 -1
  131. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  132. package/dist/seeders/module-metadata-seeder.service.js +18 -2
  133. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  134. package/dist/seeders/seed-data/solid-core-metadata.json +4172 -2411
  135. package/dist/services/ai-interaction.service.d.ts +31 -0
  136. package/dist/services/ai-interaction.service.d.ts.map +1 -0
  137. package/dist/services/ai-interaction.service.js +182 -0
  138. package/dist/services/ai-interaction.service.js.map +1 -0
  139. package/dist/services/chatter-message.service.d.ts.map +1 -1
  140. package/dist/services/chatter-message.service.js +8 -6
  141. package/dist/services/chatter-message.service.js.map +1 -1
  142. package/dist/services/dashboard-question-sql-dataset-config.service.d.ts +22 -0
  143. package/dist/services/dashboard-question-sql-dataset-config.service.d.ts.map +1 -0
  144. package/dist/services/dashboard-question-sql-dataset-config.service.js +56 -0
  145. package/dist/services/dashboard-question-sql-dataset-config.service.js.map +1 -0
  146. package/dist/services/dashboard-question.service.d.ts +29 -0
  147. package/dist/services/dashboard-question.service.d.ts.map +1 -0
  148. package/dist/services/dashboard-question.service.js +117 -0
  149. package/dist/services/dashboard-question.service.js.map +1 -0
  150. package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.d.ts +12 -0
  151. package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.d.ts.map +1 -0
  152. package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.js +55 -0
  153. package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.js.map +1 -0
  154. package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.d.ts +11 -0
  155. package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.d.ts.map +1 -0
  156. package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.js +45 -0
  157. package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.js.map +1 -0
  158. package/dist/services/dashboard-variable.service.d.ts +23 -0
  159. package/dist/services/dashboard-variable.service.d.ts.map +1 -0
  160. package/dist/services/dashboard-variable.service.js +57 -0
  161. package/dist/services/dashboard-variable.service.js.map +1 -0
  162. package/dist/services/dashboard.service.d.ts +38 -0
  163. package/dist/services/dashboard.service.d.ts.map +1 -0
  164. package/dist/services/dashboard.service.js +179 -0
  165. package/dist/services/dashboard.service.js.map +1 -0
  166. package/dist/services/field-metadata.service.d.ts.map +1 -1
  167. package/dist/services/field-metadata.service.js +1 -0
  168. package/dist/services/field-metadata.service.js.map +1 -1
  169. package/dist/services/import-transaction.service.d.ts +3 -1
  170. package/dist/services/import-transaction.service.d.ts.map +1 -1
  171. package/dist/services/import-transaction.service.js +22 -0
  172. package/dist/services/import-transaction.service.js.map +1 -1
  173. package/dist/services/list-of-values.service.d.ts +1 -0
  174. package/dist/services/list-of-values.service.d.ts.map +1 -1
  175. package/dist/services/list-of-values.service.js +3 -0
  176. package/dist/services/list-of-values.service.js.map +1 -1
  177. package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
  178. package/dist/services/menu-item-metadata.service.js +1 -1
  179. package/dist/services/menu-item-metadata.service.js.map +1 -1
  180. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts +36 -0
  181. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts.map +1 -0
  182. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js +89 -0
  183. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js.map +1 -0
  184. package/dist/services/question-data-providers/helpers.d.ts +7 -0
  185. package/dist/services/question-data-providers/helpers.d.ts.map +1 -0
  186. package/dist/services/question-data-providers/helpers.js +25 -0
  187. package/dist/services/question-data-providers/helpers.js.map +1 -0
  188. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts +17 -0
  189. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts.map +1 -0
  190. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js +70 -0
  191. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js.map +1 -0
  192. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts +19 -0
  193. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts.map +1 -0
  194. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js +92 -0
  195. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js.map +1 -0
  196. package/dist/services/queues/publisher-factory.service.js +1 -1
  197. package/dist/services/queues/publisher-factory.service.js.map +1 -1
  198. package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
  199. package/dist/services/scheduled-jobs/scheduler.service.js +22 -11
  200. package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
  201. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.d.ts +11 -0
  202. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.d.ts.map +1 -0
  203. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js +46 -0
  204. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js.map +1 -0
  205. package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.d.ts +11 -0
  206. package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.d.ts.map +1 -0
  207. package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.js +47 -0
  208. package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.js.map +1 -0
  209. package/dist/services/solid-introspect.service.d.ts +2 -0
  210. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  211. package/dist/services/solid-introspect.service.js +28 -0
  212. package/dist/services/solid-introspect.service.js.map +1 -1
  213. package/dist/services/sql-expression-resolver.service.d.ts +9 -0
  214. package/dist/services/sql-expression-resolver.service.d.ts.map +1 -0
  215. package/dist/services/sql-expression-resolver.service.js +105 -0
  216. package/dist/services/sql-expression-resolver.service.js.map +1 -0
  217. package/dist/solid-core.module.d.ts.map +1 -1
  218. package/dist/solid-core.module.js +75 -1
  219. package/dist/solid-core.module.js.map +1 -1
  220. package/dist/subscribers/dashboard-question-sql-dataset-config.subscriber.d.ts +16 -0
  221. package/dist/subscribers/dashboard-question-sql-dataset-config.subscriber.d.ts.map +1 -0
  222. package/dist/subscribers/dashboard-question-sql-dataset-config.subscriber.js +72 -0
  223. package/dist/subscribers/dashboard-question-sql-dataset-config.subscriber.js.map +1 -0
  224. package/dist/subscribers/dashboard-question.subscriber.d.ts +16 -0
  225. package/dist/subscribers/dashboard-question.subscriber.d.ts.map +1 -0
  226. package/dist/subscribers/dashboard-question.subscriber.js +72 -0
  227. package/dist/subscribers/dashboard-question.subscriber.js.map +1 -0
  228. package/dist/subscribers/dashboard-variable.subscriber.d.ts +16 -0
  229. package/dist/subscribers/dashboard-variable.subscriber.d.ts.map +1 -0
  230. package/dist/subscribers/dashboard-variable.subscriber.js +72 -0
  231. package/dist/subscribers/dashboard-variable.subscriber.js.map +1 -0
  232. package/dist/subscribers/dashboard.subscriber.d.ts +15 -0
  233. package/dist/subscribers/dashboard.subscriber.d.ts.map +1 -0
  234. package/dist/subscribers/dashboard.subscriber.js +56 -0
  235. package/dist/subscribers/dashboard.subscriber.js.map +1 -0
  236. package/dist/tsconfig.tsbuildinfo +1 -1
  237. package/package.json +1 -1
  238. package/src/controllers/ai-interaction.controller.ts +104 -0
  239. package/src/controllers/dashboard-question-sql-dataset-config.controller.ts +93 -0
  240. package/src/controllers/dashboard-question.controller.ts +104 -0
  241. package/src/controllers/dashboard-variable.controller.ts +93 -0
  242. package/src/controllers/dashboard.controller.ts +99 -0
  243. package/src/controllers/test.controller.ts +1 -2
  244. package/src/decorators/dashboard-question-data-provider.decorator.ts +7 -0
  245. package/src/decorators/dashboard-selection-provider.decorator.ts +7 -0
  246. package/src/dtos/create-ai-interaction.dto.ts +60 -0
  247. package/src/dtos/create-dashboard-question-sql-dataset-config.dto.ts +42 -0
  248. package/src/dtos/create-dashboard-question.dto.ts +63 -0
  249. package/src/dtos/create-dashboard-variable.dto.ts +56 -0
  250. package/src/dtos/create-dashboard.dto.ts +53 -0
  251. package/src/dtos/dashboard-variable-selection-dynamic-query.dto.ts +29 -0
  252. package/src/dtos/invoke-ai-prompt.dto.ts +6 -0
  253. package/src/dtos/update-ai-interaction.dto.ts +65 -0
  254. package/src/dtos/update-dashboard-question-sql-dataset-config.dto.ts +49 -0
  255. package/src/dtos/update-dashboard-question.dto.ts +68 -0
  256. package/src/dtos/update-dashboard-variable.dto.ts +54 -0
  257. package/src/dtos/update-dashboard.dto.ts +57 -0
  258. package/src/entities/ai-interaction.entity.ts +39 -0
  259. package/src/entities/dashboard-question-sql-dataset-config.entity.ts +25 -0
  260. package/src/entities/dashboard-question.entity.ts +33 -0
  261. package/src/entities/dashboard-variable.entity.ts +30 -0
  262. package/src/entities/dashboard.entity.ts +21 -0
  263. package/src/helpers/solid-registry.ts +44 -2
  264. package/src/index.ts +10 -2
  265. package/src/interfaces.ts +57 -29
  266. package/src/jobs/database/trigger-mcp-client-publisher-database.service.ts +22 -0
  267. package/src/jobs/database/trigger-mcp-client-queue-options.ts +9 -0
  268. package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +71 -0
  269. package/src/mappers/dashboard-mapper.ts +52 -0
  270. package/src/repository/dashboard.repository.ts +101 -0
  271. package/src/seeders/module-metadata-seeder.service.ts +21 -1
  272. package/src/seeders/seed-data/solid-core-metadata.json +4175 -2414
  273. package/src/services/ai-interaction.service.ts +163 -0
  274. package/src/services/chatter-message.service.ts +12 -6
  275. package/src/services/dashboard-question-sql-dataset-config.service.ts +34 -0
  276. package/src/services/dashboard-question.service.ts +115 -0
  277. package/src/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.ts +56 -0
  278. package/src/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.ts +37 -0
  279. package/src/services/dashboard-variable.service.ts +36 -0
  280. package/src/services/dashboard.service.ts +147 -0
  281. package/src/services/field-metadata.service.ts +1 -0
  282. package/src/services/import-transaction.service.ts +29 -1
  283. package/src/services/list-of-values.service.ts +5 -0
  284. package/src/services/menu-item-metadata.service.ts +2 -1
  285. package/src/services/question-data-providers/chartjs-sql-data-provider.service.ts +125 -0
  286. package/src/services/question-data-providers/helpers.ts +30 -0
  287. package/src/services/question-data-providers/prime-react-datatable-sql-data-provider.service.ts +78 -0
  288. package/src/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.ts +119 -0
  289. package/src/services/question-data-providers/test.sql +1 -0
  290. package/src/services/queues/publisher-factory.service.ts +1 -1
  291. package/src/services/scheduled-jobs/scheduler.service.ts +32 -64
  292. package/src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts +41 -0
  293. package/src/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.ts +41 -0
  294. package/src/services/solid-introspect.service.ts +42 -0
  295. package/src/services/sql-expression-resolver.service.ts +125 -0
  296. package/src/solid-core.module.ts +77 -2
  297. package/src/subscribers/dashboard-question-sql-dataset-config.subscriber.ts +61 -0
  298. package/src/subscribers/dashboard-question.subscriber.ts +62 -0
  299. package/src/subscribers/dashboard-variable.subscriber.ts +63 -0
  300. package/src/subscribers/dashboard.subscriber.ts +43 -0
@@ -0,0 +1,163 @@
1
+ import { BadRequestException, Logger, Injectable } from '@nestjs/common';
2
+ import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
3
+ import { DiscoveryService, ModuleRef } from "@nestjs/core";
4
+ import { EntityManager, Repository } from 'typeorm';
5
+
6
+ import { CRUDService } from 'src/services/crud.service';
7
+ import { ModelMetadataService } from 'src/services/model-metadata.service';
8
+ import { ModuleMetadataService } from 'src/services/module-metadata.service';
9
+ import { ConfigService } from '@nestjs/config';
10
+ import { FileService } from 'src/services/file.service';
11
+ import { CrudHelperService } from 'src/services/crud-helper.service';
12
+ import { spawn } from 'child_process';
13
+ import { AiInteraction } from '../entities/ai-interaction.entity';
14
+ import * as fs from 'fs/promises';
15
+ import { McpResponse, TriggerMcpClientOptions } from 'src/interfaces';
16
+ import { PublisherFactory } from './queues/publisher-factory.service';
17
+ import { RequestContextService } from './request-context.service';
18
+ import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
19
+
20
+ @Injectable()
21
+ export class AiInteractionService extends CRUDService<AiInteraction> {
22
+ private readonly logger = new Logger(AiInteractionService.name);
23
+
24
+ constructor(
25
+ readonly modelMetadataService: ModelMetadataService,
26
+ readonly moduleMetadataService: ModuleMetadataService,
27
+ readonly configService: ConfigService,
28
+ readonly fileService: FileService,
29
+ readonly discoveryService: DiscoveryService,
30
+ readonly crudHelperService: CrudHelperService,
31
+ @InjectEntityManager()
32
+ readonly entityManager: EntityManager,
33
+ @InjectRepository(AiInteraction, 'default')
34
+ readonly repo: Repository<AiInteraction>,
35
+ readonly moduleRef: ModuleRef,
36
+ readonly publisherFactory: PublisherFactory<TriggerMcpClientOptions>,
37
+ readonly requestContextService: RequestContextService,
38
+
39
+ ) {
40
+ super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'aiInteraction', 'solid-core', moduleRef);
41
+ }
42
+
43
+ async triggerMcpClientJob(prompt: string): Promise<string> {
44
+ const activeUser: ActiveUserData = this.requestContextService.getActiveUser();
45
+
46
+ const aiInteraction = await this.create({
47
+ userId: activeUser.sub,
48
+ threadId: `thread-${activeUser.sub}`,
49
+ role: 'human',
50
+ message: prompt,
51
+ contentType: '',
52
+ errorMessage: '',
53
+ modelUsed: '',
54
+ responseTimeMs: 0,
55
+ metadata: ''
56
+ });
57
+ const m = {
58
+ payload: {
59
+ aiInteractionId: aiInteraction.id,
60
+ },
61
+ parentEntity: 'aiInteraction',
62
+ parentEntityId: aiInteraction.id,
63
+ };
64
+
65
+ return await this.publisherFactory.publish(m, 'TriggerMcpClientPublisher');
66
+ }
67
+
68
+ /**
69
+ * Runs the Python MCP client with a prompt and returns the parsed JSON embedded in the 'response'.
70
+ * @param prompt - The question or instruction to send to the MCP client.
71
+ * @returns The parsed object inside the 'response' field of the JSON output.
72
+ */
73
+ async runMcpPrompt(prompt: string): Promise<McpResponse> {
74
+ const pythonExecutable = process.env.MCP_PYTHON_EXECUTABLE;
75
+ const mcpClient = process.env.MCP_CLIENT;
76
+
77
+ // TODO: We can return an error if the above env variables are not properly setup...
78
+ if (!pythonExecutable || !mcpClient) {
79
+ throw new BadRequestException('SolidX AI MCP python executable or client path not configured.');
80
+ }
81
+
82
+ // Check if both paths are valid and accessible
83
+ try {
84
+ const [pyStat, clientStat] = await Promise.all([
85
+ fs.stat(pythonExecutable),
86
+ fs.stat(mcpClient),
87
+ ]);
88
+
89
+ if (!pyStat.isFile()) {
90
+ throw new BadRequestException(`MCP_PYTHON_EXECUTABLE path is not a file: ${pythonExecutable}`);
91
+ }
92
+
93
+ if (!clientStat.isFile()) {
94
+ throw new BadRequestException(`MCP_CLIENT path is not a file: ${mcpClient}`);
95
+ }
96
+
97
+ } catch (err: any) {
98
+ throw new BadRequestException(`Invalid MCP executable or client path: ${err.message}`);
99
+ }
100
+
101
+ // TODO: Refactor to use the command.service.ts instead...
102
+ return new Promise((resolve, reject) => {
103
+ this.logger.log(`Attempting to run command:`)
104
+ this.logger.log(`${pythonExecutable} ${mcpClient} ${prompt}`);
105
+
106
+ const python = spawn(pythonExecutable, [mcpClient, prompt]);
107
+
108
+ let stdout = '';
109
+ let stderr = '';
110
+
111
+ python.stdout.on('data', (data) => {
112
+ stdout += data.toString();
113
+ });
114
+
115
+ python.stderr.on('data', (data) => {
116
+ stderr += data.toString();
117
+ });
118
+
119
+ python.on('close', (code) => {
120
+ this.logger.log(`Python script exited with code ${code}`);
121
+
122
+ if (code !== 0) {
123
+ this.logger.error(`Python script exited with a non-zero exit code: ${stderr}`);
124
+ return reject(new Error(`Python script exited with a non-zero exit code: ${stderr}`));
125
+ }
126
+
127
+ try {
128
+ this.logger.log(`Python script exited with zero exit code: ${stdout}`);
129
+ const raw: McpResponse = JSON.parse(stdout);
130
+
131
+ // if (!raw.success) {
132
+ // return reject(new Error(`MCP error: ${raw.errors?.join(', ')}`));
133
+ // }
134
+ // let cleaned = raw.response.trim();
135
+
136
+ // Don't need to re-parse this...
137
+ // const parsed = JSON.parse(cleaned);
138
+ // resolve(cleaned);
139
+
140
+ resolve(raw);
141
+ } catch (err: any) {
142
+ reject(new Error(`Mcp Invocation Failed: ${err.message}`));
143
+ }
144
+ });
145
+ });
146
+ }
147
+
148
+ cleanResponse(response: string) {
149
+ this.logger.log(`mcp server response is: ${response}`);
150
+
151
+ // Remove markdown-style code block wrapper
152
+ if (response.startsWith('```json')) {
153
+ response = response.replace(/^```json/, '').trim();
154
+ }
155
+ if (response.endsWith('```')) {
156
+ response = response.replace(/```$/, '').trim();
157
+ }
158
+ this.logger.log(`mcp server response after removing doc tags is: ${response}`);
159
+
160
+ return response;
161
+ }
162
+
163
+ }
@@ -125,7 +125,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage>{
125
125
 
126
126
  for (const field of auditFields) {
127
127
  const fieldValue = entity[field.name];
128
- if (fieldValue !== undefined && fieldValue !== null) {
128
+ if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {
129
129
  const messageDetail = new ChatterMessageDetails();
130
130
  messageDetail.chatterMessage = savedMessage;
131
131
  messageDetail.fieldName = field.name;
@@ -289,19 +289,25 @@ private formatFieldValueDisplay(field: any, value: any): string {
289
289
  }
290
290
 
291
291
  private hasValueChanged(newValue: any, oldValue: any): boolean {
292
- if (newValue === oldValue) {
292
+ if (
293
+ (newValue === null || newValue === undefined) &&
294
+ (oldValue === null || oldValue === undefined)
295
+ ) {
293
296
  return false;
294
297
  }
295
298
 
296
- if (newValue === null && oldValue === null) {
299
+ if (newValue === oldValue) {
297
300
  return false;
298
301
  }
299
302
 
300
- if (newValue === undefined && oldValue === undefined) {
301
- return false;
303
+ if (Array.isArray(newValue) && Array.isArray(oldValue)) {
304
+ return JSON.stringify(newValue) !== JSON.stringify(oldValue);
302
305
  }
303
306
 
304
- if (Array.isArray(newValue) && Array.isArray(oldValue)) {
307
+ if (
308
+ typeof newValue === 'object' && newValue !== null &&
309
+ typeof oldValue === 'object' && oldValue !== null
310
+ ) {
305
311
  return JSON.stringify(newValue) !== JSON.stringify(oldValue);
306
312
  }
307
313
 
@@ -0,0 +1,34 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
3
+ import { DiscoveryService, ModuleRef } from "@nestjs/core";
4
+ import { EntityManager, Repository } from 'typeorm';
5
+
6
+ import { CRUDService } from 'src/services/crud.service';
7
+ import { ModelMetadataService } from 'src/services/model-metadata.service';
8
+ import { ModuleMetadataService } from 'src/services/module-metadata.service';
9
+ import { ConfigService } from '@nestjs/config';
10
+ import { FileService } from 'src/services/file.service';
11
+ import { CrudHelperService } from 'src/services/crud-helper.service';
12
+
13
+
14
+ import { DashboardQuestionSqlDatasetConfig } from '../entities/dashboard-question-sql-dataset-config.entity';
15
+
16
+ @Injectable()
17
+ export class DashboardQuestionSqlDatasetConfigService extends CRUDService<DashboardQuestionSqlDatasetConfig>{
18
+ constructor(
19
+ readonly modelMetadataService: ModelMetadataService,
20
+ readonly moduleMetadataService: ModuleMetadataService,
21
+ readonly configService: ConfigService,
22
+ readonly fileService: FileService,
23
+ readonly discoveryService: DiscoveryService,
24
+ readonly crudHelperService: CrudHelperService,
25
+ @InjectEntityManager()
26
+ readonly entityManager: EntityManager,
27
+ @InjectRepository(DashboardQuestionSqlDatasetConfig, 'default')
28
+ readonly repo: Repository<DashboardQuestionSqlDatasetConfig>,
29
+ readonly moduleRef: ModuleRef
30
+
31
+ ) {
32
+ super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService,entityManager, repo, 'dashboardQuestionSqlDatasetConfig', 'solid-core', moduleRef);
33
+ }
34
+ }
@@ -0,0 +1,115 @@
1
+ import { BadRequestException, Injectable, Logger, NotImplementedException } from '@nestjs/common';
2
+ import { DiscoveryService, ModuleRef } from "@nestjs/core";
3
+ import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
4
+ import { EntityManager, Repository } from 'typeorm';
5
+
6
+ import { ConfigService } from '@nestjs/config';
7
+ import { CrudHelperService } from 'src/services/crud-helper.service';
8
+ import { CRUDService } from 'src/services/crud.service';
9
+ import { FileService } from 'src/services/file.service';
10
+ import { ModelMetadataService } from 'src/services/model-metadata.service';
11
+ import { ModuleMetadataService } from 'src/services/module-metadata.service';
12
+
13
+
14
+ import { DashboardVariable } from 'src/entities/dashboard-variable.entity';
15
+ import { SolidRegistry } from 'src/helpers/solid-registry';
16
+ import { DashboardQuestion } from '../entities/dashboard-question.entity';
17
+ import { SqlExpression, SqlExpressionOperator } from './question-data-providers/chartjs-sql-data-provider.service';
18
+ import { DashboardService } from './dashboard.service';
19
+ import { Dashboard } from 'src/entities/dashboard.entity';
20
+
21
+ enum SOURCE_TYPE {
22
+ SQL = 'sql',
23
+ PROVIDER = 'provider',
24
+ }
25
+
26
+ const CHARTJS_SQL_DATA_PROVIDER_NAME = 'ChartJsSqlDataProvider';
27
+ const PRIME_REACT_METER_GROUP_SQL_DATA_PROVIDER_NAME = 'PrimeReactMeterGroupSqlDataProvider';
28
+ const PRIME_REACT_DATATABLE_SQL_DATA_PROVIDER_NAME = 'PrimeReactDatatableSqlDataProvider';
29
+
30
+ @Injectable()
31
+ export class DashboardQuestionService extends CRUDService<DashboardQuestion> {
32
+ private readonly logger = new Logger(this.constructor.name);
33
+ constructor(
34
+ readonly modelMetadataService: ModelMetadataService,
35
+ readonly moduleMetadataService: ModuleMetadataService,
36
+ readonly configService: ConfigService,
37
+ readonly fileService: FileService,
38
+ readonly discoveryService: DiscoveryService,
39
+ readonly crudHelperService: CrudHelperService,
40
+ @InjectEntityManager()
41
+ readonly entityManager: EntityManager,
42
+ @InjectRepository(DashboardQuestion, 'default')
43
+ readonly repo: Repository<DashboardQuestion>,
44
+ readonly moduleRef: ModuleRef,
45
+ readonly solidRegistry: SolidRegistry, // Assuming solidRegistry is injected for data providers
46
+ ) {
47
+ super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'dashboardQuestion', 'solid-core', moduleRef);
48
+ }
49
+
50
+ // Get the data for a specific question
51
+ async getData(id: number, inputExpressions: SqlExpression[] = [], isPreview = false): Promise<any> {
52
+ // Load the question
53
+ const question = await this.loadQuestion(id);
54
+ if (!question) {
55
+ throw new BadRequestException(`Question with id ${id} not found`);
56
+ }
57
+
58
+ // Get the dashbbard variables from the question
59
+ const dashboardVariables = question.dashboard?.dashboardVariables || [];
60
+ const expressions: SqlExpression[] = this.getExpressions(isPreview, dashboardVariables, inputExpressions);
61
+
62
+ // Try to resolve the dataProvider based on a combination of sourceType and visualisedAs
63
+ let dataProvider = null;
64
+
65
+ if (question.sourceType === SOURCE_TYPE.SQL && ['bar', 'pie', 'line', 'donut'].includes(question.visualisedAs)) {
66
+ dataProvider = this.solidRegistry.getDashboardQuestionDataProviderInstance(CHARTJS_SQL_DATA_PROVIDER_NAME);
67
+ }
68
+ if (question.sourceType === SOURCE_TYPE.SQL && ['prime-meter-group'].includes(question.visualisedAs)) {
69
+ dataProvider = this.solidRegistry.getDashboardQuestionDataProviderInstance(PRIME_REACT_METER_GROUP_SQL_DATA_PROVIDER_NAME);
70
+ }
71
+ if (question.sourceType === SOURCE_TYPE.SQL && ['prime-datatable'].includes(question.visualisedAs)) {
72
+ dataProvider = this.solidRegistry.getDashboardQuestionDataProviderInstance(PRIME_REACT_DATATABLE_SQL_DATA_PROVIDER_NAME);
73
+ }
74
+
75
+ if (!dataProvider) {
76
+ throw new NotImplementedException(`Invalid data source type ${question.sourceType}`);
77
+ }
78
+
79
+ return await dataProvider.getData(question, expressions);
80
+
81
+ }
82
+
83
+ private getExpressions(isPreview: boolean, dashboardVariables: DashboardVariable[], inputExpressions: SqlExpression[]) {
84
+ const expressions: SqlExpression[] = [];
85
+ if (isPreview) {
86
+ // Convert the dashboard variables into objects of interface type SqlExpression using the default value, default operator and the variable name
87
+ const expr: SqlExpression[] = dashboardVariables.map(variable => {
88
+ return {
89
+ variableName: variable.variableName,
90
+ operator: variable.defaultOperator as SqlExpressionOperator, // Assuming defaultOperator is a valid SqlExpressionOperator
91
+ value: JSON.parse(variable.defaultValue || '[]'), // Assuming defaultValue is a string or can be converted to a string array
92
+ };
93
+ });
94
+ expressions.push(...expr);
95
+ }
96
+ else {
97
+ expressions.push(...inputExpressions);
98
+ }
99
+ return expressions;
100
+ }
101
+
102
+ private async loadQuestion(id: number) {
103
+ const repo = this.entityManager.getRepository(DashboardQuestion);
104
+
105
+ // Load the dashboard record using the field
106
+ const question = await repo.findOne({
107
+ where: {
108
+ id,
109
+ },
110
+ relations: ['questionSqlDatasetConfigs', 'dashboard', 'dashboard.dashboardVariables'],
111
+ });
112
+ return question;
113
+ }
114
+
115
+ }
@@ -0,0 +1,56 @@
1
+ import { Injectable } from "@nestjs/common";
2
+ import { IDashboardVariableSelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from "../../interfaces";
3
+ // import localeCodes from 'locale-codes';
4
+ import { EntityManager } from "typeorm";
5
+ import { DashboardVariableSelectionProvider } from "src/decorators/dashboard-selection-provider.decorator";
6
+
7
+ @DashboardVariableSelectionProvider()
8
+ @Injectable()
9
+ export class DashboardVariableSQLDynamicProvider implements IDashboardVariableSelectionProvider<ISelectionProviderContext> {
10
+
11
+ constructor(private readonly entityManager: EntityManager) {
12
+ }
13
+
14
+ help(): string {
15
+ return "# Get the dashboard variable after executing the SQL query configured for the dashboard variable.\n";
16
+ }
17
+
18
+ name(): string {
19
+ return 'DashboardVariableSQLDynamicProvider';
20
+ }
21
+
22
+ async value(optionValue: string, ctxt: ISelectionProviderContext): Promise<ISelectionProviderValues | any> {
23
+ throw new Error("DashboardVariableSQLDynamicProvider does not support value method. Use values method instead.");
24
+ }
25
+
26
+ async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {
27
+ const { sql, limit, offset } = ctxt as unknown as { sql: string, limit?: number, offset?: number };
28
+ if (!sql) {
29
+ throw new Error("DashboardVariableSQLDynamicProvider requires a SQL query to be provided in the context.");
30
+ }
31
+
32
+ // Here you would execute the SQL query against your database
33
+ // For demonstration, let's assume we have a mock database function that executes the SQL query
34
+ const results = await this.entityManager.query(this.appendLimitOffset(sql), [limit, offset]);
35
+
36
+ // Transform the results into the expected format
37
+ return results.map((result: any) => {
38
+ const transformedResult: ISelectionProviderValues = {
39
+ value: result.value, // Assuming the result has a 'value' field
40
+ label: result.label, // Assuming the result has a 'label' field
41
+ // Add any other fields you need to transform here
42
+ };
43
+ return transformedResult;
44
+ });
45
+ }
46
+
47
+ appendLimitOffset(sql: string): string {
48
+ // Strip trailing semicolon if present
49
+ const trimmedSql = sql.trim().replace(/;$/, '');
50
+
51
+ // Append the LIMIT/OFFSET
52
+ const finalSql = `${trimmedSql} LIMIT $1 OFFSET $2`; // FIXME This works with PostgreSQL. for mysql use ?. For this we will need to identify the datasource using the model for the particular dashboard variable
53
+
54
+ return finalSql;
55
+ }
56
+ }
@@ -0,0 +1,37 @@
1
+ import { Injectable } from "@nestjs/common";
2
+ import { IDashboardVariableSelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from "../../interfaces";
3
+ // import localeCodes from 'locale-codes';
4
+ import { EntityManager } from "typeorm";
5
+ import { DashboardVariableSelectionProvider } from "src/decorators/dashboard-selection-provider.decorator";
6
+
7
+ @DashboardVariableSelectionProvider()
8
+ @Injectable()
9
+ export class DasbhoardVariableTestDynamicProvider implements IDashboardVariableSelectionProvider<ISelectionProviderContext> {
10
+
11
+ constructor(private readonly entityManager: EntityManager) {
12
+ }
13
+
14
+ help(): string {
15
+ return "# Get the dashboard variable values.\n";
16
+ }
17
+
18
+ name(): string {
19
+ return 'DasbhoardVariableTestDynamicProvider';
20
+ }
21
+
22
+ async value(optionValue: string, ctxt: ISelectionProviderContext): Promise<ISelectionProviderValues | any> {
23
+ throw new Error("DasbhoardVariableTestDynamicProvider does not support value method. Use values method instead.");
24
+ }
25
+
26
+ async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {
27
+ // Return some dummy data for testing
28
+ const { sql, limit, offset } = ctxt as unknown as { sql: string, limit?: number, offset?: number };
29
+ return [
30
+ { value: '1', label: 'Option 1' },
31
+ { value: '2', label: 'Option 2' },
32
+ { value: '3', label: 'Option 3' },
33
+ { value: '4', label: 'Option 4' },
34
+ ];
35
+ }
36
+
37
+ }
@@ -0,0 +1,36 @@
1
+ import { Injectable, Logger } from '@nestjs/common';
2
+ import { DiscoveryService, ModuleRef } from "@nestjs/core";
3
+ import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
4
+ import { EntityManager, Repository } from 'typeorm';
5
+
6
+ import { ConfigService } from '@nestjs/config';
7
+ import { CrudHelperService } from 'src/services/crud-helper.service';
8
+ import { CRUDService } from 'src/services/crud.service';
9
+ import { FileService } from 'src/services/file.service';
10
+ import { ModelMetadataService } from 'src/services/model-metadata.service';
11
+ import { ModuleMetadataService } from 'src/services/module-metadata.service';
12
+
13
+
14
+ import { DashboardVariable } from '../entities/dashboard-variable.entity';
15
+
16
+ @Injectable()
17
+ export class DashboardVariableService extends CRUDService<DashboardVariable> {
18
+ private readonly logger = new Logger(this.constructor.name);
19
+ constructor(
20
+ readonly modelMetadataService: ModelMetadataService,
21
+ readonly moduleMetadataService: ModuleMetadataService,
22
+ readonly configService: ConfigService,
23
+ readonly fileService: FileService,
24
+ readonly discoveryService: DiscoveryService,
25
+ readonly crudHelperService: CrudHelperService,
26
+ @InjectEntityManager()
27
+ readonly entityManager: EntityManager,
28
+ @InjectRepository(DashboardVariable, 'default')
29
+ readonly repo: Repository<DashboardVariable>,
30
+ readonly moduleRef: ModuleRef,
31
+ ) {
32
+ super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'dashboardVariable', 'solid-core', moduleRef);
33
+ }
34
+
35
+
36
+ }
@@ -0,0 +1,147 @@
1
+ import { Injectable, Logger, NotFoundException } from '@nestjs/common';
2
+ import { DiscoveryService, ModuleRef } from "@nestjs/core";
3
+ import { InjectEntityManager } from '@nestjs/typeorm';
4
+ import { EntityManager } from 'typeorm';
5
+
6
+ import { ConfigService } from '@nestjs/config';
7
+ import { CrudHelperService } from 'src/services/crud-helper.service';
8
+ import { CRUDService } from 'src/services/crud.service';
9
+ import { FileService } from 'src/services/file.service';
10
+ import { ModelMetadataService } from 'src/services/model-metadata.service';
11
+ import { ModuleMetadataService } from 'src/services/module-metadata.service';
12
+
13
+
14
+ import * as fs from 'fs/promises'; // Use the Promise-based version of fs for async/await
15
+ import { SelectionDynamicSourceType } from 'src/dtos/create-dashboard-variable.dto';
16
+ import { DashboardVariableSelectionDynamicQueryDto } from 'src/dtos/dashboard-variable-selection-dynamic-query.dto';
17
+ import { DashboardVariable } from 'src/entities/dashboard-variable.entity';
18
+ import { ModuleMetadataHelperService } from 'src/helpers/module-metadata-helper.service';
19
+ import { SolidRegistry } from 'src/helpers/solid-registry';
20
+ import { DashboardMapper } from 'src/mappers/dashboard-mapper';
21
+ import { DashboardRepository } from 'src/repository/dashboard.repository';
22
+ import { Dashboard } from '../entities/dashboard.entity';
23
+
24
+
25
+ export const SQL_DYNAMIC_PROVIDER_NAME = 'DashboardVariableSQLDynamicProvider';
26
+ @Injectable()
27
+ export class DashboardService extends CRUDService<Dashboard> {
28
+ private readonly logger = new Logger(this.constructor.name);
29
+ constructor(
30
+ readonly modelMetadataService: ModelMetadataService,
31
+ readonly moduleMetadataService: ModuleMetadataService,
32
+ readonly configService: ConfigService,
33
+ readonly fileService: FileService,
34
+ readonly discoveryService: DiscoveryService,
35
+ readonly crudHelperService: CrudHelperService,
36
+ @InjectEntityManager()
37
+ readonly entityManager: EntityManager,
38
+ readonly repo: DashboardRepository, // Assuming you have a DashboardRepository for custom queries
39
+ readonly moduleRef: ModuleRef,
40
+ readonly solidRegistry: SolidRegistry, // Assuming solidRegistry is injected for selection providers
41
+ readonly moduleMetadataHelperService: ModuleMetadataHelperService,
42
+ readonly dashboardMapper: DashboardMapper,
43
+ ) {
44
+ super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'dashboard', 'solid-core', moduleRef);
45
+ }
46
+
47
+ async getSelectionDynamicValues(query: DashboardVariableSelectionDynamicQueryDto) {
48
+ // Get the dashboard variable repo
49
+ const dashboardVariable = await this.loadDashboardVariable(query.variableId);
50
+
51
+ // Get the providerName and context for the dashboard variable
52
+ const [providerName, context] = this.getProviderNameAndContext(dashboardVariable, query);
53
+
54
+ // Get hold of the provider instance from the SolidRegistry
55
+ const selectionProviderInstance = this.solidRegistry.getDashboardVariableSelectionProviderInstance(providerName);
56
+ if (!selectionProviderInstance) {
57
+ throw new NotFoundException(`Field incorrectly configured. No provider with name ${providerName} registered in backend.`);
58
+ }
59
+
60
+ // 4. Call the provider's getSelectionDynamicValues method
61
+ return selectionProviderInstance.values(query.query, context);
62
+ }
63
+
64
+
65
+ private getProviderNameAndContext(dashboardVariable: DashboardVariable, query: DashboardVariableSelectionDynamicQueryDto): [string, any] {
66
+ const sourceType = dashboardVariable.selectionDynamicSourceType;
67
+
68
+ // Get the appropriate provide name based on the source type
69
+ let providerName: string;
70
+ const context = { limit: query.limit, offset: query.offset };
71
+ switch (sourceType) {
72
+ case SelectionDynamicSourceType.SQL:
73
+ providerName = SQL_DYNAMIC_PROVIDER_NAME;
74
+ context['sql'] = dashboardVariable.selectionDynamicSQL;
75
+ break;
76
+ case SelectionDynamicSourceType.PROVIDER:
77
+ providerName = dashboardVariable.selectionDynamicProviderName;
78
+ break;
79
+ default:
80
+ throw new Error(`Unsupported selection dynamic source type: ${sourceType}`);
81
+ }
82
+ return [providerName, context];
83
+ }
84
+
85
+ private async loadDashboardVariable(variableId: number) {
86
+ const dashboardVariableRepo = this.entityManager.getRepository(DashboardVariable);
87
+
88
+ // Load the dashboard record using the field
89
+ const dashboardVariable = await dashboardVariableRepo.findOne({
90
+ where: {
91
+ id: variableId,
92
+ },
93
+ });
94
+ return dashboardVariable;
95
+ }
96
+
97
+ async saveDashboardToConfig(entity: Dashboard) {
98
+ if (!entity) {
99
+ this.logger.debug('No entity found in the DashboardSubscriber saveDashboardToConfig method');
100
+ return;
101
+ }
102
+
103
+ // Validate dashboard details
104
+ const dashboard = entity as Dashboard;
105
+ const moduleMetadata = entity.module;
106
+ if (!moduleMetadata) {
107
+ throw new Error(`Module metadata not found for dashboard id ${entity.id}`);
108
+ }
109
+
110
+ // Get config file details
111
+ const { filePath, metaData } = await this.getConfigFileDetails(moduleMetadata.name);
112
+ if (!filePath || !metaData) {
113
+ throw new Error(`Configuration details not found for module: ${moduleMetadata.name}`);
114
+ }
115
+
116
+ // Write the dashboard to the config file
117
+ await this.writeToConfig(metaData, dashboard, filePath);
118
+ }
119
+
120
+ private async getConfigFileDetails(moduleName: string): Promise<{ filePath: string; metaData: any }> {
121
+ const filePath = await this.moduleMetadataHelperService.getModuleMetadataFilePath(moduleName);
122
+ try {
123
+ await fs.access(filePath);
124
+ } catch (error) {
125
+ throw new Error(`Configuration file not found for module: ${moduleName}`);
126
+ }
127
+ const metaData = await this.moduleMetadataHelperService.getModuleMetadataConfiguration(filePath);
128
+ return { filePath, metaData };
129
+ }
130
+
131
+ private async writeToConfig(metaData: any, dashboard: Dashboard, filePath: string) {
132
+ if (metaData.dashboards) {
133
+ const dashboardIndex = metaData.dashboards?.findIndex((dashboardFromFile: { name: string; }) => dashboardFromFile.name === dashboard.name);
134
+ const dto = await this.dashboardMapper.toDto(dashboard);
135
+ metaData.dashboards[dashboardIndex] = dto;
136
+ }
137
+ else {
138
+ const dashboards = [];
139
+ const dto = await this.dashboardMapper.toDto(dashboard);
140
+ dashboards.push(dto);
141
+ metaData.dashboards = dashboards;
142
+ }
143
+ // Write the updated object back to the file
144
+ const updatedContent = JSON.stringify(metaData, null, 2);
145
+ await fs.writeFile(filePath, updatedContent);
146
+ }
147
+ }
@@ -929,6 +929,7 @@ export class FieldMetadataService implements OnApplicationBootstrap {
929
929
  "type",
930
930
  "ormType",
931
931
  "isSystem",
932
+ "computedFieldValueType",
932
933
  "computedFieldTriggerConfig",
933
934
  "computedFieldValueProvider",
934
935
  "computedFieldValueProviderCtxt",