@solidstarters/solid-core-ui 1.1.211 → 1.1.212

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 (373) hide show
  1. package/dist/components/Svg/DevDocs.tsx +9 -0
  2. package/dist/components/Svg/DocsSvg.tsx +9 -0
  3. package/dist/components/Svg/ExcelSvg.tsx +15 -0
  4. package/dist/components/Svg/FieldSvg.tsx +9 -0
  5. package/dist/components/Svg/FileSvg.tsx +18 -0
  6. package/dist/components/Svg/HomePageModuleSvg.tsx +179 -0
  7. package/dist/components/Svg/ModelSvg.tsx +9 -0
  8. package/dist/components/Svg/ModuleSvg.tsx +9 -0
  9. package/dist/components/Svg/PDFSvg.tsx +15 -0
  10. package/dist/components/Svg/RightArrowSvg.tsx +9 -0
  11. package/dist/components/Svg/SettingsSvg.tsx +9 -0
  12. package/dist/components/auth/AuthLayout.tsx +223 -0
  13. package/dist/components/auth/ForgotPasswordThankYou.tsx +33 -0
  14. package/dist/components/auth/GoogleAuthChecking.tsx +63 -0
  15. package/dist/components/auth/SolidChangeForcePassword.tsx +222 -0
  16. package/dist/components/auth/SolidForgotPassword.tsx +127 -0
  17. package/dist/components/auth/SolidInitialLoginOtp.tsx +271 -0
  18. package/dist/components/auth/SolidInitiateRegisterOtp.tsx +218 -0
  19. package/dist/components/auth/SolidLogin.d.ts.map +1 -1
  20. package/dist/components/auth/SolidLogin.js +14 -8
  21. package/dist/components/auth/SolidLogin.js.map +1 -1
  22. package/dist/components/auth/SolidLogin.tsx +428 -0
  23. package/dist/components/auth/SolidOTPVerify.tsx +133 -0
  24. package/dist/components/auth/SolidRegister.tsx +454 -0
  25. package/dist/components/auth/SolidResetPassword.tsx +194 -0
  26. package/dist/components/common/AuthBanner.tsx +41 -0
  27. package/dist/components/common/AutoCompleteField.tsx +79 -0
  28. package/dist/components/common/BackButton.tsx +72 -0
  29. package/dist/components/common/CancelButton.tsx +61 -0
  30. package/dist/components/common/CodeEditor.tsx +38 -0
  31. package/dist/components/common/CreateButton.tsx +17 -0
  32. package/dist/components/common/DownloadProgressToast.tsx +55 -0
  33. package/dist/components/common/DropzonePlaceholder.tsx +31 -0
  34. package/dist/components/common/DropzoneUpload.tsx +11 -0
  35. package/dist/components/common/FileReaderExt.tsx +20 -0
  36. package/dist/components/common/GeneralSettings.tsx +1225 -0
  37. package/dist/components/common/HeaderDynamicTitles.tsx +13 -0
  38. package/dist/components/common/MarkdownViewer.tsx +84 -0
  39. package/dist/components/common/MultipleSelectAutoCompleteField.tsx +64 -0
  40. package/dist/components/common/NotFound.tsx +22 -0
  41. package/dist/components/common/SingleSelectAutoCompleteField.tsx +73 -0
  42. package/dist/components/common/SocialMediaLogin.tsx +53 -0
  43. package/dist/components/common/SolidAdmin.tsx +6 -0
  44. package/dist/components/common/SolidBreadcrumb.tsx +129 -0
  45. package/dist/components/common/SolidExport.tsx +563 -0
  46. package/dist/components/common/SolidExportStepper.tsx +135 -0
  47. package/dist/components/common/SolidFieldTooltip.tsx +23 -0
  48. package/dist/components/common/SolidFormHeader.tsx +25 -0
  49. package/dist/components/common/SolidFormStepper.tsx +350 -0
  50. package/dist/components/common/SolidModuleHome.tsx +128 -0
  51. package/dist/components/common/SolidPopupContainer.tsx +37 -0
  52. package/dist/components/common/SolidSettings/LlmSettings/AnthropicProviderComponent.tsx +45 -0
  53. package/dist/components/common/SolidSettings/LlmSettings/OpenAiProviderComponent.tsx +45 -0
  54. package/dist/components/common/SolidSettings/SettingDropzoneActivePlaceholder.tsx +20 -0
  55. package/dist/components/common/SolidSettings/SettingsImageRemoveButton.tsx +15 -0
  56. package/dist/components/common/SolidSettings/SolidUploadedImage.tsx +16 -0
  57. package/dist/components/common/SolidThemeLink.tsx +6 -0
  58. package/dist/components/common/SolidThemeProvider.tsx +44 -0
  59. package/dist/components/common/StepperArrows/ActiveArrowStep.tsx +18 -0
  60. package/dist/components/common/StepperArrows/ActiveBeforeStepArrow.tsx +18 -0
  61. package/dist/components/common/StepperArrows/InactiveStepArrow.tsx +19 -0
  62. package/dist/components/common/error.tsx +30 -0
  63. package/dist/components/common/useHandleFormCustomButtonClick.ts +40 -0
  64. package/dist/components/common/useHandleListCustomButtonClick.ts +42 -0
  65. package/dist/components/core/chatter/SolidChatter.tsx +248 -0
  66. package/dist/components/core/chatter/SolidChatterAuditMessage.tsx +35 -0
  67. package/dist/components/core/chatter/SolidChatterCustomMessage.tsx +46 -0
  68. package/dist/components/core/chatter/SolidChatterDateDivider.tsx +16 -0
  69. package/dist/components/core/chatter/SolidChatterHeader.tsx +218 -0
  70. package/dist/components/core/chatter/SolidChatterMessageBox.tsx +163 -0
  71. package/dist/components/core/chatter/SolidMessageComposer.tsx +146 -0
  72. package/dist/components/core/common/AvatarWidget.tsx +55 -0
  73. package/dist/components/core/common/DateFieldViewComponent.tsx +36 -0
  74. package/dist/components/core/common/FilterComponent.tsx +458 -0
  75. package/dist/components/core/common/LoadDynamicJsxComponent.tsx +70 -0
  76. package/dist/components/core/common/PDFViewer.tsx +117 -0
  77. package/dist/components/core/common/SolidAccountSettings/SolidAccountSettings.tsx +89 -0
  78. package/dist/components/core/common/SolidAccountSettings/SolidChangePassword.tsx +188 -0
  79. package/dist/components/core/common/SolidAccountSettings/SolidNotifications.tsx +139 -0
  80. package/dist/components/core/common/SolidAccountSettings/SolidPersonalInfo.tsx +311 -0
  81. package/dist/components/core/common/SolidCreateButton.tsx +48 -0
  82. package/dist/components/core/common/SolidGenericImport/DocumentSvg.tsx +15 -0
  83. package/dist/components/core/common/SolidGenericImport/SolidGenericImport.tsx +64 -0
  84. package/dist/components/core/common/SolidGenericImport/SolidImportDropzone.tsx +125 -0
  85. package/dist/components/core/common/SolidGenericImport/SolidImportInstructions.tsx +122 -0
  86. package/dist/components/core/common/SolidGenericImport/SolidImportStepper.tsx +217 -0
  87. package/dist/components/core/common/SolidGenericImport/SolidImportTransaction.tsx +205 -0
  88. package/dist/components/core/common/SolidGenericImport/SolidImportTransactionStatus.tsx +158 -0
  89. package/dist/components/core/common/SolidGenericImport/SolidImportWrapper.tsx +29 -0
  90. package/dist/components/core/common/SolidGlobalSearchElement.tsx +1470 -0
  91. package/dist/components/core/common/SolidLayoutViews.tsx +87 -0
  92. package/dist/components/core/common/SolidListViewOptions.tsx +31 -0
  93. package/dist/components/core/common/SolidLoaders/SolidCircularLoader.tsx +7 -0
  94. package/dist/components/core/common/SolidPasswordHelperText.tsx +34 -0
  95. package/dist/components/core/common/SolidSaveCustomFilterForm.tsx +75 -0
  96. package/dist/components/core/common/SolidSearchBox.tsx +17 -0
  97. package/dist/components/core/common/SolidViewLayoutManager.ts +421 -0
  98. package/dist/components/core/common/SolidXAiIframe.tsx +77 -0
  99. package/dist/components/core/dashboard/SolidDashboard.tsx +332 -0
  100. package/dist/components/core/dashboard/SolidDashboardBody.tsx +117 -0
  101. package/dist/components/core/dashboard/SolidDashboardFilterRequired.tsx +28 -0
  102. package/dist/components/core/dashboard/SolidDashboardHeader.tsx +10 -0
  103. package/dist/components/core/dashboard/SolidDashboardLoading.tsx +55 -0
  104. package/dist/components/core/dashboard/SolidDashboardNotAvailable.tsx +32 -0
  105. package/dist/components/core/dashboard/SolidDashboardRenderError.tsx +29 -0
  106. package/dist/components/core/dashboard/SolidDashboardVariable.tsx +256 -0
  107. package/dist/components/core/dashboard/SolidQuestionRenderer.tsx +78 -0
  108. package/dist/components/core/dashboard/chart-renderers/ChartJsRenderer.tsx +18 -0
  109. package/dist/components/core/dashboard/chart-renderers/PrimeReactDatatableRenderer.tsx +54 -0
  110. package/dist/components/core/dashboard/chart-renderers/init-chartjs.ts +25 -0
  111. package/dist/components/core/dashboard/dashboard-utils.ts +39 -0
  112. package/dist/components/core/extension/solid-core/CustomIcon/StatusIcon.tsx +17 -0
  113. package/dist/components/core/extension/solid-core/dashboardQuestion/ChartFormPreviewWidget.tsx +36 -0
  114. package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeChangeHandler.ts +18 -0
  115. package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeLoad.ts +18 -0
  116. package/dist/components/core/extension/solid-core/modelMetadata/list/DeleteModelRowAction.tsx +114 -0
  117. package/dist/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.tsx +213 -0
  118. package/dist/components/core/extension/solid-core/moduleMetadata/list/DeleteModuleRowAction.tsx +138 -0
  119. package/dist/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.tsx +209 -0
  120. package/dist/components/core/extension/solid-core/roleMetadata/RolePermissionsManyToManyFieldWidget.tsx +131 -0
  121. package/dist/components/core/field/FieldListViewData.tsx +313 -0
  122. package/dist/components/core/filter/SolidBooleanFilterElement.tsx +30 -0
  123. package/dist/components/core/filter/SolidFilterFields.tsx +131 -0
  124. package/dist/components/core/filter/SolidManyToManyFilterElement.tsx +64 -0
  125. package/dist/components/core/filter/SolidManyToOneFilterElement.tsx +61 -0
  126. package/dist/components/core/filter/SolidSelectionDynamicFilterElement.tsx +50 -0
  127. package/dist/components/core/filter/SolidSelectionStaticFilterElement.tsx +32 -0
  128. package/dist/components/core/filter/SolidVarInputsFilterElement.tsx +209 -0
  129. package/dist/components/core/filter/fields/SolidBigintField.tsx +9 -0
  130. package/dist/components/core/filter/fields/SolidBooleanField.tsx +68 -0
  131. package/dist/components/core/filter/fields/SolidComputedField.tsx +23 -0
  132. package/dist/components/core/filter/fields/SolidDateField.tsx +63 -0
  133. package/dist/components/core/filter/fields/SolidDatetimeField.tsx +54 -0
  134. package/dist/components/core/filter/fields/SolidDecimalField.tsx +9 -0
  135. package/dist/components/core/filter/fields/SolidExternalIdField.tsx +52 -0
  136. package/dist/components/core/filter/fields/SolidFloatField.tsx +9 -0
  137. package/dist/components/core/filter/fields/SolidIdField.tsx +46 -0
  138. package/dist/components/core/filter/fields/SolidIntField.tsx +61 -0
  139. package/dist/components/core/filter/fields/SolidLongTextField.tsx +9 -0
  140. package/dist/components/core/filter/fields/SolidMediaMultipleField.tsx +60 -0
  141. package/dist/components/core/filter/fields/SolidMediaSingleField.tsx +62 -0
  142. package/dist/components/core/filter/fields/SolidRelationField.tsx +17 -0
  143. package/dist/components/core/filter/fields/SolidRichTextField.tsx +9 -0
  144. package/dist/components/core/filter/fields/SolidSelectionDynamicField.tsx +52 -0
  145. package/dist/components/core/filter/fields/SolidSelectionStaticField.tsx +54 -0
  146. package/dist/components/core/filter/fields/SolidShortTextField.tsx +60 -0
  147. package/dist/components/core/filter/fields/SolidTimeField.tsx +48 -0
  148. package/dist/components/core/filter/fields/SolidUuidField.tsx +51 -0
  149. package/dist/components/core/filter/fields/relations/SolidRelationManyToManyField.tsx +62 -0
  150. package/dist/components/core/filter/fields/relations/SolidRelationManyToOneField.tsx +84 -0
  151. package/dist/components/core/form/SolidFormActionHeader.tsx +497 -0
  152. package/dist/components/core/form/SolidFormFieldRender.tsx +53 -0
  153. package/dist/components/core/form/SolidFormFieldRenderExtension.tsx +26 -0
  154. package/dist/components/core/form/SolidFormFooter.tsx +162 -0
  155. package/dist/components/core/form/SolidFormLayouts.tsx +104 -0
  156. package/dist/components/core/form/SolidFormUserViewLayout.tsx +84 -0
  157. package/dist/components/core/form/SolidFormView.tsx +1856 -0
  158. package/dist/components/core/form/SolidFormViewContextMenuHeaderButton.tsx +52 -0
  159. package/dist/components/core/form/SolidFormViewNormalHeaderButton.tsx +52 -0
  160. package/dist/components/core/form/SolidFormViewShimmerLoading.tsx +109 -0
  161. package/dist/components/core/form/fields/ISolidField.tsx +71 -0
  162. package/dist/components/core/form/fields/SolidBooleanField.tsx +434 -0
  163. package/dist/components/core/form/fields/SolidDateField.tsx +247 -0
  164. package/dist/components/core/form/fields/SolidDateTimeField.tsx +229 -0
  165. package/dist/components/core/form/fields/SolidDecimalField.tsx +171 -0
  166. package/dist/components/core/form/fields/SolidEmailField.tsx +176 -0
  167. package/dist/components/core/form/fields/SolidIntegerField.tsx +282 -0
  168. package/dist/components/core/form/fields/SolidJsonField.tsx +185 -0
  169. package/dist/components/core/form/fields/SolidLongTextField.tsx +618 -0
  170. package/dist/components/core/form/fields/SolidMediaMultipleField.tsx +663 -0
  171. package/dist/components/core/form/fields/SolidMediaSingleField.tsx +547 -0
  172. package/dist/components/core/form/fields/SolidPasswordField.tsx +390 -0
  173. package/dist/components/core/form/fields/SolidRelationField.tsx +56 -0
  174. package/dist/components/core/form/fields/SolidRichTextField.tsx +188 -0
  175. package/dist/components/core/form/fields/SolidSelectionDynamicField.tsx +340 -0
  176. package/dist/components/core/form/fields/SolidSelectionStaticField.tsx +462 -0
  177. package/dist/components/core/form/fields/SolidShortTextField.tsx +399 -0
  178. package/dist/components/core/form/fields/SolidTimeField.tsx +245 -0
  179. package/dist/components/core/form/fields/relations/SolidRelationManyToManyField.tsx +453 -0
  180. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +1036 -0
  181. package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.tsx +627 -0
  182. package/dist/components/core/form/fields/relations/widgets/helpers/InlineRelationEntityDialog.tsx +38 -0
  183. package/dist/components/core/form/fields/relations/widgets/helpers/useRelationEntityHandler.ts +64 -0
  184. package/dist/components/core/form/fields/widgets/SolidAiInteractionMessageFieldFormWidget.tsx +135 -0
  185. package/dist/components/core/form/fields/widgets/SolidAiInteractionMetadataFieldFormWidget.tsx +144 -0
  186. package/dist/components/core/form/fields/widgets/SolidIconEditWidget.tsx +265 -0
  187. package/dist/components/core/form/fields/widgets/SolidIconViewWidget.tsx +32 -0
  188. package/dist/components/core/form/fields/widgets/SolidRelationFieldAvatarFormWidget.tsx +50 -0
  189. package/dist/components/core/form/fields/widgets/SolidS3FileViewerWidget.tsx +222 -0
  190. package/dist/components/core/form/fields/widgets/SolidShortTextFieldAvatarWidget.tsx +70 -0
  191. package/dist/components/core/form/widgets/CustomHtml.tsx +20 -0
  192. package/dist/components/core/kanban/KanbanBoard.tsx +150 -0
  193. package/dist/components/core/kanban/KanbanCard.tsx +279 -0
  194. package/dist/components/core/kanban/KanbanColumn.tsx +139 -0
  195. package/dist/components/core/kanban/KanbanUserViewLayout.tsx +84 -0
  196. package/dist/components/core/kanban/SolidKanbanView.tsx +894 -0
  197. package/dist/components/core/kanban/SolidKanbanViewConfigure.tsx +154 -0
  198. package/dist/components/core/kanban/SolidKanbanViewFields.tsx +164 -0
  199. package/dist/components/core/kanban/SolidManyToOneFilterElement.tsx +59 -0
  200. package/dist/components/core/kanban/SolidSelectionDynamicFilterElement.tsx +50 -0
  201. package/dist/components/core/kanban/SolidSelectionStaticFilterElement.tsx +32 -0
  202. package/dist/components/core/kanban/SolidVarInputsFilterElement.tsx +184 -0
  203. package/dist/components/core/kanban/kanban-fields/SolidBigintKanbanField.tsx +9 -0
  204. package/dist/components/core/kanban/kanban-fields/SolidBooleanKanbanField.tsx +16 -0
  205. package/dist/components/core/kanban/kanban-fields/SolidComputedKanbanField.tsx +23 -0
  206. package/dist/components/core/kanban/kanban-fields/SolidDateKanbanField.tsx +14 -0
  207. package/dist/components/core/kanban/kanban-fields/SolidDatetimeKanbanField.tsx +13 -0
  208. package/dist/components/core/kanban/kanban-fields/SolidDecimalKanbanField.tsx +9 -0
  209. package/dist/components/core/kanban/kanban-fields/SolidExternalIdKanbanField.tsx +12 -0
  210. package/dist/components/core/kanban/kanban-fields/SolidFloatKanbanField.tsx +9 -0
  211. package/dist/components/core/kanban/kanban-fields/SolidIdKanbanField.tsx +14 -0
  212. package/dist/components/core/kanban/kanban-fields/SolidIntKanbanField.tsx +20 -0
  213. package/dist/components/core/kanban/kanban-fields/SolidLongTextKanbanField.tsx +9 -0
  214. package/dist/components/core/kanban/kanban-fields/SolidMediaMultipleKanbanField.tsx +140 -0
  215. package/dist/components/core/kanban/kanban-fields/SolidMediaSingleKanbanField.tsx +164 -0
  216. package/dist/components/core/kanban/kanban-fields/SolidRelationKanbanField.tsx +13 -0
  217. package/dist/components/core/kanban/kanban-fields/SolidRichTextKanbanField.tsx +9 -0
  218. package/dist/components/core/kanban/kanban-fields/SolidSelectionDynamicKanbanField.tsx +14 -0
  219. package/dist/components/core/kanban/kanban-fields/SolidSelectionStaticKanbanField.tsx +14 -0
  220. package/dist/components/core/kanban/kanban-fields/SolidShortTextKanbanField.tsx +121 -0
  221. package/dist/components/core/kanban/kanban-fields/SolidTimeKanbanField.tsx +12 -0
  222. package/dist/components/core/kanban/kanban-fields/SolidUuidKanbanField.tsx +13 -0
  223. package/dist/components/core/kanban/kanban-fields/relations/SolidRelationManyToOneKanbanField.tsx +16 -0
  224. package/dist/components/core/list/ListViewRowActionPopup.tsx +41 -0
  225. package/dist/components/core/list/SolidColumnSelector/SolidListColumnSelector.tsx +242 -0
  226. package/dist/components/core/list/SolidEmptyListViewPlaceholder.tsx +111 -0
  227. package/dist/components/core/list/SolidListView.tsx +2007 -0
  228. package/dist/components/core/list/SolidListViewColumn.tsx +165 -0
  229. package/dist/components/core/list/SolidListViewConfigure.tsx +339 -0
  230. package/dist/components/core/list/SolidListViewHeaderButton.tsx +31 -0
  231. package/dist/components/core/list/SolidListViewHeaderContextMenuButton.tsx +30 -0
  232. package/dist/components/core/list/SolidListViewRowButtonContextMenu.tsx +41 -0
  233. package/dist/components/core/list/SolidListViewShimmerLoading.tsx +78 -0
  234. package/dist/components/core/list/SolidListingHeader.tsx +42 -0
  235. package/dist/components/core/list/SolidManyToOneFilterElement.tsx +60 -0
  236. package/dist/components/core/list/SolidSelectionDynamicFilterElement.tsx +50 -0
  237. package/dist/components/core/list/SolidSelectionStaticFilterElement.tsx +32 -0
  238. package/dist/components/core/list/SolidTableRowCell.tsx +35 -0
  239. package/dist/components/core/list/SolidVarInputsFilterElement.tsx +184 -0
  240. package/dist/components/core/list/columns/SolidBigintColumn.tsx +9 -0
  241. package/dist/components/core/list/columns/SolidBooleanColumn.tsx +90 -0
  242. package/dist/components/core/list/columns/SolidComputedColumn.tsx +27 -0
  243. package/dist/components/core/list/columns/SolidDateColumn.tsx +90 -0
  244. package/dist/components/core/list/columns/SolidDatetimeColumn.tsx +79 -0
  245. package/dist/components/core/list/columns/SolidDecimalColumn.tsx +9 -0
  246. package/dist/components/core/list/columns/SolidExternalIdColumn.tsx +80 -0
  247. package/dist/components/core/list/columns/SolidFloatColumn.tsx +9 -0
  248. package/dist/components/core/list/columns/SolidIdColumn.tsx +79 -0
  249. package/dist/components/core/list/columns/SolidIntColumn.tsx +87 -0
  250. package/dist/components/core/list/columns/SolidLongTextColumn.tsx +9 -0
  251. package/dist/components/core/list/columns/SolidMediaMultipleColumn.tsx +301 -0
  252. package/dist/components/core/list/columns/SolidMediaSingleColumn.tsx +170 -0
  253. package/dist/components/core/list/columns/SolidRelationColumn.tsx +21 -0
  254. package/dist/components/core/list/columns/SolidRichTextColumn.tsx +9 -0
  255. package/dist/components/core/list/columns/SolidSelectionDynamicColumn.tsx +80 -0
  256. package/dist/components/core/list/columns/SolidSelectionStaticColumn.tsx +81 -0
  257. package/dist/components/core/list/columns/SolidShortTextColumn.tsx +160 -0
  258. package/dist/components/core/list/columns/SolidTimeColumn.tsx +78 -0
  259. package/dist/components/core/list/columns/SolidUuidColumn.tsx +79 -0
  260. package/dist/components/core/list/columns/relations/SolidRelationManyToManyColumn.tsx +106 -0
  261. package/dist/components/core/list/columns/relations/SolidRelationManyToOneColumn.tsx +117 -0
  262. package/dist/components/core/list/columns/relations/SolidRelationOneToManyColumn.tsx +110 -0
  263. package/dist/components/core/list/widgets/SolidManyToManyRelationAvatarListWidget.tsx +30 -0
  264. package/dist/components/core/list/widgets/SolidManyToOneRelationAvatarListWidget.tsx +30 -0
  265. package/dist/components/core/list/widgets/SolidShortTextAvatarWidget.tsx +70 -0
  266. package/dist/components/core/list/widgets/SolidShortTextFieldImageRenderModeWidget.tsx +21 -0
  267. package/dist/components/core/locales/SolidChatterLocaleTabView.tsx +91 -0
  268. package/dist/components/core/locales/SolidLocale.tsx +127 -0
  269. package/dist/components/core/model/CreateModel.tsx +495 -0
  270. package/dist/components/core/model/FieldMetaData.tsx +263 -0
  271. package/dist/components/core/model/FieldMetaDataForm.tsx +3509 -0
  272. package/dist/components/core/model/FieldSelector.tsx +62 -0
  273. package/dist/components/core/model/ModelListViewData.tsx +384 -0
  274. package/dist/components/core/model/ModelMetaData.tsx +921 -0
  275. package/dist/components/core/module/CreateModule.tsx +617 -0
  276. package/dist/components/core/module/ModuleListViewData.tsx +431 -0
  277. package/dist/components/core/solid-ai/SolidAiMainWrapper.tsx +8 -0
  278. package/dist/components/core/solid-ai/SolidXAIIcon.tsx +37 -0
  279. package/dist/components/core/users/CreateUser.tsx +467 -0
  280. package/dist/components/core/users/CreateUserRole.tsx +212 -0
  281. package/dist/components/core/users/UserListView.tsx +376 -0
  282. package/dist/components/layout/AdminLayout.tsx +57 -0
  283. package/dist/components/layout/AdminSidebar.tsx +65 -0
  284. package/dist/components/layout/AppConfig.tsx +104 -0
  285. package/dist/components/layout/AppSidebar.tsx +232 -0
  286. package/dist/components/layout/ButtonLoader.tsx +7 -0
  287. package/dist/components/layout/CustomPagination.tsx +55 -0
  288. package/dist/components/layout/DashboardHeader.tsx +89 -0
  289. package/dist/components/layout/FilterMenu.tsx +122 -0
  290. package/dist/components/layout/Footer.tsx +13 -0
  291. package/dist/components/layout/GlobalSearch.tsx +37 -0
  292. package/dist/components/layout/Header.tsx +8 -0
  293. package/dist/components/layout/Layout.tsx +205 -0
  294. package/dist/components/layout/ListingHeader.tsx +204 -0
  295. package/dist/components/layout/Loader.tsx +16 -0
  296. package/dist/components/layout/UserSidebar.tsx +53 -0
  297. package/dist/components/layout/context/layoutcontext.tsx +52 -0
  298. package/dist/components/layout/navbar-one.tsx +258 -0
  299. package/dist/components/layout/navbar-two-menu.tsx +72 -0
  300. package/dist/components/layout/navbar-two.tsx +37 -0
  301. package/dist/components/layout/user-profile-menu.tsx +213 -0
  302. package/dist/components/layout/user-profile.tsx +7 -0
  303. package/dist/components/modelsComponents/filterIcon.tsx +9 -0
  304. package/dist/constants/error-messages.ts +238 -0
  305. package/dist/declarations.d.ts +22 -0
  306. package/dist/helpers/AppTitle.tsx +12 -0
  307. package/dist/helpers/ToastContainer.tsx +94 -0
  308. package/dist/helpers/autoCompleteVirtualScroll.ts +41 -0
  309. package/dist/helpers/countries.tsx +260 -0
  310. package/dist/helpers/downloadFileWithProgress.ts +91 -0
  311. package/dist/helpers/downloadMediaFile.tsx +21 -0
  312. package/dist/helpers/getAcceptedFileTypes.tsx +22 -0
  313. package/dist/helpers/getRandomColors.tsx +68 -0
  314. package/dist/helpers/helpers.ts +61 -0
  315. package/dist/helpers/hydrateRelationRules.ts +120 -0
  316. package/dist/helpers/permissions.ts +7 -0
  317. package/dist/helpers/registry.ts +337 -0
  318. package/dist/helpers/resendOtpHelper.tsx +5 -0
  319. package/dist/helpers/revalidate.ts +7 -0
  320. package/dist/helpers/rolesHelper.ts +17 -0
  321. package/dist/helpers/solidIcons.tsx +1831 -0
  322. package/dist/helpers/updatePasswordField.ts +41 -0
  323. package/dist/index.ts +421 -0
  324. package/dist/nextAuth/authProviders.d.ts.map +1 -1
  325. package/dist/nextAuth/authProviders.js +6 -5
  326. package/dist/nextAuth/authProviders.js.map +1 -1
  327. package/dist/nextAuth/authProviders.tsx +232 -0
  328. package/dist/nextAuth/handleLogout.tsx +39 -0
  329. package/dist/nextAuth/refreshAccessToken.tsx +28 -0
  330. package/dist/redux/api/aiInteractionApi.ts +59 -0
  331. package/dist/redux/api/authApi.ts +131 -0
  332. package/dist/redux/api/dashboardApi.ts +56 -0
  333. package/dist/redux/api/dashboardQuestionApi.ts +17 -0
  334. package/dist/redux/api/exportTemplateApi.tsx +59 -0
  335. package/dist/redux/api/fetchBaseQuery.tsx +118 -0
  336. package/dist/redux/api/fieldApi.ts +86 -0
  337. package/dist/redux/api/importTransactionApi.tsx +69 -0
  338. package/dist/redux/api/mediaApi.ts +55 -0
  339. package/dist/redux/api/mediaStorageProviderApi.ts +55 -0
  340. package/dist/redux/api/modelApi.ts +80 -0
  341. package/dist/redux/api/moduleApi.ts +72 -0
  342. package/dist/redux/api/permissionApi.ts +32 -0
  343. package/dist/redux/api/pincodeApi.tsx +56 -0
  344. package/dist/redux/api/roleApi.ts +58 -0
  345. package/dist/redux/api/solidActionApi.ts +66 -0
  346. package/dist/redux/api/solidChatterMessageApi.ts +25 -0
  347. package/dist/redux/api/solidEntityApi.tsx +164 -0
  348. package/dist/redux/api/solidMenuApi.ts +71 -0
  349. package/dist/redux/api/solidServiceApi.ts +31 -0
  350. package/dist/redux/api/solidSettingsApi.tsx +83 -0
  351. package/dist/redux/api/solidViewApi.ts +73 -0
  352. package/dist/redux/api/stateApi.tsx +56 -0
  353. package/dist/redux/api/testApi.ts +21 -0
  354. package/dist/redux/api/userApi.ts +135 -0
  355. package/dist/redux/features/authSlice.ts +19 -0
  356. package/dist/redux/features/dataViewSlice.ts +26 -0
  357. package/dist/redux/features/navbarSlice.ts +21 -0
  358. package/dist/redux/features/popupSlice.ts +37 -0
  359. package/dist/redux/features/settingsSlice.ts +60 -0
  360. package/dist/redux/features/themeSlice.ts +17 -0
  361. package/dist/redux/features/userSlice.ts +28 -0
  362. package/dist/redux/hooks/useSolidPopup.ts +20 -0
  363. package/dist/redux/store/defaultStoreConfig.ts +62 -0
  364. package/dist/styles.ts +4 -0
  365. package/dist/types/handlebars.d.ts +4 -0
  366. package/dist/types/index.d.ts +76 -0
  367. package/dist/types/layout.d.ts +94 -0
  368. package/dist/types/next-auth.d.ts +0 -0
  369. package/dist/types/next.d.ts +46 -0
  370. package/dist/types/solid-core.d.ts +320 -0
  371. package/package.json +1 -1
  372. package/src/components/auth/SolidLogin.tsx +26 -13
  373. package/src/nextAuth/authProviders.tsx +9 -5
