terrier-engine 4.4.0 → 4.4.3

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 (313) hide show
  1. package/data-dive/dd-app.ts +45 -0
  2. package/data-dive/dd-db.ts +12 -0
  3. package/data-dive/dd-routes.ts +10 -0
  4. package/data-dive/dd-session.ts +45 -0
  5. package/data-dive/dd-user.ts +12 -0
  6. package/data-dive/dives/dive-editor.ts +244 -0
  7. package/data-dive/dives/dive-list.ts +164 -0
  8. package/data-dive/dives/dive-runs.ts +272 -0
  9. package/data-dive/dives/dive-settings.ts +227 -0
  10. package/data-dive/dives/dives.ts +81 -0
  11. package/data-dive/dives/group-editor.ts +139 -0
  12. package/data-dive/gen/models.ts +192 -0
  13. package/data-dive/queries/columns.ts +355 -0
  14. package/data-dive/queries/dates.ts +286 -0
  15. package/data-dive/queries/filters.ts +723 -0
  16. package/data-dive/queries/queries.ts +263 -0
  17. package/data-dive/queries/query-editor.ts +232 -0
  18. package/data-dive/queries/query-form.ts +51 -0
  19. package/data-dive/queries/tables.ts +395 -0
  20. package/data-dive/queries/test/dates.test.ts +178 -0
  21. package/package.json +1 -1
  22. package/{parts → terrier/parts}/panel-part.ts +5 -1
  23. package/tsconfig.json +21 -0
  24. /package/{README.md → terrier/README.md} +0 -0
  25. /package/{api.ts → terrier/api.ts} +0 -0
  26. /package/{app.ts → terrier/app.ts} +0 -0
  27. /package/{attachments.ts → terrier/attachments.ts} +0 -0
  28. /package/{db-client.ts → terrier/db-client.ts} +0 -0
  29. /package/{dropdowns.ts → terrier/dropdowns.ts} +0 -0
  30. /package/{format.ts → terrier/format.ts} +0 -0
  31. /package/{forms.ts → terrier/forms.ts} +0 -0
  32. /package/{fragments.ts → terrier/fragments.ts} +0 -0
  33. /package/{gen → terrier/gen}/hub-icons.ts +0 -0
  34. /package/{glyps.ts → terrier/glyps.ts} +0 -0
  35. /package/{ids.ts → terrier/ids.ts} +0 -0
  36. /package/{images → terrier/images}/icons/active.svg +0 -0
  37. /package/{images → terrier/images}/icons/admin.svg +0 -0
  38. /package/{images → terrier/images}/icons/archive.svg +0 -0
  39. /package/{images → terrier/images}/icons/arrow_down.svg +0 -0
  40. /package/{images → terrier/images}/icons/arrow_left.svg +0 -0
  41. /package/{images → terrier/images}/icons/arrow_right.svg +0 -0
  42. /package/{images → terrier/images}/icons/arrow_up.svg +0 -0
  43. /package/{images → terrier/images}/icons/assign.svg +0 -0
  44. /package/{images → terrier/images}/icons/attachment.svg +0 -0
  45. /package/{images → terrier/images}/icons/back.svg +0 -0
  46. /package/{images → terrier/images}/icons/badge.svg +0 -0
  47. /package/{images → terrier/images}/icons/board.svg +0 -0
  48. /package/{images → terrier/images}/icons/branch.svg +0 -0
  49. /package/{images → terrier/images}/icons/bug.svg +0 -0
  50. /package/{images → terrier/images}/icons/calculator.svg +0 -0
  51. /package/{images → terrier/images}/icons/checkmark.svg +0 -0
  52. /package/{images → terrier/images}/icons/close.svg +0 -0
  53. /package/{images → terrier/images}/icons/clypboard.svg +0 -0
  54. /package/{images → terrier/images}/icons/comment.svg +0 -0
  55. /package/{images → terrier/images}/icons/complete.svg +0 -0
  56. /package/{images → terrier/images}/icons/dashboard.svg +0 -0
  57. /package/{images → terrier/images}/icons/data_pull.svg +0 -0
  58. /package/{images → terrier/images}/icons/data_update.svg +0 -0
  59. /package/{images → terrier/images}/icons/database.svg +0 -0
  60. /package/{images → terrier/images}/icons/day.svg +0 -0
  61. /package/{images → terrier/images}/icons/delete.svg +0 -0
  62. /package/{images → terrier/images}/icons/documentation.svg +0 -0
  63. /package/{images → terrier/images}/icons/edit.svg +0 -0
  64. /package/{images → terrier/images}/icons/feature.svg +0 -0
  65. /package/{images → terrier/images}/icons/flex.svg +0 -0
  66. /package/{images → terrier/images}/icons/forward.svg +0 -0
  67. /package/{images → terrier/images}/icons/github.svg +0 -0
  68. /package/{images → terrier/images}/icons/history.svg +0 -0
  69. /package/{images → terrier/images}/icons/home.svg +0 -0
  70. /package/{images → terrier/images}/icons/image.svg +0 -0
  71. /package/{images → terrier/images}/icons/inbox.svg +0 -0
  72. /package/{images → terrier/images}/icons/info.svg +0 -0
  73. /package/{images → terrier/images}/icons/issue.svg +0 -0
  74. /package/{images → terrier/images}/icons/lane.svg +0 -0
  75. /package/{images → terrier/images}/icons/lane_asap.svg +0 -0
  76. /package/{images → terrier/images}/icons/lane_days.svg +0 -0
  77. /package/{images → terrier/images}/icons/lane_hours.svg +0 -0
  78. /package/{images → terrier/images}/icons/lane_weeks.svg +0 -0
  79. /package/{images → terrier/images}/icons/lanes_board.svg +0 -0
  80. /package/{images → terrier/images}/icons/level_complete.svg +0 -0
  81. /package/{images → terrier/images}/icons/level_highway.svg +0 -0
  82. /package/{images → terrier/images}/icons/level_on_ramp.svg +0 -0
  83. /package/{images → terrier/images}/icons/level_parking.svg +0 -0
  84. /package/{images → terrier/images}/icons/minus.svg +0 -0
  85. /package/{images → terrier/images}/icons/night.svg +0 -0
  86. /package/{images → terrier/images}/icons/origin.svg +0 -0
  87. /package/{images → terrier/images}/icons/pending.svg +0 -0
  88. /package/{images → terrier/images}/icons/plus.svg +0 -0
  89. /package/{images → terrier/images}/icons/post.svg +0 -0
  90. /package/{images → terrier/images}/icons/pr_closed.svg +0 -0
  91. /package/{images → terrier/images}/icons/pr_merged.svg +0 -0
  92. /package/{images → terrier/images}/icons/pr_open.svg +0 -0
  93. /package/{images → terrier/images}/icons/prioritized.svg +0 -0
  94. /package/{images → terrier/images}/icons/project.svg +0 -0
  95. /package/{images → terrier/images}/icons/question.svg +0 -0
  96. /package/{images → terrier/images}/icons/reaction.svg +0 -0
  97. /package/{images → terrier/images}/icons/recent.svg +0 -0
  98. /package/{images → terrier/images}/icons/refresh.svg +0 -0
  99. /package/{images → terrier/images}/icons/request.svg +0 -0
  100. /package/{images → terrier/images}/icons/settings.svg +0 -0
  101. /package/{images → terrier/images}/icons/status.svg +0 -0
  102. /package/{images → terrier/images}/icons/step_deploy.svg +0 -0
  103. /package/{images → terrier/images}/icons/step_develop.svg +0 -0
  104. /package/{images → terrier/images}/icons/step_investigate.svg +0 -0
  105. /package/{images → terrier/images}/icons/step_review.svg +0 -0
  106. /package/{images → terrier/images}/icons/step_test.svg +0 -0
  107. /package/{images → terrier/images}/icons/steps.svg +0 -0
  108. /package/{images → terrier/images}/icons/steps_board.svg +0 -0
  109. /package/{images → terrier/images}/icons/subscribe.svg +0 -0
  110. /package/{images → terrier/images}/icons/support.svg +0 -0
  111. /package/{images → terrier/images}/icons/terrier.svg +0 -0
  112. /package/{images → terrier/images}/icons/thumbs_up.svg +0 -0
  113. /package/{images → terrier/images}/icons/type.svg +0 -0
  114. /package/{images → terrier/images}/icons/unprioritized.svg +0 -0
  115. /package/{images → terrier/images}/icons/upload.svg +0 -0
  116. /package/{images → terrier/images}/icons/user.svg +0 -0
  117. /package/{images → terrier/images}/icons/users.svg +0 -0
  118. /package/{images → terrier/images}/optimized/icon-active.svg +0 -0
  119. /package/{images → terrier/images}/optimized/icon-admin.svg +0 -0
  120. /package/{images → terrier/images}/optimized/icon-archive.svg +0 -0
  121. /package/{images → terrier/images}/optimized/icon-arrow_down.svg +0 -0
  122. /package/{images → terrier/images}/optimized/icon-arrow_left.svg +0 -0
  123. /package/{images → terrier/images}/optimized/icon-arrow_right.svg +0 -0
  124. /package/{images → terrier/images}/optimized/icon-arrow_up.svg +0 -0
  125. /package/{images → terrier/images}/optimized/icon-assign.svg +0 -0
  126. /package/{images → terrier/images}/optimized/icon-attachment.svg +0 -0
  127. /package/{images → terrier/images}/optimized/icon-back.svg +0 -0
  128. /package/{images → terrier/images}/optimized/icon-badge.svg +0 -0
  129. /package/{images → terrier/images}/optimized/icon-board.svg +0 -0
  130. /package/{images → terrier/images}/optimized/icon-branch.svg +0 -0
  131. /package/{images → terrier/images}/optimized/icon-bug.svg +0 -0
  132. /package/{images → terrier/images}/optimized/icon-calculator.svg +0 -0
  133. /package/{images → terrier/images}/optimized/icon-checkmark.svg +0 -0
  134. /package/{images → terrier/images}/optimized/icon-close.svg +0 -0
  135. /package/{images → terrier/images}/optimized/icon-clypboard.svg +0 -0
  136. /package/{images → terrier/images}/optimized/icon-comment.svg +0 -0
  137. /package/{images → terrier/images}/optimized/icon-complete.svg +0 -0
  138. /package/{images → terrier/images}/optimized/icon-dashboard.svg +0 -0
  139. /package/{images → terrier/images}/optimized/icon-data_pull.svg +0 -0
  140. /package/{images → terrier/images}/optimized/icon-data_update.svg +0 -0
  141. /package/{images → terrier/images}/optimized/icon-database.svg +0 -0
  142. /package/{images → terrier/images}/optimized/icon-day.svg +0 -0
  143. /package/{images → terrier/images}/optimized/icon-delete.svg +0 -0
  144. /package/{images → terrier/images}/optimized/icon-documentation.svg +0 -0
  145. /package/{images → terrier/images}/optimized/icon-edit.svg +0 -0
  146. /package/{images → terrier/images}/optimized/icon-feature.svg +0 -0
  147. /package/{images → terrier/images}/optimized/icon-flex.svg +0 -0
  148. /package/{images → terrier/images}/optimized/icon-forward.svg +0 -0
  149. /package/{images → terrier/images}/optimized/icon-github.svg +0 -0
  150. /package/{images → terrier/images}/optimized/icon-history.svg +0 -0
  151. /package/{images → terrier/images}/optimized/icon-home.svg +0 -0
  152. /package/{images → terrier/images}/optimized/icon-image.svg +0 -0
  153. /package/{images → terrier/images}/optimized/icon-inbox.svg +0 -0
  154. /package/{images → terrier/images}/optimized/icon-info.svg +0 -0
  155. /package/{images → terrier/images}/optimized/icon-issue.svg +0 -0
  156. /package/{images → terrier/images}/optimized/icon-lane.svg +0 -0
  157. /package/{images → terrier/images}/optimized/icon-lane_asap.svg +0 -0
  158. /package/{images → terrier/images}/optimized/icon-lane_days.svg +0 -0
  159. /package/{images → terrier/images}/optimized/icon-lane_hours.svg +0 -0
  160. /package/{images → terrier/images}/optimized/icon-lane_weeks.svg +0 -0
  161. /package/{images → terrier/images}/optimized/icon-lanes_board.svg +0 -0
  162. /package/{images → terrier/images}/optimized/icon-level_complete.svg +0 -0
  163. /package/{images → terrier/images}/optimized/icon-level_highway.svg +0 -0
  164. /package/{images → terrier/images}/optimized/icon-level_on_ramp.svg +0 -0
  165. /package/{images → terrier/images}/optimized/icon-level_parking.svg +0 -0
  166. /package/{images → terrier/images}/optimized/icon-minus.svg +0 -0
  167. /package/{images → terrier/images}/optimized/icon-night.svg +0 -0
  168. /package/{images → terrier/images}/optimized/icon-origin.svg +0 -0
  169. /package/{images → terrier/images}/optimized/icon-pending.svg +0 -0
  170. /package/{images → terrier/images}/optimized/icon-plus.svg +0 -0
  171. /package/{images → terrier/images}/optimized/icon-post.svg +0 -0
  172. /package/{images → terrier/images}/optimized/icon-pr_closed.svg +0 -0
  173. /package/{images → terrier/images}/optimized/icon-pr_merged.svg +0 -0
  174. /package/{images → terrier/images}/optimized/icon-pr_open.svg +0 -0
  175. /package/{images → terrier/images}/optimized/icon-prioritized.svg +0 -0
  176. /package/{images → terrier/images}/optimized/icon-project.svg +0 -0
  177. /package/{images → terrier/images}/optimized/icon-question.svg +0 -0
  178. /package/{images → terrier/images}/optimized/icon-reaction.svg +0 -0
  179. /package/{images → terrier/images}/optimized/icon-recent.svg +0 -0
  180. /package/{images → terrier/images}/optimized/icon-refresh.svg +0 -0
  181. /package/{images → terrier/images}/optimized/icon-request.svg +0 -0
  182. /package/{images → terrier/images}/optimized/icon-settings.svg +0 -0
  183. /package/{images → terrier/images}/optimized/icon-status.svg +0 -0
  184. /package/{images → terrier/images}/optimized/icon-step_deploy.svg +0 -0
  185. /package/{images → terrier/images}/optimized/icon-step_develop.svg +0 -0
  186. /package/{images → terrier/images}/optimized/icon-step_investigate.svg +0 -0
  187. /package/{images → terrier/images}/optimized/icon-step_review.svg +0 -0
  188. /package/{images → terrier/images}/optimized/icon-step_test.svg +0 -0
  189. /package/{images → terrier/images}/optimized/icon-steps.svg +0 -0
  190. /package/{images → terrier/images}/optimized/icon-steps_board.svg +0 -0
  191. /package/{images → terrier/images}/optimized/icon-subscribe.svg +0 -0
  192. /package/{images → terrier/images}/optimized/icon-support.svg +0 -0
  193. /package/{images → terrier/images}/optimized/icon-terrier.svg +0 -0
  194. /package/{images → terrier/images}/optimized/icon-thumbs_up.svg +0 -0
  195. /package/{images → terrier/images}/optimized/icon-type.svg +0 -0
  196. /package/{images → terrier/images}/optimized/icon-unprioritized.svg +0 -0
  197. /package/{images → terrier/images}/optimized/icon-upload.svg +0 -0
  198. /package/{images → terrier/images}/optimized/icon-user.svg +0 -0
  199. /package/{images → terrier/images}/optimized/icon-users.svg +0 -0
  200. /package/{images → terrier/images}/optimized/terrier-hub-favicon.svg +0 -0
  201. /package/{images → terrier/images}/optimized/terrier-hub-icon-dark.svg +0 -0
  202. /package/{images → terrier/images}/optimized/terrier-hub-icon-light.svg +0 -0
  203. /package/{images → terrier/images}/optimized/terrier-hub-loader.svg +0 -0
  204. /package/{images → terrier/images}/optimized/terrier-hub-logo-dark.svg +0 -0
  205. /package/{images → terrier/images}/optimized/terrier-hub-logo-light.svg +0 -0
  206. /package/{images → terrier/images}/raw/icon-active.svg +0 -0
  207. /package/{images → terrier/images}/raw/icon-admin.svg +0 -0
  208. /package/{images → terrier/images}/raw/icon-archive.svg +0 -0
  209. /package/{images → terrier/images}/raw/icon-arrow_down.svg +0 -0
  210. /package/{images → terrier/images}/raw/icon-arrow_left.svg +0 -0
  211. /package/{images → terrier/images}/raw/icon-arrow_right.svg +0 -0
  212. /package/{images → terrier/images}/raw/icon-arrow_up.svg +0 -0
  213. /package/{images → terrier/images}/raw/icon-assign.svg +0 -0
  214. /package/{images → terrier/images}/raw/icon-attachment.svg +0 -0
  215. /package/{images → terrier/images}/raw/icon-back.svg +0 -0
  216. /package/{images → terrier/images}/raw/icon-badge.svg +0 -0
  217. /package/{images → terrier/images}/raw/icon-board.svg +0 -0
  218. /package/{images → terrier/images}/raw/icon-branch.svg +0 -0
  219. /package/{images → terrier/images}/raw/icon-bug.svg +0 -0
  220. /package/{images → terrier/images}/raw/icon-calculator.svg +0 -0
  221. /package/{images → terrier/images}/raw/icon-checkmark.svg +0 -0
  222. /package/{images → terrier/images}/raw/icon-close.svg +0 -0
  223. /package/{images → terrier/images}/raw/icon-clypboard.svg +0 -0
  224. /package/{images → terrier/images}/raw/icon-comment.svg +0 -0
  225. /package/{images → terrier/images}/raw/icon-complete.svg +0 -0
  226. /package/{images → terrier/images}/raw/icon-dashboard.svg +0 -0
  227. /package/{images → terrier/images}/raw/icon-data_pull.svg +0 -0
  228. /package/{images → terrier/images}/raw/icon-data_update.svg +0 -0
  229. /package/{images → terrier/images}/raw/icon-database.svg +0 -0
  230. /package/{images → terrier/images}/raw/icon-day.svg +0 -0
  231. /package/{images → terrier/images}/raw/icon-delete.svg +0 -0
  232. /package/{images → terrier/images}/raw/icon-documentation.svg +0 -0
  233. /package/{images → terrier/images}/raw/icon-edit.svg +0 -0
  234. /package/{images → terrier/images}/raw/icon-feature.svg +0 -0
  235. /package/{images → terrier/images}/raw/icon-flex.svg +0 -0
  236. /package/{images → terrier/images}/raw/icon-forward.svg +0 -0
  237. /package/{images → terrier/images}/raw/icon-github.svg +0 -0
  238. /package/{images → terrier/images}/raw/icon-history.svg +0 -0
  239. /package/{images → terrier/images}/raw/icon-home.svg +0 -0
  240. /package/{images → terrier/images}/raw/icon-image.svg +0 -0
  241. /package/{images → terrier/images}/raw/icon-inbox.svg +0 -0
  242. /package/{images → terrier/images}/raw/icon-info.svg +0 -0
  243. /package/{images → terrier/images}/raw/icon-issue.svg +0 -0
  244. /package/{images → terrier/images}/raw/icon-lane.svg +0 -0
  245. /package/{images → terrier/images}/raw/icon-lane_asap.svg +0 -0
  246. /package/{images → terrier/images}/raw/icon-lane_days.svg +0 -0
  247. /package/{images → terrier/images}/raw/icon-lane_hours.svg +0 -0
  248. /package/{images → terrier/images}/raw/icon-lane_weeks.svg +0 -0
  249. /package/{images → terrier/images}/raw/icon-lanes_board.svg +0 -0
  250. /package/{images → terrier/images}/raw/icon-level_complete.svg +0 -0
  251. /package/{images → terrier/images}/raw/icon-level_highway.svg +0 -0
  252. /package/{images → terrier/images}/raw/icon-level_on_ramp.svg +0 -0
  253. /package/{images → terrier/images}/raw/icon-level_parking.svg +0 -0
  254. /package/{images → terrier/images}/raw/icon-minus.svg +0 -0
  255. /package/{images → terrier/images}/raw/icon-night.svg +0 -0
  256. /package/{images → terrier/images}/raw/icon-origin.svg +0 -0
  257. /package/{images → terrier/images}/raw/icon-pending.svg +0 -0
  258. /package/{images → terrier/images}/raw/icon-plus.svg +0 -0
  259. /package/{images → terrier/images}/raw/icon-post.svg +0 -0
  260. /package/{images → terrier/images}/raw/icon-pr_closed.svg +0 -0
  261. /package/{images → terrier/images}/raw/icon-pr_merged.svg +0 -0
  262. /package/{images → terrier/images}/raw/icon-pr_open.svg +0 -0
  263. /package/{images → terrier/images}/raw/icon-prioritized.svg +0 -0
  264. /package/{images → terrier/images}/raw/icon-project.svg +0 -0
  265. /package/{images → terrier/images}/raw/icon-question.svg +0 -0
  266. /package/{images → terrier/images}/raw/icon-reaction.svg +0 -0
  267. /package/{images → terrier/images}/raw/icon-recent.svg +0 -0
  268. /package/{images → terrier/images}/raw/icon-refresh.svg +0 -0
  269. /package/{images → terrier/images}/raw/icon-request.svg +0 -0
  270. /package/{images → terrier/images}/raw/icon-settings.svg +0 -0
  271. /package/{images → terrier/images}/raw/icon-status.svg +0 -0
  272. /package/{images → terrier/images}/raw/icon-step_deploy.svg +0 -0
  273. /package/{images → terrier/images}/raw/icon-step_develop.svg +0 -0
  274. /package/{images → terrier/images}/raw/icon-step_investigate.svg +0 -0
  275. /package/{images → terrier/images}/raw/icon-step_review.svg +0 -0
  276. /package/{images → terrier/images}/raw/icon-step_test.svg +0 -0
  277. /package/{images → terrier/images}/raw/icon-steps.svg +0 -0
  278. /package/{images → terrier/images}/raw/icon-steps_board.svg +0 -0
  279. /package/{images → terrier/images}/raw/icon-subscribe.svg +0 -0
  280. /package/{images → terrier/images}/raw/icon-support.svg +0 -0
  281. /package/{images → terrier/images}/raw/icon-terrier.svg +0 -0
  282. /package/{images → terrier/images}/raw/icon-thumbs_up.svg +0 -0
  283. /package/{images → terrier/images}/raw/icon-type.svg +0 -0
  284. /package/{images → terrier/images}/raw/icon-unprioritized.svg +0 -0
  285. /package/{images → terrier/images}/raw/icon-upload.svg +0 -0
  286. /package/{images → terrier/images}/raw/icon-user.svg +0 -0
  287. /package/{images → terrier/images}/raw/icon-users.svg +0 -0
  288. /package/{images → terrier/images}/raw/terrier-hub-favicon-alert.png +0 -0
  289. /package/{images → terrier/images}/raw/terrier-hub-favicon-dark.png +0 -0
  290. /package/{images → terrier/images}/raw/terrier-hub-favicon.png +0 -0
  291. /package/{images → terrier/images}/raw/terrier-hub-favicon.svg +0 -0
  292. /package/{images → terrier/images}/raw/terrier-hub-icon-dark.svg +0 -0
  293. /package/{images → terrier/images}/raw/terrier-hub-icon-light.png +0 -0
  294. /package/{images → terrier/images}/raw/terrier-hub-icon-light.svg +0 -0
  295. /package/{images → terrier/images}/raw/terrier-hub-loader.svg +0 -0
  296. /package/{images → terrier/images}/raw/terrier-hub-logo-dark.svg +0 -0
  297. /package/{images → terrier/images}/raw/terrier-hub-logo-light.png +0 -0
  298. /package/{images → terrier/images}/raw/terrier-hub-logo-light.svg +0 -0
  299. /package/{lightbox.ts → terrier/lightbox.ts} +0 -0
  300. /package/{loading.ts → terrier/loading.ts} +0 -0
  301. /package/{modals.ts → terrier/modals.ts} +0 -0
  302. /package/{overlays.ts → terrier/overlays.ts} +0 -0
  303. /package/{parts → terrier/parts}/content-part.ts +0 -0
  304. /package/{parts → terrier/parts}/not-found-page.ts +0 -0
  305. /package/{parts → terrier/parts}/page-part.ts +0 -0
  306. /package/{parts → terrier/parts}/terrier-form-part.ts +0 -0
  307. /package/{parts → terrier/parts}/terrier-part.ts +0 -0
  308. /package/{schema.ts → terrier/schema.ts} +0 -0
  309. /package/{sheets.ts → terrier/sheets.ts} +0 -0
  310. /package/{tabs.ts → terrier/tabs.ts} +0 -0
  311. /package/{theme.ts → terrier/theme.ts} +0 -0
  312. /package/{toasts.ts → terrier/toasts.ts} +0 -0
  313. /package/{tooltips.ts → terrier/tooltips.ts} +0 -0
