@oneuptime/common 9.2.27 → 9.3.1

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 (263) hide show
  1. package/Models/DatabaseModels/AIAgent.ts +589 -0
  2. package/Models/DatabaseModels/AIAgentOwnerTeam.ts +434 -0
  3. package/Models/DatabaseModels/AIAgentOwnerUser.ts +433 -0
  4. package/Models/DatabaseModels/AIAgentTask.ts +549 -0
  5. package/Models/DatabaseModels/AIAgentTaskLog.ts +417 -0
  6. package/Models/DatabaseModels/AIAgentTaskPullRequest.ts +731 -0
  7. package/Models/DatabaseModels/AIAgentTaskTelemetryException.ts +388 -0
  8. package/Models/DatabaseModels/Index.ts +15 -0
  9. package/Models/DatabaseModels/Monitor.ts +33 -0
  10. package/Models/DatabaseModels/Project.ts +25 -0
  11. package/Models/DatabaseModels/TelemetryException.ts +1 -1
  12. package/Server/API/AIAgentAPI.ts +200 -0
  13. package/Server/API/AIAgentDataAPI.ts +692 -0
  14. package/Server/API/AIAgentTaskAPI.ts +286 -0
  15. package/Server/API/AIAgentTaskLogAPI.ts +165 -0
  16. package/Server/API/AIAgentTaskPullRequestAPI.ts +14 -0
  17. package/Server/API/GitHubAPI.ts +25 -7
  18. package/Server/API/TelemetryExceptionAPI.ts +169 -0
  19. package/Server/EnvironmentConfig.ts +3 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1766590916627-MigrationName.ts +195 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1766600860972-MigrationName.ts +31 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1766606720183-MigrationName.ts +17 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1766688107858-MigrationName.ts +63 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1766754182870-MigrationName.ts +75 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1766774689743-MigrationName.ts +157 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1766777986427-MigrationName.ts +33 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1766918848434-AddAIAgentIsDefault.ts +27 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1766923324521-MigrationName.ts +37 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1766958924188-AddGitHubAppInstallationIdToProject.ts +31 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1767009661768-MigrationName.ts +35 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +22 -0
  32. package/Server/Services/AIAgentOwnerTeamService.ts +10 -0
  33. package/Server/Services/AIAgentOwnerUserService.ts +10 -0
  34. package/Server/Services/AIAgentService.ts +564 -0
  35. package/Server/Services/AIAgentTaskLogService.ts +10 -0
  36. package/Server/Services/AIAgentTaskPullRequestService.ts +10 -0
  37. package/Server/Services/AIAgentTaskService.ts +178 -0
  38. package/Server/Services/AIAgentTaskTelemetryExceptionService.ts +39 -0
  39. package/Server/Services/Index.ts +10 -0
  40. package/Server/Services/TelemetryExceptionService.ts +162 -0
  41. package/Server/Utils/Monitor/MonitorResource.ts +228 -0
  42. package/Server/Utils/PushNotificationUtil.ts +29 -0
  43. package/Server/Utils/WhatsAppTemplateUtil.ts +6 -0
  44. package/Tests/UI/Components/Badge.test.tsx +5 -5
  45. package/Tests/UI/Components/Card.test.tsx +4 -8
  46. package/Tests/UI/Components/HiddenText.test.tsx +2 -5
  47. package/Tests/UI/Components/SideMenuItem.test.tsx +4 -2
  48. package/Types/AI/AIAgentTaskMetadata.ts +25 -0
  49. package/Types/AI/AIAgentTaskStatus.ts +65 -0
  50. package/Types/AI/AIAgentTaskType.ts +40 -0
  51. package/Types/Email/EmailTemplateType.ts +2 -0
  52. package/Types/Monitor/MonitorEvaluationSummary.ts +2 -1
  53. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  54. package/Types/Permission.ts +176 -0
  55. package/Types/WhatsApp/WhatsAppTemplates.ts +9 -0
  56. package/UI/Components/AIAgent/AIAgent.tsx +69 -0
  57. package/UI/Components/Badge/Badge.tsx +9 -5
  58. package/UI/Components/Banner/Banner.tsx +1 -1
  59. package/UI/Components/Card/Card.tsx +14 -12
  60. package/UI/Components/CodeBlock/CodeBlock.tsx +47 -4
  61. package/UI/Components/Detail/Detail.tsx +239 -49
  62. package/UI/Components/Detail/FieldLabel.tsx +35 -11
  63. package/UI/Components/Detail/PlaceholderText.tsx +18 -1
  64. package/UI/Components/Footer/Footer.tsx +9 -7
  65. package/UI/Components/Header/Header.tsx +4 -3
  66. package/UI/Components/Header/HeaderIconDropdownButton.tsx +13 -11
  67. package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +3 -3
  68. package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +1 -1
  69. package/UI/Components/Header/ProjectPicker/CreateNewProjectButton.tsx +4 -4
  70. package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -6
  71. package/UI/Components/Header/ProjectPicker/ProjectPickerFilterBox.tsx +3 -3
  72. package/UI/Components/Header/ProjectPicker/ProjectPickerMenu.tsx +1 -1
  73. package/UI/Components/Header/ProjectPicker/ProjectPickerMenuItem.tsx +4 -4
  74. package/UI/Components/HeaderAlert/HeaderAlert.tsx +32 -32
  75. package/UI/Components/HeaderAlert/HeaderAlertGroup.tsx +1 -7
  76. package/UI/Components/HiddenText/HiddenText.tsx +98 -27
  77. package/UI/Components/Icon/Icon.tsx +12 -9
  78. package/UI/Components/InfoCard/InfoCard.tsx +7 -3
  79. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  80. package/UI/Components/ObjectID/ObjectIDView.tsx +73 -0
  81. package/UI/Components/Page/Page.tsx +3 -5
  82. package/UI/Components/SideMenu/SideMenu.tsx +175 -40
  83. package/UI/Components/SideMenu/SideMenuDivider.tsx +17 -0
  84. package/UI/Components/SideMenu/SideMenuItem.tsx +111 -158
  85. package/UI/Components/SideMenu/SideMenuSection.tsx +53 -3
  86. package/UI/Components/Table/Table.tsx +1 -1
  87. package/UI/Components/Types/FieldType.ts +2 -0
  88. package/UI/Config.ts +5 -0
  89. package/build/dist/Models/DatabaseModels/AIAgent.js +614 -0
  90. package/build/dist/Models/DatabaseModels/AIAgent.js.map +1 -0
  91. package/build/dist/Models/DatabaseModels/AIAgentOwnerTeam.js +452 -0
  92. package/build/dist/Models/DatabaseModels/AIAgentOwnerTeam.js.map +1 -0
  93. package/build/dist/Models/DatabaseModels/AIAgentOwnerUser.js +451 -0
  94. package/build/dist/Models/DatabaseModels/AIAgentOwnerUser.js.map +1 -0
  95. package/build/dist/Models/DatabaseModels/AIAgentTask.js +580 -0
  96. package/build/dist/Models/DatabaseModels/AIAgentTask.js.map +1 -0
  97. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js +438 -0
  98. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js.map +1 -0
  99. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +771 -0
  100. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -0
  101. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js +404 -0
  102. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js.map +1 -0
  103. package/build/dist/Models/DatabaseModels/Index.js +14 -0
  104. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  105. package/build/dist/Models/DatabaseModels/Monitor.js +34 -0
  106. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  107. package/build/dist/Models/DatabaseModels/Project.js +26 -0
  108. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  109. package/build/dist/Models/DatabaseModels/TelemetryException.js +1 -1
  110. package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
  111. package/build/dist/Server/API/AIAgentAPI.js +141 -0
  112. package/build/dist/Server/API/AIAgentAPI.js.map +1 -0
  113. package/build/dist/Server/API/AIAgentDataAPI.js +415 -0
  114. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -0
  115. package/build/dist/Server/API/AIAgentTaskAPI.js +199 -0
  116. package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -0
  117. package/build/dist/Server/API/AIAgentTaskLogAPI.js +106 -0
  118. package/build/dist/Server/API/AIAgentTaskLogAPI.js.map +1 -0
  119. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js +9 -0
  120. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js.map +1 -0
  121. package/build/dist/Server/API/GitHubAPI.js +23 -8
  122. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  123. package/build/dist/Server/API/TelemetryExceptionAPI.js +120 -0
  124. package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -0
  125. package/build/dist/Server/EnvironmentConfig.js +2 -0
  126. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  127. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766590916627-MigrationName.js +74 -0
  128. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766590916627-MigrationName.js.map +1 -0
  129. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766600860972-MigrationName.js +18 -0
  130. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766600860972-MigrationName.js.map +1 -0
  131. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766606720183-MigrationName.js +12 -0
  132. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766606720183-MigrationName.js.map +1 -0
  133. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766688107858-MigrationName.js +28 -0
  134. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766688107858-MigrationName.js.map +1 -0
  135. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766754182870-MigrationName.js +32 -0
  136. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766754182870-MigrationName.js.map +1 -0
  137. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766774689743-MigrationName.js +60 -0
  138. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766774689743-MigrationName.js.map +1 -0
  139. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766777986427-MigrationName.js +18 -0
  140. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766777986427-MigrationName.js.map +1 -0
  141. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766918848434-AddAIAgentIsDefault.js +16 -0
  142. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766918848434-AddAIAgentIsDefault.js.map +1 -0
  143. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766923324521-MigrationName.js +20 -0
  144. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766923324521-MigrationName.js.map +1 -0
  145. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766958924188-AddGitHubAppInstallationIdToProject.js +16 -0
  146. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1766958924188-AddGitHubAppInstallationIdToProject.js.map +1 -0
  147. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1767009661768-MigrationName.js +18 -0
  148. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1767009661768-MigrationName.js.map +1 -0
  149. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +22 -0
  150. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  151. package/build/dist/Server/Services/AIAgentOwnerTeamService.js +9 -0
  152. package/build/dist/Server/Services/AIAgentOwnerTeamService.js.map +1 -0
  153. package/build/dist/Server/Services/AIAgentOwnerUserService.js +9 -0
  154. package/build/dist/Server/Services/AIAgentOwnerUserService.js.map +1 -0
  155. package/build/dist/Server/Services/AIAgentService.js +471 -0
  156. package/build/dist/Server/Services/AIAgentService.js.map +1 -0
  157. package/build/dist/Server/Services/AIAgentTaskLogService.js +9 -0
  158. package/build/dist/Server/Services/AIAgentTaskLogService.js.map +1 -0
  159. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js +9 -0
  160. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js.map +1 -0
  161. package/build/dist/Server/Services/AIAgentTaskService.js +158 -0
  162. package/build/dist/Server/Services/AIAgentTaskService.js.map +1 -0
  163. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js +36 -0
  164. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js.map +1 -0
  165. package/build/dist/Server/Services/Index.js +10 -0
  166. package/build/dist/Server/Services/Index.js.map +1 -1
  167. package/build/dist/Server/Services/TelemetryExceptionService.js +137 -0
  168. package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
  169. package/build/dist/Server/Utils/Monitor/MonitorResource.js +168 -0
  170. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  171. package/build/dist/Server/Utils/PushNotificationUtil.js +21 -0
  172. package/build/dist/Server/Utils/PushNotificationUtil.js.map +1 -1
  173. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +4 -0
  174. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  175. package/build/dist/Tests/UI/Components/Badge.test.js +5 -5
  176. package/build/dist/Tests/UI/Components/Badge.test.js.map +1 -1
  177. package/build/dist/Tests/UI/Components/Card.test.js +4 -8
  178. package/build/dist/Tests/UI/Components/Card.test.js.map +1 -1
  179. package/build/dist/Tests/UI/Components/HiddenText.test.js +2 -3
  180. package/build/dist/Tests/UI/Components/HiddenText.test.js.map +1 -1
  181. package/build/dist/Tests/UI/Components/SideMenuItem.test.js +3 -2
  182. package/build/dist/Tests/UI/Components/SideMenuItem.test.js.map +1 -1
  183. package/build/dist/Types/AI/AIAgentTaskMetadata.js +6 -0
  184. package/build/dist/Types/AI/AIAgentTaskMetadata.js.map +1 -0
  185. package/build/dist/Types/AI/AIAgentTaskStatus.js +51 -0
  186. package/build/dist/Types/AI/AIAgentTaskStatus.js.map +1 -0
  187. package/build/dist/Types/AI/AIAgentTaskType.js +29 -0
  188. package/build/dist/Types/AI/AIAgentTaskType.js.map +1 -0
  189. package/build/dist/Types/Email/EmailTemplateType.js +2 -0
  190. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  191. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  192. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  193. package/build/dist/Types/Permission.js +160 -0
  194. package/build/dist/Types/Permission.js.map +1 -1
  195. package/build/dist/Types/WhatsApp/WhatsAppTemplates.js +6 -0
  196. package/build/dist/Types/WhatsApp/WhatsAppTemplates.js.map +1 -1
  197. package/build/dist/UI/Components/AIAgent/AIAgent.js +32 -0
  198. package/build/dist/UI/Components/AIAgent/AIAgent.js.map +1 -0
  199. package/build/dist/UI/Components/Badge/Badge.js +9 -5
  200. package/build/dist/UI/Components/Badge/Badge.js.map +1 -1
  201. package/build/dist/UI/Components/Banner/Banner.js +1 -1
  202. package/build/dist/UI/Components/Banner/Banner.js.map +1 -1
  203. package/build/dist/UI/Components/Card/Card.js +12 -12
  204. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  205. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +22 -2
  206. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  207. package/build/dist/UI/Components/Detail/Detail.js +117 -37
  208. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  209. package/build/dist/UI/Components/Detail/FieldLabel.js +12 -7
  210. package/build/dist/UI/Components/Detail/FieldLabel.js.map +1 -1
  211. package/build/dist/UI/Components/Detail/PlaceholderText.js +4 -1
  212. package/build/dist/UI/Components/Detail/PlaceholderText.js.map +1 -1
  213. package/build/dist/UI/Components/Footer/Footer.js +6 -6
  214. package/build/dist/UI/Components/Footer/Footer.js.map +1 -1
  215. package/build/dist/UI/Components/Header/Header.js +4 -3
  216. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  217. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +7 -7
  218. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  219. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +3 -3
  220. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
  221. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +1 -1
  222. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
  223. package/build/dist/UI/Components/Header/ProjectPicker/CreateNewProjectButton.js +4 -4
  224. package/build/dist/UI/Components/Header/ProjectPicker/CreateNewProjectButton.js.map +1 -1
  225. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +6 -6
  226. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
  227. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPickerFilterBox.js +2 -2
  228. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPickerFilterBox.js.map +1 -1
  229. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPickerMenu.js +1 -1
  230. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPickerMenu.js.map +1 -1
  231. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPickerMenuItem.js +4 -4
  232. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPickerMenuItem.js.map +1 -1
  233. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js +31 -29
  234. package/build/dist/UI/Components/HeaderAlert/HeaderAlert.js.map +1 -1
  235. package/build/dist/UI/Components/HeaderAlert/HeaderAlertGroup.js +1 -3
  236. package/build/dist/UI/Components/HeaderAlert/HeaderAlertGroup.js.map +1 -1
  237. package/build/dist/UI/Components/HiddenText/HiddenText.js +33 -14
  238. package/build/dist/UI/Components/HiddenText/HiddenText.js.map +1 -1
  239. package/build/dist/UI/Components/Icon/Icon.js +3 -4
  240. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  241. package/build/dist/UI/Components/InfoCard/InfoCard.js +3 -3
  242. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  243. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  244. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  245. package/build/dist/UI/Components/ObjectID/ObjectIDView.js +30 -0
  246. package/build/dist/UI/Components/ObjectID/ObjectIDView.js.map +1 -0
  247. package/build/dist/UI/Components/Page/Page.js +3 -3
  248. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  249. package/build/dist/UI/Components/SideMenu/SideMenu.js +82 -17
  250. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  251. package/build/dist/UI/Components/SideMenu/SideMenuDivider.js +7 -0
  252. package/build/dist/UI/Components/SideMenu/SideMenuDivider.js.map +1 -0
  253. package/build/dist/UI/Components/SideMenu/SideMenuItem.js +68 -97
  254. package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
  255. package/build/dist/UI/Components/SideMenu/SideMenuSection.js +18 -3
  256. package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
  257. package/build/dist/UI/Components/Table/Table.js +1 -1
  258. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  259. package/build/dist/UI/Components/Types/FieldType.js +2 -0
  260. package/build/dist/UI/Components/Types/FieldType.js.map +1 -1
  261. package/build/dist/UI/Config.js +2 -0
  262. package/build/dist/UI/Config.js.map +1 -1
  263. package/package.json +1 -1
