@inventreedb/ui 0.10.1 → 0.11.0

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 (184) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/.vite/manifest.json +444 -1
  3. package/dist/components/Boundary.d.ts +10 -0
  4. package/dist/components/Boundary.js +37 -0
  5. package/dist/components/Boundary.js.map +1 -0
  6. package/dist/components/CopyButton.d.ts +13 -0
  7. package/dist/components/CopyButton.js +51 -0
  8. package/dist/components/CopyButton.js.map +1 -0
  9. package/dist/components/CopyableCell.d.ts +11 -0
  10. package/dist/components/CopyableCell.js +24 -0
  11. package/dist/components/CopyableCell.js.map +1 -0
  12. package/dist/components/InvenTreeTable.d.ts +17 -0
  13. package/dist/components/InvenTreeTable.js +41 -0
  14. package/dist/components/InvenTreeTable.js.map +1 -0
  15. package/dist/components/TableColumnSelect.d.ts +4 -0
  16. package/dist/components/TableColumnSelect.js +38 -0
  17. package/dist/components/TableColumnSelect.js.map +1 -0
  18. package/dist/enums/ApiEndpoints.d.ts +1 -1
  19. package/dist/enums/ApiEndpoints.js +1 -1
  20. package/dist/enums/ApiEndpoints.js.map +1 -1
  21. package/dist/enums/ModelInformation.js +17 -0
  22. package/dist/enums/ModelInformation.js.map +1 -1
  23. package/dist/enums/ModelType.d.ts +1 -0
  24. package/dist/enums/ModelType.js +1 -0
  25. package/dist/enums/ModelType.js.map +1 -1
  26. package/dist/functions/Forms.d.ts +11 -0
  27. package/dist/functions/Forms.js +27 -0
  28. package/dist/functions/Forms.js.map +1 -0
  29. package/dist/functions/Notification.d.ts +16 -0
  30. package/dist/functions/Notification.js +82 -0
  31. package/dist/functions/Notification.js.map +1 -0
  32. package/dist/functions/String.d.ts +13 -0
  33. package/dist/functions/String.js +25 -0
  34. package/dist/functions/String.js.map +1 -0
  35. package/dist/hooks/UseFilterSet.d.ts +2 -0
  36. package/dist/hooks/UseFilterSet.js +35 -0
  37. package/dist/hooks/UseFilterSet.js.map +1 -0
  38. package/dist/hooks/UseTable.d.ts +12 -0
  39. package/dist/hooks/UseTable.js +92 -0
  40. package/dist/hooks/UseTable.js.map +1 -0
  41. package/dist/index.d.ts +13 -2
  42. package/dist/index.js +32 -4
  43. package/dist/index.js.map +1 -1
  44. package/dist/node_modules/@mantine/hooks/esm/use-local-storage/create-storage.js +129 -0
  45. package/dist/node_modules/@mantine/hooks/esm/use-local-storage/create-storage.js.map +1 -0
  46. package/dist/node_modules/@mantine/hooks/esm/use-local-storage/use-local-storage.js +8 -0
  47. package/dist/node_modules/@mantine/hooks/esm/use-local-storage/use-local-storage.js.map +1 -0
  48. package/dist/node_modules/@mantine/hooks/esm/use-window-event/use-window-event.js +11 -0
  49. package/dist/node_modules/@mantine/hooks/esm/use-window-event/use-window-event.js.map +1 -0
  50. package/dist/node_modules/@mantine/hooks/esm/utils/random-id/random-id.js +7 -0
  51. package/dist/node_modules/@mantine/hooks/esm/utils/random-id/random-id.js.map +1 -0
  52. package/dist/node_modules/@remix-run/router/dist/router.js +272 -0
  53. package/dist/node_modules/@remix-run/router/dist/router.js.map +1 -0
  54. package/dist/node_modules/@sentry/browser/build/npm/esm/prod/debug-build.js +5 -0
  55. package/dist/node_modules/@sentry/browser/build/npm/esm/prod/debug-build.js.map +1 -0
  56. package/dist/node_modules/@sentry/browser/build/npm/esm/prod/helpers.js +6 -0
  57. package/dist/node_modules/@sentry/browser/build/npm/esm/prod/helpers.js.map +1 -0
  58. package/dist/node_modules/@sentry/browser/build/npm/esm/prod/report-dialog.js +54 -0
  59. package/dist/node_modules/@sentry/browser/build/npm/esm/prod/report-dialog.js.map +1 -0
  60. package/dist/node_modules/@sentry/core/build/esm/api.js +41 -0
  61. package/dist/node_modules/@sentry/core/build/esm/api.js.map +1 -0
  62. package/dist/node_modules/@sentry/core/build/esm/asyncContext/index.js +13 -0
  63. package/dist/node_modules/@sentry/core/build/esm/asyncContext/index.js.map +1 -0
  64. package/dist/node_modules/@sentry/core/build/esm/asyncContext/stackStrategy.js +124 -0
  65. package/dist/node_modules/@sentry/core/build/esm/asyncContext/stackStrategy.js.map +1 -0
  66. package/dist/node_modules/@sentry/core/build/esm/carrier.js +22 -0
  67. package/dist/node_modules/@sentry/core/build/esm/carrier.js.map +1 -0
  68. package/dist/node_modules/@sentry/core/build/esm/currentScopes.js +34 -0
  69. package/dist/node_modules/@sentry/core/build/esm/currentScopes.js.map +1 -0
  70. package/dist/node_modules/@sentry/core/build/esm/debug-build.js +5 -0
  71. package/dist/node_modules/@sentry/core/build/esm/debug-build.js.map +1 -0
  72. package/dist/node_modules/@sentry/core/build/esm/defaultScopes.js +13 -0
  73. package/dist/node_modules/@sentry/core/build/esm/defaultScopes.js.map +1 -0
  74. package/dist/node_modules/@sentry/core/build/esm/exports.js +13 -0
  75. package/dist/node_modules/@sentry/core/build/esm/exports.js.map +1 -0
  76. package/dist/node_modules/@sentry/core/build/esm/scope.js +577 -0
  77. package/dist/node_modules/@sentry/core/build/esm/scope.js.map +1 -0
  78. package/dist/node_modules/@sentry/core/build/esm/session.js +61 -0
  79. package/dist/node_modules/@sentry/core/build/esm/session.js.map +1 -0
  80. package/dist/node_modules/@sentry/core/build/esm/utils/chain-and-copy-promiselike.js +39 -0
  81. package/dist/node_modules/@sentry/core/build/esm/utils/chain-and-copy-promiselike.js.map +1 -0
  82. package/dist/node_modules/@sentry/core/build/esm/utils/debug-logger.js +79 -0
  83. package/dist/node_modules/@sentry/core/build/esm/utils/debug-logger.js.map +1 -0
  84. package/dist/node_modules/@sentry/core/build/esm/utils/dsn.js +88 -0
  85. package/dist/node_modules/@sentry/core/build/esm/utils/dsn.js.map +1 -0
  86. package/dist/node_modules/@sentry/core/build/esm/utils/is.js +35 -0
  87. package/dist/node_modules/@sentry/core/build/esm/utils/is.js.map +1 -0
  88. package/dist/node_modules/@sentry/core/build/esm/utils/merge.js +19 -0
  89. package/dist/node_modules/@sentry/core/build/esm/utils/merge.js.map +1 -0
  90. package/dist/node_modules/@sentry/core/build/esm/utils/misc.js +32 -0
  91. package/dist/node_modules/@sentry/core/build/esm/utils/misc.js.map +1 -0
  92. package/dist/node_modules/@sentry/core/build/esm/utils/object.js +18 -0
  93. package/dist/node_modules/@sentry/core/build/esm/utils/object.js.map +1 -0
  94. package/dist/node_modules/@sentry/core/build/esm/utils/prepareEvent.js +34 -0
  95. package/dist/node_modules/@sentry/core/build/esm/utils/prepareEvent.js.map +1 -0
  96. package/dist/node_modules/@sentry/core/build/esm/utils/propagationContext.js +8 -0
  97. package/dist/node_modules/@sentry/core/build/esm/utils/propagationContext.js.map +1 -0
  98. package/dist/node_modules/@sentry/core/build/esm/utils/randomSafeContext.js +27 -0
  99. package/dist/node_modules/@sentry/core/build/esm/utils/randomSafeContext.js.map +1 -0
  100. package/dist/node_modules/@sentry/core/build/esm/utils/spanOnScope.js +17 -0
  101. package/dist/node_modules/@sentry/core/build/esm/utils/spanOnScope.js.map +1 -0
  102. package/dist/node_modules/@sentry/core/build/esm/utils/string.js +10 -0
  103. package/dist/node_modules/@sentry/core/build/esm/utils/string.js.map +1 -0
  104. package/dist/node_modules/@sentry/core/build/esm/utils/time.js +26 -0
  105. package/dist/node_modules/@sentry/core/build/esm/utils/time.js.map +1 -0
  106. package/dist/node_modules/@sentry/core/build/esm/utils/version.js +5 -0
  107. package/dist/node_modules/@sentry/core/build/esm/utils/version.js.map +1 -0
  108. package/dist/node_modules/@sentry/core/build/esm/utils/worldwide.js +5 -0
  109. package/dist/node_modules/@sentry/core/build/esm/utils/worldwide.js.map +1 -0
  110. package/dist/node_modules/@sentry/react/build/esm/debug-build.js +5 -0
  111. package/dist/node_modules/@sentry/react/build/esm/debug-build.js.map +1 -0
  112. package/dist/node_modules/@sentry/react/build/esm/error.js +40 -0
  113. package/dist/node_modules/@sentry/react/build/esm/error.js.map +1 -0
  114. package/dist/node_modules/@sentry/react/build/esm/errorboundary.js +103 -0
  115. package/dist/node_modules/@sentry/react/build/esm/errorboundary.js.map +1 -0
  116. package/dist/node_modules/@tabler/icons-react/dist/esm/createReactComponent.js +0 -6
  117. package/dist/node_modules/@tabler/icons-react/dist/esm/createReactComponent.js.map +1 -1
  118. package/dist/node_modules/@tabler/icons-react/dist/esm/defaultAttributes.js +0 -6
  119. package/dist/node_modules/@tabler/icons-react/dist/esm/defaultAttributes.js.map +1 -1
  120. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconAdjustments.js +8 -0
  121. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconAdjustments.js.map +1 -0
  122. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowRight.js +0 -6
  123. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowRight.js.map +1 -1
  124. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.js +8 -0
  125. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.js.map +1 -0
  126. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleCheck.js +0 -6
  127. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleCheck.js.map +1 -1
  128. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleX.js +0 -6
  129. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleX.js.map +1 -1
  130. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.js +0 -6
  131. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.js.map +1 -1
  132. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconDots.js +0 -6
  133. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconDots.js.map +1 -1
  134. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconEdit.js +0 -6
  135. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconEdit.js.map +1 -1
  136. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconExclamationCircle.js +0 -6
  137. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconExclamationCircle.js.map +1 -1
  138. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.js +0 -6
  139. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.js.map +1 -1
  140. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconSearch.js +0 -6
  141. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconSearch.js.map +1 -1
  142. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconTrash.js +0 -6
  143. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconTrash.js.map +1 -1
  144. package/dist/node_modules/react/cjs/react-jsx-runtime.development.js +1 -10
  145. package/dist/node_modules/react/cjs/react-jsx-runtime.development.js.map +1 -1
  146. package/dist/node_modules/react/cjs/react-jsx-runtime.production.js +1 -10
  147. package/dist/node_modules/react/cjs/react-jsx-runtime.production.js.map +1 -1
  148. package/dist/node_modules/react-router/dist/index.js +377 -0
  149. package/dist/node_modules/react-router/dist/index.js.map +1 -0
  150. package/dist/node_modules/react-router-dom/dist/index.js +560 -0
  151. package/dist/node_modules/react-router-dom/dist/index.js.map +1 -0
  152. package/dist/node_modules/zustand/esm/middleware.js +202 -0
  153. package/dist/node_modules/zustand/esm/middleware.js.map +1 -0
  154. package/dist/node_modules/zustand/esm/react.js +24 -0
  155. package/dist/node_modules/zustand/esm/react.js.map +1 -0
  156. package/dist/node_modules/zustand/esm/vanilla.js +26 -0
  157. package/dist/node_modules/zustand/esm/vanilla.js.map +1 -0
  158. package/dist/states/StoredTableState.d.ts +37 -0
  159. package/dist/states/StoredTableState.js +58 -0
  160. package/dist/states/StoredTableState.js.map +1 -0
  161. package/dist/types/Forms.d.ts +2 -0
  162. package/dist/types/Plugins.d.ts +14 -7
  163. package/dist/types/Plugins.js +1 -1
  164. package/dist/types/Plugins.js.map +1 -1
  165. package/dist/types/Tables.d.ts +10 -0
  166. package/lib/components/Boundary.tsx +46 -0
  167. package/lib/components/CopyButton.tsx +76 -0
  168. package/lib/components/CopyableCell.tsx +51 -0
  169. package/lib/components/InvenTreeTable.tsx +63 -0
  170. package/lib/components/TableColumnSelect.tsx +40 -0
  171. package/lib/enums/ApiEndpoints.tsx +1 -1
  172. package/lib/enums/ModelInformation.tsx +7 -0
  173. package/lib/enums/ModelType.tsx +1 -0
  174. package/lib/functions/Forms.tsx +47 -0
  175. package/lib/functions/Notification.tsx +50 -0
  176. package/lib/functions/String.tsx +38 -0
  177. package/lib/hooks/UseFilterSet.tsx +47 -0
  178. package/lib/hooks/UseTable.tsx +160 -0
  179. package/lib/index.ts +49 -1
  180. package/lib/states/StoredTableState.tsx +91 -0
  181. package/lib/types/Forms.tsx +2 -0
  182. package/lib/types/Plugins.tsx +15 -7
  183. package/lib/types/Tables.tsx +11 -0
  184. package/package.json +2 -2
