@inventreedb/ui 0.0.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 (541) hide show
  1. package/.babelrc +8 -0
  2. package/.linguirc +55 -0
  3. package/README.md +17 -0
  4. package/index.html +15 -0
  5. package/lib/enums/ApiEndpoints.tsx +233 -0
  6. package/lib/enums/ModelType.tsx +38 -0
  7. package/lib/enums/Roles.tsx +25 -0
  8. package/lib/functions/Api.tsx +42 -0
  9. package/lib/functions/Plugins.tsx +27 -0
  10. package/lib/index.ts +11 -0
  11. package/lib/types/Auth.tsx +51 -0
  12. package/lib/types/Core.tsx +13 -0
  13. package/lib/types/Filters.tsx +69 -0
  14. package/lib/types/Forms.tsx +185 -0
  15. package/lib/types/Modals.tsx +17 -0
  16. package/lib/types/Plugins.tsx +68 -0
  17. package/lib/types/Server.tsx +8 -0
  18. package/lib/types/Settings.tsx +55 -0
  19. package/lib/types/Tables.tsx +69 -0
  20. package/lib/types/User.tsx +62 -0
  21. package/netlify.toml +22 -0
  22. package/package.json +125 -0
  23. package/playwright/global-setup.ts +45 -0
  24. package/playwright.config.ts +99 -0
  25. package/public/inventree.svg +291 -0
  26. package/src/App.tsx +35 -0
  27. package/src/assets/inventree.svg +1 -0
  28. package/src/components/Boundary.tsx +43 -0
  29. package/src/components/SplashScreen.tsx +35 -0
  30. package/src/components/barcodes/BarcodeCameraInput.tsx +207 -0
  31. package/src/components/barcodes/BarcodeInput.tsx +127 -0
  32. package/src/components/barcodes/BarcodeKeyboardInput.tsx +50 -0
  33. package/src/components/barcodes/BarcodeScanDialog.tsx +101 -0
  34. package/src/components/barcodes/BarcodeScanItem.tsx +23 -0
  35. package/src/components/barcodes/QRCode.tsx +211 -0
  36. package/src/components/buttons/ActionButton.tsx +61 -0
  37. package/src/components/buttons/AddItemButton.tsx +10 -0
  38. package/src/components/buttons/AdminButton.tsx +91 -0
  39. package/src/components/buttons/ButtonMenu.tsx +33 -0
  40. package/src/components/buttons/CopyButton.tsx +52 -0
  41. package/src/components/buttons/PrimaryActionButton.tsx +40 -0
  42. package/src/components/buttons/PrintingActions.tsx +191 -0
  43. package/src/components/buttons/RemoveRowButton.tsx +22 -0
  44. package/src/components/buttons/SSOButton.tsx +53 -0
  45. package/src/components/buttons/ScanButton.tsx +27 -0
  46. package/src/components/buttons/SegmentedIconControl.tsx +51 -0
  47. package/src/components/buttons/SplitButton.css.ts +19 -0
  48. package/src/components/buttons/SplitButton.tsx +111 -0
  49. package/src/components/buttons/SpotlightButton.tsx +22 -0
  50. package/src/components/buttons/StarredToggleButton.tsx +62 -0
  51. package/src/components/buttons/YesNoButton.tsx +42 -0
  52. package/src/components/calendar/Calendar.tsx +193 -0
  53. package/src/components/calendar/OrderCalendar.tsx +209 -0
  54. package/src/components/charts/colors.tsx +12 -0
  55. package/src/components/charts/tooltipFormatter.tsx +12 -0
  56. package/src/components/dashboard/DashboardLayout.tsx +327 -0
  57. package/src/components/dashboard/DashboardMenu.tsx +136 -0
  58. package/src/components/dashboard/DashboardWidget.tsx +82 -0
  59. package/src/components/dashboard/DashboardWidgetDrawer.tsx +130 -0
  60. package/src/components/dashboard/DashboardWidgetLibrary.tsx +189 -0
  61. package/src/components/dashboard/widgets/ColorToggleWidget.tsx +28 -0
  62. package/src/components/dashboard/widgets/GetStartedWidget.tsx +19 -0
  63. package/src/components/dashboard/widgets/LanguageSelectWidget.tsx +28 -0
  64. package/src/components/dashboard/widgets/NewsWidget.tsx +143 -0
  65. package/src/components/dashboard/widgets/QueryCountDashboardWidget.tsx +134 -0
  66. package/src/components/details/Details.tsx +514 -0
  67. package/src/components/details/DetailsBadge.tsx +20 -0
  68. package/src/components/details/DetailsImage.tsx +462 -0
  69. package/src/components/details/ItemDetails.tsx +17 -0
  70. package/src/components/editors/NotesEditor.tsx +232 -0
  71. package/src/components/editors/TemplateEditor/CodeEditor/CodeEditor.tsx +158 -0
  72. package/src/components/editors/TemplateEditor/CodeEditor/index.tsx +12 -0
  73. package/src/components/editors/TemplateEditor/PdfPreview/PdfPreview.tsx +90 -0
  74. package/src/components/editors/TemplateEditor/PdfPreview/index.tsx +12 -0
  75. package/src/components/editors/TemplateEditor/TemplateEditor.tsx +425 -0
  76. package/src/components/editors/TemplateEditor/index.tsx +3 -0
  77. package/src/components/errors/ClientError.tsx +28 -0
  78. package/src/components/errors/GenericErrorPage.tsx +73 -0
  79. package/src/components/errors/NotAuthenticated.tsx +12 -0
  80. package/src/components/errors/NotFound.tsx +12 -0
  81. package/src/components/errors/PermissionDenied.tsx +12 -0
  82. package/src/components/errors/ServerError.tsx +13 -0
  83. package/src/components/forms/ApiForm.tsx +718 -0
  84. package/src/components/forms/AuthFormOptions.tsx +39 -0
  85. package/src/components/forms/AuthenticationForm.tsx +332 -0
  86. package/src/components/forms/HostOptionsForm.tsx +96 -0
  87. package/src/components/forms/InstanceOptions.tsx +178 -0
  88. package/src/components/forms/StandaloneField.tsx +55 -0
  89. package/src/components/forms/fields/ApiFormField.tsx +281 -0
  90. package/src/components/forms/fields/ChoiceField.tsx +86 -0
  91. package/src/components/forms/fields/DateField.tsx +79 -0
  92. package/src/components/forms/fields/DependentField.tsx +91 -0
  93. package/src/components/forms/fields/IconField.tsx +353 -0
  94. package/src/components/forms/fields/NestedObjectField.tsx +45 -0
  95. package/src/components/forms/fields/RelatedModelField.tsx +339 -0
  96. package/src/components/forms/fields/TableField.tsx +275 -0
  97. package/src/components/forms/fields/TextField.tsx +81 -0
  98. package/src/components/images/ApiImage.tsx +35 -0
  99. package/src/components/images/Thumbnail.tsx +52 -0
  100. package/src/components/importer/ImportDataSelector.tsx +433 -0
  101. package/src/components/importer/ImporterColumnSelector.tsx +244 -0
  102. package/src/components/importer/ImporterDrawer.tsx +173 -0
  103. package/src/components/importer/ImporterImportProgress.tsx +45 -0
  104. package/src/components/items/ActionDropdown.tsx +290 -0
  105. package/src/components/items/ApiIcon.css.ts +13 -0
  106. package/src/components/items/ApiIcon.tsx +32 -0
  107. package/src/components/items/AttachmentLink.tsx +79 -0
  108. package/src/components/items/ColorToggle.tsx +34 -0
  109. package/src/components/items/DashboardItem.tsx +33 -0
  110. package/src/components/items/DocInfo.tsx +20 -0
  111. package/src/components/items/DocTooltip.tsx +98 -0
  112. package/src/components/items/ErrorItem.tsx +17 -0
  113. package/src/components/items/Expand.tsx +14 -0
  114. package/src/components/items/GettingStartedCarousel.css.ts +30 -0
  115. package/src/components/items/GettingStartedCarousel.tsx +49 -0
  116. package/src/components/items/InfoItem.tsx +64 -0
  117. package/src/components/items/InvenTreeLogo.tsx +24 -0
  118. package/src/components/items/LanguageSelect.tsx +43 -0
  119. package/src/components/items/LanguageToggle.tsx +37 -0
  120. package/src/components/items/MenuLinks.tsx +113 -0
  121. package/src/components/items/OnlyStaff.tsx +10 -0
  122. package/src/components/items/ProgressBar.tsx +45 -0
  123. package/src/components/items/StylishText.tsx +59 -0
  124. package/src/components/items/TitleWithDoc.tsx +26 -0
  125. package/src/components/items/UnavailableIndicator.tsx +5 -0
  126. package/src/components/items/inventree.svg +1 -0
  127. package/src/components/modals/AboutInvenTreeModal.tsx +203 -0
  128. package/src/components/modals/LicenseModal.tsx +116 -0
  129. package/src/components/modals/QrModal.tsx +21 -0
  130. package/src/components/modals/ServerInfoModal.tsx +136 -0
  131. package/src/components/nav/Alerts.tsx +130 -0
  132. package/src/components/nav/BreadcrumbList.tsx +84 -0
  133. package/src/components/nav/DetailDrawer.css.ts +6 -0
  134. package/src/components/nav/DetailDrawer.tsx +105 -0
  135. package/src/components/nav/Footer.tsx +11 -0
  136. package/src/components/nav/Header.tsx +226 -0
  137. package/src/components/nav/InstanceDetail.tsx +46 -0
  138. package/src/components/nav/Layout.tsx +85 -0
  139. package/src/components/nav/MainMenu.tsx +101 -0
  140. package/src/components/nav/NavHoverMenu.tsx +15 -0
  141. package/src/components/nav/NavigationDrawer.tsx +230 -0
  142. package/src/components/nav/NavigationTree.tsx +210 -0
  143. package/src/components/nav/NotificationDrawer.tsx +231 -0
  144. package/src/components/nav/PageDetail.tsx +171 -0
  145. package/src/components/nav/PageTitle.tsx +53 -0
  146. package/src/components/nav/SearchDrawer.tsx +598 -0
  147. package/src/components/nav/SettingsHeader.tsx +50 -0
  148. package/src/components/panels/AttachmentPanel.tsx +27 -0
  149. package/src/components/panels/NotesPanel.tsx +36 -0
  150. package/src/components/panels/Panel.tsx +15 -0
  151. package/src/components/panels/PanelGroup.css.ts +10 -0
  152. package/src/components/panels/PanelGroup.tsx +292 -0
  153. package/src/components/plugins/LocateItemButton.tsx +94 -0
  154. package/src/components/plugins/PluginContext.tsx +67 -0
  155. package/src/components/plugins/PluginDrawer.tsx +156 -0
  156. package/src/components/plugins/PluginInterface.tsx +34 -0
  157. package/src/components/plugins/PluginPanel.tsx +37 -0
  158. package/src/components/plugins/PluginSettingsPanel.tsx +34 -0
  159. package/src/components/plugins/PluginSource.tsx +48 -0
  160. package/src/components/plugins/PluginUIFeature.tsx +174 -0
  161. package/src/components/plugins/PluginUIFeatureTypes.ts +78 -0
  162. package/src/components/plugins/RemoteComponent.tsx +137 -0
  163. package/src/components/render/Build.tsx +54 -0
  164. package/src/components/render/Company.tsx +114 -0
  165. package/src/components/render/Generic.tsx +49 -0
  166. package/src/components/render/Instance.tsx +240 -0
  167. package/src/components/render/InstanceFromUrl.tsx +33 -0
  168. package/src/components/render/ModelType.tsx +293 -0
  169. package/src/components/render/Order.tsx +124 -0
  170. package/src/components/render/Part.tsx +109 -0
  171. package/src/components/render/Plugin.tsx +21 -0
  172. package/src/components/render/Report.tsx +29 -0
  173. package/src/components/render/StatusRenderer.tsx +178 -0
  174. package/src/components/render/Stock.tsx +84 -0
  175. package/src/components/render/User.tsx +42 -0
  176. package/src/components/settings/FactCollection.tsx +31 -0
  177. package/src/components/settings/FactItem.tsx +17 -0
  178. package/src/components/settings/SettingItem.tsx +176 -0
  179. package/src/components/settings/SettingList.tsx +217 -0
  180. package/src/components/wizards/OrderPartsWizard.tsx +473 -0
  181. package/src/components/wizards/WizardDrawer.tsx +188 -0
  182. package/src/contexts/ApiContext.tsx +31 -0
  183. package/src/contexts/LanguageContext.tsx +155 -0
  184. package/src/contexts/ThemeContext.tsx +58 -0
  185. package/src/contexts/colorSchema.tsx +67 -0
  186. package/src/defaults/actions.tsx +87 -0
  187. package/src/defaults/backendMappings.tsx +32 -0
  188. package/src/defaults/defaultHostList.tsx +4 -0
  189. package/src/defaults/defaults.tsx +38 -0
  190. package/src/defaults/formatters.tsx +176 -0
  191. package/src/defaults/links.tsx +193 -0
  192. package/src/defaults/templates.tsx +53 -0
  193. package/src/forms/BomForms.tsx +26 -0
  194. package/src/forms/BuildForms.tsx +615 -0
  195. package/src/forms/CommonForms.tsx +89 -0
  196. package/src/forms/CompanyForms.tsx +133 -0
  197. package/src/forms/ImporterForms.tsx +20 -0
  198. package/src/forms/PartForms.tsx +281 -0
  199. package/src/forms/PurchaseOrderForms.tsx +779 -0
  200. package/src/forms/ReturnOrderForms.tsx +263 -0
  201. package/src/forms/SalesOrderForms.tsx +408 -0
  202. package/src/forms/StockForms.tsx +1296 -0
  203. package/src/forms/selectionListFields.tsx +120 -0
  204. package/src/functions/api.tsx +61 -0
  205. package/src/functions/auth.tsx +574 -0
  206. package/src/functions/conversion.tsx +42 -0
  207. package/src/functions/events.tsx +6 -0
  208. package/src/functions/forms.tsx +173 -0
  209. package/src/functions/icons.tsx +294 -0
  210. package/src/functions/loading.tsx +29 -0
  211. package/src/functions/navigation.tsx +20 -0
  212. package/src/functions/notifications.tsx +101 -0
  213. package/src/functions/tables.tsx +26 -0
  214. package/src/functions/uid.tsx +15 -0
  215. package/src/functions/urls.tsx +58 -0
  216. package/src/hooks/UseCalendar.tsx +178 -0
  217. package/src/hooks/UseDashboardItems.tsx +118 -0
  218. package/src/hooks/UseDataExport.tsx +125 -0
  219. package/src/hooks/UseDataOutput.tsx +109 -0
  220. package/src/hooks/UseFilter.tsx +67 -0
  221. package/src/hooks/UseFilterSet.tsx +24 -0
  222. package/src/hooks/UseForm.tsx +161 -0
  223. package/src/hooks/UseGenerator.tsx +92 -0
  224. package/src/hooks/UseImportSession.tsx +139 -0
  225. package/src/hooks/UseInstance.tsx +137 -0
  226. package/src/hooks/UseInstanceName.tsx +14 -0
  227. package/src/hooks/UseModal.tsx +38 -0
  228. package/src/hooks/UsePlaceholder.tsx +66 -0
  229. package/src/hooks/UsePluginPanels.tsx +123 -0
  230. package/src/hooks/UsePluginUIFeature.tsx +95 -0
  231. package/src/hooks/UsePlugins.tsx +45 -0
  232. package/src/hooks/UseSelectedRows.tsx +37 -0
  233. package/src/hooks/UseStatusCodes.tsx +50 -0
  234. package/src/hooks/UseTable.tsx +145 -0
  235. package/src/hooks/UseWizard.tsx +133 -0
  236. package/src/locales/ar/messages.d.ts +4 -0
  237. package/src/locales/ar/messages.po +10695 -0
  238. package/src/locales/ar/messages.ts +1 -0
  239. package/src/locales/bg/messages.d.ts +4 -0
  240. package/src/locales/bg/messages.po +10695 -0
  241. package/src/locales/bg/messages.ts +1 -0
  242. package/src/locales/cs/messages.d.ts +4 -0
  243. package/src/locales/cs/messages.po +10695 -0
  244. package/src/locales/cs/messages.ts +1 -0
  245. package/src/locales/da/messages.d.ts +4 -0
  246. package/src/locales/da/messages.po +10695 -0
  247. package/src/locales/da/messages.ts +1 -0
  248. package/src/locales/de/messages.d.ts +4 -0
  249. package/src/locales/de/messages.po +10695 -0
  250. package/src/locales/de/messages.ts +1 -0
  251. package/src/locales/el/messages.d.ts +4 -0
  252. package/src/locales/el/messages.po +10695 -0
  253. package/src/locales/el/messages.ts +1 -0
  254. package/src/locales/en/messages.d.ts +4 -0
  255. package/src/locales/en/messages.po +10689 -0
  256. package/src/locales/en/messages.ts +1 -0
  257. package/src/locales/es/messages.d.ts +4 -0
  258. package/src/locales/es/messages.po +10695 -0
  259. package/src/locales/es/messages.ts +1 -0
  260. package/src/locales/es_MX/messages.d.ts +4 -0
  261. package/src/locales/es_MX/messages.po +10695 -0
  262. package/src/locales/es_MX/messages.ts +1 -0
  263. package/src/locales/et/messages.d.ts +4 -0
  264. package/src/locales/et/messages.po +10695 -0
  265. package/src/locales/et/messages.ts +1 -0
  266. package/src/locales/fa/messages.d.ts +4 -0
  267. package/src/locales/fa/messages.po +10695 -0
  268. package/src/locales/fa/messages.ts +1 -0
  269. package/src/locales/fi/messages.d.ts +4 -0
  270. package/src/locales/fi/messages.po +10695 -0
  271. package/src/locales/fi/messages.ts +1 -0
  272. package/src/locales/fr/messages.d.ts +4 -0
  273. package/src/locales/fr/messages.po +10695 -0
  274. package/src/locales/fr/messages.ts +1 -0
  275. package/src/locales/he/messages.d.ts +4 -0
  276. package/src/locales/he/messages.po +10695 -0
  277. package/src/locales/he/messages.ts +1 -0
  278. package/src/locales/hi/messages.d.ts +4 -0
  279. package/src/locales/hi/messages.po +10695 -0
  280. package/src/locales/hi/messages.ts +1 -0
  281. package/src/locales/hu/messages.d.ts +4 -0
  282. package/src/locales/hu/messages.po +10695 -0
  283. package/src/locales/hu/messages.ts +1 -0
  284. package/src/locales/id/messages.po +10695 -0
  285. package/src/locales/it/messages.d.ts +4 -0
  286. package/src/locales/it/messages.po +10695 -0
  287. package/src/locales/it/messages.ts +1 -0
  288. package/src/locales/ja/messages.d.ts +4 -0
  289. package/src/locales/ja/messages.po +10695 -0
  290. package/src/locales/ja/messages.ts +1 -0
  291. package/src/locales/ko/messages.d.ts +4 -0
  292. package/src/locales/ko/messages.po +10695 -0
  293. package/src/locales/ko/messages.ts +1 -0
  294. package/src/locales/lt/messages.d.ts +4 -0
  295. package/src/locales/lt/messages.po +10695 -0
  296. package/src/locales/lt/messages.ts +1 -0
  297. package/src/locales/lv/messages.d.ts +4 -0
  298. package/src/locales/lv/messages.po +10695 -0
  299. package/src/locales/lv/messages.ts +1 -0
  300. package/src/locales/nl/messages.d.ts +4 -0
  301. package/src/locales/nl/messages.po +10695 -0
  302. package/src/locales/nl/messages.ts +1 -0
  303. package/src/locales/no/messages.d.ts +4 -0
  304. package/src/locales/no/messages.po +10695 -0
  305. package/src/locales/no/messages.ts +1 -0
  306. package/src/locales/pl/messages.d.ts +4 -0
  307. package/src/locales/pl/messages.po +10695 -0
  308. package/src/locales/pl/messages.ts +1 -0
  309. package/src/locales/pseudo-LOCALE/messages.d.ts +4 -0
  310. package/src/locales/pseudo-LOCALE/messages.po +8003 -0
  311. package/src/locales/pseudo-LOCALE/messages.ts +1 -0
  312. package/src/locales/pt/messages.d.ts +4 -0
  313. package/src/locales/pt/messages.po +10696 -0
  314. package/src/locales/pt/messages.ts +1 -0
  315. package/src/locales/pt_BR/messages.d.ts +4 -0
  316. package/src/locales/pt_BR/messages.po +10695 -0
  317. package/src/locales/pt_BR/messages.ts +1 -0
  318. package/src/locales/ro/messages.po +10695 -0
  319. package/src/locales/ro/messages.ts +1 -0
  320. package/src/locales/ru/messages.d.ts +4 -0
  321. package/src/locales/ru/messages.po +10695 -0
  322. package/src/locales/ru/messages.ts +1 -0
  323. package/src/locales/sk/messages.d.ts +4 -0
  324. package/src/locales/sk/messages.po +10695 -0
  325. package/src/locales/sk/messages.ts +1 -0
  326. package/src/locales/sl/messages.d.ts +4 -0
  327. package/src/locales/sl/messages.po +10695 -0
  328. package/src/locales/sl/messages.ts +1 -0
  329. package/src/locales/sr/messages.d.ts +4 -0
  330. package/src/locales/sr/messages.po +10695 -0
  331. package/src/locales/sr/messages.ts +1 -0
  332. package/src/locales/sv/messages.d.ts +4 -0
  333. package/src/locales/sv/messages.po +10695 -0
  334. package/src/locales/sv/messages.ts +1 -0
  335. package/src/locales/th/messages.d.ts +4 -0
  336. package/src/locales/th/messages.po +10695 -0
  337. package/src/locales/th/messages.ts +1 -0
  338. package/src/locales/tr/messages.d.ts +4 -0
  339. package/src/locales/tr/messages.po +10695 -0
  340. package/src/locales/tr/messages.ts +1 -0
  341. package/src/locales/uk/messages.d.ts +3 -0
  342. package/src/locales/uk/messages.po +10695 -0
  343. package/src/locales/uk/messages.ts +1 -0
  344. package/src/locales/vi/messages.d.ts +4 -0
  345. package/src/locales/vi/messages.po +10695 -0
  346. package/src/locales/vi/messages.ts +1 -0
  347. package/src/locales/zh_Hans/messages.d.ts +4 -0
  348. package/src/locales/zh_Hans/messages.po +10695 -0
  349. package/src/locales/zh_Hans/messages.ts +1 -0
  350. package/src/locales/zh_Hant/messages.d.ts +4 -0
  351. package/src/locales/zh_Hant/messages.po +10695 -0
  352. package/src/locales/zh_Hant/messages.ts +1 -0
  353. package/src/main.css.ts +148 -0
  354. package/src/main.tsx +123 -0
  355. package/src/pages/Auth/ChangePassword.tsx +84 -0
  356. package/src/pages/Auth/Layout.tsx +74 -0
  357. package/src/pages/Auth/LoggedIn.tsx +21 -0
  358. package/src/pages/Auth/Login.tsx +133 -0
  359. package/src/pages/Auth/Logout.tsx +16 -0
  360. package/src/pages/Auth/MFA.tsx +36 -0
  361. package/src/pages/Auth/MFASetup.tsx +38 -0
  362. package/src/pages/Auth/Register.tsx +28 -0
  363. package/src/pages/Auth/Reset.tsx +30 -0
  364. package/src/pages/Auth/ResetPassword.tsx +48 -0
  365. package/src/pages/Auth/VerifyEmail.tsx +34 -0
  366. package/src/pages/ErrorPage.tsx +26 -0
  367. package/src/pages/Index/Home.tsx +12 -0
  368. package/src/pages/Index/Scan.tsx +258 -0
  369. package/src/pages/Index/Settings/AccountSettings/AccountDetailPanel.tsx +162 -0
  370. package/src/pages/Index/Settings/AccountSettings/QrRegistrationForm.tsx +38 -0
  371. package/src/pages/Index/Settings/AccountSettings/SecurityContent.tsx +713 -0
  372. package/src/pages/Index/Settings/AccountSettings/UserPanel.tsx +24 -0
  373. package/src/pages/Index/Settings/AccountSettings/UserThemePanel.tsx +207 -0
  374. package/src/pages/Index/Settings/AccountSettings/useConfirm.tsx +117 -0
  375. package/src/pages/Index/Settings/AdminCenter/CurrencyManagementPanel.tsx +111 -0
  376. package/src/pages/Index/Settings/AdminCenter/Index.tsx +251 -0
  377. package/src/pages/Index/Settings/AdminCenter/LabelTemplatePanel.tsx +23 -0
  378. package/src/pages/Index/Settings/AdminCenter/MachineManagementPanel.tsx +110 -0
  379. package/src/pages/Index/Settings/AdminCenter/PartParameterPanel.tsx +29 -0
  380. package/src/pages/Index/Settings/AdminCenter/PluginManagementPanel.tsx +84 -0
  381. package/src/pages/Index/Settings/AdminCenter/ReportTemplatePanel.tsx +38 -0
  382. package/src/pages/Index/Settings/AdminCenter/StocktakePanel.tsx +31 -0
  383. package/src/pages/Index/Settings/AdminCenter/TaskManagementPanel.tsx +73 -0
  384. package/src/pages/Index/Settings/AdminCenter/UnitManagementPanel.tsx +74 -0
  385. package/src/pages/Index/Settings/AdminCenter/UserManagementPanel.tsx +49 -0
  386. package/src/pages/Index/Settings/SystemSettings.tsx +339 -0
  387. package/src/pages/Index/Settings/UserSettings.tsx +143 -0
  388. package/src/pages/Notifications.tsx +134 -0
  389. package/src/pages/build/BuildDetail.tsx +579 -0
  390. package/src/pages/build/BuildIndex.tsx +100 -0
  391. package/src/pages/company/CompanyDetail.tsx +352 -0
  392. package/src/pages/company/CustomerDetail.tsx +13 -0
  393. package/src/pages/company/ManufacturerDetail.tsx +13 -0
  394. package/src/pages/company/ManufacturerPartDetail.tsx +307 -0
  395. package/src/pages/company/SupplierDetail.tsx +13 -0
  396. package/src/pages/company/SupplierPartDetail.tsx +433 -0
  397. package/src/pages/core/CoreIndex.tsx +50 -0
  398. package/src/pages/core/GroupDetail.tsx +97 -0
  399. package/src/pages/core/UserDetail.tsx +193 -0
  400. package/src/pages/part/CategoryDetail.tsx +369 -0
  401. package/src/pages/part/PartAllocationPanel.tsx +40 -0
  402. package/src/pages/part/PartDetail.tsx +1071 -0
  403. package/src/pages/part/PartPricingPanel.tsx +155 -0
  404. package/src/pages/part/PartSchedulingDetail.tsx +315 -0
  405. package/src/pages/part/PartStocktakeDetail.tsx +285 -0
  406. package/src/pages/part/PartSupplierDetail.tsx +31 -0
  407. package/src/pages/part/pricing/BomPricingPanel.tsx +269 -0
  408. package/src/pages/part/pricing/PriceBreakPanel.tsx +182 -0
  409. package/src/pages/part/pricing/PricingOverviewPanel.tsx +338 -0
  410. package/src/pages/part/pricing/PricingPanel.tsx +82 -0
  411. package/src/pages/part/pricing/PurchaseHistoryPanel.tsx +134 -0
  412. package/src/pages/part/pricing/SaleHistoryPanel.tsx +95 -0
  413. package/src/pages/part/pricing/SupplierPricingPanel.tsx +80 -0
  414. package/src/pages/part/pricing/VariantPricingPanel.tsx +112 -0
  415. package/src/pages/purchasing/PurchaseOrderDetail.tsx +547 -0
  416. package/src/pages/purchasing/PurchasingIndex.tsx +131 -0
  417. package/src/pages/sales/ReturnOrderDetail.tsx +529 -0
  418. package/src/pages/sales/SalesIndex.tsx +148 -0
  419. package/src/pages/sales/SalesOrderDetail.tsx +593 -0
  420. package/src/pages/sales/SalesOrderShipmentDetail.tsx +385 -0
  421. package/src/pages/stock/LocationDetail.tsx +413 -0
  422. package/src/pages/stock/StockDetail.tsx +951 -0
  423. package/src/router.tsx +213 -0
  424. package/src/states/ApiState.tsx +85 -0
  425. package/src/states/IconState.tsx +94 -0
  426. package/src/states/LocalState.tsx +181 -0
  427. package/src/states/SettingsState.tsx +206 -0
  428. package/src/states/StatusState.tsx +55 -0
  429. package/src/states/UserState.tsx +202 -0
  430. package/src/states/states.tsx +69 -0
  431. package/src/tables/Column.tsx +29 -0
  432. package/src/tables/ColumnRenderers.tsx +320 -0
  433. package/src/tables/ColumnSelect.tsx +39 -0
  434. package/src/tables/Filter.tsx +297 -0
  435. package/src/tables/FilterSelectDrawer.tsx +358 -0
  436. package/src/tables/InvenTreeTable.tsx +750 -0
  437. package/src/tables/InvenTreeTableHeader.tsx +257 -0
  438. package/src/tables/RowActions.tsx +176 -0
  439. package/src/tables/RowExpansionIcon.tsx +16 -0
  440. package/src/tables/Search.tsx +42 -0
  441. package/src/tables/TableHoverCard.tsx +91 -0
  442. package/src/tables/bom/BomTable.tsx +590 -0
  443. package/src/tables/bom/UsedInTable.tsx +114 -0
  444. package/src/tables/build/BuildAllocatedStockTable.tsx +233 -0
  445. package/src/tables/build/BuildLineTable.tsx +800 -0
  446. package/src/tables/build/BuildOrderTable.tsx +226 -0
  447. package/src/tables/build/BuildOrderTestTable.tsx +265 -0
  448. package/src/tables/build/BuildOutputTable.tsx +599 -0
  449. package/src/tables/company/AddressTable.tsx +211 -0
  450. package/src/tables/company/CompanyTable.tsx +176 -0
  451. package/src/tables/company/ContactTable.tsx +182 -0
  452. package/src/tables/core/UserTable.tsx +88 -0
  453. package/src/tables/general/AttachmentTable.tsx +404 -0
  454. package/src/tables/general/BarcodeScanTable.tsx +124 -0
  455. package/src/tables/general/ExtraLineItemTable.tsx +174 -0
  456. package/src/tables/machine/MachineListTable.tsx +634 -0
  457. package/src/tables/machine/MachineTypeTable.tsx +395 -0
  458. package/src/tables/notifications/NotificationTable.tsx +60 -0
  459. package/src/tables/part/ParametricPartTable.tsx +297 -0
  460. package/src/tables/part/PartBuildAllocationsTable.tsx +128 -0
  461. package/src/tables/part/PartCategoryTable.tsx +208 -0
  462. package/src/tables/part/PartCategoryTemplateTable.tsx +157 -0
  463. package/src/tables/part/PartParameterTable.tsx +226 -0
  464. package/src/tables/part/PartParameterTemplateTable.tsx +168 -0
  465. package/src/tables/part/PartPurchaseOrdersTable.tsx +163 -0
  466. package/src/tables/part/PartSalesAllocationsTable.tsx +130 -0
  467. package/src/tables/part/PartTable.tsx +423 -0
  468. package/src/tables/part/PartTestTemplateTable.tsx +290 -0
  469. package/src/tables/part/PartThumbTable.tsx +230 -0
  470. package/src/tables/part/PartVariantTable.tsx +52 -0
  471. package/src/tables/part/RelatedPartTable.tsx +182 -0
  472. package/src/tables/part/SelectionListTable.tsx +134 -0
  473. package/src/tables/plugin/PluginErrorTable.tsx +58 -0
  474. package/src/tables/plugin/PluginListTable.tsx +440 -0
  475. package/src/tables/purchasing/ManufacturerPartParameterTable.tsx +136 -0
  476. package/src/tables/purchasing/ManufacturerPartTable.tsx +158 -0
  477. package/src/tables/purchasing/PurchaseOrderLineItemTable.tsx +424 -0
  478. package/src/tables/purchasing/PurchaseOrderTable.tsx +193 -0
  479. package/src/tables/purchasing/SupplierPartTable.tsx +281 -0
  480. package/src/tables/purchasing/SupplierPriceBreakTable.tsx +222 -0
  481. package/src/tables/sales/ReturnOrderLineItemTable.tsx +271 -0
  482. package/src/tables/sales/ReturnOrderTable.tsx +201 -0
  483. package/src/tables/sales/SalesOrderAllocationTable.tsx +330 -0
  484. package/src/tables/sales/SalesOrderLineItemTable.tsx +508 -0
  485. package/src/tables/sales/SalesOrderShipmentTable.tsx +225 -0
  486. package/src/tables/sales/SalesOrderTable.tsx +212 -0
  487. package/src/tables/settings/ApiTokenTable.tsx +203 -0
  488. package/src/tables/settings/BarcodeScanHistoryTable.tsx +281 -0
  489. package/src/tables/settings/CustomStateTable.tsx +226 -0
  490. package/src/tables/settings/CustomUnitsTable.tsx +125 -0
  491. package/src/tables/settings/ErrorTable.tsx +170 -0
  492. package/src/tables/settings/ExportSessionTable.tsx +60 -0
  493. package/src/tables/settings/FailedTasksTable.tsx +103 -0
  494. package/src/tables/settings/GroupTable.tsx +240 -0
  495. package/src/tables/settings/ImportSessionTable.tsx +175 -0
  496. package/src/tables/settings/PendingTasksTable.tsx +63 -0
  497. package/src/tables/settings/ProjectCodeTable.tsx +115 -0
  498. package/src/tables/settings/ScheduledTasksTable.tsx +62 -0
  499. package/src/tables/settings/StocktakeReportTable.tsx +111 -0
  500. package/src/tables/settings/TemplateTable.tsx +404 -0
  501. package/src/tables/settings/UserTable.tsx +329 -0
  502. package/src/tables/stock/InstalledItemsTable.tsx +146 -0
  503. package/src/tables/stock/LocationTypesTable.tsx +132 -0
  504. package/src/tables/stock/StockItemTable.tsx +707 -0
  505. package/src/tables/stock/StockItemTestResultTable.tsx +487 -0
  506. package/src/tables/stock/StockLocationTable.tsx +208 -0
  507. package/src/tables/stock/StockTrackingTable.tsx +244 -0
  508. package/src/theme.ts +5 -0
  509. package/src/views/DesktopAppView.tsx +28 -0
  510. package/src/views/MainView.tsx +38 -0
  511. package/src/views/MobileAppView.tsx +43 -0
  512. package/tests/baseFixtures.ts +93 -0
  513. package/tests/defaults.ts +18 -0
  514. package/tests/helpers.ts +122 -0
  515. package/tests/login.ts +97 -0
  516. package/tests/pages/pui_build.spec.ts +373 -0
  517. package/tests/pages/pui_company.spec.ts +40 -0
  518. package/tests/pages/pui_core.spec.ts +26 -0
  519. package/tests/pages/pui_dashboard.spec.ts +64 -0
  520. package/tests/pages/pui_part.spec.ts +413 -0
  521. package/tests/pages/pui_purchase_order.spec.ts +388 -0
  522. package/tests/pages/pui_sales_order.spec.ts +224 -0
  523. package/tests/pages/pui_scan.spec.ts +114 -0
  524. package/tests/pages/pui_stock.spec.ts +259 -0
  525. package/tests/pui_exporting.spec.ts +124 -0
  526. package/tests/pui_forms.spec.ts +131 -0
  527. package/tests/pui_general.spec.ts +60 -0
  528. package/tests/pui_login.spec.ts +74 -0
  529. package/tests/pui_modals.spec.ts +144 -0
  530. package/tests/pui_plugins.spec.ts +216 -0
  531. package/tests/pui_printing.spec.ts +149 -0
  532. package/tests/pui_settings.spec.ts +285 -0
  533. package/tests/pui_tables.spec.ts +65 -0
  534. package/tests/settings/selectionList.spec.ts +103 -0
  535. package/tests/settings.ts +54 -0
  536. package/tsconfig.json +25 -0
  537. package/tsconfig.lib.json +13 -0
  538. package/tsconfig.node.json +11 -0
  539. package/vite-env.d.ts +11 -0
  540. package/vite.config.ts +98 -0
  541. package/vite.lib.config.ts +50 -0