@@ -32,16 +32,18 @@ const Card: FunctionComponent<ComponentProps> = (
32
32
 
33
33
  return (
34
34
  <React.Fragment>
35
- <div data-testid="card" className={`mb-4 ${props.className || ""}`}>
36
- <div className="shadow md:rounded-md">
37
- <div className="bg-white py-6 px-4 md:p-6">
38
- <div className="flex flex-col md:flex-row md:justify-between">
39
- <div className={`${noRightElementsOrButtons ? "w-full" : ""}`}>
35
+ <div data-testid="card" className={`mb-5 ${props.className || ""}`}>
36
+ <div className="bg-white border border-gray-200 rounded-xl shadow-sm overflow-hidden">
37
+ <div className="py-6 px-5 md:px-6">
38
+ <div className="flex flex-col md:flex-row md:justify-between md:items-start">
39
+ <div
40
+ className={`${noRightElementsOrButtons ? "w-full" : "flex-1 min-w-0"}`}
41
+ >
40
42
  {props.title && (
41
43
  <h2
42
44
  data-testid="card-details-heading"
43
45
  id="card-details-heading"
44
- className="text-lg font-medium leading-6 text-gray-900"
46
+ className="text-lg font-semibold leading-6 text-gray-900"
45
47
  >
46
48
  {props.title}
47
49
  </h2>
@@ -49,7 +51,7 @@ const Card: FunctionComponent<ComponentProps> = (
49
51
  {props.description && (
50
52
  <p
51
53
  data-testid="card-description"
52
- className="mt-1 text-sm text-gray-500 w-full hidden md:block"
54
+ className="mt-1.5 text-sm text-gray-500 w-full hidden md:block leading-relaxed"
53
55
  >
54
56
  {props.description}
55
57
  </p>
@@ -57,21 +59,21 @@ const Card: FunctionComponent<ComponentProps> = (
57
59
  </div>
58
60
  {(props.rightElement ||
59
61
  (props.buttons && props.buttons.length > 0)) && (
60
- <div className="flex flex-col md:flex-row md:w-fit mt-4 md:mt-0 gap-2 md:gap-0">
62
+ <div className="flex flex-col md:flex-row md:items-center md:w-fit mt-4 md:mt-0 md:ml-4 gap-2 md:gap-0 flex-shrink-0">
61
63
  {props.rightElement && (
62
- <div className="mb-2 md:mb-0 md:mr-2">
64
+ <div className="mb-2 md:mb-0 md:mr-3">
63
65
  {props.rightElement}
64
66
  </div>
65
67
  )}
66
68
  {props.buttons && props.buttons.length > 0 && (
67
- <div className="flex flex-wrap gap-2 md:gap-0">
69
+ <div className="flex flex-wrap items-center gap-2">
68
70
  {props.buttons.map(
69
71
  (
70
72
  button: CardButtonSchema | ReactElement,
71
73
  i: number,
72
74
  ) => {
73
75
  return (
74
- <div className="md:ml-2 first:md:ml-0" key={i}>
76
+ <div key={i}>
75
77
  {React.isValidElement(button) ? button : null}
76
78
  {React.isValidElement(button) ? null : (
77
79
  <Button
@@ -112,7 +114,7 @@ const Card: FunctionComponent<ComponentProps> = (
112
114
  </div>
113
115
 
114
116
  {props.children && (
115
- <div className={props.bodyClassName || "mt-6"}>
117
+ <div className={props.bodyClassName || "mt-4"}>
116
118
  {props.children}
117
119
  </div>
118
120
  )}
@@ -1,19 +1,62 @@
1
1
  import "highlight.js/styles/a11y-dark.css";
2
- import React, { FunctionComponent, ReactElement } from "react";
2
+ import React, { FunctionComponent, ReactElement, useState } from "react";
3
3
  import Highlight from "react-highlight";
4
+ import Icon from "../Icon/Icon";
5
+ import IconProp from "../../../Types/Icon/IconProp";
4
6
 
5
7
  export interface ComponentProps {
6
8
  code: string | ReactElement;
7
9
  language: string;
10
+ maxHeight?: string | undefined;
11
+ showCopyButton?: boolean | undefined;
8
12
  }
9
13
 
10
14
  const CodeBlock: FunctionComponent<ComponentProps> = (
11
15
  props: ComponentProps,
12
16
  ): ReactElement => {
17
+ const [copied, setCopied] = useState<boolean>(false);
18
+
19
+ const handleCopy: () => void = (): void => {
20
+ if (typeof props.code === "string") {
21
+ navigator.clipboard.writeText(props.code).catch(() => {
22
+ /* ignore clipboard errors */
23
+ });
24
+ setCopied(true);
25
+ setTimeout(() => {
26
+ setCopied(false);
27
+ }, 2000);
28
+ }
29
+ };
30
+
31
+ const maxHeight: string = props.maxHeight || "500px";
32
+ const showCopyButton: boolean = props.showCopyButton !== false;
33
+
13
34
  return (
14
- <Highlight className={`p-3 language-${props.language} rounded-md shadow`}>
15
- {props.code}
16
- </Highlight>
35
+ <div className="relative group">
36
+ {showCopyButton && typeof props.code === "string" && (
37
+ <button
38
+ onClick={handleCopy}
39
+ className="absolute top-2 right-2 p-2 rounded-md bg-gray-700 hover:bg-gray-600 text-gray-300 hover:text-white transition-all opacity-0 group-hover:opacity-100 z-10"
40
+ title={copied ? "Copied!" : "Copy to clipboard"}
41
+ type="button"
42
+ >
43
+ <Icon
44
+ icon={copied ? IconProp.Check : IconProp.Copy}
45
+ className="h-4 w-4"
46
+ />
47
+ </button>
48
+ )}
49
+ <div
50
+ className="overflow-auto rounded-lg border border-gray-700"
51
+ style={{ maxHeight: maxHeight }}
52
+ >
53
+ <Highlight
54
+ className={`p-4 language-${props.language} text-sm leading-relaxed`}
55
+ >
56
+ {props.code}
57
+ </Highlight>
58
+ </div>
59
+ </div>
17
60
  );
18
61
  };
19
62
 
@@ -1,18 +1,18 @@
1
1
  import AlignItem from "../../Types/AlignItem";
2
2
  import { Logger } from "../../Utils/Logger";
3
- import CodeEditor from "../CodeEditor/CodeEditor";
3
+ import CodeBlock from "../CodeBlock/CodeBlock";
4
4
  import ColorViewer from "../ColorViewer/ColorViewer";
5
5
  import CopyableButton from "../CopyableButton/CopyableButton";
6
6
  import DictionaryOfStringsViewer from "../Dictionary/DictionaryOfStingsViewer";
7
7
  import { DropdownOption } from "../Dropdown/Dropdown";
8
8
  import HiddenText from "../HiddenText/HiddenText";
9
9
  import MarkdownViewer from "../Markdown.tsx/LazyMarkdownViewer";
10
+ import ObjectIDView from "../ObjectID/ObjectIDView";
10
11
  import FieldType from "../Types/FieldType";
11
12
  import Field from "./Field";
12
13
  import FieldLabelElement from "./FieldLabel";
13
14
  import PlaceholderText from "./PlaceholderText";
14
15
  import FileModel from "../../../Models/DatabaseModels/DatabaseBaseModel/FileModel";
15
- import CodeType from "../../../Types/Code/CodeType";
16
16
  import Color from "../../../Types/Color";
17
17
  import DatabaseProperty from "../../../Types/Database/DatabaseProperty";
18
18
  import OneUptimeDate from "../../../Types/Date";
@@ -21,11 +21,18 @@ import BadDataException from "../../../Types/Exception/BadDataException";
21
21
  import GenericObject from "../../../Types/GenericObject";
22
22
  import React, { ReactElement, useEffect, useState } from "react";
23
23
 
24
+ export enum DetailStyle {
25
+ Default = "default",
26
+ Card = "card",
27
+ Minimal = "minimal",
28
+ }
29
+
24
30
  export interface ComponentProps<T extends GenericObject> {
25
31
  item: T;
26
32
  fields: Array<Field<T>>;
27
33
  id?: string | undefined;
28
34
  showDetailsInNumberOfColumns?: number | undefined;
35
+ style?: DetailStyle | undefined;
29
36
  }
30
37
 
31
38
  type DetailFunction = <T extends GenericObject>(
@@ -75,25 +82,40 @@ const Detail: DetailFunction = <T extends GenericObject>(
75
82
  placeholder: string,
76
83
  ): ReactElement => {
77
84
  if (!options) {
78
- return <div>No options found</div>;
85
+ return (
86
+ <span className="text-gray-400 italic text-sm">No options found</span>
87
+ );
79
88
  }
80
89
 
81
- if (
82
- !options.find((i: DropdownOption) => {
90
+ const selectedOption: DropdownOption | undefined = options.find(
91
+ (i: DropdownOption) => {
83
92
  return i.value === data;
84
- })
85
- ) {
86
- return <div>{placeholder}</div>;
93
+ },
94
+ );
95
+
96
+ if (!selectedOption) {
97
+ return (
98
+ <span className="text-gray-400 italic text-sm">{placeholder}</span>
99
+ );
87
100
  }
88
101
 
89
102
  return (
90
- <div>
91
- {
92
- options.find((i: DropdownOption) => {
93
- return i.value === data;
94
- })?.label as string
95
- }
96
- </div>
103
+ <span className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-lg bg-indigo-50 border border-indigo-100 text-indigo-700 text-sm font-medium">
104
+ <svg
105
+ className="w-3.5 h-3.5 text-indigo-500"
106
+ fill="none"
107
+ viewBox="0 0 24 24"
108
+ stroke="currentColor"
109
+ >
110
+ <path
111
+ strokeLinecap="round"
112
+ strokeLinejoin="round"
113
+ strokeWidth={2}
114
+ d="M9 5l7 7-7 7"
115
+ />
116
+ </svg>
117
+ {selectedOption.label as string}
118
+ </span>
97
119
  );
98
120
  };
99
121
 
@@ -122,7 +144,34 @@ const Detail: DetailFunction = <T extends GenericObject>(
122
144
  return <></>;
123
145
  }
124
146
 
125
- return <div className="text-gray-900">{usdCents / 100} USD</div>;
147
+ const formattedAmount: string = (usdCents / 100).toLocaleString("en-US", {
148
+ minimumFractionDigits: 2,
149
+ maximumFractionDigits: 2,
150
+ });
151
+
152
+ return (
153
+ <div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-lg bg-emerald-50 border border-emerald-100">
154
+ <svg
155
+ className="w-4 h-4 text-emerald-600"
156
+ fill="none"
157
+ viewBox="0 0 24 24"
158
+ stroke="currentColor"
159
+ >
160
+ <path
161
+ strokeLinecap="round"
162
+ strokeLinejoin="round"
163
+ strokeWidth={1.5}
164
+ d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
165
+ />
166
+ </svg>
167
+ <span className="font-semibold text-emerald-700">
168
+ ${formattedAmount}
169
+ </span>
170
+ <span className="text-xs text-emerald-600 uppercase tracking-wide font-medium">
171
+ USD
172
+ </span>
173
+ </div>
174
+ );
126
175
  };
127
176
 
128
177
  type GetMinutesFieldFunction = (minutes: number | null) => ReactElement;
@@ -135,8 +184,24 @@ const Detail: DetailFunction = <T extends GenericObject>(
135
184
  }
136
185
 
137
186
  return (
138
- <div className="text-gray-900">
139
- {minutes} {minutes > 1 ? "minutes" : "minute"}
187
+ <div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-lg bg-blue-50 border border-blue-100">
188
+ <svg
189
+ className="w-4 h-4 text-blue-600"
190
+ fill="none"
191
+ viewBox="0 0 24 24"
192
+ stroke="currentColor"
193
+ >
194
+ <path
195
+ strokeLinecap="round"
196
+ strokeLinejoin="round"
197
+ strokeWidth={1.5}
198
+ d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
199
+ />
200
+ </svg>
201
+ <span className="font-semibold text-blue-700">{minutes}</span>
202
+ <span className="text-xs text-blue-600 font-medium">
203
+ {minutes > 1 ? "minutes" : "minute"}
204
+ </span>
140
205
  </div>
141
206
  );
142
207
  };
@@ -178,9 +243,28 @@ const Detail: DetailFunction = <T extends GenericObject>(
178
243
 
179
244
  if (field.fieldType === FieldType.Date) {
180
245
  if (data) {
181
- data = OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(
182
- data as string,
183
- true,
246
+ const formattedDate: string =
247
+ OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(
248
+ data as string,
249
+ true,
250
+ );
251
+ data = (
252
+ <span className="inline-flex items-center gap-2 text-gray-700">
253
+ <svg
254
+ className="w-4 h-4 text-gray-400"
255
+ fill="none"
256
+ viewBox="0 0 24 24"
257
+ stroke="currentColor"
258
+ >
259
+ <path
260
+ strokeLinecap="round"
261
+ strokeLinejoin="round"
262
+ strokeWidth={1.5}
263
+ d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
264
+ />
265
+ </svg>
266
+ <span className="font-medium">{formattedDate}</span>
267
+ </span>
184
268
  );
185
269
  } else {
186
270
  data = field.placeholder || "-";
@@ -189,17 +273,46 @@ const Detail: DetailFunction = <T extends GenericObject>(
189
273
 
190
274
  if (field.fieldType === FieldType.Boolean) {
191
275
  if (data) {
192
- data = "Yes";
276
+ data = (
277
+ <span className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-green-50 text-green-700 text-sm font-medium">
278
+ <span className="w-1.5 h-1.5 rounded-full bg-green-500"></span>
279
+ Yes
280
+ </span>
281
+ );
193
282
  } else {
194
- data = "No";
283
+ data = (
284
+ <span className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-gray-100 text-gray-600 text-sm font-medium">
285
+ <span className="w-1.5 h-1.5 rounded-full bg-gray-400"></span>
286
+ No
287
+ </span>
288
+ );
195
289
  }
196
290
  }
197
291
 
198
292
  if (field.fieldType === FieldType.DateTime) {
199
293
  if (data) {
200
- data = OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(
201
- data as string,
202
- false,
294
+ const formattedDateTime: string =
295
+ OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(
296
+ data as string,
297
+ false,
298
+ );
299
+ data = (
300
+ <span className="inline-flex items-center gap-2 text-gray-700">
301
+ <svg
302
+ className="w-4 h-4 text-gray-400"
303
+ fill="none"
304
+ viewBox="0 0 24 24"
305
+ stroke="currentColor"
306
+ >
307
+ <path
308
+ strokeLinecap="round"
309
+ strokeLinejoin="round"
310
+ strokeWidth={1.5}
311
+ d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
312
+ />
313
+ </svg>
314
+ <span className="font-medium">{formattedDateTime}</span>
315
+ </span>
203
316
  );
204
317
  } else {
205
318
  data = field.placeholder || "-";
@@ -274,13 +387,18 @@ const Detail: DetailFunction = <T extends GenericObject>(
274
387
  const url: string = URL.createObjectURL(blob);
275
388
 
276
389
  data = (
277
- <img
278
- src={url}
279
- className={"rounded"}
280
- style={{
281
- height: "100px",
282
- }}
283
- />
390
+ <div className="group/image relative inline-block">
391
+ <div className="overflow-hidden rounded-xl shadow-md border border-gray-200 bg-white p-1">
392
+ <img
393
+ src={url}
394
+ className="rounded-lg object-cover transition-all duration-300 hover:scale-105"
395
+ style={{
396
+ height: "100px",
397
+ }}
398
+ alt=""
399
+ />
400
+ </div>
401
+ </div>
284
402
  );
285
403
  } else {
286
404
  data = "";
@@ -318,14 +436,14 @@ const Detail: DetailFunction = <T extends GenericObject>(
318
436
  field.fieldType === FieldType.JavaScript ||
319
437
  field.fieldType === FieldType.Code)
320
438
  ) {
321
- let codeType: CodeType = CodeType.HTML;
439
+ let language: string = "html";
322
440
 
323
441
  if (field.fieldType === FieldType.CSS) {
324
- codeType = CodeType.CSS;
442
+ language = "css";
325
443
  }
326
444
 
327
445
  if (field.fieldType === FieldType.JSON) {
328
- codeType = CodeType.JSON;
446
+ language = "json";
329
447
 
330
448
  //make sure json is well formatted.
331
449
 
@@ -343,26 +461,62 @@ const Detail: DetailFunction = <T extends GenericObject>(
343
461
  e,
344
462
  );
345
463
  }
464
+ } else if (typeof data === "object" && data !== null) {
465
+ // If data is already an object, convert it to a formatted JSON string
466
+ try {
467
+ data = JSON.stringify(data, null, 2);
468
+ } catch (e) {
469
+ Logger.error(
470
+ "Cant stringify json object for field: " +
471
+ field.title +
472
+ " Error: " +
473
+ e,
474
+ );
475
+ data = String(data);
476
+ }
346
477
  }
347
478
  }
348
479
 
349
480
  if (field.fieldType === FieldType.JavaScript) {
350
- codeType = CodeType.JavaScript;
481
+ language = "javascript";
351
482
  }
352
483
 
353
484
  if (field.fieldType === FieldType.Code) {
354
- codeType = CodeType.Text;
485
+ language = "plaintext";
355
486
  }
356
487
 
357
488
  data = (
358
- <CodeEditor
359
- type={codeType}
360
- readOnly={true}
361
- initialValue={data as string}
489
+ <CodeBlock
490
+ code={data as string}
491
+ language={language}
492
+ maxHeight="400px"
362
493
  />
363
494
  );
364
495
  }
365
496
 
497
+ if (data && field.fieldType === FieldType.InlineCode) {
498
+ data = (
499
+ <code className="px-2 py-1 bg-gray-100 text-gray-800 rounded font-mono text-sm border border-gray-200 break-all">
500
+ {data as string}
501
+ </code>
502
+ );
503
+ }
504
+
505
+ if (data && field.fieldType === FieldType.ObjectID) {
506
+ const objectIdValue: string = data.toString();
507
+ data = <ObjectIDView objectId={objectIdValue} />;
508
+ }
509
+
510
+ if (data && field.fieldType === FieldType.Heading) {
511
+ data = (
512
+ <div className="inline-flex items-center">
513
+ <span className="text-2xl font-bold text-gray-900 tracking-tight">
514
+ {data.toString()}
515
+ </span>
516
+ </div>
517
+ );
518
+ }
519
+
366
520
  if (field.getElement) {
367
521
  data = field.getElement(props.item);
368
522
  }
@@ -387,9 +541,29 @@ const Detail: DetailFunction = <T extends GenericObject>(
387
541
  data = data.toString();
388
542
  }
389
543
 
544
+ // Determine style-based classes
545
+ const styleType: DetailStyle = props.style || DetailStyle.Default;
546
+ const isCardStyle: boolean = styleType === DetailStyle.Card;
547
+ const isMinimalStyle: boolean = styleType === DetailStyle.Minimal;
548
+
549
+ /* Container classes based on style - uses first:pt-0 to remove top padding from first field */
550
+ let containerClasses: string =
551
+ "group transition-all duration-200 ease-in-out";
552
+
553
+ if (isCardStyle) {
554
+ containerClasses +=
555
+ " bg-gradient-to-br from-white to-gray-50/50 rounded-xl border border-gray-100 p-4 shadow-sm hover:shadow-md hover:border-gray-200";
556
+ } else if (isMinimalStyle) {
557
+ containerClasses +=
558
+ " py-3 first:pt-0 last:pb-0 border-b border-gray-50 last:border-b-0 hover:bg-gray-50/50 px-2 -mx-2 rounded-lg";
559
+ } else {
560
+ containerClasses +=
561
+ " py-5 first:pt-0 last:pb-0 border-b border-gray-100 last:border-b-0 hover:bg-gray-50/30 px-3 -mx-3 rounded-lg";
562
+ }
563
+
390
564
  return (
391
565
  <div
392
- className={className}
566
+ className={`${className} ${containerClasses}`}
393
567
  key={index}
394
568
  id={props.id}
395
569
  style={
@@ -406,20 +580,29 @@ const Detail: DetailFunction = <T extends GenericObject>(
406
580
  description={field.description}
407
581
  sideLink={field.sideLink}
408
582
  alignClassName={alignClassName}
583
+ isCardStyle={isCardStyle}
409
584
  />
410
585
 
411
- <div className={`mt-1 text-sm text-gray-900 ${alignClassName}`}>
586
+ <div
587
+ className={`mt-3 text-sm leading-relaxed ${alignClassName} ${
588
+ isCardStyle ? "text-gray-800" : "text-gray-700"
589
+ }`}
590
+ >
412
591
  {data && (
413
592
  <div
414
- className={`${field.contentClassName} w-full ${
415
- field.opts?.isCopyable ? "flex" : ""
593
+ className={`${field.contentClassName || ""} w-full ${
594
+ field.opts?.isCopyable
595
+ ? "flex items-center gap-3 group/copyable"
596
+ : ""
416
597
  }`}
417
598
  >
418
- <div>{data}</div>
599
+ <div className="break-words leading-relaxed">{data}</div>
419
600
 
420
601
  {field.opts?.isCopyable &&
421
602
  field.fieldType !== FieldType.HiddenText && (
422
- <CopyableButton textToBeCopied={data.toString()} />
603
+ <div className="opacity-0 group-hover/copyable:opacity-100 transition-all duration-200 transform group-hover/copyable:translate-x-0 -translate-x-1">
604
+ <CopyableButton textToBeCopied={data.toString()} />
605
+ </div>
423
606
  )}
424
607
  </div>
425
608
  )}
@@ -430,9 +613,16 @@ const Detail: DetailFunction = <T extends GenericObject>(
430
613
  );
431
614
  };
432
615
 
616
+ // Determine grid gap based on style
617
+ const styleType: DetailStyle = props.style || DetailStyle.Default;
618
+ const isCardStyle: boolean = styleType === DetailStyle.Card;
619
+
620
+ // Grid gap classes - cards need more gap, others less since they have internal padding
621
+ const gapClasses: string = isCardStyle ? "gap-4" : "gap-0";
622
+
433
623
  return (
434
624
  <div
435
- className={`grid grid-cols-1 gap-x-4 gap-y-8 sm:grid-cols-${
625
+ className={`grid grid-cols-1 ${gapClasses} sm:grid-cols-${
436
626
  props.showDetailsInNumberOfColumns || 1
437
627
  } w-full`}
438
628
  >
@@ -5,7 +5,7 @@ import React, { FunctionComponent, ReactElement } from "react";
5
5
  export enum Size {
6
6
  Normal = "text-sm",
7
7
  Medium = "text-base",
8
- Large = "text-=lg",
8
+ Large = "text-lg",
9
9
  }
10
10
 
11
11
  export interface ComponentProps {
@@ -14,33 +14,57 @@ export interface ComponentProps {
14
14
  alignClassName?: string | undefined;
15
15
  sideLink?: DetailSideLink | undefined;
16
16
  size?: Size | undefined;
17
+ isCardStyle?: boolean | undefined;
17
18
  }
18
19
 
19
20
  const FieldLabelElement: FunctionComponent<ComponentProps> = (
20
21
  props: ComponentProps,
21
22
  ): ReactElement => {
23
+ const isCardStyle: boolean = props.isCardStyle || false;
24
+
22
25
  return (
23
- <>
26
+ <div className="space-y-1">
24
27
  {props.title && (
25
28
  <label
26
- className={`${props.size || "text-sm"} font-medium text-gray-500`}
29
+ className={`${props.size || "text-xs"} font-semibold uppercase tracking-widest ${
30
+ isCardStyle ? "text-gray-500" : "text-gray-500"
31
+ } flex items-center gap-2`}
27
32
  >
28
- <span className={props.alignClassName}>{props.title}</span>
33
+ <span className={`${props.alignClassName} flex items-center gap-1.5`}>
34
+ {props.title}
35
+ <span className="w-1 h-1 rounded-full bg-gray-300"></span>
36
+ </span>
29
37
  {props.sideLink && props.sideLink?.text && props.sideLink?.url && (
30
- <span>
31
- <Link to={props.sideLink?.url} className="hover:underline">
32
- {props.sideLink?.text}
33
- </Link>
34
- </span>
38
+ <Link
39
+ to={props.sideLink?.url}
40
+ className="inline-flex items-center gap-1 text-indigo-500 hover:text-indigo-600 transition-all duration-200 font-medium normal-case tracking-normal text-xs hover:underline underline-offset-2"
41
+ >
42
+ {props.sideLink?.text}
43
+ <svg
44
+ className="w-3 h-3"
45
+ fill="none"
46
+ viewBox="0 0 24 24"
47
+ stroke="currentColor"
48
+ >
49
+ <path
50
+ strokeLinecap="round"
51
+ strokeLinejoin="round"
52
+ strokeWidth={2}
53
+ d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
54
+ />
55
+ </svg>
56
+ </Link>
35
57
  )}
36
58
  </label>
37
59
  )}
38
60
  {props.description && (
39
- <p className={`${props.alignClassName} text-sm text-gray-400`}>
61
+ <p
62
+ className={`${props.alignClassName} text-xs text-gray-400 leading-relaxed mt-0.5`}
63
+ >
40
64
  {props.description}
41
65
  </p>
42
66
  )}
43
- </>
67
+ </div>
44
68
  );
45
69
  };
46
70
 
@@ -7,7 +7,24 @@ export interface ComponentProps {
7
7
  const PlaceholderText: FunctionComponent<ComponentProps> = (
8
8
  props: ComponentProps,
9
9
  ): ReactElement => {
10
- return <div className="text-gray-500">{props.text}</div>;
10
+ return (
11
+ <span className="inline-flex items-center gap-1.5 text-gray-400 italic text-sm select-none px-2 py-0.5 rounded-md bg-gray-50 border border-dashed border-gray-200">
12
+ <svg
13
+ className="w-3.5 h-3.5 text-gray-300"
14
+ fill="none"
15
+ viewBox="0 0 24 24"
16
+ stroke="currentColor"
17
+ >
18
+ <path
19
+ strokeLinecap="round"
20
+ strokeLinejoin="round"
21
+ strokeWidth={1.5}
22
+ d="M20 12H4"
23
+ />
24
+ </svg>
25
+ {props.text}
26
+ </span>
27
+ );
11
28
  };
12
29
 
13
30
  export default PlaceholderText;