@@ -0,0 +1,45 @@
1
+ import {NoState, PartTag} from "tuff-core/parts"
2
+ import {TerrierApp} from "../terrier/app"
3
+ import {RouterPart} from "tuff-core/routing"
4
+ import {routes} from "./dd-routes"
5
+ import {DiveListPage} from "./dives/dive-list"
6
+ import {Logger} from "tuff-core/logging"
7
+ import DdSession from "./dd-session"
8
+
9
+ Logger.level = 'debug'
10
+
11
+ class ContentRouterPart extends RouterPart {
12
+ get defaultPart() {
13
+ return DiveListPage
14
+ }
15
+
16
+ get routes() {
17
+ return routes
18
+ }
19
+
20
+ }
21
+
22
+ export default class DdApp extends TerrierApp<NoState> {
23
+
24
+ contentPart!: ContentRouterPart
25
+ session!: DdSession
26
+
27
+ async init() {
28
+ await super.init()
29
+ this.contentPart = this.makePart(ContentRouterPart, {})
30
+
31
+ this.session = await DdSession.get()
32
+
33
+ this.dirty()
34
+ }
35
+
36
+ get parentClasses(): Array<string> {
37
+ return ['tt-typography']
38
+ }
39
+
40
+ render(parent: PartTag) {
41
+ parent.part(this.contentPart)
42
+ parent.part(this.overlayPart)
43
+ }
44
+
45
+ }
@@ -0,0 +1,12 @@
1
+ import DbClient from "../terrier/db-client"
2
+ import {ModelIncludesMap, PersistedModelTypeMap, UnpersistedModelTypeMap} from "./gen/models"
3
+
4
+ /**
5
+ * DbClient specifically for the data-dive database.
6
+ */
7
+ class DdDb extends DbClient<PersistedModelTypeMap, UnpersistedModelTypeMap, ModelIncludesMap> {
8
+ }
9
+
10
+ export default function Db() {
11
+ return new DdDb()
12
+ }
@@ -0,0 +1,10 @@
1
+ import {partRoute} from "tuff-core/routing"
2
+ import {stringParser} from 'typesafe-routes'
3
+ import {DiveListPage} from "./dives/dive-list"
4
+ import {DiveEditorPage} from "./dives/dive-editor"
5
+
6
+
7
+ export const routes = {
8
+ list: partRoute(DiveListPage, '/data_dive', {}),
9
+ editor: partRoute(DiveEditorPage, '/data_dive/editor/:id', {id: stringParser})
10
+ }
@@ -0,0 +1,45 @@
1
+ import {DdUser} from "./dd-user"
2
+ import Api from "../terrier/api"
3
+ import {DdDiveGroup} from "./gen/models"
4
+ import {arrays} from "tuff-core";
5
+ import {SelectOptions} from "tuff-core/forms"
6
+
7
+
8
+ type DdSessionData = {
9
+ user: DdUser
10
+ groupMap: Record<string, DdDiveGroup>
11
+ }
12
+
13
+ /**
14
+ * Stores authentication information as well as various options from the server.
15
+ */
16
+ export default class DdSession {
17
+
18
+ constructor(readonly data: DdSessionData) {
19
+ }
20
+
21
+ get user(): DdUser {
22
+ return this.data.user
23
+ }
24
+
25
+ get isSuper(): boolean {
26
+ return this.user.role == 'super'
27
+ }
28
+
29
+ groupsInOrder(): DdDiveGroup[] {
30
+ return arrays.sortBy(Object.values(this.data.groupMap), 'name')
31
+ }
32
+
33
+ groupOptions(): SelectOptions {
34
+ return this.groupsInOrder().map(g => {
35
+ return {title: g.name, value: g.id}
36
+ })
37
+ }
38
+
39
+ static async get(): Promise<DdSession> {
40
+ const data = await Api.safeGet<DdSessionData>("/data_dive/user_session.json", {})
41
+ return new DdSession(data)
42
+ }
43
+
44
+
45
+ }
@@ -0,0 +1,12 @@
1
+
2
+ /**
3
+ * We don't know what the users will look like,
4
+ * so we'll just use a stub.
5
+ */
6
+ export type DdUser = {
7
+ id: string
8
+ role: string
9
+ first_name?: string
10
+ last_name?: string
11
+ name?: string
12
+ }
@@ -0,0 +1,244 @@
1
+ import Schema, {SchemaDef} from "../../terrier/schema"
2
+ import {PartTag} from "tuff-core/parts"
3
+ import Dives from "./dives"
4
+ import {Query, QueryModelPicker} from "../queries/queries"
5
+ import QueryEditor from "../queries/query-editor"
6
+ import {Logger} from "tuff-core/logging"
7
+ import QueryForm from "../queries/query-form"
8
+ import {arrays, messages} from "tuff-core"
9
+ import {TabContainerPart} from "../../terrier/tabs"
10
+ import PagePart from "../../terrier/parts/page-part"
11
+ import ContentPart from "../../terrier/parts/content-part"
12
+ import {ModalPart} from "../../terrier/modals"
13
+ import {DdDive} from "../gen/models"
14
+ import Ids from "../../terrier/ids"
15
+ import Db from "../dd-db"
16
+ import DdSession from "../dd-session"
17
+ import {DiveRunModal} from "./dive-runs";
18
+
19
+ const log = new Logger("DiveEditor")
20
+
21
+
22
+ ////////////////////////////////////////////////////////////////////////////////
23
+ // Editor
24
+ ////////////////////////////////////////////////////////////////////////////////
25
+
26
+ export type DiveEditorState = {
27
+ schema: SchemaDef
28
+ dive: DdDive
29
+ }
30
+
31
+ export default class DiveEditor extends ContentPart<DiveEditorState> {
32
+
33
+ tabs!: TabContainerPart
34
+
35
+ newQueryKey = messages.untypedKey()
36
+
37
+ queries = new Array<Query>()
38
+
39
+ async init() {
40
+ this.tabs = this.makePart(TabContainerPart, {side: 'top'})
41
+
42
+ this.tabs.setBeforeAction({
43
+ title: 'Queries:',
44
+ icon: 'glyp-data_dive_query'
45
+ })
46
+ this.tabs.setAfterAction({
47
+ icon: 'glyp-plus_outline',
48
+ click: {key: this.newQueryKey}
49
+ })
50
+
51
+ this.queries = this.state.dive.query_data?.queries || []
52
+ for (const query of this.queries) {
53
+ this.addQuery(query)
54
+ }
55
+
56
+ this.listenMessage(QueryForm.settingsChangedKey, m => {
57
+ const query = m.data
58
+ log.info(`Query settings changed`, query)
59
+ this.tabs.updateTab({key: query.id, title: query.name})
60
+ })
61
+
62
+ this.onClick(this.newQueryKey, _ => {
63
+ this.app.showModal(NewQueryModal, {editor: this as DiveEditor, schema: this.state.schema})
64
+ })
65
+
66
+ this.onClick(DiveEditor.deleteQueryKey, m => {
67
+ this.app.confirm({title: "Delete Query", icon: 'glyp-delete', body: "Are you sure you want to delete this query?"}, () => {
68
+ this.deleteQuery(m.data.id)
69
+ })
70
+ })
71
+ }
72
+
73
+ addQuery(query: Query) {
74
+ const state = {...this.state, query}
75
+ this.tabs.upsertTab({key: query.id, title: query.name}, QueryEditor, state)
76
+ }
77
+
78
+ deleteQuery(id: string) {
79
+ log.info(`Deleting query ${id}`)
80
+ if (arrays.deleteIf(this.queries, q => q.id == id) > 0) {
81
+ this.tabs.removeTab(id)
82
+ this.dirty()
83
+ }
84
+ }
85
+
86
+ get parentClasses(): Array<string> {
87
+ return ['dd-dive-editor']
88
+ }
89
+
90
+ renderContent(parent: PartTag) {
91
+ parent.part(this.tabs)
92
+ }
93
+
94
+ static readonly deleteQueryKey = messages.typedKey<{ id: string }>()
95
+
96
+ async serialize(): Promise<DdDive> {
97
+ const queries = this.queries
98
+ return {...this.state.dive, query_data: {queries}}
99
+ }
100
+
101
+ }
102
+
103
+
104
+ export class DiveEditorPage extends PagePart<{id: string}> {
105
+
106
+ editor!: DiveEditor
107
+ session!: DdSession
108
+
109
+ saveKey = messages.untypedKey()
110
+ runKey = messages.untypedKey()
111
+
112
+ async init() {
113
+ log.info(`Loading dive ${this.state.id}`)
114
+
115
+ const schema = await Schema.get()
116
+ this.session = await DdSession.get()
117
+ const dive = await Dives.get(this.state.id)
118
+ this.editor = this.makePart(DiveEditor, {schema, dive})
119
+
120
+ this.addBreadcrumb({
121
+ title: "Dives",
122
+ icon: 'glyp-data_dives',
123
+ href: "/data_dive"
124
+ })
125
+ this.addBreadcrumb({
126
+ title: dive.name,
127
+ icon: 'glyp-data_dive'
128
+ })
129
+
130
+ this.addAction({
131
+ title: 'Save',
132
+ icon: 'glyp-checkmark',
133
+ click: {key: this.saveKey}
134
+ }, 'tertiary')
135
+
136
+ this.addAction({
137
+ title: 'Run',
138
+ icon: 'glyp-play',
139
+ click: {key: this.runKey}
140
+ }, 'tertiary')
141
+
142
+ this.onClick(this.saveKey, _ => this.save())
143
+
144
+ this.onClick(this.runKey, _ => this.run())
145
+
146
+ this.dirty()
147
+ }
148
+
149
+ get parentClasses(): Array<string> {
150
+ return ['dd-dive-editor-page']
151
+ }
152
+
153
+ renderContent(parent: PartTag) {
154
+ parent.part(this.editor)
155
+ }
156
+
157
+ async save() {
158
+ const dive = await this.editor.serialize()
159
+ log.info(`Saving dive ${dive.name}`, dive)
160
+ const res = await Db().upsert('dd_dive', dive)
161
+ if (res.status == 'success') {
162
+ this.successToast(`Saved Dive!`)
163
+ }
164
+ else {
165
+ this.alertToast(res.message)
166
+ }
167
+ }
168
+
169
+ async run() {
170
+ const dive = await this.editor.serialize()
171
+ this.app.showModal(DiveRunModal, {dive})
172
+ }
173
+ }
174
+
175
+
176
+ ////////////////////////////////////////////////////////////////////////////////
177
+ // New Query Modal
178
+ ////////////////////////////////////////////////////////////////////////////////
179
+
180
+ type NewQueryState = {
181
+ editor: DiveEditor
182
+ schema: SchemaDef
183
+ }
184
+
185
+ class NewQueryModal extends ModalPart<NewQueryState> {
186
+
187
+ addKey = messages.untypedKey()
188
+ settingsForm!: QueryForm
189
+ modelPicker!: QueryModelPicker
190
+
191
+ async init() {
192
+ this.settingsForm = this.makePart(QueryForm, {query: {id: 'new', name: '', notes: ''}})
193
+ this.modelPicker = this.makePart(QueryModelPicker, {schema: this.state.schema})
194
+
195
+ this.setIcon('glyp-data_dive_query')
196
+ this.setTitle("New Query")
197
+
198
+ this.addAction({
199
+ title: "Add",
200
+ icon: 'glyp-plus',
201
+ click: {key: this.addKey}
202
+ })
203
+
204
+ this.onClick(this.addKey, async _ => {
205
+ await this.save()
206
+ })
207
+
208
+ this.onChange(this.modelPicker.pickedKey, m => {
209
+ log.info(`Picked model ${m.data.model}`)
210
+ const model = this.state.schema.models[m.data.model]
211
+ if (!this.settingsForm.state.query.name?.length) {
212
+ this.settingsForm.state.query.name = model.name
213
+ this.settingsForm.dirty()
214
+ }
215
+ })
216
+ }
217
+
218
+ renderContent(parent: PartTag): void {
219
+ parent.div('.tt-flex.tt-form.padded.column.gap.dd-new-query-form', col => {
220
+ col.part(this.settingsForm)
221
+ col.part(this.modelPicker)
222
+ })
223
+ }
224
+
225
+ async save() {
226
+ log.info(`Saving new query`)
227
+ const settings = await this.settingsForm.fields.serialize()
228
+ if (!settings.name?.length) {
229
+ this.showToast("Please enter a query name", {color: 'alert'})
230
+ this.dirty()
231
+ return
232
+ }
233
+ const model = this.modelPicker.model
234
+ if (!model) {
235
+ this.showToast("Please select a model", {color: 'alert'})
236
+ return
237
+ }
238
+ const query = {...settings, id: Ids.makeUuid(), from: {model: model.name}}
239
+ this.state.editor.addQuery(query)
240
+ this.state.editor.tabs.showTab(query.id)
241
+ this.pop()
242
+ }
243
+
244
+ }
@@ -0,0 +1,164 @@
1
+ import {Logger} from "tuff-core/logging"
2
+ import PagePart from "../../terrier/parts/page-part"
3
+ import {PartTag} from "tuff-core/parts"
4
+ import Schema, {SchemaDef} from "../../terrier/schema"
5
+ import {arrays, messages} from "tuff-core"
6
+ import {DdDive, DdDiveGroup, UnpersistedDdDive, UnpersistedDdDiveGroup} from "../gen/models"
7
+ import Dives, {DiveListResult} from "./dives"
8
+ import {GroupEditorModal} from "./group-editor"
9
+ import Fragments from "../../terrier/fragments"
10
+ import {IconName} from "../../terrier/theme"
11
+ import {routes} from "../dd-routes"
12
+ import {DiveSettingsModal} from "./dive-settings"
13
+ import DdSession from "../dd-session"
14
+
15
+ const log = new Logger("DiveList")
16
+
17
+
18
+ ////////////////////////////////////////////////////////////////////////////////
19
+ // List
20
+ ////////////////////////////////////////////////////////////////////////////////
21
+
22
+ export class DiveListPage extends PagePart<{}> {
23
+
24
+ newGroupKey = messages.untypedKey()
25
+ editGroupKey = messages.typedKey<{id: string}>()
26
+ newDiveKey = messages.typedKey<{group_id: string}>()
27
+ editDiveKey = messages.typedKey<{id: string}>()
28
+
29
+ session!: DdSession
30
+ result!: DiveListResult
31
+ schema!: SchemaDef
32
+ groupMap: Record<string, DdDiveGroup> = {}
33
+ diveMap: Record<string,DdDive> = {}
34
+
35
+ async init() {
36
+ this.setTitle("Data Dive")
37
+ this.setIcon('glyp-data_dives')
38
+
39
+ this.schema = await Schema.get()
40
+ this.session = await DdSession.get()
41
+
42
+ this.addAction({
43
+ title: "New Group",
44
+ icon: 'glyp-plus_outline',
45
+ click: {key: this.newGroupKey}
46
+ }, 'tertiary')
47
+
48
+ this.onClick(this.newGroupKey, _ => {
49
+ log.info("Showing new dive group model")
50
+ const newGroup = {name: '', group_types: []}
51
+ this.app.showModal(GroupEditorModal, {session: this.session,
52
+ group: newGroup,
53
+ callback: _ => this.reload()
54
+ })
55
+ })
56
+
57
+ this.onClick(this.editGroupKey, m => {
58
+ log.info(`Edit group ${m.data.id}`)
59
+ const group = this.groupMap[m.data.id]
60
+ if (group) {
61
+ this.app.showModal(GroupEditorModal, {
62
+ session: this.session,
63
+ group: group as UnpersistedDdDiveGroup,
64
+ callback: _ => this.reload()
65
+ })
66
+ }
67
+ else {
68
+ this.alertToast(`No group with id ${m.data.id}`)
69
+ }
70
+ })
71
+
72
+ this.onClick(this.newDiveKey, m => {
73
+ const groupId = m.data.group_id
74
+ log.info(`Showing new dive modal for group ${groupId}`)
75
+ const dive: UnpersistedDdDive = {
76
+ name: '',
77
+ description_raw: '',
78
+ visibility: 'public',
79
+ owner_id: this.session.user.id,
80
+ dd_dive_group_id: groupId,
81
+ dive_types: []
82
+ }
83
+ this.app.showModal(DiveSettingsModal, {schema: this.schema, dive, session: this.session})
84
+ })
85
+
86
+ this.onClick(this.editDiveKey, m => {
87
+ const dive = this.diveMap[m.data.id] as UnpersistedDdDive
88
+ if (dive) {
89
+ log.info(`Editing settings for dive: ${dive.name}`)
90
+ this.app.showModal(DiveSettingsModal, {schema: this.schema, dive, session: this.session})
91
+ }
92
+ else {
93
+ log.warn(`No dive with id ${m.data.id}`)
94
+ }
95
+ })
96
+
97
+ await this.reload()
98
+ }
99
+
100
+ async reload() {
101
+ this.session = await DdSession.get()
102
+ this.result = await Dives.list()
103
+ log.info("Loading data dive list", this.result)
104
+ this.groupMap = this.session.data.groupMap
105
+ this.diveMap = arrays.indexBy(this.result.dives, 'id')
106
+ this.dirty()
107
+ }
108
+
109
+ renderContent(parent: PartTag): void {
110
+
111
+ const groupedDives = arrays.groupBy(this.result.dives, 'dd_dive_group_id')
112
+
113
+ parent.div('.dd-group-grid', grid => {
114
+ const groups = arrays.sortBy(Object.values(this.groupMap), 'name')
115
+ for (const group of groups) {
116
+ this.renderGroupPanel(grid, group, groupedDives[group.id] || [])
117
+ }
118
+ })
119
+ }
120
+
121
+ renderGroupPanel(parent: PartTag, group: DdDiveGroup, dives: DdDive[]) {
122
+ Fragments.panel(this.theme)
123
+ .title(group.name)
124
+ .icon((group.icon || 'glyp-data_dives') as IconName)
125
+ .classes('group')
126
+ .content(content => {
127
+ content.class('tt-list')
128
+ for (const dive of arrays.sortBy(dives, 'name')) {
129
+ this.renderDiveRow(content, dive)
130
+ }
131
+ })
132
+ .addAction({
133
+ title: "New Dive",
134
+ icon: 'glyp-data_dive',
135
+ click: {key: this.newDiveKey, data: {group_id: group.id}}
136
+ }, 'secondary')
137
+ .addAction({
138
+ icon: 'glyp-settings',
139
+ click: {key: this.editGroupKey, data: {id: group.id}}
140
+ }, 'tertiary')
141
+ .render(parent)
142
+ }
143
+
144
+ renderDiveRow(parent: PartTag, dive: DdDive) {
145
+ parent.div('.dive', row => {
146
+ row.a({href: routes.editor.path({id: dive.id})}, a => {
147
+ if (dive.visibility == 'private') {
148
+ a.i('.glyp-privacy')
149
+ .data({tooltip: "Private Dive"})
150
+ }
151
+ else {
152
+ a.i('.glyp-data_dive')
153
+ }
154
+ a.span().text(dive.name)
155
+ }).data({tooltip: "Open Editor"})
156
+ row.a('.icon-only', a => {
157
+ a.i('.glyp-settings')
158
+ }).data({tooltip: "Dive Settings"})
159
+ .emitClick(this.editDiveKey, {id: dive.id})
160
+ })
161
+ }
162
+
163
+ }
164
+