@@ -0,0 +1,388 @@
1
+ import { expect } from '@playwright/test';
2
+ import { test } from '../baseFixtures.ts';
3
+ import {
4
+ activateCalendarView,
5
+ activateTableView,
6
+ clearTableFilters,
7
+ clickButtonIfVisible,
8
+ clickOnRowMenu,
9
+ loadTab,
10
+ navigate,
11
+ openFilterDrawer,
12
+ setTableChoiceFilter
13
+ } from '../helpers.ts';
14
+ import { doCachedLogin } from '../login.ts';
15
+
16
+ test('Purchase Orders - Table', async ({ browser }) => {
17
+ const page = await doCachedLogin(browser);
18
+
19
+ await page.getByRole('tab', { name: 'Purchasing' }).click();
20
+ await page.waitForURL('**/purchasing/index/**');
21
+
22
+ await loadTab(page, 'Purchase Orders');
23
+ await activateTableView(page);
24
+
25
+ await clearTableFilters(page);
26
+
27
+ // Check for expected values
28
+ await page.getByRole('cell', { name: 'PO0014' }).waitFor();
29
+ await page.getByText('Wire-E-Coyote').waitFor();
30
+ await page.getByText('Cancelled').first().waitFor();
31
+ await page.getByText('Pending').first().waitFor();
32
+ await page.getByText('On Hold').first().waitFor();
33
+
34
+ // Filter by 'has start date'
35
+ await setTableChoiceFilter(page, 'Has Start Date', 'Yes');
36
+ await page.getByRole('cell', { name: 'Scheduled purchase order' }).waitFor();
37
+
38
+ // Click through to a particular purchase order
39
+ await page.getByRole('cell', { name: 'PO0015' }).click();
40
+ await page.getByRole('button', { name: 'Issue Order' }).waitFor();
41
+
42
+ // Expected values
43
+ await page.getByText('2025-06-12').waitFor(); // Start Date
44
+ await page.getByText('2025-07-17').waitFor(); // Target Date
45
+ });
46
+
47
+ test('Purchase Orders - Calendar', async ({ browser }) => {
48
+ const page = await doCachedLogin(browser);
49
+
50
+ await page.getByRole('tab', { name: 'Purchasing' }).click();
51
+ await page.waitForURL('**/purchasing/index/**');
52
+ await loadTab(page, 'Purchase Orders');
53
+
54
+ // Ensure view is in "calendar" mode
55
+ await activateCalendarView(page);
56
+
57
+ // Check for expected components
58
+ await page.getByLabel('action-button-previous-month').waitFor();
59
+ await page.getByLabel('action-button-next-month').waitFor();
60
+
61
+ await page.getByLabel('calendar-select-month').click();
62
+ await page.getByRole('button', { name: 'Jan' }).waitFor();
63
+ await page.getByRole('button', { name: 'Feb' }).waitFor();
64
+ await page.getByRole('button', { name: 'Dec' }).click();
65
+
66
+ await page.getByText('December').waitFor();
67
+
68
+ // Put back into table view
69
+ await activateTableView(page);
70
+ });
71
+
72
+ test('Purchase Orders - Barcodes', async ({ browser }) => {
73
+ const page = await doCachedLogin(browser, {
74
+ url: 'purchasing/purchase-order/13/detail'
75
+ });
76
+
77
+ await page.getByRole('button', { name: 'Issue Order' }).waitFor();
78
+
79
+ // Display QR code
80
+ await page.getByLabel('action-menu-barcode-actions').click();
81
+ await page.getByLabel('action-menu-barcode-actions-view').click();
82
+ await page.getByRole('img', { name: 'QR Code' }).waitFor();
83
+ await page.getByRole('banner').getByRole('button').click();
84
+
85
+ // Un-link barcode if a link exists
86
+ await page.getByLabel('action-menu-barcode-actions').click();
87
+ await page.waitForTimeout(100);
88
+
89
+ if (
90
+ await page
91
+ .getByLabel('action-menu-barcode-actions-unlink-barcode')
92
+ .isVisible()
93
+ ) {
94
+ await page.getByLabel('action-menu-barcode-actions-unlink-barcode').click();
95
+ await page.getByRole('button', { name: 'Unlink Barcode' }).click();
96
+ await page.waitForTimeout(100);
97
+ } else {
98
+ await page.keyboard.press('Escape');
99
+ }
100
+
101
+ // Link to barcode
102
+ await page.getByLabel('action-menu-barcode-actions', { exact: true }).click();
103
+ await page.getByLabel('action-menu-barcode-actions-link-barcode').click();
104
+
105
+ await page.getByLabel('barcode-input-scanner').click();
106
+
107
+ // Simulate barcode scan
108
+ await page.getByPlaceholder('Enter barcode data').fill('1234567890');
109
+ await page.getByRole('button', { name: 'Scan', exact: true }).click();
110
+ await page.waitForTimeout(250);
111
+
112
+ await page.getByRole('button', { name: 'Issue Order' }).waitFor();
113
+
114
+ // Ensure we can scan back to this page, with the associated barcode
115
+ await page.getByRole('tab', { name: 'Sales' }).click();
116
+ await page.waitForTimeout(250);
117
+ await page.getByRole('button', { name: 'Open Barcode Scanner' }).click();
118
+ await page.getByPlaceholder('Enter barcode data').fill('1234567890');
119
+ await page.getByRole('button', { name: 'Scan', exact: true }).click();
120
+
121
+ await page.getByText('Purchase Order: PO0013', { exact: true }).waitFor();
122
+
123
+ // Unlink barcode
124
+ await page.getByLabel('action-menu-barcode-actions').click();
125
+ await page.getByLabel('action-menu-barcode-actions-unlink-barcode').click();
126
+ await page.getByRole('heading', { name: 'Unlink Barcode' }).waitFor();
127
+ await page.getByText('This will remove the link to').waitFor();
128
+ await page.getByRole('button', { name: 'Unlink Barcode' }).click();
129
+ await page.waitForTimeout(250);
130
+ await page.getByRole('button', { name: 'Issue Order' }).waitFor();
131
+ });
132
+
133
+ test('Purchase Orders - General', async ({ browser }) => {
134
+ const page = await doCachedLogin(browser);
135
+
136
+ await page.getByRole('tab', { name: 'Purchasing' }).click();
137
+ await page.waitForURL('**/purchasing/index/**');
138
+
139
+ await page.getByRole('cell', { name: 'PO0012' }).click();
140
+ await page.waitForTimeout(200);
141
+
142
+ await loadTab(page, 'Line Items');
143
+ await loadTab(page, 'Received Stock');
144
+ await loadTab(page, 'Attachments');
145
+
146
+ await page.getByRole('tab', { name: 'Purchasing' }).click();
147
+ await loadTab(page, 'Suppliers');
148
+ await page.getByText('Arrow', { exact: true }).click();
149
+ await page.waitForTimeout(200);
150
+
151
+ await loadTab(page, 'Supplied Parts');
152
+ await loadTab(page, 'Purchase Orders');
153
+ await loadTab(page, 'Stock Items');
154
+ await loadTab(page, 'Contacts');
155
+ await loadTab(page, 'Addresses');
156
+ await loadTab(page, 'Attachments');
157
+
158
+ await page.getByRole('tab', { name: 'Purchasing' }).click();
159
+ await loadTab(page, 'Manufacturers');
160
+ await page.getByText('AVX Corporation').click();
161
+ await page.waitForTimeout(200);
162
+
163
+ await loadTab(page, 'Addresses');
164
+ await page.getByRole('cell', { name: 'West Branch' }).click();
165
+ await page.locator('.mantine-ScrollArea-root').click();
166
+ await page
167
+ .getByRole('row', { name: 'West Branch Yes Surf Avenue 9' })
168
+ .getByRole('button')
169
+ .click();
170
+ await page.getByRole('menuitem', { name: 'Edit' }).click();
171
+
172
+ await page.getByLabel('text-field-title').waitFor();
173
+ await page.getByLabel('text-field-line2').waitFor();
174
+
175
+ // Read the current value of the cell, to ensure we always *change* it!
176
+ const value = await page.getByLabel('text-field-line2').inputValue();
177
+ await page
178
+ .getByLabel('text-field-line2')
179
+ .fill(value == 'old' ? 'new' : 'old');
180
+
181
+ await page.getByRole('button', { name: 'Submit' }).isEnabled();
182
+
183
+ await page.getByRole('button', { name: 'Submit' }).click();
184
+ await page.getByRole('tab', { name: 'Details' }).waitFor();
185
+ });
186
+
187
+ test('Purchase Orders - Filters', async ({ browser }) => {
188
+ const page = await doCachedLogin(browser, {
189
+ username: 'reader',
190
+ password: 'readonly'
191
+ });
192
+
193
+ await page.getByRole('tab', { name: 'Purchasing' }).click();
194
+ await page.waitForURL('**/purchasing/index/**');
195
+
196
+ await loadTab(page, 'Purchase Orders');
197
+ await activateTableView(page);
198
+
199
+ // Open filters drawer
200
+ await openFilterDrawer(page);
201
+ await clickButtonIfVisible(page, 'Clear Filters');
202
+
203
+ await page.getByRole('button', { name: 'Add Filter' }).click();
204
+
205
+ // Check for expected filter options
206
+ await page.getByPlaceholder('Select filter').fill('before');
207
+ await page.getByRole('option', { name: 'Created Before' }).waitFor();
208
+ await page.getByRole('option', { name: 'Completed Before' }).waitFor();
209
+ await page.getByRole('option', { name: 'Target Date Before' }).waitFor();
210
+
211
+ await page.getByPlaceholder('Select filter').fill('after');
212
+ await page.getByRole('option', { name: 'Created After' }).waitFor();
213
+ await page.getByRole('option', { name: 'Completed After' }).waitFor();
214
+ await page.getByRole('option', { name: 'Target Date After' }).waitFor();
215
+ });
216
+
217
+ test('Purchase Orders - Order Parts', async ({ browser }) => {
218
+ const page = await doCachedLogin(browser);
219
+
220
+ // Open "Order Parts" wizard from the "parts" table
221
+ await page.getByRole('tab', { name: 'Parts' }).click();
222
+ await page.waitForURL('**/part/category/index/**');
223
+
224
+ await page
225
+ .getByLabel('panel-tabs-partcategory')
226
+ .getByRole('tab', { name: 'Parts' })
227
+ .click();
228
+
229
+ // Select multiple parts
230
+ for (let ii = 1; ii < 5; ii++) {
231
+ await page.getByLabel(`Select record ${ii}`, { exact: true }).click();
232
+ }
233
+
234
+ await page.getByLabel('action-menu-part-actions').click();
235
+ await page.getByLabel('action-menu-part-actions-order-parts').click();
236
+ await page
237
+ .getByRole('heading', { name: 'Order Parts' })
238
+ .locator('div')
239
+ .first()
240
+ .waitFor();
241
+ await page.getByRole('banner').getByRole('button').click();
242
+
243
+ // Open "Order Parts" wizard from the "Stock Items" table
244
+ await page.getByRole('tab', { name: 'Stock' }).click();
245
+ await loadTab(page, 'Stock Items');
246
+
247
+ // Select multiple stock items
248
+ for (let ii = 2; ii < 7; ii += 2) {
249
+ await page.getByLabel(`Select record ${ii}`, { exact: true }).click();
250
+ }
251
+
252
+ await page
253
+ .getByLabel('Stock Items')
254
+ .getByLabel('action-menu-stock-actions')
255
+ .click();
256
+ await page.getByLabel('action-menu-stock-actions-order-stock').click();
257
+ await page.getByRole('banner').getByRole('button').click();
258
+
259
+ // Order from the part detail page
260
+ await navigate(page, 'part/69/');
261
+ await page.waitForURL('**/part/69/**');
262
+
263
+ await page.getByLabel('action-menu-stock-actions').click();
264
+ await page.getByLabel('action-menu-stock-actions-order').click();
265
+
266
+ // Select supplier part
267
+ await page.getByLabel('related-field-supplier_part').click();
268
+ await page.getByText('WM1731-ND').click();
269
+
270
+ // Option to create a new supplier part
271
+ await page.getByLabel('action-button-new-supplier-part').click();
272
+ await page.getByLabel('related-field-supplier', { exact: true }).click();
273
+ await page.getByText('Future').click();
274
+ await page.getByRole('button', { name: 'Cancel' }).click();
275
+
276
+ // Select purchase order
277
+ await page.getByLabel('related-field-purchase_order').click();
278
+ await page.getByText('PO0001').click();
279
+
280
+ // Option to create a new purchase order
281
+ await page.getByLabel('action-button-new-purchase-order').click();
282
+ await page.getByLabel('related-field-project_code').click();
283
+ await page.getByText('PRJ-PHO').click();
284
+ await page.getByRole('button', { name: 'Cancel' }).click();
285
+
286
+ await page.getByLabel('number-field-quantity').fill('100');
287
+
288
+ // Add the part to the purchase order
289
+ await page.getByLabel('action-button-add-to-selected').click();
290
+ await page.getByLabel('number-field-quantity').fill('100');
291
+ await page.waitForTimeout(250);
292
+ await page.getByRole('button', { name: 'Submit' }).click();
293
+ await page
294
+ .getByText('All selected parts added to a purchase order')
295
+ .waitFor();
296
+ });
297
+
298
+ /**
299
+ * Tests for receiving items against a purchase order
300
+ */
301
+ test('Purchase Orders - Receive Items', async ({ browser }) => {
302
+ const page = await doCachedLogin(browser);
303
+
304
+ await page.getByRole('tab', { name: 'Purchasing' }).click();
305
+ await page.waitForURL('**/purchasing/index/**');
306
+
307
+ await page.getByRole('cell', { name: 'PO0014' }).click();
308
+
309
+ await loadTab(page, 'Order Details');
310
+
311
+ // Select all line items to receive
312
+ await loadTab(page, 'Line Items');
313
+
314
+ await page.getByLabel('Select all records').click();
315
+ await page.waitForTimeout(200);
316
+ await page.getByLabel('action-button-receive-items').click();
317
+
318
+ // Check for display of individual locations
319
+ await page
320
+ .getByRole('cell', { name: /Choose Location/ })
321
+ .getByText('Parts Bins')
322
+ .waitFor();
323
+ await page
324
+ .getByRole('cell', { name: /Choose Location/ })
325
+ .getByText('Room 101')
326
+ .waitFor();
327
+ await page.getByText('Mechanical Lab').waitFor();
328
+
329
+ await page.getByRole('button', { name: 'Cancel' }).click();
330
+
331
+ // Let's actually receive an item (with custom values)
332
+ await navigate(page, 'purchasing/purchase-order/2/line-items');
333
+
334
+ const cell = await page.getByText('Red Paint', { exact: true });
335
+ await clickOnRowMenu(cell);
336
+ await page.getByRole('menuitem', { name: 'Receive line item' }).click();
337
+
338
+ // Select destination location
339
+ await page.getByLabel('related-field-location').click();
340
+ await page.getByRole('option', { name: 'Factory', exact: true }).click();
341
+
342
+ // Receive only a *single* item
343
+ await page.getByLabel('number-field-quantity').fill('1');
344
+
345
+ // Assign custom information
346
+ await page.getByLabel('action-button-assign-batch-').click();
347
+ await page.getByLabel('action-button-adjust-packaging').click();
348
+ await page.getByLabel('action-button-change-status').click();
349
+ await page.getByLabel('action-button-add-note').click();
350
+
351
+ await page.getByLabel('text-field-batch_code').fill('my-batch-code');
352
+ await page.getByLabel('text-field-packaging').fill('bucket');
353
+ await page.getByLabel('text-field-note').fill('The quick brown fox');
354
+ await page.getByLabel('choice-field-status').click();
355
+ await page.getByRole('option', { name: 'Destroyed' }).click();
356
+
357
+ // Short timeout to allow for debouncing
358
+ await page.waitForTimeout(200);
359
+
360
+ await page.getByRole('button', { name: 'Submit' }).click();
361
+ await page.getByText('Items received').waitFor();
362
+
363
+ await loadTab(page, 'Received Stock');
364
+ await clearTableFilters(page);
365
+
366
+ await page.getByRole('cell', { name: 'my-batch-code' }).first().waitFor();
367
+ await page.getByRole('cell', { name: 'bucket' }).first().waitFor();
368
+ });
369
+
370
+ test('Purchase Orders - Duplicate', async ({ browser }) => {
371
+ const page = await doCachedLogin(browser, {
372
+ url: 'purchasing/purchase-order/13/detail'
373
+ });
374
+
375
+ await page.getByLabel('action-menu-order-actions').click();
376
+ await page.getByLabel('action-menu-order-actions-duplicate').click();
377
+
378
+ // Ensure a new reference is suggested
379
+ await expect(page.getByLabel('text-field-reference')).not.toBeEmpty();
380
+
381
+ // Submit the duplicate request and ensure it completes
382
+ await page.getByRole('button', { name: 'Submit' }).isEnabled();
383
+ await page.getByRole('button', { name: 'Submit' }).click();
384
+ await page.getByRole('tab', { name: 'Order Details' }).waitFor();
385
+ await page.getByRole('tab', { name: 'Order Details' }).click();
386
+
387
+ await page.getByText('Pending').first().waitFor();
388
+ });
@@ -0,0 +1,224 @@
1
+ import { expect } from '@playwright/test';
2
+ import { test } from '../baseFixtures.ts';
3
+ import {
4
+ clearTableFilters,
5
+ globalSearch,
6
+ loadTab,
7
+ setTableChoiceFilter
8
+ } from '../helpers.ts';
9
+ import { doCachedLogin } from '../login.ts';
10
+
11
+ test('Sales Orders - Tabs', async ({ browser }) => {
12
+ const page = await doCachedLogin(browser, { url: 'sales/index/' });
13
+
14
+ await page.waitForURL('**/web/sales/**');
15
+
16
+ await loadTab(page, 'Sales Orders');
17
+ await page.waitForURL('**/web/sales/index/salesorders');
18
+ await loadTab(page, 'Return Orders');
19
+
20
+ // Customers
21
+ await loadTab(page, 'Customers');
22
+ await page.getByText('Customer A').click();
23
+ await loadTab(page, 'Notes');
24
+ await loadTab(page, 'Attachments');
25
+ await loadTab(page, 'Contacts');
26
+ await loadTab(page, 'Assigned Stock');
27
+ await loadTab(page, 'Return Orders');
28
+ await loadTab(page, 'Sales Orders');
29
+ await loadTab(page, 'Contacts');
30
+ await page.getByRole('cell', { name: 'Dorathy Gross' }).waitFor();
31
+ await page
32
+ .getByRole('row', { name: 'Dorathy Gross dorathy.gross@customer.com' })
33
+ .waitFor();
34
+
35
+ // Sales Order Details
36
+ await loadTab(page, 'Sales Orders');
37
+
38
+ await clearTableFilters(page);
39
+
40
+ await page.getByRole('cell', { name: 'SO0001' }).click();
41
+ await page
42
+ .getByLabel('Order Details')
43
+ .getByText('Selling some stuff')
44
+ .waitFor();
45
+ await loadTab(page, 'Line Items');
46
+ await loadTab(page, 'Shipments');
47
+ await loadTab(page, 'Build Orders');
48
+ await page.getByText('No records found').first().waitFor();
49
+ await loadTab(page, 'Attachments');
50
+ await page.getByText('No attachments found').first().waitFor();
51
+ await loadTab(page, 'Notes');
52
+ await loadTab(page, 'Order Details');
53
+
54
+ // Return Order Details
55
+ await page.getByRole('link', { name: 'Customer A' }).click();
56
+ await loadTab(page, 'Return Orders');
57
+ await page.getByRole('cell', { name: 'RMA-' }).click();
58
+ await page.getByText('RMA-0001', { exact: true }).waitFor();
59
+ await loadTab(page, 'Line Items');
60
+ await loadTab(page, 'Attachments');
61
+ await loadTab(page, 'Notes');
62
+ });
63
+
64
+ test('Sales Orders - Basic Tests', async ({ browser }) => {
65
+ const page = await doCachedLogin(browser);
66
+
67
+ await page.getByRole('tab', { name: 'Sales' }).click();
68
+ await page.waitForURL('**/sales/index/**');
69
+
70
+ await loadTab(page, 'Sales Orders');
71
+
72
+ await clearTableFilters(page);
73
+
74
+ await setTableChoiceFilter(page, 'status', 'On Hold');
75
+
76
+ await page.getByText('On Hold').first().waitFor();
77
+
78
+ // Navigate to a particular sales order
79
+ await page.getByRole('cell', { name: 'SO0003' }).click();
80
+
81
+ // Order is "on hold". We will "issue" it and then place on hold again
82
+ await page.getByText('Selling stuff').first().waitFor();
83
+ await page.getByText('On Hold').first().waitFor();
84
+ await page.getByRole('button', { name: 'Issue Order' }).click();
85
+ await page.getByRole('button', { name: 'Submit' }).click();
86
+
87
+ // Order should now be "in progress"
88
+ await page.getByText('In Progress').first().waitFor();
89
+ await page.getByRole('button', { name: 'Ship Order' }).waitFor();
90
+
91
+ await page.getByLabel('action-menu-order-actions').click();
92
+
93
+ await page.getByLabel('action-menu-order-actions-edit').waitFor();
94
+ await page.getByLabel('action-menu-order-actions-duplicate').waitFor();
95
+ await page.getByLabel('action-menu-order-actions-cancel').waitFor();
96
+
97
+ // Mark the order as "on hold" again
98
+ await page.getByLabel('action-menu-order-actions-hold').click();
99
+ await page.getByRole('button', { name: 'Submit' }).click();
100
+
101
+ await page.getByText('On Hold').first().waitFor();
102
+ await page.getByRole('button', { name: 'Issue Order' }).waitFor();
103
+ });
104
+
105
+ test('Sales Orders - Shipments', async ({ browser }) => {
106
+ const page = await doCachedLogin(browser);
107
+
108
+ await page.getByRole('tab', { name: 'Sales' }).click();
109
+ await page.waitForURL('**/sales/index/**');
110
+
111
+ await loadTab(page, 'Sales Orders');
112
+
113
+ await clearTableFilters(page);
114
+ // Click through to a particular sales order
115
+ await page.getByRole('cell', { name: 'SO0006' }).first().click();
116
+ await loadTab(page, 'Shipments');
117
+
118
+ // Create a new shipment
119
+ await page.getByLabel('action-button-add-shipment').click();
120
+ await page.getByLabel('text-field-tracking_number').fill('1234567890');
121
+ await page.getByLabel('text-field-invoice_number').fill('9876543210');
122
+ await page.getByRole('button', { name: 'Submit' }).click();
123
+
124
+ // Expected field error
125
+ await page
126
+ .getByText('The fields order, reference must make a unique set')
127
+ .first()
128
+ .waitFor();
129
+ await page.getByRole('button', { name: 'Cancel' }).click();
130
+
131
+ // Edit one of the existing shipments
132
+ await page.getByLabel('row-action-menu-0').click();
133
+ await page.getByRole('menuitem', { name: 'Edit' }).click();
134
+
135
+ // Ensure the form has loaded
136
+ await page.waitForLoadState('networkidle');
137
+
138
+ let tracking_number = await page
139
+ .getByLabel('text-field-tracking_number')
140
+ .inputValue();
141
+
142
+ if (!tracking_number) {
143
+ tracking_number = '1234567890';
144
+ } else if (tracking_number.endsWith('x')) {
145
+ // Remove the 'x' from the end of the tracking number
146
+ tracking_number = tracking_number.substring(0, tracking_number.length - 1);
147
+ } else {
148
+ // Add an 'x' to the end of the tracking number
149
+ tracking_number += 'x';
150
+ }
151
+
152
+ // Change the tracking number
153
+ await page.getByLabel('text-field-tracking_number').fill(tracking_number);
154
+ await page.waitForTimeout(250);
155
+ await page.getByRole('button', { name: 'Submit' }).click();
156
+
157
+ // Click through to a particular shipment
158
+ await page.getByLabel('row-action-menu-0').click();
159
+ await page.getByRole('menuitem', { name: 'View Shipment' }).click();
160
+
161
+ // Click through the various tabs
162
+ await loadTab(page, 'Attachments');
163
+ await loadTab(page, 'Notes');
164
+ await loadTab(page, 'Allocated Stock');
165
+
166
+ // Ensure assigned items table loads correctly
167
+ await page.getByRole('cell', { name: 'BATCH-001' }).first().waitFor();
168
+
169
+ await loadTab(page, 'Shipment Details');
170
+
171
+ // The "new" tracking number should be visible
172
+ await page.getByText(tracking_number).waitFor();
173
+
174
+ // Link back to sales order
175
+ await page.getByRole('link', { name: 'SO0006' }).click();
176
+
177
+ // Let's try to allocate some stock
178
+ await loadTab(page, 'Line Items');
179
+ await page.getByLabel('row-action-menu-1').click();
180
+ await page.getByRole('menuitem', { name: 'Allocate stock' }).click();
181
+ await page
182
+ .getByText('Select the source location for the stock allocation')
183
+ .waitFor();
184
+ await page.getByLabel('number-field-quantity').fill('123');
185
+ await page.getByLabel('related-field-stock_item').click();
186
+ await page.getByText('Quantity: 42').click();
187
+ await page.getByRole('button', { name: 'Cancel' }).click();
188
+
189
+ // Search for shipment by tracking number
190
+ await globalSearch(page, 'TRK-002');
191
+
192
+ await page
193
+ .getByText(/SO0009/)
194
+ .first()
195
+ .click();
196
+
197
+ // Search for shipment by invoice number
198
+ await globalSearch(page, 'INV-123');
199
+
200
+ await page
201
+ .getByText(/SO0025/)
202
+ .first()
203
+ .click();
204
+ });
205
+
206
+ test('Sales Orders - Duplicate', async ({ browser }) => {
207
+ const page = await doCachedLogin(browser, {
208
+ url: 'sales/sales-order/11/detail'
209
+ });
210
+
211
+ await page.getByLabel('action-menu-order-actions').click();
212
+ await page.getByLabel('action-menu-order-actions-duplicate').click();
213
+
214
+ // Ensure a new reference is suggested
215
+ await expect(page.getByLabel('text-field-reference')).not.toBeEmpty();
216
+
217
+ // Submit the duplicate request and ensure it completes
218
+ await page.getByRole('button', { name: 'Submit' }).isEnabled();
219
+ await page.getByRole('button', { name: 'Submit' }).click();
220
+ await page.getByRole('tab', { name: 'Order Details' }).waitFor();
221
+ await page.getByRole('tab', { name: 'Order Details' }).click();
222
+
223
+ await page.getByText('Pending').first().waitFor();
224
+ });