@@ -0,0 +1,2007 @@
1
+ // @ts-nocheck
2
+
3
+ "use client";
4
+
5
+ import React, { useState, useEffect, useRef, useMemo } from "react";
6
+ import {
7
+ DataTable,
8
+ DataTableFilterMeta,
9
+ DataTableStateEvent,
10
+ } from "primereact/datatable";
11
+ import { Column } from "primereact/column";
12
+ import { FilterMatchMode } from "primereact/api";
13
+ import Link from "next/link";
14
+ import qs from "qs";
15
+ import { Button } from "primereact/button";
16
+ import { Dialog } from "primereact/dialog";
17
+ import { createSolidEntityApi } from "../../../redux/api/solidEntityApi";
18
+ import { useGetSolidViewLayoutQuery } from "../../../redux/api/solidViewApi";
19
+ import { SolidListViewColumn } from "./SolidListViewColumn";
20
+ // import { SolidListViewOptions } from "../common/SolidListviewOptions";
21
+ import { SolidCreateButton } from "../common/SolidCreateButton";
22
+ import { SolidGlobalSearchElement } from "../common/SolidGlobalSearchElement";
23
+ import { pascalCase } from "change-case";
24
+ import { useLazyCheckIfPermissionExistsQuery } from "../../../redux/api/userApi";
25
+ import { permissionExpression } from "../../../helpers/permissions";
26
+ import { usePathname, useRouter, useSearchParams } from "next/navigation";
27
+ import { ListViewRowActionPopup } from "./ListViewRowActionPopup";
28
+ import FilterComponent, { FilterOperator, FilterRule, FilterRuleType } from "../../../components/core/common/FilterComponent";
29
+ import { SolidLayoutViews } from "../common/SolidLayoutViews";
30
+ import { FilterIcon } from '../../../components/modelsComponents/filterIcon';
31
+ import { OverlayPanel } from "primereact/overlaypanel";
32
+ import { Toast } from "primereact/toast";
33
+ import { Divider } from "primereact/divider";
34
+ import CompactImage from '../../../resources/images/layout/images/compact.png';
35
+ import CozyImage from '../../../resources/images/layout/images/cozy.png';
36
+ import ComfortableImage from '../../../resources/images/layout/images/comfortable.png';
37
+ import KanbanImage from '../../../resources/images/layout/images/kanban.png';
38
+ import { capitalize, filter, set } from "lodash";
39
+ import Lightbox from "yet-another-react-lightbox";
40
+ import Counter from "yet-another-react-lightbox/plugins/counter";
41
+ import Download from "yet-another-react-lightbox/plugins/download";
42
+ import Video from "yet-another-react-lightbox/plugins/video";
43
+ import "yet-another-react-lightbox/styles.css";
44
+ import "yet-another-react-lightbox/plugins/counter.css";
45
+ import { SolidListViewConfigure } from "./SolidListViewConfigure";
46
+ import { SolidListViewShimmerLoading } from "./SolidListViewShimmerLoading";
47
+ import { SolidEmptyListViewPlaceholder } from "./SolidEmptyListViewPlaceholder";
48
+ import { useHandleListCustomButtonClick } from "../../../components/common/useHandleListCustomButtonClick";
49
+ import { hasAnyRole, useHasAnyRole } from "../../../helpers/rolesHelper";
50
+ import { SolidListViewHeaderButton } from "./SolidListViewHeaderButton";
51
+ import { SolidListViewRowButtonContextMenu } from "./SolidListViewRowButtonContextMenu";
52
+ import { useDispatch, useSelector } from "react-redux";
53
+ import styles from "./SolidListViewWrapper.module.css";
54
+ import { SolidXAIIcon } from "../solid-ai/SolidXAIIcon";
55
+ import { SolidBeforeListDataLoad, SolidListUiEventResponse, SolidLoadList } from "../../../types/solid-core";
56
+ import { getExtensionFunction } from "../../../helpers/registry";
57
+ import { useSession } from "next-auth/react";
58
+ import { ERROR_MESSAGES } from "../../../constants/error-messages";
59
+ import { SolidAiMainWrapper } from "../solid-ai/SolidAiMainWrapper";
60
+ import { showNavbar, toggleNavbar } from "../../../redux/features/navbarSlice";
61
+ import { useLazyGetMcpUrlQuery, useLazyGetSolidSettingsQuery } from "../../../redux/api/solidSettingsApi";
62
+ import { log } from "console";
63
+ // import { ERROR_MESSAGES } from "../../../constants/error-messages";
64
+
65
+ const getRandomInt = (min: number, max: number) => {
66
+ return Math.floor(Math.random() * (max - min + 1)) + min;
67
+ };
68
+
69
+ export const queryStringToQueryObject = () => {
70
+ const currentPageUrl = window.location.pathname; // Get the current page URL
71
+ const encodedQueryString = localStorage.getItem(currentPageUrl); // Retrieve the encoded query string from local storage
72
+
73
+ if (encodedQueryString) {
74
+ try {
75
+ const decodedQueryString = atob(encodedQueryString); // Base64 decode the string
76
+ const parsedParams = JSON.parse(decodedQueryString); // Parse the decoded string into an object
77
+ return parsedParams;
78
+ } catch (error) {
79
+ console.error(
80
+ ERROR_MESSAGES.ERROR_DECODING,
81
+ error
82
+ );
83
+ }
84
+ }
85
+ };
86
+
87
+
88
+ export const queryStringToQueryObjectByUrl = (url) => {
89
+ const currentPageUrl = url; // Get the current page URL
90
+ const encodedQueryString = localStorage.getItem(currentPageUrl); // Retrieve the encoded query string from local storage
91
+
92
+ if (encodedQueryString) {
93
+ try {
94
+ const decodedQueryString = atob(encodedQueryString); // Base64 decode the string
95
+ const parsedParams = JSON.parse(decodedQueryString); // Parse the decoded string into an object
96
+ return parsedParams;
97
+ } catch (error) {
98
+ console.error(
99
+ ERROR_MESSAGES.ERROR_DECODING,
100
+ error
101
+ );
102
+ }
103
+ }
104
+ };
105
+
106
+ export const queryObjectToQueryString = (queryObject: string) => {
107
+ if (queryObject) {
108
+ const stringifiedObject = JSON.stringify(queryObject);
109
+ // const stringifiedObject = qs.stringify(queryObject, { encodeValuesOnly: true, arrayFormat: "brackets" });
110
+ const encodedQueryString = btoa(stringifiedObject); // Base64 encode the stringified object
111
+ const currentPageUrl = window.location.pathname; // Get the current page URL
112
+ localStorage.setItem(currentPageUrl, encodedQueryString); // Store in local storage with the URL as the key
113
+ return encodedQueryString;
114
+ }
115
+ return null;
116
+ };
117
+
118
+
119
+ export const queryObjectToQueryStringByUrl = (url, queryObject: string) => {
120
+ if (queryObject) {
121
+ const stringifiedObject = JSON.stringify(queryObject);
122
+ // const stringifiedObject = qs.stringify(queryObject, { encodeValuesOnly: true, arrayFormat: "brackets" });
123
+ const encodedQueryString = btoa(stringifiedObject); // Base64 encode the stringified object
124
+ const currentPageUrl = url; // Get the current page URL
125
+ localStorage.setItem(currentPageUrl, encodedQueryString); // Store in local storage with the URL as the key
126
+ return encodedQueryString;
127
+ }
128
+ return null;
129
+ };
130
+
131
+ type SolidListViewParams = {
132
+ moduleName: string;
133
+ modelName: string;
134
+ inlineCreate?: boolean;
135
+ handlePopUpOpen?: any;
136
+ embeded?: boolean;
137
+ customLayout?: any;
138
+ customFilter?: any;
139
+ };
140
+
141
+ export const SolidListView = (params: SolidListViewParams) => {
142
+ const { user } = useSelector((state: any) => state.auth);
143
+ const session = useSession();
144
+ const dispatch = useDispatch();
145
+ const visibleNavbar = useSelector((state: any) => state.navbarState?.visibleNavbar);
146
+
147
+ const pathname = usePathname();
148
+ const solidGlobalSearchElementRef = useRef();
149
+
150
+ const router = useRouter();
151
+ const searchParams = useSearchParams();
152
+ const localeName = searchParams.get("locale");
153
+ // TODO: The initial filter state will be created based on the fields which are present on this list view.
154
+ const [filters, setFilters] = useState<any>(params.customFilter || null);
155
+
156
+ // const [customFilter, setCustomFilter] = useState<FilterRule[]>(initialState);
157
+ // const [showGlobalSearchElement, setShowGlobalSearchElement] = useState<boolean>(false);
158
+
159
+ const [toPopulate, setToPopulate] = useState<string[]>([]);
160
+ const [toPopulateMedia, setToPopulateMedia] = useState<string[]>([]);
161
+ const [actionsAllowed, setActionsAllowed] = useState<string[]>([]);
162
+ const [isOpenSolidXAiPanel, setIsOpenSolidXAiPanel] = useState(false);
163
+ const [chatterWidth, setChatterWidth] = useState(380);
164
+ const [isResizing, setIsResizing] = useState(false);
165
+ const [triggerCheckIfPermissionExists] = useLazyCheckIfPermissionExistsQuery();
166
+
167
+ const handleCustomButtonClick = useHandleListCustomButtonClick();
168
+
169
+ const [mcpUrl, setMcpUrl] = useState<string | null>(null);
170
+ const [getMcpUrl] = useLazyGetMcpUrlQuery();
171
+
172
+ const [trigger, { data: solidSettingsData }] = useLazyGetSolidSettingsQuery();
173
+ useEffect(() => {
174
+ trigger("") // Fetch settings on mount
175
+ }, [])
176
+
177
+ useEffect(() => {
178
+ if (solidSettingsData?.data?.mcpEnabled && solidSettingsData?.data?.mcpServerUrl) {
179
+ enableSolidXAiPanel();
180
+ }
181
+ }, [solidSettingsData]);
182
+
183
+ const enableSolidXAiPanel = async () => {
184
+ try {
185
+ const queryData = {
186
+ showHeader: "true",
187
+ inListView: "true"
188
+ };
189
+ const queryString = qs.stringify({ ...queryData }, { encodeValuesOnly: true });
190
+ const response = await getMcpUrl(queryString).unwrap();
191
+ console.log("response", response);
192
+ if (response && response?.data?.mcpUrl) {
193
+ setMcpUrl(response?.data?.mcpUrl);
194
+ }
195
+ } catch (error) {
196
+
197
+ }
198
+ }
199
+
200
+
201
+ useEffect(() => {
202
+ const storedOpen = localStorage.getItem("l_solidxai_open");
203
+ const storedWidth = localStorage.getItem("l_solidxai_width");
204
+
205
+ if (storedOpen !== null) {
206
+ setIsOpenSolidXAiPanel(storedOpen === "true");
207
+ }
208
+
209
+ if (storedWidth !== null) {
210
+ const width = parseInt(storedWidth, 10);
211
+ if (!isNaN(width)) {
212
+ setChatterWidth(width);
213
+ }
214
+ }
215
+ }, []);
216
+
217
+ useEffect(() => {
218
+ if (isResizing) {
219
+ const handleMouseMove = (e: MouseEvent) => {
220
+ const newWidth = window.innerWidth - e.clientX;
221
+ const clampedWidth = Math.max(280, Math.min(newWidth, 700));
222
+ setChatterWidth(clampedWidth);
223
+ localStorage.setItem("l_solidxai_width", clampedWidth.toString());
224
+ };
225
+
226
+ const handleMouseUp = () => {
227
+ setIsResizing(false);
228
+ };
229
+
230
+ window.addEventListener("mousemove", handleMouseMove);
231
+ window.addEventListener("mouseup", handleMouseUp);
232
+
233
+ return () => {
234
+ window.removeEventListener("mousemove", handleMouseMove);
235
+ window.removeEventListener("mouseup", handleMouseUp);
236
+ };
237
+ }
238
+ }, [isResizing]);
239
+
240
+ useEffect(() => {
241
+ const fetchPermissions = async () => {
242
+ if (params.modelName) {
243
+ const permissionNames = [
244
+ permissionExpression(params.modelName, 'create'),
245
+ permissionExpression(params.modelName, 'delete'),
246
+ permissionExpression(params.modelName, 'update'),
247
+ permissionExpression(params.modelName, 'deleteMany'),
248
+ permissionExpression(params.modelName, 'findOne'),
249
+ permissionExpression(params.modelName, 'findMany'),
250
+ permissionExpression(params.modelName, 'insertMany'),
251
+ permissionExpression('importTransaction', 'create'),
252
+ permissionExpression('exportTransaction', 'create'),
253
+ permissionExpression('userViewMetadata', 'create'),
254
+ permissionExpression('savedFilters', 'create')
255
+ ];
256
+ const queryData = {
257
+ permissionNames: permissionNames,
258
+ };
259
+ const queryString = qs.stringify(queryData, {
260
+ encodeValuesOnly: true,
261
+ });
262
+ const response = await triggerCheckIfPermissionExists(queryString);
263
+ setActionsAllowed(response.data.data);
264
+ }
265
+ };
266
+ fetchPermissions();
267
+ }, [params.modelName]);
268
+
269
+ const isFilterApplied = filters ? true : false;
270
+
271
+ // Create the RTK slices for this entity
272
+ const entityApi = createSolidEntityApi(params.modelName);
273
+ const {
274
+ useCreateSolidEntityMutation,
275
+ useDeleteMultipleSolidEntitiesMutation,
276
+ useDeleteSolidEntityMutation,
277
+ useGetSolidEntitiesQuery,
278
+ useGetSolidEntityByIdQuery,
279
+ useLazyGetSolidEntitiesQuery,
280
+ useLazyGetSolidEntityByIdQuery,
281
+ usePrefetch,
282
+ useUpdateSolidEntityMutation,
283
+ useRecoverSolidEntityByIdQuery,
284
+ useLazyRecoverSolidEntityByIdQuery,
285
+ useRecoverSolidEntityMutation,
286
+ } = entityApi;
287
+
288
+ const menuItemId = searchParams.get("menuItemId");
289
+ const menuItemName = searchParams.get("menuItemName");
290
+ const actionId = searchParams.get("actionId");
291
+ const actionName = searchParams.get("actionName");
292
+ // Get the list view layout & metadata first.
293
+ const listViewMetaDataQs = qs.stringify(
294
+ {
295
+ modelName: params.modelName,
296
+ moduleName: params.moduleName,
297
+ viewType: "list",
298
+ menuItemId: menuItemId,
299
+ menuItemName: menuItemName,
300
+ actionId: actionId,
301
+ actionName: actionName,
302
+ },
303
+ {
304
+ encodeValuesOnly: true,
305
+ }
306
+ );
307
+
308
+ const [solidListViewMetaData, setSolidListViewMetaData] = useState(null);
309
+ const [solidListViewLayout, setSolidListViewLayout] = useState(null);
310
+ const [isDraftPublishWorkflowEnabled, setIsDraftPublishWorkflowEnabled] = useState(false);
311
+ const {
312
+ data: solidListViewInitialMetaData,
313
+ error: solidListViewMetaDataError,
314
+ isLoading: solidListViewMetaDataIsLoading,
315
+ isError: solidListViewMetaDataIsError,
316
+ refetch,
317
+ } = useGetSolidViewLayoutQuery(listViewMetaDataQs);
318
+
319
+ const initialFilterMethod = () => {
320
+ const solidView = solidListViewMetaData?.data?.solidView;
321
+ const solidFieldsMetadata =
322
+ solidListViewMetaData?.data?.solidFieldsMetadata;
323
+
324
+ const initialFilters: any = {};
325
+ const toPopulate: string[] = [];
326
+ const toPopulateMedia: string[] = [];
327
+ const currentLayout = params.customLayout ? params.customLayout : solidView?.layout;
328
+ for (let i = 0; i < currentLayout?.children.length; i++) {
329
+ const column = currentLayout?.children[i];
330
+ const fieldMetadata = solidFieldsMetadata?.[column.attrs.name];
331
+ if (!fieldMetadata?.type) {
332
+ console.log(`Some problem in rendering column: `, column);
333
+ showFieldError(ERROR_MESSAGES.FIELD_NOT_IN_METADATA(column.attrs.label));
334
+ // return;
335
+ }
336
+ if (fieldMetadata) {
337
+ // Form the initial filters after iterating over the columns and field metadata.
338
+ if (
339
+ ["int", "bigint", "float", "decimal"].includes(fieldMetadata?.type)
340
+ ) {
341
+ // initialFilters[column.attrs.name] = { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }
342
+ initialFilters[column.attrs.name] = {
343
+ value: null,
344
+ matchMode: FilterMatchMode.EQUALS,
345
+ };
346
+ } else if (
347
+ ["date", "datetime", "time", "boolean"].includes(fieldMetadata?.type)
348
+ ) {
349
+ // initialFilters[column.attrs.name] = { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] }
350
+ initialFilters[column.attrs.name] = {
351
+ value: null,
352
+ matchMode: FilterMatchMode.EQUALS,
353
+ };
354
+ } else if (
355
+ ["relation", "selectionStatic", "selectionDynamic"].includes(
356
+ fieldMetadata?.type
357
+ )
358
+ ) {
359
+ initialFilters[column.attrs.name] = {
360
+ value: null,
361
+ matchMode: FilterMatchMode.IN,
362
+ };
363
+ } else {
364
+ // initialFilters[column.attrs.name] = { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] }
365
+ initialFilters[column.attrs.name] = {
366
+ value: null,
367
+ matchMode: FilterMatchMode.STARTS_WITH,
368
+ };
369
+ }
370
+
371
+ if (column.attrs.name === "id") {
372
+ initialFilters[column.attrs.name] = {
373
+ value: null,
374
+ matchMode: FilterMatchMode.IN,
375
+ };
376
+ }
377
+
378
+ // Form the "toPopulate" array.
379
+ if (fieldMetadata.type === "relation") {
380
+ if (!toPopulate.includes(fieldMetadata.name)) {
381
+ toPopulate.push(fieldMetadata.name);
382
+ }
383
+ }
384
+ if (
385
+ fieldMetadata.type === "mediaSingle" ||
386
+ fieldMetadata.type === "mediaMultiple"
387
+ ) {
388
+ if (!toPopulateMedia.includes(fieldMetadata.name)) {
389
+ toPopulateMedia.push(fieldMetadata.name);
390
+ }
391
+ }
392
+ }
393
+ }
394
+ const populate = toPopulate;
395
+ const populateMedia = toPopulateMedia;
396
+ const rows = currentLayout?.attrs?.defaultPageSize ?? 25;
397
+ const sortField = "id";
398
+ const sortOrder = -1;
399
+ // setRows(rows);
400
+ // setToPopulate(populate);
401
+ // setToPopulateMedia(populateMedia);
402
+ // setSortField("id");
403
+ // setSortOrder(-1);
404
+ return { sortField, sortOrder, rows, populate, populateMedia };
405
+ };
406
+
407
+ // Set the initial filter state based on the metadata.
408
+ useEffect(() => {
409
+ // refetch();
410
+ if (solidListViewInitialMetaData) {
411
+ if (params.customLayout) {
412
+ setSolidListViewLayout(params.customLayout);
413
+ } else {
414
+ setSolidListViewLayout(solidListViewInitialMetaData?.data.solidView.layout);
415
+ }
416
+ setSolidListViewMetaData(solidListViewInitialMetaData);
417
+ setIsDraftPublishWorkflowEnabled(solidListViewInitialMetaData?.data?.solidView?.model?.draftPublishWorkflow === true);
418
+ }
419
+ }, [solidListViewInitialMetaData]);
420
+
421
+ // set layout and actions for create and edit buttons and view modes
422
+ // useEffect(() => {
423
+ // if (solidListViewMetaData) {
424
+ // const listLayoutAttrs = solidListViewMetaData?.data?.solidView?.layout?.attrs;
425
+ // const createActionUrl = listLayoutAttrs?.createAction && listLayoutAttrs?.createAction?.type === "custom" ? listLayoutAttrs?.createAction?.customComponent : "form/new";
426
+ // const editActionUrl = listLayoutAttrs?.editAction && listLayoutAttrs?.editAction?.type === "custom" ? listLayoutAttrs?.editAction?.customComponent : "form";
427
+
428
+ // if (listLayoutAttrs?.createAction) {
429
+ // setCreateActionQueryParams({
430
+ // actionName: listLayoutAttrs.createAction.name,
431
+ // actionType: listLayoutAttrs.createAction.type,
432
+ // actionContext: listLayoutAttrs.createAction.context,
433
+ // });
434
+ // }
435
+ // if (listLayoutAttrs?.editAction) {
436
+ // setEditActionQueryParams({
437
+ // actionName: listLayoutAttrs.editAction.name,
438
+ // actionType: listLayoutAttrs.editAction.type,
439
+ // actionContext: listLayoutAttrs.editAction.context,
440
+ // });
441
+ // }
442
+
443
+ // const viewModes = listLayoutAttrs?.allowedViews && listLayoutAttrs?.allowedViews.length > 0 && listLayoutAttrs?.allowedViews.map((view: any) => { return { label: capitalize(view), value: view }; });
444
+ // setViewModes(viewModes);
445
+ // if (createActionUrl) {
446
+ // setCreateButtonUrl(createActionUrl);
447
+ // }
448
+ // if (editActionUrl) {
449
+ // setEditButtonUrl(editActionUrl);
450
+ // }
451
+ // }
452
+ // }, [solidListViewMetaData]);
453
+
454
+ // set layout and actions for create and edit buttons and view modes
455
+ useEffect(() => {
456
+ if (solidListViewLayout) {
457
+ const listLayoutAttrs = solidListViewLayout.attrs;
458
+ const createActionUrl = listLayoutAttrs?.createAction && listLayoutAttrs?.createAction?.type === "custom" ? listLayoutAttrs?.createAction?.customComponent : "form/new";
459
+ const editActionUrl = listLayoutAttrs?.editAction && listLayoutAttrs?.editAction?.type === "custom" ? listLayoutAttrs?.editAction?.customComponent : "form";
460
+
461
+ if (listLayoutAttrs?.createAction) {
462
+ setCreateActionQueryParams({
463
+ actionName: listLayoutAttrs.createAction.name,
464
+ actionType: listLayoutAttrs.createAction.type,
465
+ actionContext: listLayoutAttrs.createAction.context,
466
+ });
467
+ }
468
+ if (listLayoutAttrs?.editAction) {
469
+ setEditActionQueryParams({
470
+ actionName: listLayoutAttrs.editAction.name,
471
+ actionType: listLayoutAttrs.editAction.type,
472
+ actionContext: listLayoutAttrs.editAction.context,
473
+ });
474
+ }
475
+
476
+ const viewModes = listLayoutAttrs?.allowedViews && listLayoutAttrs?.allowedViews.length > 0 && listLayoutAttrs?.allowedViews.map((view: any) => { return { label: capitalize(view), value: view }; });
477
+ setViewModes(viewModes);
478
+ if (createActionUrl) {
479
+ setCreateButtonUrl(createActionUrl);
480
+ }
481
+ if (editActionUrl) {
482
+ setEditButtonUrl(editActionUrl);
483
+ }
484
+ }
485
+ }, [solidListViewLayout]);
486
+
487
+ // All list view state.
488
+ const [listViewData, setListViewData] = useState<any[]>([]);
489
+ const [first, setFirst] = useState(0);
490
+ const [rows, setRows] = useState(solidListViewLayout?.attrs?.defaultPageSize ? solidListViewLayout?.attrs?.defaultPageSize : 10);
491
+ const [totalRecords, setTotalRecords] = useState(0);
492
+ let [sortField, setSortField] = useState("id");
493
+ const [sortOrder, setSortOrder] = useState(-1);
494
+ const [selectedRecords, setSelectedRecords] = useState<any[]>([]);
495
+ const [selectedRecoverRecords, setSelectedRecoverRecords] = useState<any[]>([]);
496
+ const [loading, setLoading] = useState<boolean>(true);
497
+ const [isDialogVisible, setDialogVisible] = useState(false);
498
+ const [isRecoverDialogVisible, setRecoverDialogVisible] = useState(false);
499
+ const [createButtonUrl, setCreateButtonUrl] = useState<string>();
500
+ const [editButtonUrl, setEditButtonUrl] = useState<string>();
501
+ const [createActionQueryParams, setCreateActionQueryParams] = useState<Record<string, string>>({});
502
+ const [editActionQueryParams, setEditActionQueryParams] = useState<Record<string, string>>({});
503
+ const [showArchived, setShowArchived] = useState(false);
504
+ const [queryDataLoaded, setQueryDataLoaded] = useState(false);
505
+ const [customFilter, setCustomFilter] = useState(null);
506
+ const [showSaveFilterPopup, setShowSaveFilterPopup] = useState<boolean>(false);
507
+
508
+ const sizeOptions = [
509
+ { label: "Compact", value: "small", image: CompactImage },
510
+ { label: "Cozy", value: "normal", image: CozyImage },
511
+ { label: "Comfortable", value: "large", image: ComfortableImage },
512
+ ];
513
+
514
+ // const viewModes = [
515
+ // { label: 'List ', value: 'list', image: ListImage },
516
+ // { label: 'Kanban', value: 'kanban', image: KanbanImage },
517
+ // ]
518
+
519
+ const [size, setSize] = useState<string | any>(sizeOptions[1].value);
520
+ const [viewModes, setViewModes] = useState<any>([]);
521
+
522
+ // Custom Row Action
523
+ const [listViewRowActionPopupState, setListViewRowActionPopupState] = useState(false);
524
+ const [listViewRowActionData, setListRowActionData] = useState<any>();
525
+
526
+ const toast = useRef<Toast>(null);
527
+
528
+ // Get the list view data.
529
+ const [triggerGetSolidEntities, { data: solidEntityListViewData, isLoading, error },] = useLazyGetSolidEntitiesQuery();
530
+
531
+ const [
532
+ triggerRecoverSolidEntitiesById,
533
+ {
534
+ data: recoverByIdData,
535
+ isLoading: recoverByIdIsLoading,
536
+ error: recoverByIdError,
537
+ isError: recoverByIdIsError,
538
+ isSuccess: recoverByIdIsSuccess,
539
+ },
540
+ ] = useLazyRecoverSolidEntityByIdQuery();
541
+
542
+ const [
543
+ triggerRecoverSolidEntities,
544
+ {
545
+ data: recoverByData,
546
+ isLoading: recoverByIsLoading,
547
+ error: recoverError,
548
+ isError: recoverIsError,
549
+ isSuccess: recoverByIsSuccess,
550
+ },
551
+ ] = useRecoverSolidEntityMutation();
552
+
553
+ // After data is fetched populate the list view state so as to be able to render the data.
554
+ useEffect(() => {
555
+ if (solidEntityListViewData) {
556
+ const cleanedRecords = solidEntityListViewData.records.map((record) => {
557
+ const newRecord = { ...record };
558
+
559
+ Object.entries(newRecord).forEach(([key, value]) => {
560
+ if (typeof value === "string") {
561
+ try {
562
+ const parsed = JSON.parse(value);
563
+ if (Array.isArray(parsed)) {
564
+ newRecord[key] = parsed.join(", ");
565
+ }
566
+ } catch {
567
+ // If not valid JSON array, optionally strip brackets/quotes
568
+ if (/^\[.*\]$/.test(value)) {
569
+ newRecord[key] = value.replace(/[\[\]"]+/g, "");
570
+ }
571
+ }
572
+ }
573
+ });
574
+
575
+ return newRecord;
576
+ });
577
+ setListViewData(cleanedRecords);
578
+ // setListViewData(solidEntityListViewData?.records);
579
+ setTotalRecords(solidEntityListViewData?.meta.totalRecords);
580
+ setLoading(false);
581
+ }
582
+ }, [solidEntityListViewData]);
583
+
584
+ const [
585
+ deleteSolidSingleEntiry,
586
+ { isSuccess: isDeleteSolidSingleEntitySuccess },
587
+ ] = useDeleteSolidEntityMutation();
588
+
589
+ // Delete mutation
590
+ const [
591
+ deleteManySolidEntities,
592
+ {
593
+ isLoading: isSolidEntitiesDeleted,
594
+ isSuccess: isDeleteSolidEntitiesSucess,
595
+ isError: isSolidEntitiesDeleteError,
596
+ error: SolidEntitiesDeleteError,
597
+ data: DeletedSolidEntities,
598
+ },
599
+ ] = useDeleteMultipleSolidEntitiesMutation();
600
+
601
+ // Fetch data after toPopulate has been populated...
602
+ useEffect(() => {
603
+ console.log(
604
+ "useEffect: [isDeleteSolidEntitiesSucess, isDeleteSolidSingleEntitySuccess, recoverByIdIsSuccess, recoverByIsSuccess, solidListViewMetaData]"
605
+ );
606
+ if (solidListViewMetaData && solidListViewLayout) {
607
+ const queryObject = queryStringToQueryObject();
608
+
609
+ if (queryObject) {
610
+ const queryData = {
611
+ offset: queryObject.offset || 0,
612
+ limit: queryObject.limit || 25,
613
+ populate: queryObject.populate,
614
+ populateMedia: queryObject.populateMedia,
615
+ sort: queryObject.sort
616
+ ? queryObject.sort?.map((sortItem: string) => {
617
+ const [field, order] = sortItem.split(":");
618
+ return { field, order };
619
+ })
620
+ : [`id:desc`],
621
+ filters: queryObject.filters,
622
+ };
623
+ const filters = {
624
+ $and: [],
625
+ };
626
+
627
+ if (queryObject.custom_filter_predicate) {
628
+ filters.$and.push(queryObject.custom_filter_predicate);
629
+ }
630
+ if (queryObject.search_predicate) {
631
+ filters.$and.push(queryObject.search_predicate);
632
+ }
633
+ // if (queryObject.saved_filter_predicate) {
634
+ // filters.$and.push(queryObject.saved_filter_predicate);
635
+ // }
636
+ // if (queryObject.predefined_search_predicate) {
637
+ // filters.$and.push(queryObject.predefined_search_predicate);
638
+ // }
639
+
640
+ // if (queryObject.s_filter) {
641
+ // filters.$and.push(queryObject.s_filter);
642
+ // }
643
+ // if (queryObject.c_filter) {
644
+ // filters.$and.push(queryObject.c_filter);
645
+ // }
646
+ setRows(Number(queryData.limit));
647
+ setFirst(Number(queryData?.offset));
648
+ setSortField(queryData?.sort[0]?.field);
649
+ setSortOrder(queryData?.sort[0]?.order);
650
+ // latestFiltersRef.current = filters;
651
+ // setFilters(filters);
652
+
653
+ const { sortField, sortOrder, rows, populate, populateMedia } = initialFilterMethod();
654
+ setToPopulate(populate);
655
+ setToPopulateMedia(populateMedia);
656
+
657
+ setQueryDataLoaded(true);
658
+ } else {
659
+ const { sortField, sortOrder, rows, populate, populateMedia } = initialFilterMethod();
660
+ setRows(rows);
661
+ setSortField(sortField);
662
+ setSortOrder(sortOrder);
663
+ setQueryDataLoaded(true);
664
+ setToPopulate(populate);
665
+ setToPopulateMedia(populateMedia);
666
+
667
+ }
668
+ setSelectedRecords([]);
669
+ setSelectedRecoverRecords([]);
670
+ }
671
+ }, [
672
+ isDeleteSolidEntitiesSucess,
673
+ isDeleteSolidSingleEntitySuccess,
674
+ recoverByIdIsSuccess,
675
+ recoverByIsSuccess,
676
+ solidListViewMetaData,
677
+ solidListViewLayout
678
+ ]);
679
+
680
+ useEffect(() => {
681
+ if (solidListViewMetaData && solidListViewMetaData?.data && !loading) {
682
+ const handleDynamicFunction = async () => {
683
+ const dynamicHeader = solidListViewMetaData?.data?.solidView?.layout?.onListLoad;
684
+ let dynamicExtensionFunction = null;
685
+ let listViewRecords = listViewData;
686
+ let listLayout = solidListViewMetaData?.data?.solidView?.layout;
687
+ if (params.customLayout) {
688
+ listLayout = params.customLayout;
689
+ }
690
+ const event: SolidLoadList = {
691
+ fieldsMetadata: solidListViewMetaData?.data?.solidFieldsMetadata,
692
+ listData: listViewData,
693
+ totalRecords: totalRecords,
694
+ type: "onListLoad",
695
+ viewMetadata: solidListViewMetaData?.data?.solidView,
696
+ listViewLayout: listLayout,
697
+ queryParams: {
698
+ menuItemId: menuItemId,
699
+ menuItemName: menuItemName,
700
+ actionId: actionId,
701
+ actionName: actionName,
702
+ },
703
+ user: user,
704
+ session: session.data,
705
+ params: params
706
+ };
707
+
708
+ if (dynamicHeader) {
709
+ dynamicExtensionFunction = getExtensionFunction(dynamicHeader);
710
+ if (dynamicExtensionFunction) {
711
+ const updatedListData: SolidListUiEventResponse = await dynamicExtensionFunction(event);
712
+
713
+ if (updatedListData && updatedListData?.dataChanged && updatedListData?.newListData) {
714
+ listViewRecords = updatedListData.newListData;
715
+ }
716
+ if (updatedListData && updatedListData?.layoutChanged && updatedListData?.newLayout) {
717
+ listLayout = updatedListData.newLayout;
718
+ }
719
+ }
720
+ if (listViewRecords) {
721
+ setListViewData(listViewRecords);
722
+ }
723
+ if (listLayout) {
724
+ setSolidListViewLayout(listLayout);
725
+ }
726
+ }
727
+ };
728
+ handleDynamicFunction();
729
+ }
730
+ }, [solidListViewMetaData, loading]);
731
+
732
+
733
+
734
+ // Create a ref that always has the latest filters
735
+ const latestFiltersRef = useRef(filters);
736
+ const latestCustomFilterRef = useRef(customFilter);
737
+
738
+ // Keep refs in sync
739
+ useEffect(() => {
740
+ latestFiltersRef.current = filters;
741
+ }, [filters]);
742
+
743
+ useEffect(() => {
744
+ latestCustomFilterRef.current = customFilter;
745
+ }, [customFilter]);
746
+
747
+
748
+ useEffect(() => {
749
+ console.log(
750
+ "useEffect: [first, rows, sortField, sortOrder, showArchived, toPopulate, toPopulateMedia, queryDataLoaded]"
751
+ );
752
+
753
+ if (queryDataLoaded && filters) {
754
+ setQueryString();
755
+ }
756
+ }, [
757
+ first,
758
+ rows,
759
+ sortField,
760
+ sortOrder,
761
+ filters,
762
+ showArchived,
763
+ toPopulate,
764
+ toPopulateMedia,
765
+ queryDataLoaded
766
+ ]);
767
+
768
+ // Handle pagination event.
769
+ const onPageChange = (event: any) => {
770
+ setFirst(event.first);
771
+ setRows(event.rows);
772
+ };
773
+
774
+ // Handle sort event.
775
+ const onSort = (event: DataTableStateEvent) => {
776
+ const { sortField, sortOrder } = event;
777
+ const validSortOrder = sortOrder === 1 || sortOrder === -1 ? sortOrder : 0;
778
+ setSortField(sortField);
779
+ setSortOrder(validSortOrder);
780
+ setFirst(0);
781
+
782
+ };
783
+
784
+ // handle change in the records which are currently selected...
785
+ const onSelectionChange = (event: any) => {
786
+ const value = event.value;
787
+ const activeRecords = value.filter(
788
+ (record: any) => record.deletedAt === null
789
+ );
790
+ const deletedRecords = value.filter(
791
+ (record: any) => record.deletedAt !== null
792
+ );
793
+
794
+ setSelectedRecords(activeRecords);
795
+ setSelectedRecoverRecords(deletedRecords);
796
+ };
797
+
798
+
799
+
800
+ const setQueryString = async () => {
801
+ const solidFieldsMetadata =
802
+ solidListViewMetaData?.data?.solidFieldsMetadata;
803
+
804
+ let queryData: any = {
805
+ offset: first,
806
+ limit: rows,
807
+ filters: latestFiltersRef.current ?? latestFiltersRef.current,
808
+ populate: toPopulate,
809
+ populateMedia: toPopulateMedia,
810
+ locale: localeName ? localeName : "en",
811
+ };
812
+
813
+
814
+
815
+ if (sortField && solidFieldsMetadata && solidFieldsMetadata[sortField]) {
816
+ const sortFieldMetadata = solidFieldsMetadata[sortField];
817
+ if (
818
+ sortFieldMetadata?.type === "relation" &&
819
+ sortFieldMetadata?.relationType === "many-to-one"
820
+ ) {
821
+ sortField = `${sortField}.${sortFieldMetadata?.relationModel?.userKeyField?.name}`;
822
+ }
823
+ queryData.sort = [
824
+ `${sortField}:${sortOrder == 0 ? null : sortOrder == 1 ? "asc" : "desc"
825
+ }`,
826
+ ];
827
+ } else {
828
+ queryData.sort = [`id:desc`];
829
+ }
830
+
831
+ if (showArchived) {
832
+ queryData.showSoftDeleted = "inclusive";
833
+ }
834
+
835
+ // SolidBeforeListDataLoad Event that allows filter modification just before api call
836
+ const dynamicHeader = solidListViewMetaData?.data?.solidView?.layout?.onBeforeListDataLoad;
837
+ let dynamicExtensionFunction = null;
838
+ const event: SolidBeforeListDataLoad = {
839
+ type: "onBeforeListDataLoad",
840
+ fieldsMetadata: solidListViewMetaData?.data?.solidFieldsMetadata,
841
+ viewMetadata: solidListViewMetaData?.data?.solidView,
842
+ listViewLayout: solidListViewMetaData?.data.solidView.layout,
843
+ filter: structuredClone(queryData),
844
+ queryParams: {
845
+ menuItemId: menuItemId,
846
+ menuItemName: menuItemName,
847
+ actionId: actionId,
848
+ actionName: actionName,
849
+ },
850
+ user: user,
851
+ session: session.data,
852
+ params: params
853
+ };
854
+
855
+ if (dynamicHeader) {
856
+ dynamicExtensionFunction = getExtensionFunction(dynamicHeader);
857
+ if (dynamicExtensionFunction) {
858
+ try {
859
+ const updatedListData: SolidListUiEventResponse = await dynamicExtensionFunction(event);
860
+ if (updatedListData && updatedListData?.filterApplied && updatedListData?.newFilter) {
861
+ queryData = updatedListData?.newFilter;
862
+ }
863
+ } catch (err) {
864
+ console.error("Error executing onBeforeListDataLoad extension:", err);
865
+ }
866
+ }
867
+ }
868
+
869
+ const queryString = qs.stringify(queryData, { encodeValuesOnly: true });
870
+
871
+ if (latestCustomFilterRef.current) {
872
+ let url;
873
+ const urlData = structuredClone(queryData);
874
+ delete urlData.filters;
875
+ urlData.custom_filter_predicate = latestCustomFilterRef.current.custom_filter_predicate || null;
876
+ urlData.search_predicate = latestCustomFilterRef.current.search_predicate || null;
877
+
878
+ queryObjectToQueryString(urlData);
879
+ }
880
+ triggerGetSolidEntities(queryString);
881
+ };
882
+
883
+ // handle filter...
884
+ const handleApplyCustomFilter = (transformedFilter: any) => {
885
+ const queryfilter = params.customFilter || {
886
+ $and: [],
887
+ };
888
+
889
+ // custom_filter_predicate
890
+ // search_predicate
891
+ // saved_filter_predicate
892
+ // predefined_search_predicate
893
+ if (transformedFilter.custom_filter_predicate) {
894
+ queryfilter.$and.push(transformedFilter.custom_filter_predicate);
895
+ }
896
+ if (transformedFilter.search_predicate) {
897
+ queryfilter.$and.push(transformedFilter.search_predicate);
898
+ }
899
+ if (transformedFilter.saved_filter_predicate) {
900
+ queryfilter.$and.push(transformedFilter.saved_filter_predicate);
901
+ }
902
+ if (transformedFilter.predefined_search_predicate) {
903
+ queryfilter.$and.push(transformedFilter.predefined_search_predicate);
904
+ }
905
+
906
+ const customFilter = transformedFilter;
907
+ const updatedFilter = { ...(filters || {}), ...(queryfilter || {}) };
908
+
909
+ // Update refs IMMEDIATELY (synchronously)
910
+ latestFiltersRef.current = updatedFilter;
911
+ latestCustomFilterRef.current = transformedFilter;
912
+
913
+ // Then update state
914
+ setFilters(updatedFilter);
915
+ setCustomFilter(transformedFilter);
916
+
917
+
918
+ // Force synchronous state updates
919
+
920
+
921
+ };
922
+
923
+ // clear Filter
924
+ const clearFilter = () => {
925
+ if (solidListViewMetaData) {
926
+ const { sortField, sortOrder, rows, populate, populateMedia } = initialFilterMethod();
927
+ setRows(rows);
928
+ setSortField(sortField);
929
+ setSortOrder(sortOrder);
930
+ setToPopulate(populate);
931
+ setToPopulateMedia(populateMedia);
932
+ }
933
+ latestFiltersRef.current = {
934
+ $and: []
935
+ };
936
+
937
+
938
+ setFilters({
939
+ $and: []
940
+ });
941
+ solidGlobalSearchElementRef.current.clearFilter();
942
+ };
943
+
944
+ const [selectedSolidViewData, setSelectedSolidViewData] = useState<any>();
945
+ const selectedDataRef = useRef<any>();
946
+ const op = useRef(null);
947
+ const [deleteEntity, setDeleteEntity] = useState(false);
948
+
949
+ // clickable link allowing one to open the detail / form view.
950
+ const detailsBodyTemplate = (solidViewData: any) => {
951
+ return (
952
+ <div>
953
+ <Button
954
+ type="button"
955
+ text
956
+ size="small"
957
+ className=""
958
+ onClick={(e) =>
959
+ // @ts-ignore
960
+ {
961
+ e.stopPropagation();
962
+ selectedDataRef.current = solidViewData;
963
+ setSelectedSolidViewData(solidViewData);
964
+ op.current.toggle(e)
965
+ }
966
+ }
967
+ >
968
+ <svg
969
+ xmlns="http://www.w3.org/2000/svg"
970
+ width="3"
971
+ height="10"
972
+ viewBox="0 0 4 16"
973
+ fill="none"
974
+ >
975
+ <path
976
+ d="M4 14C4 14.55 3.80417 15.0208 3.4125 15.4125C3.02083 15.8042 2.55 16 2 16C1.45 16 0.979167 15.8042 0.5875 15.4125C0.195833 15.0208 0 14.55 0 14C0 13.45 0.195833 12.9792 0.5875 12.5875C0.979167 12.1958 1.45 12 2 12C2.55 12 3.02083 12.1958 3.4125 12.5875C3.80417 12.9792 4 13.45 4 14ZM4 8C4 8.55 3.80417 9.02083 3.4125 9.4125C3.02083 9.80417 2.55 10 2 10C1.45 10 0.979167 9.80417 0.5875 9.4125C0.195833 9.02083 0 8.55 0 8C0 7.45 0.195833 6.97917 0.5875 6.5875C0.979167 6.19583 1.45 6 2 6C2.55 6 3.02083 6.19583 3.4125 6.5875C3.80417 6.97917 4 7.45 4 8ZM4 2C4 2.55 3.80417 3.02083 3.4125 3.4125C3.02083 3.80417 2.55 4 2 4C1.45 4 0.979167 3.80417 0.5875 3.4125C0.195833 3.02083 0 2.55 0 2C0 1.45 0.195833 0.979166 0.5875 0.5875C0.979167 0.195833 1.45 0 2 0C2.55 0 3.02083 0.195833 3.4125 0.5875C3.80417 0.979166 4 1.45 4 2Z"
977
+ fill="#666666"
978
+ />
979
+ </svg>
980
+ </Button>
981
+ </div>
982
+ // <a onClick={() => {
983
+ // if (params.embeded == true) {
984
+ // params.handlePopUpOpen(solidViewData.id);
985
+ // } else {
986
+ // router.push(`${editButtonUrl}/${solidViewData.id}`)
987
+ // }
988
+ // }} rel="noopener noreferrer" className="text-sm font-bold p-0" style={{ color: "#12415D" }}>
989
+ // <i className="pi pi-pencil" style={{ fontSize: "1rem" }}></i>
990
+ // </a>
991
+ );
992
+ };
993
+
994
+ // Recover functions
995
+ const recoverById = (id) => {
996
+ triggerRecoverSolidEntitiesById(id);
997
+ };
998
+
999
+ const recoverAll = () => {
1000
+ let recoverList: any = [];
1001
+ selectedRecoverRecords.forEach((element: any) => {
1002
+ recoverList.push(element.id);
1003
+ });
1004
+ triggerRecoverSolidEntities(recoverList);
1005
+ setRecoverDialogVisible(false);
1006
+ };
1007
+
1008
+ useEffect(() => {
1009
+ if (recoverByIdIsSuccess && recoverByIdData) {
1010
+ toast.current?.show({
1011
+ severity: "success",
1012
+ summary: "Success",
1013
+ detail: recoverByIdData.data.message,
1014
+ life: 3000,
1015
+ });
1016
+ return;
1017
+ }
1018
+ if (recoverByIdIsError && recoverByIdError) {
1019
+ showError(recoverByIdError);
1020
+ return;
1021
+ }
1022
+
1023
+ if (recoverIsError && recoverError) {
1024
+ showError(recoverError);
1025
+ }
1026
+ }, [recoverByIdIsSuccess, recoverByIdData, recoverByIdIsError, recoverByIdError, recoverIsError, recoverError]);
1027
+
1028
+ const showError = async (error) => {
1029
+ const errorMessages = error?.data?.message;
1030
+ const messages = Array.isArray(errorMessages)
1031
+ ? errorMessages
1032
+ : errorMessages
1033
+ ? [errorMessages]
1034
+ : [];
1035
+ if (messages.length > 0) {
1036
+ toast?.current?.show({
1037
+ severity: "error",
1038
+ summary: ERROR_MESSAGES.SEND_REPORT,
1039
+ sticky: true,
1040
+ //@ts-ignore
1041
+ content: (props) => (
1042
+ <div
1043
+ className="flex flex-column align-items-left"
1044
+ style={{ flex: "1" }}
1045
+ >
1046
+ {messages.map((m, index) => (
1047
+ <div className="flex align-items-center gap-2" key={index}>
1048
+ <span className="font-bold text-900">{String(m)}</span>
1049
+ </div>
1050
+ ))}
1051
+ </div>
1052
+ ),
1053
+ });
1054
+ }
1055
+ };
1056
+
1057
+ const showFieldError = async (error) => {
1058
+ if (error) {
1059
+ toast?.current?.show({
1060
+ severity: "error",
1061
+ summary: ERROR_MESSAGES.SEND_REPORT,
1062
+ // sticky: true,
1063
+ life: 3000,
1064
+ //@ts-ignore
1065
+ content: (props) => (
1066
+ <div
1067
+ className="flex flex-column align-items-left"
1068
+ style={{ flex: "1" }}
1069
+ >
1070
+ <div className="flex align-items-center gap-2">
1071
+ <span className="font-bold text-900">{String(error)}</span>
1072
+ </div>
1073
+ </div>
1074
+ ),
1075
+ });
1076
+ }
1077
+ };
1078
+
1079
+ // handle bulk deletion
1080
+ const deleteBulk = () => {
1081
+ let deleteList: any = [];
1082
+ selectedRecords.forEach((element: any) => {
1083
+ deleteList.push(element.id);
1084
+ });
1085
+ deleteManySolidEntities(deleteList)
1086
+ .unwrap()
1087
+ .then(() => {
1088
+ toast.current?.show({
1089
+ severity: 'success',
1090
+ summary: 'Deleted',
1091
+ detail: ERROR_MESSAGES.RECORD_DELETE,
1092
+ life: 3000
1093
+ });
1094
+ setDialogVisible(false);
1095
+ })
1096
+ .catch((error) => {
1097
+ toast.current?.show({
1098
+ severity: 'error',
1099
+ summary: 'Delete Failed',
1100
+ detail: error?.data?.message,
1101
+ life: 4000
1102
+ });
1103
+ });
1104
+ };
1105
+
1106
+ // handle closing of the delete dialog...
1107
+ const onDeleteClose = () => {
1108
+ setDialogVisible(false);
1109
+ setSelectedRecords([]);
1110
+ setSelectedRecoverRecords([]);
1111
+ };
1112
+
1113
+ const [openLightbox, setOpenLightbox] = useState(false);
1114
+ const [lightboxUrls, setLightboxUrls] = useState({});
1115
+ const [showGlobalSearchElement, setShowGlobalSearchElement] = useState(false);
1116
+
1117
+ // Render columns dynamically based on metadata
1118
+ const renderColumnsDynamically = (solidListViewMetaData: any, solidListViewLayout: any) => {
1119
+ if (!solidListViewMetaData) {
1120
+ return;
1121
+ }
1122
+ if (!solidListViewMetaData.data) {
1123
+ return;
1124
+ }
1125
+ const solidView = solidListViewMetaData.data.solidView;
1126
+ const solidFieldsMetadata = solidListViewMetaData.data.solidFieldsMetadata;
1127
+ if (!solidView || !solidFieldsMetadata) {
1128
+ return;
1129
+ }
1130
+ const currentLayout = solidListViewLayout;
1131
+
1132
+ return currentLayout.children?.map((column: any) => {
1133
+ const fieldMetadata = solidFieldsMetadata[column.attrs.name];
1134
+ if (!fieldMetadata) {
1135
+ return;
1136
+ }
1137
+ const visibleToRole = column?.attrs?.roles || [];
1138
+
1139
+ if (visibleToRole.length > 0) {
1140
+ if (hasAnyRole(user?.user?.roles, visibleToRole)) {
1141
+ return SolidListViewColumn({
1142
+ solidListViewMetaData,
1143
+ fieldMetadata,
1144
+ column,
1145
+ setLightboxUrls,
1146
+ setOpenLightbox,
1147
+ });
1148
+ } else {
1149
+ return null;
1150
+ }
1151
+ } else {
1152
+ return SolidListViewColumn({
1153
+ solidListViewMetaData,
1154
+ fieldMetadata,
1155
+ column,
1156
+ setLightboxUrls,
1157
+ setOpenLightbox,
1158
+ });
1159
+ }
1160
+ });
1161
+ };
1162
+
1163
+ //Note - Custom Row Action Popup
1164
+ const closeListViewRowActionPopup = () => {
1165
+ setListViewRowActionPopupState(false);
1166
+ };
1167
+
1168
+ // if (loading || isLoading) {
1169
+ // return <SolidListViewShimmerLoading />;
1170
+ // }
1171
+
1172
+ const viewMode = searchParams.get("viewMode");
1173
+
1174
+ // if (
1175
+ // (loading || isLoading) && params.embeded == false && viewMode !== "view"
1176
+ // ) {
1177
+ // return <SolidListViewShimmerLoading />;
1178
+ // }
1179
+
1180
+ const isListViewEmptyWithoutFilters =
1181
+ !loading &&
1182
+ (!filters || Object.keys(filters).length === 0) &&
1183
+ listViewData.length === 0;
1184
+
1185
+ // if (isListViewEmptyWithoutFilters) {
1186
+ // return (
1187
+ // <SolidEmptyListViewPlaceholder
1188
+ // createButtonUrl={createButtonUrl}
1189
+ // actionsAllowed={actionsAllowed}
1190
+ // params={params}
1191
+ // solidListViewMetaData={solidListViewMetaData}
1192
+ // />
1193
+ // );
1194
+ // }
1195
+
1196
+ const handleFetchUpdatedRecords = () => {
1197
+ setQueryString();
1198
+ };
1199
+ const handleOpenSolidXAIPanel = () => {
1200
+ setIsOpenSolidXAiPanel(true);
1201
+ localStorage.setItem("l_solidxai_open", "true");
1202
+ };
1203
+
1204
+ const handleCloseSolidXAIPanel = () => {
1205
+ setIsOpenSolidXAiPanel(false);
1206
+ localStorage.setItem("l_solidxai_open", "false");
1207
+ };
1208
+
1209
+ const handleDeleteEntity = async () => {
1210
+ try {
1211
+ if (!selectedSolidViewData?.id) {
1212
+ throw new Error(ERROR_MESSAGES.NO_ENTITY_SELECTED);
1213
+ }
1214
+
1215
+ const response = await deleteSolidSingleEntiry(selectedSolidViewData.id);
1216
+
1217
+ if (response?.data?.statusCode === 200) {
1218
+ setDeleteEntity(false);
1219
+ toast.current?.show({
1220
+ severity: "success",
1221
+ summary: ERROR_MESSAGES.DELETED,
1222
+ detail: ERROR_MESSAGES.ENTITY_DELETE,
1223
+ ...(severity === "error"
1224
+ ? { sticky: true } // stays until user closes
1225
+ : { life: 3000 }),
1226
+ });
1227
+ } else {
1228
+ toast.current?.show({
1229
+ severity: "error",
1230
+ summary: ERROR_MESSAGES.DELETE_FAIELD,
1231
+ detail: response?.error?.data?.error,
1232
+ ...(severity === "error"
1233
+ ? { sticky: true } // stays until user closes
1234
+ : { life: 3000 }),
1235
+ });
1236
+ }
1237
+ } catch (error: any) {
1238
+ toast.current?.show({
1239
+ severity: "error",
1240
+ summary: ERROR_MESSAGES.DELETE_FAIELD,
1241
+ detail: ERROR_MESSAGES.SOMETHING_WRONG,
1242
+ ...(severity === "error"
1243
+ ? { sticky: true } // stays until user closes
1244
+ : { life: 3000 }),
1245
+ });
1246
+ }
1247
+ };
1248
+
1249
+ const isVideoOrAudio = (url: string) => {
1250
+ // Remove query params if present
1251
+ const cleanUrl = url.split("?")[0];
1252
+ const ext = cleanUrl.split(".").pop()?.toLowerCase();
1253
+
1254
+ const mediaExt = ["mp4", "webm", "ogg", "mov", "mp3", "wav", "m4a", "aac"];
1255
+
1256
+ return ext ? mediaExt.includes(ext) : false;
1257
+ };
1258
+
1259
+ const controlsList = ["nodownload", "nofullscreen", "noremoteplayback"];
1260
+
1261
+ const slides = Array.isArray(lightboxUrls)
1262
+ ? lightboxUrls.map((item: any) => {
1263
+ const url = item?.src || item?.downloadUrl || "";
1264
+ if (isVideoOrAudio(url)) {
1265
+ return {
1266
+ type: "video" as const,
1267
+ sources: [{ src: url, type: "video/mp4" }],
1268
+ };
1269
+ }
1270
+ return { src: url };
1271
+ })
1272
+ : [];
1273
+
1274
+ const hasMedia = slides.some((s) => (s as any).type === "video");
1275
+
1276
+ const hasEditInContextMenu = actionsAllowed.includes(`${permissionExpression(params.modelName, 'update')}`) &&
1277
+ solidListViewLayout?.attrs?.edit !== false &&
1278
+ solidListViewLayout?.attrs?.showDefaultEditButton !== false &&
1279
+ solidListViewLayout?.attrs?.showRowEditInContextMenu !== false &&
1280
+ !(isDraftPublishWorkflowEnabled && selectedDataRef.current?.publishedAt);
1281
+
1282
+ const hasDeleteInContextMenu = actionsAllowed.includes(`${permissionExpression(params.modelName, 'delete')}`) &&
1283
+ solidListViewLayout?.attrs?.delete !== false &&
1284
+ solidListViewLayout?.attrs?.showRowDeleteInContextMenu !== false &&
1285
+ !(isDraftPublishWorkflowEnabled && selectedDataRef.current?.publishedAt);
1286
+
1287
+ const hasCustomContextMenuButtons =
1288
+ solidListViewLayout?.attrs?.rowButtons?.some(
1289
+ (rb) => rb?.attrs?.actionInContextMenu === true
1290
+ );
1291
+
1292
+ const hasAnyContextMenuActions =
1293
+ hasEditInContextMenu || hasDeleteInContextMenu || hasCustomContextMenuButtons;
1294
+
1295
+ const toggleBothSidebars = () => {
1296
+ if (visibleNavbar) {
1297
+ dispatch(toggleNavbar()); // close both
1298
+ } else {
1299
+ dispatch(showNavbar()); // open both
1300
+ }
1301
+ };
1302
+ return (
1303
+ <div className="page-parent-wrapper flex">
1304
+ <div className={`h-full flex-grow-1 ${styles.ListContentWrapper}`}>
1305
+ {solidListViewInitialMetaData && queryDataLoaded &&
1306
+ <div className="page-header flex-column lg:flex-row">
1307
+ <Toast ref={toast} />
1308
+ {/* <div> */}
1309
+ <div className="flex justify-content-between w-full">
1310
+ <div className="flex gap-3 align-items-center w-full ">
1311
+ <div className='flex align-items-center gap-2'>
1312
+ {params.embeded !== true &&
1313
+ <div className="apps-icon block md:hidden cursor-pointer" onClick={toggleBothSidebars}>
1314
+ <i className="pi pi-th-large"></i>
1315
+ </div>
1316
+ }
1317
+ <p className="m-0 view-title solid-text-wrapper">
1318
+ {solidListViewMetaData?.data?.solidView?.action?.displayName || solidListViewMetaData?.data?.solidView?.displayName}
1319
+ </p>
1320
+ </div>
1321
+ {solidListViewLayout?.attrs?.enableGlobalSearch === true &&
1322
+ params.embeded === false && (
1323
+ <div className="hidden lg:flex">
1324
+ <SolidGlobalSearchElement
1325
+ showSaveFilterPopup={showSaveFilterPopup}
1326
+ setShowSaveFilterPopup={setShowSaveFilterPopup}
1327
+ filters={filters}
1328
+ clearFilter={clearFilter}
1329
+ ref={solidGlobalSearchElementRef}
1330
+ viewData={solidListViewMetaData}
1331
+ handleApplyCustomFilter={handleApplyCustomFilter}>
1332
+ </SolidGlobalSearchElement>
1333
+ </div>
1334
+
1335
+ )}
1336
+
1337
+ </div>
1338
+ <div className="flex align-items-center solid-header-buttons-wrapper">
1339
+ {solidListViewLayout?.attrs?.enableGlobalSearch === true &&
1340
+ params.embeded === false && (
1341
+ <div className="flex lg:hidden">
1342
+ <Button
1343
+ type="button"
1344
+ size="small"
1345
+ icon="pi pi-search"
1346
+ severity="secondary"
1347
+ outlined
1348
+ className="solid-icon-button"
1349
+ onClick={() => setShowGlobalSearchElement(!showGlobalSearchElement)}
1350
+ >
1351
+ </Button>
1352
+ </div>
1353
+
1354
+ )}
1355
+
1356
+ <div className="hidden lg:flex align-items-center solid-header-buttons-wrapper">
1357
+ {solidListViewLayout?.attrs?.headerButtons
1358
+ ?.filter((rb) => rb.attrs.actionInContextMenu != true)
1359
+ ?.map((button: any, index: number) => (
1360
+ <SolidListViewHeaderButton
1361
+ key={index}
1362
+ button={button}
1363
+ params={params}
1364
+ solidListViewMetaData={solidListViewMetaData}
1365
+ handleCustomButtonClick={handleCustomButtonClick}
1366
+ selectedRecords={selectedRecords}
1367
+ filters={filters}
1368
+ />
1369
+ ))}
1370
+ </div>
1371
+
1372
+ {actionsAllowed.includes(`${permissionExpression(params.modelName, 'create')}`) &&
1373
+ solidListViewLayout?.attrs?.create !== false &&
1374
+ params.embeded !== true &&
1375
+ solidListViewMetaData?.data?.solidView?.layout?.attrs
1376
+ .showDefaultAddButton !== false && (
1377
+ <SolidCreateButton
1378
+ createButtonUrl={createButtonUrl}
1379
+ createActionQueryParams={createActionQueryParams}
1380
+ solidListViewLayout={solidListViewLayout}
1381
+ responsiveIconOnly={true}
1382
+ />
1383
+ )}
1384
+ {actionsAllowed.includes(`${permissionExpression(params.modelName, 'create')}`) &&
1385
+ solidListViewLayout?.attrs?.create !== false &&
1386
+ params.embeded == true &&
1387
+ params.inlineCreate == true &&
1388
+ searchParams.get("viewMode") !== "view" && (
1389
+
1390
+ <Button
1391
+ type="button"
1392
+ icon={solidListViewLayout?.attrs?.addButtonIcon ? solidListViewLayout?.attrs?.addButtonIcon : "pi pi-plus"}
1393
+ label={solidListViewLayout?.attrs?.addButtonTitle ? solidListViewLayout?.attrs?.addButtonTitle : "Add"}
1394
+ className={`${solidListViewLayout?.attrs?.addButtonClassName}`}
1395
+ size="small"
1396
+ onClick={() => params.handlePopUpOpen("new")}
1397
+ ></Button>
1398
+ )}
1399
+ {/* Button For Manual Refresh */}
1400
+ {params.embeded !== true && (
1401
+ <Button
1402
+ type="button"
1403
+ size="small"
1404
+ icon="pi pi-refresh"
1405
+ severity="secondary"
1406
+ className="solid-icon-button "
1407
+ outlined
1408
+ onClick={() => {
1409
+ setQueryString();
1410
+ }}
1411
+ />
1412
+ )}
1413
+ {showArchived && (
1414
+ <Button
1415
+ type="button"
1416
+ icon="pi pi-refresh"
1417
+ label="Recover"
1418
+ size="small"
1419
+ severity="secondary"
1420
+ className="hidden lg:flex solid-icon-button "
1421
+ onClick={() => setRecoverDialogVisible(true)}
1422
+ ></Button>
1423
+ )}
1424
+
1425
+ {params.embeded === false &&
1426
+ solidListViewLayout?.attrs?.configureView !== false && (
1427
+ <SolidListViewConfigure
1428
+ listViewMetaData={solidListViewMetaData}
1429
+ solidListViewLayout={solidListViewLayout}
1430
+ setShowArchived={setShowArchived}
1431
+ showArchived={showArchived}
1432
+ viewData={solidListViewMetaData}
1433
+ sizeOptions={sizeOptions}
1434
+ setSize={setSize}
1435
+ size={size}
1436
+ viewModes={viewModes}
1437
+ params={params}
1438
+ actionsAllowed={actionsAllowed}
1439
+ selectedRecords={selectedRecords}
1440
+ setDialogVisible={setDialogVisible}
1441
+ setShowSaveFilterPopup={setShowSaveFilterPopup}
1442
+ filters={filters}
1443
+ handleFetchUpdatedRecords={handleFetchUpdatedRecords}
1444
+ setRecoverDialogVisible={setRecoverDialogVisible}
1445
+ />
1446
+ )}
1447
+ </div>
1448
+ </div>
1449
+ {/* </div> */}
1450
+ {solidListViewLayout?.attrs?.enableGlobalSearch === true && showGlobalSearchElement &&
1451
+ params.embeded === false && (
1452
+ <div className="flex lg:hidden">
1453
+ <SolidGlobalSearchElement
1454
+ showSaveFilterPopup={showSaveFilterPopup}
1455
+ setShowSaveFilterPopup={setShowSaveFilterPopup}
1456
+ filters={filters}
1457
+ clearFilter={clearFilter}
1458
+ ref={solidGlobalSearchElementRef}
1459
+ viewData={solidListViewMetaData}
1460
+ handleApplyCustomFilter={handleApplyCustomFilter}>
1461
+ </SolidGlobalSearchElement>
1462
+ </div>
1463
+
1464
+ )}
1465
+ {/* <Dialog
1466
+ visible={showGlobalSearchElement}
1467
+ // header="Confirm Delete"
1468
+ onHide={() => setShowGlobalSearchElement(false)}
1469
+ headerClassName="py-2"
1470
+ contentClassName="px-0 pb-0"
1471
+ // style={{ width: '20vw' }}
1472
+ style={{height:'50vw'}}
1473
+ breakpoints={{ '1199px': '20vw', '1024px': '30vw', '767px': '90vw', '250px': '80vw' }}
1474
+ >
1475
+ <SolidGlobalSearchElement
1476
+ showSaveFilterPopup={showSaveFilterPopup}
1477
+ setShowSaveFilterPopup={setShowSaveFilterPopup}
1478
+ filters={filters}
1479
+ clearFilter={clearFilter}
1480
+ ref={solidGlobalSearchElementRef}
1481
+ viewData={solidListViewMetaData}
1482
+ handleApplyCustomFilter={handleApplyCustomFilter}>
1483
+ </SolidGlobalSearchElement>
1484
+ </Dialog> */}
1485
+ </div>
1486
+ }
1487
+
1488
+ {(loading || isLoading) && params.embeded == false && viewMode !== "view" ?
1489
+ < SolidListViewShimmerLoading />
1490
+ :
1491
+ <>
1492
+ {isListViewEmptyWithoutFilters ? (
1493
+ <SolidEmptyListViewPlaceholder
1494
+ createButtonUrl={createButtonUrl}
1495
+ createActionQueryParams={createActionQueryParams}
1496
+ actionsAllowed={actionsAllowed}
1497
+ params={params}
1498
+ solidListViewMetaData={solidListViewMetaData}
1499
+ />
1500
+
1501
+ ) : (
1502
+ <div className="solid-datatable-wrapper flex-1 min-h-0 overflow-auto">
1503
+ <DataTable
1504
+ value={listViewData}
1505
+ rowClassName={(rowData) => {
1506
+ return rowData.deletedAt ? "greyed-out-row" : "";
1507
+ }}
1508
+ showGridlines={false}
1509
+ lazy
1510
+ scrollable
1511
+ // scrollHeight="90vh"
1512
+ size={size}
1513
+ resizableColumns
1514
+ columnResizeMode="expand"
1515
+ paginator={true}
1516
+ rows={rows}
1517
+ rowsPerPageOptions={solidListViewLayout?.attrs?.pageSizeOptions}
1518
+ dataKey="id"
1519
+ emptyMessage={
1520
+ solidListViewMetaData?.data?.solidView?.model?.description ||
1521
+ "No Entities found."
1522
+ }
1523
+ filterDisplay="menu"
1524
+ totalRecords={totalRecords}
1525
+ first={first}
1526
+ onPage={onPageChange}
1527
+ onSort={(e: DataTableStateEvent) => onSort(e)}
1528
+ sortField={sortField}
1529
+ sortOrder={sortOrder === 1 || sortOrder === -1 ? sortOrder : 0}
1530
+ loading={false}
1531
+ // loading={loading || isLoading}
1532
+ // loadingIcon="pi pi-spinner"
1533
+ selection={
1534
+ params.embeded === true
1535
+ ? null
1536
+ : [...selectedRecords, ...selectedRecoverRecords]
1537
+ }
1538
+ onSelectionChange={
1539
+ params.embeded === true ? undefined : onSelectionChange
1540
+ }
1541
+ selectionMode={params.embeded === true ? null : "checkbox"}
1542
+ removableSort
1543
+ filterIcon={<FilterIcon />}
1544
+ tableClassName="solid-data-table"
1545
+ paginatorClassName="solid-paginator"
1546
+ paginatorTemplate="RowsPerPageDropdown CurrentPageReport PrevPageLink NextPageLink"
1547
+ currentPageReportTemplate="{first} - {last} of {totalRecords}"
1548
+ onRowClick={(e) => {
1549
+ const rowData = e.data;
1550
+
1551
+ if (solidListViewLayout?.attrs?.disableRowClick === true) return;
1552
+
1553
+ const hasFindPermission = actionsAllowed.includes(
1554
+ permissionExpression(params.modelName, 'findOne')
1555
+ );
1556
+ const hasUpdatePermission =
1557
+ actionsAllowed.includes(permissionExpression(params.modelName, 'update')) &&
1558
+ solidListViewLayout?.attrs?.edit !== false;
1559
+
1560
+ if (!(hasFindPermission || hasUpdatePermission)) return;
1561
+
1562
+ if (params.embeded === true) {
1563
+ params.handlePopUpOpen(rowData?.id);
1564
+ } else {
1565
+ if (typeof window !== "undefined") {
1566
+ // store a simple marker for the caller
1567
+
1568
+ // also store the full current URL so Back can restore exact state (including action params)
1569
+ try {
1570
+ sessionStorage.setItem("fromView", "list");
1571
+ sessionStorage.setItem("fromViewUrl", window.location.pathname + window.location.search);
1572
+ } catch (e) {
1573
+ // ignore storage errors
1574
+ }
1575
+ }
1576
+ router.push(`${editButtonUrl}/${rowData?.id}?viewMode=view&${new URLSearchParams(editActionQueryParams).toString()}`);
1577
+ }
1578
+ }
1579
+ }
1580
+ >
1581
+ {params.embeded === true ? null : (
1582
+ <Column
1583
+ selectionMode="multiple"
1584
+ headerStyle={{ width: "3em" }}
1585
+ />
1586
+ )}
1587
+ {solidListViewMetaData && solidListViewLayout && renderColumnsDynamically(solidListViewMetaData, solidListViewLayout)}
1588
+ {solidListViewLayout?.attrs?.rowButtons &&
1589
+ solidListViewLayout?.attrs?.rowButtons
1590
+ .filter((rb: any) => {
1591
+ const roles = rb?.attrs?.roles || [];
1592
+ const isInContextMenu =
1593
+ rb.attrs.actionInContextMenu === true;
1594
+
1595
+ // Only check hasAnyRole if roles are provided
1596
+ const isAllowed =
1597
+ roles.length === 0 ||
1598
+ hasAnyRole(user?.user?.roles, roles);
1599
+
1600
+ const isVisible = rb?.attrs?.visible !== false;
1601
+
1602
+ return !isInContextMenu && isAllowed && isVisible;
1603
+ })
1604
+ .map((button: any, index: number) => {
1605
+ // const hasRole = button.attrs.roles && button.attrs.roles.length > 0 ? useHasAnyRole(button.attrs.roles) : true;
1606
+ // if (!hasRole) return null;
1607
+
1608
+ return (
1609
+ <Column
1610
+ key={index}
1611
+ header={button.attrs.label}
1612
+ body={(rowData) => {
1613
+ return (
1614
+ <Button
1615
+ type="button"
1616
+ icon={
1617
+ button?.attrs?.icon
1618
+ ? button?.attrs?.icon
1619
+ : "pi pi-pencil"
1620
+ }
1621
+ className={`w-full text-left gap-2 ${button?.attrs?.className
1622
+ ? button?.attrs?.className
1623
+ : ""
1624
+ }`}
1625
+ label={
1626
+ button.attrs.showLabel !== false
1627
+ ? button.attrs.label
1628
+ : ""
1629
+ }
1630
+ size="small"
1631
+ iconPos="left"
1632
+ onClick={() => {
1633
+ const event = {
1634
+ params,
1635
+ rowData: rowData,
1636
+ solidListViewMetaData:
1637
+ solidListViewMetaData?.data,
1638
+ };
1639
+ handleCustomButtonClick(button.attrs, event);
1640
+ }}
1641
+ />
1642
+ );
1643
+ }}
1644
+ />
1645
+ );
1646
+ })}
1647
+
1648
+ {actionsAllowed.includes(
1649
+ `${permissionExpression(params.modelName, 'update')}`
1650
+ ) &&
1651
+ solidListViewLayout?.attrs?.edit !== false &&
1652
+ solidListViewLayout?.attrs?.showRowEditInContextMenu ===
1653
+ false && (
1654
+ <Column
1655
+ header="Edit"
1656
+ body={(rowData) => {
1657
+ const shouldHideEditOrDeleteButton = isDraftPublishWorkflowEnabled && rowData?.publishedAt;
1658
+ return (
1659
+ <>
1660
+ {!shouldHideEditOrDeleteButton && (
1661
+ <Button
1662
+ text
1663
+ type="button"
1664
+ severity="secondary"
1665
+ className=""
1666
+ label=""
1667
+ size="small"
1668
+ iconPos="left"
1669
+ icon={"pi pi-pencil"}
1670
+ onClick={() => {
1671
+ if (params.embeded == true) {
1672
+ params.handlePopUpOpen(rowData?.id);
1673
+ } else {
1674
+ if (typeof window !== "undefined") {
1675
+ try {
1676
+ sessionStorage.setItem("fromView", "list");
1677
+ sessionStorage.setItem("fromViewUrl", window.location.pathname + window.location.search);
1678
+ } catch (e) { }
1679
+ }
1680
+ router.push(
1681
+ `${editButtonUrl}/${rowData?.id}?viewMode=edit&${new URLSearchParams(editActionQueryParams).toString()}`
1682
+ );
1683
+ }
1684
+ }}
1685
+ />
1686
+ )}
1687
+ </>
1688
+ );
1689
+ }}
1690
+ />
1691
+ )}
1692
+
1693
+ {actionsAllowed.includes(
1694
+ `${permissionExpression(params.modelName, 'delete')}`
1695
+ ) &&
1696
+ solidListViewLayout?.attrs?.delete !== false &&
1697
+ solidListViewLayout?.attrs?.showRowDeleteInContextMenu ===
1698
+ false && (
1699
+ <Column
1700
+ header="Delete"
1701
+ body={(rowData) => {
1702
+ const shouldHideEditOrDeleteButton = isDraftPublishWorkflowEnabled && rowData?.publishedAt;
1703
+ return (
1704
+ <>
1705
+ {!shouldHideEditOrDeleteButton && (
1706
+ <Button
1707
+ text
1708
+ type="button"
1709
+ className=""
1710
+ size="small"
1711
+ iconPos="left"
1712
+ severity="danger"
1713
+ icon={"pi pi-trash"}
1714
+ onClick={() => {
1715
+ setSelectedSolidViewData(rowData);
1716
+ setDeleteEntity(true);
1717
+ }}
1718
+ />
1719
+ )}
1720
+ </>
1721
+ );
1722
+ }}
1723
+ />
1724
+ )}
1725
+
1726
+ {hasAnyContextMenuActions && (
1727
+ <Column
1728
+ frozen
1729
+ alignFrozen="right"
1730
+ body={(rowData) =>
1731
+ rowData?.deletedAt ? (
1732
+ <a
1733
+ onClick={(event) => {
1734
+ event.stopPropagation();
1735
+ recoverById(rowData.id);
1736
+ }}
1737
+ className="retrieve-button"
1738
+ >
1739
+ <i
1740
+ className="pi pi-refresh"
1741
+ style={{ fontSize: "1rem" }}
1742
+ />
1743
+ </a>
1744
+ ) : (
1745
+ <>
1746
+ {solidListViewLayout?.attrs?.showRowContextMenu !==
1747
+ false && (
1748
+ <>
1749
+ {detailsBodyTemplate(rowData)}
1750
+ <OverlayPanel
1751
+ ref={op}
1752
+ className="solid-custom-overlay"
1753
+ style={{ top: 10, minWidth: 120 }}
1754
+ >
1755
+ <div className="flex flex-column gap-1 p-1">
1756
+ {hasEditInContextMenu && (
1757
+ <Button
1758
+ type="button"
1759
+ className="w-full text-left gap-1"
1760
+ label="Edit"
1761
+ size="small"
1762
+ iconPos="left"
1763
+ icon={"pi pi-pencil"}
1764
+ onClick={() => {
1765
+ if (params.embeded == true) {
1766
+ params.handlePopUpOpen(
1767
+ selectedDataRef.current?.id
1768
+ );
1769
+ } else {
1770
+ try {
1771
+ sessionStorage.setItem("fromView", "list");
1772
+ sessionStorage.setItem("fromViewUrl", window.location.pathname + window.location.search);
1773
+ } catch (e) { }
1774
+ router.push(
1775
+ `${editButtonUrl}/${selectedDataRef.current?.id}?viewMode=edit&${new URLSearchParams(editActionQueryParams).toString()}`
1776
+ );
1777
+ }
1778
+ }}
1779
+ />
1780
+ )}
1781
+
1782
+ {hasDeleteInContextMenu && (
1783
+ <Button
1784
+ text
1785
+ type="button"
1786
+ className="w-full text-left gap-1"
1787
+ label="Delete"
1788
+ size="small"
1789
+ iconPos="left"
1790
+ severity="danger"
1791
+ icon={"pi pi-trash"}
1792
+ onClick={() => setDeleteEntity(true)}
1793
+ />
1794
+ )}
1795
+ {hasCustomContextMenuButtons && solidListViewLayout?.attrs?.rowButtons
1796
+ ?.filter(
1797
+ (rb) =>
1798
+ rb?.attrs?.actionInContextMenu === true &&
1799
+ rb?.attrs?.visible !== false
1800
+ )
1801
+ .map((button: any, index: number) => (
1802
+ <SolidListViewRowButtonContextMenu
1803
+ key={`${index}-${selectedDataRef?.current?.id || ''}`}
1804
+ button={button}
1805
+ params={params}
1806
+ getSelectedSolidViewData={() => selectedDataRef.current}
1807
+ // selectedSolidViewData={selectedSolidViewData}
1808
+ solidListViewMetaData={
1809
+ solidListViewMetaData
1810
+ }
1811
+ handleCustomButtonClick={
1812
+ handleCustomButtonClick
1813
+ }
1814
+ />
1815
+ ))}
1816
+ </div>
1817
+ </OverlayPanel>
1818
+ </>
1819
+ )}
1820
+ </>
1821
+ )
1822
+ }
1823
+ ></Column>
1824
+ )}
1825
+ </DataTable>
1826
+ </div>
1827
+ )}
1828
+ </>
1829
+ }
1830
+ </div>
1831
+ {
1832
+ mcpUrl &&
1833
+ params.embeded !== true && (
1834
+ <div
1835
+ className={`chatter-section ${isOpenSolidXAiPanel === false ? "collapsed" : "open"
1836
+ }`}
1837
+ style={{ width: chatterWidth }}
1838
+ >
1839
+ {isOpenSolidXAiPanel && (
1840
+ <div
1841
+ style={{
1842
+ width: 5,
1843
+ cursor: "col-resize",
1844
+ position: "absolute",
1845
+ left: 0,
1846
+ top: 0,
1847
+ bottom: 0,
1848
+ height: "100%",
1849
+ zIndex: 9,
1850
+ }}
1851
+ onMouseDown={() => setIsResizing(true)}
1852
+ />
1853
+ )}
1854
+ {isOpenSolidXAiPanel && (
1855
+ <Button
1856
+ icon="pi pi-angle-double-right"
1857
+ size="small"
1858
+ text
1859
+ className="chatter-collapse-btn"
1860
+ style={{ width: 30, height: 30, aspectRatio: "1/1" }}
1861
+ onClick={handleCloseSolidXAIPanel}
1862
+ />
1863
+ )}
1864
+
1865
+ {isOpenSolidXAiPanel === false ? (
1866
+ <div className="flex flex-column gap-2 justify-content-center p-2">
1867
+ <div
1868
+ className="chatter-collapsed-content"
1869
+ onClick={handleOpenSolidXAIPanel}
1870
+ >
1871
+ <div className="flex gap-2">
1872
+ {" "}
1873
+ <SolidXAIIcon /> SolidX AI{" "}
1874
+ </div>
1875
+ </div>
1876
+ <Button
1877
+ icon="pi pi-chevron-left"
1878
+ size="small"
1879
+ className="px-0"
1880
+ style={{ width: 30 }}
1881
+ onClick={handleOpenSolidXAIPanel}
1882
+ />
1883
+ </div>
1884
+ ) : (
1885
+ <SolidAiMainWrapper mcpUrl={mcpUrl} />
1886
+ )}
1887
+ </div>
1888
+ )
1889
+ }
1890
+ <Dialog
1891
+ visible={isDialogVisible}
1892
+ header="Confirm Delete"
1893
+ onHide={() => setDialogVisible(false)}
1894
+ headerClassName="py-2"
1895
+ contentClassName="px-0 pb-0"
1896
+ // style={{ width: '20vw' }}
1897
+ breakpoints={{ '1199px': '30rem', '550px': '85vw' }}
1898
+ >
1899
+ <Divider className="m-0" />
1900
+ <div className="p-4">
1901
+ <p className="m-0 solid-primary-title" style={{ fontSize: 16 }}>Are you sure you want to delete the selected records?</p>
1902
+ <div className="flex align-items-center gap-2 mt-3">
1903
+ <Button label="Delete" severity="danger" size="small" onClick={handleDeleteEntity} autoFocus onClick={deleteBulk} />
1904
+ <Button label="Cancel" size="small" onClick={onDeleteClose} outlined className='bg-primary-reverse' />
1905
+ </div>
1906
+ </div>
1907
+ </Dialog>
1908
+ <Dialog
1909
+ visible={isRecoverDialogVisible}
1910
+ header="Confirm Recover"
1911
+ modal
1912
+ className="solid-confirm-dialog"
1913
+ footer={() => (
1914
+ <div className="flex justify-content-center">
1915
+ <Button
1916
+ label="Yes"
1917
+ icon="pi pi-check"
1918
+ severity="danger"
1919
+ autoFocus
1920
+ onClick={recoverAll}
1921
+ />
1922
+ <Button
1923
+ label="No"
1924
+ icon="pi pi-times"
1925
+ onClick={() => setRecoverDialogVisible(false)}
1926
+ />
1927
+ </div>
1928
+ )}
1929
+ onHide={() => setRecoverDialogVisible(false)}
1930
+ >
1931
+ <p>Are you sure you want to recover all records?</p>
1932
+ </Dialog>
1933
+
1934
+ {
1935
+ listViewRowActionData && (
1936
+ <Dialog
1937
+ visible={listViewRowActionPopupState}
1938
+ modal
1939
+ onHide={closeListViewRowActionPopup}
1940
+ >
1941
+ <ListViewRowActionPopup
1942
+ context={listViewRowActionData}
1943
+ ></ListViewRowActionPopup>
1944
+ </Dialog>
1945
+ )
1946
+ }
1947
+ <Dialog
1948
+ header={`Delete ${solidListViewMetaData?.data?.solidView?.model?.displayName
1949
+ ? solidListViewMetaData?.data?.solidView?.model?.displayName
1950
+ : params?.modelName
1951
+ }`}
1952
+ headerClassName="py-2"
1953
+ contentClassName="px-0 pb-0"
1954
+ visible={deleteEntity}
1955
+ style={{ width: "20vw" }}
1956
+ onHide={() => {
1957
+ if (!deleteEntity) return;
1958
+ setDeleteEntity(false);
1959
+ }}
1960
+ className="solid-confirm-dialog"
1961
+ >
1962
+ <Divider className="m-0" />
1963
+ <div className="p-4">
1964
+ <p className="m-0 solid-primary-title" style={{ fontSize: 16 }}>
1965
+ {`Are you sure you want to delete this ${solidListViewMetaData?.data?.solidView?.model?.displayName
1966
+ ? solidListViewMetaData?.data?.solidView?.model?.displayName
1967
+ : params?.modelName
1968
+ }?`}
1969
+ </p>
1970
+ {/* <p className="" style={{ color: 'var{--solid-grey-500}' }}>{selectedSolidViewData?.singularName}</p> */}
1971
+ <div className="flex align-items-center gap-2 mt-3">
1972
+ <Button label="Delete" severity="danger" size="small" onClick={handleDeleteEntity} />
1973
+ <Button label="Cancel" size="small" onClick={() => setDeleteEntity(false)} outlined className='bg-primary-reverse' />
1974
+ </div>
1975
+ </div>
1976
+ </Dialog>
1977
+ {
1978
+ openLightbox && (
1979
+ <Lightbox
1980
+ open={openLightbox}
1981
+ plugins={
1982
+ hasMedia
1983
+ ? [Counter, Download, Video] // add Video plugin if needed
1984
+ : [Counter, Download]
1985
+ }
1986
+ close={() => setOpenLightbox(false)}
1987
+ slides={[...slides]}
1988
+ {...(hasMedia && {
1989
+ video: {
1990
+ controls: true,
1991
+ playsInline: true,
1992
+ autoPlay: false,
1993
+ loop: false,
1994
+ muted: false,
1995
+ disablePictureInPicture: false,
1996
+ disableRemotePlayback: false,
1997
+ controlsList: controlsList.join(" "),
1998
+ crossOrigin: "anonymous",
1999
+ preload: "auto",
2000
+ },
2001
+ })}
2002
+ />
2003
+ )
2004
+ }
2005
+ </div >
2006
+ );
2007
+ };