@@ -9,6 +9,7 @@ import { ApiFormModalProps, BulkEditApiFormModalProps, StockOperationProps } fro
9
9
  import { UseModalReturn } from './Modals';
10
10
  import { RenderInstanceProps } from './Rendering';
11
11
  import { SettingsStateProps } from './Settings';
12
+ import { InvenTreeTableRenderProps } from './Tables';
12
13
  import { UserStateProps } from './User';
13
14
  export interface PluginProps {
14
15
  name: string;
@@ -39,6 +40,9 @@ export type InvenTreeFormsContext = {
39
40
  edit: (props: ApiFormModalProps) => UseModalReturn;
40
41
  stockActions: StockAdjustmentFormsContext;
41
42
  };
43
+ export type InvenTreeTablesContext<T extends Record<string, any>> = {
44
+ renderTable: (props: InvenTreeTableRenderProps<T>) => React.ReactNode;
45
+ };
42
46
  export type ImporterDrawerContext = {
43
47
  open: (sessionId: number, options?: {
44
48
  onClose?: () => void;
@@ -53,20 +57,22 @@ export type ImporterDrawerContext = {
53
57
  *
54
58
  * @param version - The version of the running InvenTree software stack
55
59
  * @param api - The Axios API instance (see ../states/ApiState.tsx)
60
+ * @param queryClient - The Tanstack QueryClient instance (see ../states/QueryState.tsx)
56
61
  * @param user - The current user instance (see ../states/UserState.tsx)
57
62
  * @param userSettings - The current user settings (see ../states/SettingsState.tsx)
58
63
  * @param globalSettings - The global settings (see ../states/SettingsState.tsx)
64
+ * @param modelInformation - A dictionary of available model information
65
+ * @param renderInstance - A component function for rendering a model instance
66
+ * @param host - The current host URL
67
+ * @param i18n - The i18n instance for translations (from @lingui/core)
68
+ * @param locale - The current locale string (e.g. 'en' / 'de')
59
69
  * @param navigate - The navigation function (see react-router-dom)
60
70
  * @param theme - The current Mantine theme
71
+ * @param colorScheme - The current Mantine color scheme (e.g. 'light' / 'dark')
61
72
  * @param forms - A set of functions for opening various API forms (see ../components/Forms.tsx)
73
+ * @param tables - A set of functions for rendering API tables
62
74
  * @param importer - A set of functions for controlling the global importer drawer (see ../components/importer/GlobalImporterDrawer.tsx)
63
- * @param colorScheme - The current Mantine color scheme (e.g. 'light' / 'dark')
64
- * @param host - The current host URL
65
- * @param i18n - The i18n instance for translations (from @lingui/core)
66
- * @param locale - The current locale string (e.g. 'en' / 'de')
67
75
  * @param model - The model type associated with the rendered component (if applicable)
68
- * @param modelInformation - A dictionary of available model information
69
- * @param renderInstance - A component function for rendering a model instance
70
76
  * @param id - The ID (primary key) of the model instance for the plugin (if applicable)
71
77
  * @param instance - The model instance data (if available)
72
78
  * @param reloadContent - A function which can be called to reload the plugin content
@@ -87,9 +93,10 @@ export type InvenTreePluginContext = {
87
93
  locale: string;
88
94
  navigate: NavigateFunction;
89
95
  theme: MantineTheme;
96
+ colorScheme: MantineColorScheme;
90
97
  forms: InvenTreeFormsContext;
98
+ tables: InvenTreeTablesContext<any>;
91
99
  importer: ImporterDrawerContext;
92
- colorScheme: MantineColorScheme;
93
100
  model?: ModelType | string;
94
101
  id?: string | number | null;
95
102
  instance?: any;
@@ -1,4 +1,4 @@
1
- const INVENTREE_PLUGIN_VERSION = "0.10.1";
1
+ const INVENTREE_PLUGIN_VERSION = "0.11.0";
2
2
  const INVENTREE_REACT_VERSION = "19.2.4";
3
3
  const INVENTREE_REACT_DOM_VERSION = (
4
4
  // @ts-ignore
@@ -1 +1 @@
1
- {"version":3,"file":"Plugins.js","sources":["../../lib/types/Plugins.tsx"],"sourcesContent":["import type { I18n } from '@lingui/core';\nimport type { MantineColorScheme, MantineTheme } from '@mantine/core';\nimport type { QueryClient } from '@tanstack/react-query';\nimport type { AxiosInstance } from 'axios';\nimport type { NavigateFunction } from 'react-router-dom';\nimport type { ModelDict } from '../enums/ModelInformation';\nimport type { ModelType } from '../enums/ModelType';\nimport type {\n ApiFormModalProps,\n BulkEditApiFormModalProps,\n StockOperationProps\n} from './Forms';\nimport type { UseModalReturn } from './Modals';\nimport type { RenderInstanceProps } from './Rendering';\nimport type { SettingsStateProps } from './Settings';\nimport type { UserStateProps } from './User';\n\nexport interface PluginProps {\n name: string;\n slug: string;\n version: null | string;\n}\n\nexport interface PluginVersion {\n inventree: string;\n react: string;\n reactDom: string;\n mantine: string;\n}\n\nexport type StockAdjustmentFormsContext = {\n addStock: (props: StockOperationProps) => UseModalReturn;\n assignStock: (props: StockOperationProps) => UseModalReturn;\n changeStatus: (props: StockOperationProps) => UseModalReturn;\n countStock: (props: StockOperationProps) => UseModalReturn;\n deleteStock: (props: StockOperationProps) => UseModalReturn;\n mergeStock: (props: StockOperationProps) => UseModalReturn;\n removeStock: (props: StockOperationProps) => UseModalReturn;\n transferStock: (props: StockOperationProps) => UseModalReturn;\n returnStock: (props: StockOperationProps) => UseModalReturn;\n};\n\nexport type InvenTreeFormsContext = {\n bulkEdit: (props: BulkEditApiFormModalProps) => UseModalReturn;\n create: (props: ApiFormModalProps) => UseModalReturn;\n delete: (props: ApiFormModalProps) => UseModalReturn;\n edit: (props: ApiFormModalProps) => UseModalReturn;\n stockActions: StockAdjustmentFormsContext;\n};\n\nexport type ImporterDrawerContext = {\n open: (sessionId: number, options?: { onClose?: () => void }) => void;\n close: () => void;\n isOpen: () => boolean;\n sessionId: () => number | null;\n};\n\n/**\n * A set of properties which are passed to a plugin,\n * for rendering an element in the user interface.\n *\n * @param version - The version of the running InvenTree software stack\n * @param api - The Axios API instance (see ../states/ApiState.tsx)\n * @param user - The current user instance (see ../states/UserState.tsx)\n * @param userSettings - The current user settings (see ../states/SettingsState.tsx)\n * @param globalSettings - The global settings (see ../states/SettingsState.tsx)\n * @param navigate - The navigation function (see react-router-dom)\n * @param theme - The current Mantine theme\n * @param forms - A set of functions for opening various API forms (see ../components/Forms.tsx)\n * @param importer - A set of functions for controlling the global importer drawer (see ../components/importer/GlobalImporterDrawer.tsx)\n * @param colorScheme - The current Mantine color scheme (e.g. 'light' / 'dark')\n * @param host - The current host URL\n * @param i18n - The i18n instance for translations (from @lingui/core)\n * @param locale - The current locale string (e.g. 'en' / 'de')\n * @param model - The model type associated with the rendered component (if applicable)\n * @param modelInformation - A dictionary of available model information\n * @param renderInstance - A component function for rendering a model instance\n * @param id - The ID (primary key) of the model instance for the plugin (if applicable)\n * @param instance - The model instance data (if available)\n * @param reloadContent - A function which can be called to reload the plugin content\n * @param reloadInstance - A function which can be called to reload the model instance\n * @param context - Any additional context data which may be passed to the plugin\n */\nexport type InvenTreePluginContext = {\n version: PluginVersion;\n api: AxiosInstance;\n queryClient: QueryClient;\n user: UserStateProps;\n userSettings: SettingsStateProps;\n globalSettings: SettingsStateProps;\n modelInformation: ModelDict;\n renderInstance: (props: Readonly<RenderInstanceProps>) => React.ReactNode;\n host: string;\n i18n: I18n;\n locale: string;\n navigate: NavigateFunction;\n theme: MantineTheme;\n forms: InvenTreeFormsContext;\n importer: ImporterDrawerContext;\n colorScheme: MantineColorScheme;\n model?: ModelType | string;\n id?: string | number | null;\n instance?: any;\n reloadContent?: () => void;\n reloadInstance?: () => void;\n context?: any;\n};\n\n/*\n * The version of the InvenTree plugin context interface.\n * This number should be incremented if the interface changes.\n */\n\n// @ts-ignore\nexport const INVENTREE_PLUGIN_VERSION: string = __INVENTREE_LIB_VERSION__;\n// @ts-ignore\nexport const INVENTREE_REACT_VERSION: string = __INVENTREE_REACT_VERSION__;\n// @ts-ignore\nexport const INVENTREE_REACT_DOM_VERSION: string =\n // @ts-ignore\n __INVENTREE_REACT_DOM_VERSION__;\n// @ts-ignore\nexport const INVENTREE_MANTINE_VERSION: string = __INVENTREE_MANTINE_VERSION__;\n"],"names":["INVENTREE_PLUGIN_VERSION","__INVENTREE_LIB_VERSION__","INVENTREE_REACT_VERSION","__INVENTREE_REACT_VERSION__","INVENTREE_REACT_DOM_VERSION","__INVENTREE_REACT_DOM_VERSION__","INVENTREE_MANTINE_VERSION","__INVENTREE_MANTINE_VERSION__"],"mappings":"AAkHO,MAAMA,2BAAmCC;AAEzC,MAAMC,0BAAkCC;AAExC,MAAMC;AAAAA;AAAAA,EAEXC;AAAAA;AAEK,MAAMC,4BAAoCC;"}
1
+ {"version":3,"file":"Plugins.js","sources":["../../lib/types/Plugins.tsx"],"sourcesContent":["import type { I18n } from '@lingui/core';\nimport type { MantineColorScheme, MantineTheme } from '@mantine/core';\nimport type { QueryClient } from '@tanstack/react-query';\nimport type { AxiosInstance } from 'axios';\nimport type { NavigateFunction } from 'react-router-dom';\nimport type { ModelDict } from '../enums/ModelInformation';\nimport type { ModelType } from '../enums/ModelType';\nimport type {\n ApiFormModalProps,\n BulkEditApiFormModalProps,\n StockOperationProps\n} from './Forms';\nimport type { UseModalReturn } from './Modals';\nimport type { RenderInstanceProps } from './Rendering';\nimport type { SettingsStateProps } from './Settings';\nimport type { InvenTreeTableRenderProps } from './Tables';\nimport type { UserStateProps } from './User';\n\nexport interface PluginProps {\n name: string;\n slug: string;\n version: null | string;\n}\n\nexport interface PluginVersion {\n inventree: string;\n react: string;\n reactDom: string;\n mantine: string;\n}\n\nexport type StockAdjustmentFormsContext = {\n addStock: (props: StockOperationProps) => UseModalReturn;\n assignStock: (props: StockOperationProps) => UseModalReturn;\n changeStatus: (props: StockOperationProps) => UseModalReturn;\n countStock: (props: StockOperationProps) => UseModalReturn;\n deleteStock: (props: StockOperationProps) => UseModalReturn;\n mergeStock: (props: StockOperationProps) => UseModalReturn;\n removeStock: (props: StockOperationProps) => UseModalReturn;\n transferStock: (props: StockOperationProps) => UseModalReturn;\n returnStock: (props: StockOperationProps) => UseModalReturn;\n};\n\nexport type InvenTreeFormsContext = {\n bulkEdit: (props: BulkEditApiFormModalProps) => UseModalReturn;\n create: (props: ApiFormModalProps) => UseModalReturn;\n delete: (props: ApiFormModalProps) => UseModalReturn;\n edit: (props: ApiFormModalProps) => UseModalReturn;\n stockActions: StockAdjustmentFormsContext;\n};\n\nexport type InvenTreeTablesContext<T extends Record<string, any>> = {\n renderTable: (props: InvenTreeTableRenderProps<T>) => React.ReactNode;\n};\n\nexport type ImporterDrawerContext = {\n open: (sessionId: number, options?: { onClose?: () => void }) => void;\n close: () => void;\n isOpen: () => boolean;\n sessionId: () => number | null;\n};\n\n/**\n * A set of properties which are passed to a plugin,\n * for rendering an element in the user interface.\n *\n * @param version - The version of the running InvenTree software stack\n * @param api - The Axios API instance (see ../states/ApiState.tsx)\n * @param queryClient - The Tanstack QueryClient instance (see ../states/QueryState.tsx)\n * @param user - The current user instance (see ../states/UserState.tsx)\n * @param userSettings - The current user settings (see ../states/SettingsState.tsx)\n * @param globalSettings - The global settings (see ../states/SettingsState.tsx)\n * @param modelInformation - A dictionary of available model information\n * @param renderInstance - A component function for rendering a model instance\n * @param host - The current host URL\n * @param i18n - The i18n instance for translations (from @lingui/core)\n * @param locale - The current locale string (e.g. 'en' / 'de')\n * @param navigate - The navigation function (see react-router-dom)\n * @param theme - The current Mantine theme\n * @param colorScheme - The current Mantine color scheme (e.g. 'light' / 'dark')\n * @param forms - A set of functions for opening various API forms (see ../components/Forms.tsx)\n * @param tables - A set of functions for rendering API tables\n * @param importer - A set of functions for controlling the global importer drawer (see ../components/importer/GlobalImporterDrawer.tsx)\n * @param model - The model type associated with the rendered component (if applicable)\n * @param id - The ID (primary key) of the model instance for the plugin (if applicable)\n * @param instance - The model instance data (if available)\n * @param reloadContent - A function which can be called to reload the plugin content\n * @param reloadInstance - A function which can be called to reload the model instance\n * @param context - Any additional context data which may be passed to the plugin\n */\nexport type InvenTreePluginContext = {\n version: PluginVersion;\n api: AxiosInstance;\n queryClient: QueryClient;\n user: UserStateProps;\n userSettings: SettingsStateProps;\n globalSettings: SettingsStateProps;\n modelInformation: ModelDict;\n renderInstance: (props: Readonly<RenderInstanceProps>) => React.ReactNode;\n host: string;\n i18n: I18n;\n locale: string;\n navigate: NavigateFunction;\n theme: MantineTheme;\n colorScheme: MantineColorScheme;\n forms: InvenTreeFormsContext;\n tables: InvenTreeTablesContext<any>;\n importer: ImporterDrawerContext;\n model?: ModelType | string;\n id?: string | number | null;\n instance?: any;\n reloadContent?: () => void;\n reloadInstance?: () => void;\n context?: any;\n};\n\n/*\n * The version of the InvenTree plugin context interface.\n * This number should be incremented if the interface changes.\n */\n\n// @ts-ignore\nexport const INVENTREE_PLUGIN_VERSION: string = __INVENTREE_LIB_VERSION__;\n// @ts-ignore\nexport const INVENTREE_REACT_VERSION: string = __INVENTREE_REACT_VERSION__;\n// @ts-ignore\nexport const INVENTREE_REACT_DOM_VERSION: string =\n // @ts-ignore\n __INVENTREE_REACT_DOM_VERSION__;\n// @ts-ignore\nexport const INVENTREE_MANTINE_VERSION: string = __INVENTREE_MANTINE_VERSION__;\n"],"names":["INVENTREE_PLUGIN_VERSION","__INVENTREE_LIB_VERSION__","INVENTREE_REACT_VERSION","__INVENTREE_REACT_VERSION__","INVENTREE_REACT_DOM_VERSION","__INVENTREE_REACT_DOM_VERSION__","INVENTREE_MANTINE_VERSION","__INVENTREE_MANTINE_VERSION__"],"mappings":"AA0HO,MAAMA,2BAAmCC;AAEzC,MAAMC,0BAAkCC;AAExC,MAAMC;AAAAA;AAAAA,EAEXC;AAAAA;AAEK,MAAMC,4BAAoCC;"}
@@ -1,4 +1,5 @@
1
1
  import { MantineStyleProp } from '@mantine/core';
2
+ import { AxiosInstance } from 'axios';
2
3
  import { DataTableCellClickHandler, DataTableRowExpansionProps } from 'mantine-datatable';
3
4
  import { ReactNode } from 'react';
4
5
  import { NavigateFunction, SetURLSearchParams } from 'react-router-dom';
@@ -174,4 +175,13 @@ export type InvenTreeTableProps<T = any> = {
174
175
  minHeight?: number;
175
176
  noHeader?: boolean;
176
177
  };
178
+ export type InvenTreeTableRenderProps<T extends Record<string, any>> = {
179
+ url?: string;
180
+ tableState: TableState;
181
+ tableData?: T[];
182
+ columns: TableColumn<T>[];
183
+ props: InvenTreeTableProps<T>;
184
+ api: AxiosInstance;
185
+ navigate: NavigateFunction;
186
+ };
177
187
  export {};
@@ -0,0 +1,46 @@
1
+ import { t } from '@lingui/core/macro';
2
+ import { Alert } from '@mantine/core';
3
+ import { ErrorBoundary, type FallbackRender } from '@sentry/react';
4
+ import { IconExclamationCircle } from '@tabler/icons-react';
5
+ import { type ReactNode, useCallback } from 'react';
6
+
7
+ export function DefaultFallback({
8
+ title
9
+ }: Readonly<{ title: string }>): ReactNode {
10
+ return (
11
+ <Alert
12
+ color='red'
13
+ icon={<IconExclamationCircle />}
14
+ title={`${t`Error rendering component`}: ${title}`}
15
+ >
16
+ {t`An error occurred while rendering this component. Refer to the console for more information.`}
17
+ </Alert>
18
+ );
19
+ }
20
+
21
+ export function Boundary({
22
+ children,
23
+ label,
24
+ fallback
25
+ }: Readonly<{
26
+ children: ReactNode;
27
+ label: string;
28
+ fallback?: React.ReactElement<any> | FallbackRender;
29
+ }>): ReactNode {
30
+ const onError = useCallback(
31
+ (error: unknown, componentStack: string | undefined, eventId: string) => {
32
+ console.error(`ERR: Error rendering component: ${label}`);
33
+ console.error(error);
34
+ },
35
+ []
36
+ );
37
+
38
+ return (
39
+ <ErrorBoundary
40
+ fallback={fallback ?? <DefaultFallback title={label} />}
41
+ onError={onError}
42
+ >
43
+ {children}
44
+ </ErrorBoundary>
45
+ );
46
+ }
@@ -0,0 +1,76 @@
1
+ import { t } from '@lingui/core/macro';
2
+ import {
3
+ ActionIcon,
4
+ type ActionIconVariant,
5
+ Button,
6
+ type DefaultMantineColor,
7
+ type FloatingPosition,
8
+ CopyButton as MantineCopyButton,
9
+ type MantineSize,
10
+ Text,
11
+ Tooltip
12
+ } from '@mantine/core';
13
+ import { IconCheck, IconCopy } from '@tabler/icons-react';
14
+
15
+ import type { JSX } from 'react';
16
+
17
+ export function CopyButton({
18
+ value,
19
+ label,
20
+ tooltip,
21
+ disabled,
22
+ tooltipPosition,
23
+ content,
24
+ size,
25
+ color = 'gray',
26
+ variant = 'transparent'
27
+ }: Readonly<{
28
+ value: any;
29
+ label?: string;
30
+ tooltip?: string;
31
+ disabled?: boolean;
32
+ tooltipPosition?: FloatingPosition;
33
+ content?: JSX.Element;
34
+ size?: MantineSize;
35
+ color?: DefaultMantineColor;
36
+ variant?: ActionIconVariant;
37
+ }>) {
38
+ const ButtonComponent = label ? Button : ActionIcon;
39
+
40
+ // Disable the copy button if we are not in a secure context, as the Clipboard API is not available
41
+ if (!window.isSecureContext) {
42
+ return null;
43
+ }
44
+
45
+ return (
46
+ <MantineCopyButton value={value}>
47
+ {({ copied, copy }) => (
48
+ <Tooltip
49
+ label={copied ? t`Copied` : (tooltip ?? t`Copy`)}
50
+ withArrow
51
+ position={tooltipPosition}
52
+ >
53
+ <ButtonComponent
54
+ disabled={disabled}
55
+ color={copied ? 'teal' : color}
56
+ onClick={(e: any) => {
57
+ e.stopPropagation();
58
+ e.preventDefault();
59
+ copy();
60
+ }}
61
+ variant={copied ? 'transparent' : (variant ?? 'transparent')}
62
+ size={size ?? 'sm'}
63
+ >
64
+ {copied ? <IconCheck /> : <IconCopy />}
65
+ {content}
66
+ {label && (
67
+ <Text p={size ?? 'sm'} size={size ?? 'sm'}>
68
+ {label}
69
+ </Text>
70
+ )}
71
+ </ButtonComponent>
72
+ </Tooltip>
73
+ )}
74
+ </MantineCopyButton>
75
+ );
76
+ }
@@ -0,0 +1,51 @@
1
+ import { Group } from '@mantine/core';
2
+ import { useState } from 'react';
3
+ import { CopyButton } from './CopyButton';
4
+
5
+ /**
6
+ * A wrapper component that adds a copy button to cell content on hover
7
+ * This component is used to make table cells copyable without adding visual clutter
8
+ *
9
+ * @param children - The cell content to render
10
+ * @param value - The value to copy when the copy button is clicked
11
+ */
12
+ export function CopyableCell({
13
+ children,
14
+ value
15
+ }: Readonly<{
16
+ children: React.ReactNode;
17
+ value: string;
18
+ }>) {
19
+ const [isHovered, setIsHovered] = useState(false);
20
+
21
+ return (
22
+ <Group
23
+ gap={0}
24
+ p={0}
25
+ wrap='nowrap'
26
+ onMouseEnter={() => setIsHovered(true)}
27
+ onMouseLeave={() => setIsHovered(false)}
28
+ justify='space-between'
29
+ align='center'
30
+ >
31
+ {children}
32
+ {window.isSecureContext && isHovered && value != null && (
33
+ <span
34
+ style={{ position: 'relative' }}
35
+ onClick={(e) => e.stopPropagation()}
36
+ onKeyDown={(e) => e.stopPropagation()}
37
+ >
38
+ <div
39
+ style={{
40
+ position: 'absolute',
41
+ right: 0,
42
+ transform: 'translateY(-50%)'
43
+ }}
44
+ >
45
+ <CopyButton value={value} variant={'default'} />
46
+ </div>
47
+ </span>
48
+ )}
49
+ </Group>
50
+ );
51
+ }
@@ -0,0 +1,63 @@
1
+ import { Alert } from '@mantine/core';
2
+ import {
3
+ INVENTREE_PLUGIN_VERSION,
4
+ type InvenTreePluginContext
5
+ } from '../types/Plugins';
6
+ import type {
7
+ InvenTreeTableProps,
8
+ TableColumn,
9
+ TableState
10
+ } from '../types/Tables';
11
+
12
+ /**
13
+ * Wrapper function which allows plugins to render an InvenTree component instance directly,
14
+ * in a similar way to the standard InvenTreeTable component.
15
+ *
16
+ * Note: The InventreePluginContext "context" object must be provided when rendering the table
17
+ *
18
+ */
19
+
20
+ export default function InvenTreeTable({
21
+ url,
22
+ tableState,
23
+ tableData,
24
+ columns,
25
+ props,
26
+ context
27
+ }: {
28
+ url?: string;
29
+ tableState: TableState;
30
+ tableData?: any[];
31
+ columns: TableColumn<any>[];
32
+ props: InvenTreeTableProps;
33
+ context: InvenTreePluginContext;
34
+ }) {
35
+ if (!context?.tables?.renderTable) {
36
+ return (
37
+ <Alert title='Plugin Version Error' color='red'>
38
+ {
39
+ 'The <InvenTreeTable> component cannot be rendered because the plugin context is missing the "renderTable" function.'
40
+ }
41
+ <br />
42
+ {
43
+ 'This means that the InvenTree UI library version is incompatible with this plugin version.'
44
+ }
45
+ <br />
46
+ <b>Plugin Version:</b> {INVENTREE_PLUGIN_VERSION}
47
+ <br />
48
+ <b>UI Version:</b> {context?.version?.inventree || 'unknown'}
49
+ <br />
50
+ </Alert>
51
+ );
52
+ }
53
+
54
+ return context?.tables.renderTable({
55
+ url: url,
56
+ tableState: tableState,
57
+ tableData: tableData,
58
+ columns: columns,
59
+ props: props,
60
+ api: context.api,
61
+ navigate: context.navigate
62
+ });
63
+ }
@@ -0,0 +1,40 @@
1
+ import { t } from '@lingui/core/macro';
2
+ import { ActionIcon, Checkbox, Divider, Menu, Tooltip } from '@mantine/core';
3
+ import { IconAdjustments } from '@tabler/icons-react';
4
+
5
+ export function TableColumnSelect({
6
+ columns,
7
+ onToggleColumn
8
+ }: Readonly<{
9
+ columns: any[];
10
+ onToggleColumn: (columnName: string) => void;
11
+ }>) {
12
+ return (
13
+ <Menu shadow='xs' closeOnItemClick={false}>
14
+ <Menu.Target>
15
+ <ActionIcon variant='transparent' aria-label='table-select-columns'>
16
+ <Tooltip label={t`Select Columns`} position='top-end'>
17
+ <IconAdjustments />
18
+ </Tooltip>
19
+ </ActionIcon>
20
+ </Menu.Target>
21
+
22
+ <Menu.Dropdown style={{ maxHeight: '400px', overflowY: 'auto' }}>
23
+ <Menu.Label>{t`Select Columns`}</Menu.Label>
24
+ <Divider />
25
+ {columns
26
+ .filter((col) => col.switchable ?? true)
27
+ .map((col) => (
28
+ <Menu.Item key={col.accessor}>
29
+ <Checkbox
30
+ checked={!col.hidden}
31
+ label={col.title || col.accessor}
32
+ onChange={() => onToggleColumn(col.accessor)}
33
+ radius='sm'
34
+ />
35
+ </Menu.Item>
36
+ ))}
37
+ </Menu.Dropdown>
38
+ </Menu>
39
+ );
40
+ }
@@ -64,7 +64,7 @@ export enum ApiEndpoints {
64
64
  content_type_list = 'contenttype/',
65
65
  icons = 'icons/',
66
66
  selectionlist_list = 'selection/',
67
- selectionlist_detail = 'selection/:id/',
67
+ selectionentry_list = 'selection/:id/entry/',
68
68
 
69
69
  // Barcode API endpoints
70
70
  barcode = 'barcode/',
@@ -287,6 +287,13 @@ export const ModelInformationDict: ModelDict = {
287
287
  api_endpoint: ApiEndpoints.selectionlist_list,
288
288
  icon: 'list_details'
289
289
  },
290
+ selectionentry: {
291
+ label: () => t`Selection Entry`,
292
+ label_multiple: () => t`Selection Entries`,
293
+ url_overview: '/settings/admin/part-parameters',
294
+ api_endpoint: ApiEndpoints.selectionentry_list,
295
+ icon: 'list_details'
296
+ },
290
297
  error: {
291
298
  label: () => t`Error`,
292
299
  label_multiple: () => t`Errors`,
@@ -35,5 +35,6 @@ export enum ModelType {
35
35
  pluginconfig = 'pluginconfig',
36
36
  contenttype = 'contenttype',
37
37
  selectionlist = 'selectionlist',
38
+ selectionentry = 'selectionentry',
38
39
  error = 'error'
39
40
  }
@@ -0,0 +1,47 @@
1
+ import type { ApiEndpoints } from '../enums/ApiEndpoints';
2
+ import type { PathParams } from '../types/Core';
3
+ import type { ApiFormFieldSet, ApiFormFieldType } from '../types/Forms';
4
+ import { apiUrl } from './Api';
5
+
6
+ /**
7
+ * Construct an API url from the provided ApiFormProps object
8
+ */
9
+ export function constructFormUrl(
10
+ url: ApiEndpoints | string,
11
+ pk?: string | number,
12
+ pathParams?: PathParams,
13
+ queryParams?: URLSearchParams
14
+ ): string {
15
+ let formUrl = apiUrl(url, pk, pathParams);
16
+
17
+ if (queryParams) {
18
+ formUrl += `?${queryParams.toString()}`;
19
+ }
20
+
21
+ return formUrl;
22
+ }
23
+
24
+ export type NestedDict = { [key: string]: string | number | NestedDict };
25
+
26
+ export function mapFields(
27
+ fields: ApiFormFieldSet,
28
+ fieldFunction: (path: string, value: ApiFormFieldType, key: string) => any,
29
+ _path?: string
30
+ ): NestedDict {
31
+ const res: NestedDict = {};
32
+
33
+ for (const [k, v] of Object.entries(fields)) {
34
+ const path = _path ? `${_path}.${k}` : k;
35
+ let value: any;
36
+
37
+ if (v.field_type === 'nested object' && v.children) {
38
+ value = mapFields(v.children, fieldFunction, path);
39
+ } else {
40
+ value = fieldFunction(path, v, k);
41
+ }
42
+
43
+ if (value !== undefined) res[k] = value;
44
+ }
45
+
46
+ return res;
47
+ }
@@ -0,0 +1,50 @@
1
+ import { t } from '@lingui/core/macro';
2
+ import { notifications } from '@mantine/notifications';
3
+
4
+ /**
5
+ * Show a notification that the feature is not yet implemented
6
+ */
7
+ export function notYetImplemented() {
8
+ notifications.hide('not-implemented');
9
+
10
+ notifications.show({
11
+ title: t`Not implemented`,
12
+ message: t`This feature is not yet implemented`,
13
+ color: 'red',
14
+ id: 'not-implemented'
15
+ });
16
+ }
17
+
18
+ /**
19
+ * Show a notification that the user does not have permission to perform the action
20
+ */
21
+ export function permissionDenied() {
22
+ notifications.show({
23
+ title: t`Permission Denied`,
24
+ message: t`You do not have permission to perform this action`,
25
+ color: 'red'
26
+ });
27
+ }
28
+
29
+ /**
30
+ * Display a notification on an invalid return code
31
+ */
32
+ export function invalidResponse(returnCode: number) {
33
+ // TODO: Specific return code messages
34
+ notifications.show({
35
+ title: t`Invalid Return Code`,
36
+ message: t`Server returned status ${returnCode}`,
37
+ color: 'red'
38
+ });
39
+ }
40
+
41
+ /**
42
+ * Display a notification on timeout
43
+ */
44
+ export function showTimeoutNotification() {
45
+ notifications.show({
46
+ title: t`Timeout`,
47
+ message: t`The request timed out`,
48
+ color: 'red'
49
+ });
50
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Reduce an input string to a given length, adding an ellipsis if necessary
3
+ * @param str - String to shorten
4
+ * @param len - Length to shorten to
5
+ */
6
+ export function shortenString({
7
+ str,
8
+ len = 100
9
+ }: {
10
+ str: string | undefined;
11
+ len?: number;
12
+ }) {
13
+ // Ensure that the string is a string
14
+ str = str ?? '';
15
+ str = str.toString();
16
+
17
+ // If the string is already short enough, return it
18
+ if (str.length <= len) {
19
+ return str;
20
+ }
21
+
22
+ // Otherwise, shorten it
23
+ const N = Math.floor(len / 2 - 1);
24
+
25
+ return `${str.slice(0, N)} ... ${str.slice(-N)}`;
26
+ }
27
+
28
+ /**
29
+ * Generate a short hash from a long string
30
+ */
31
+ export function hashString(str: string): string {
32
+ let hash = 0;
33
+ for (let i = 0; i < str.length; i++) {
34
+ hash = (hash << 5) - hash + str.charCodeAt(i);
35
+ hash |= 0; // Convert to 32bit integer
36
+ }
37
+ return hash.toString(36);
38
+ }
@@ -0,0 +1,47 @@
1
+ import { useLocalStorage } from '@mantine/hooks';
2
+ import { useCallback, useMemo } from 'react';
3
+ import type { FilterSetState, TableFilter } from '../types/Filters';
4
+
5
+ export default function useFilterSet(
6
+ filterKey: string,
7
+ initialFilters?: TableFilter[]
8
+ ): FilterSetState {
9
+ // Array of active filters (saved to local storage)
10
+ const [storedFilters, setStoredFilters] = useLocalStorage<
11
+ TableFilter[] | null
12
+ >({
13
+ key: `inventree-filterset-${filterKey}`,
14
+ defaultValue: null,
15
+ sync: false,
16
+ getInitialValueInEffect: false
17
+ });
18
+
19
+ const activeFilters: TableFilter[] = useMemo(() => {
20
+ if (storedFilters == null) {
21
+ // If there are no stored filters, set initial values
22
+ const filters = initialFilters || [];
23
+ setStoredFilters(filters);
24
+ return filters;
25
+ }
26
+ return storedFilters || [];
27
+ }, [storedFilters]);
28
+
29
+ // Callback to clear all active filters from the table
30
+ const clearActiveFilters = useCallback(() => {
31
+ setStoredFilters([]);
32
+ }, []);
33
+
34
+ const setActiveFilters = useCallback(
35
+ (filters: TableFilter[]) => {
36
+ setStoredFilters(filters);
37
+ },
38
+ [setStoredFilters]
39
+ );
40
+
41
+ return {
42
+ filterKey,
43
+ activeFilters,
44
+ setActiveFilters,
45
+ clearActiveFilters
46
+ };
47
+ }