@inventreedb/ui 0.11.3 → 1.4.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 (165) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/.vite/manifest.json +45 -5
  3. package/dist/_virtual/dynamic-import-helper.js +20 -0
  4. package/dist/_virtual/dynamic-import-helper.js.map +1 -0
  5. package/dist/components/Boundary.js +5 -4
  6. package/dist/components/Boundary.js.map +1 -1
  7. package/dist/components/InvenTreeTable.js +4 -3
  8. package/dist/components/InvenTreeTable.js.map +1 -1
  9. package/dist/components/RowActions.js +3 -2
  10. package/dist/components/RowActions.js.map +1 -1
  11. package/dist/components/TableColumnSelect.js +1 -1
  12. package/dist/components/TableColumnSelect.js.map +1 -1
  13. package/dist/components/TagsList.d.ts +3 -0
  14. package/dist/components/TagsList.js +21 -0
  15. package/dist/components/TagsList.js.map +1 -0
  16. package/dist/components/nav/DetailDrawer.d.ts +1 -0
  17. package/dist/components/nav/DetailDrawer.js +1 -0
  18. package/dist/components/nav/DetailDrawer.js.map +1 -1
  19. package/dist/enums/ApiEndpoints.d.ts +15 -4
  20. package/dist/enums/ApiEndpoints.js +15 -4
  21. package/dist/enums/ApiEndpoints.js.map +1 -1
  22. package/dist/enums/ModelInformation.d.ts +1 -0
  23. package/dist/enums/ModelInformation.js +55 -2
  24. package/dist/enums/ModelInformation.js.map +1 -1
  25. package/dist/enums/ModelType.d.ts +4 -1
  26. package/dist/enums/ModelType.js +3 -0
  27. package/dist/enums/ModelType.js.map +1 -1
  28. package/dist/enums/Roles.d.ts +1 -0
  29. package/dist/enums/Roles.js +1 -0
  30. package/dist/enums/Roles.js.map +1 -1
  31. package/dist/functions/Events.js +4 -3
  32. package/dist/functions/Events.js.map +1 -1
  33. package/dist/functions/Navigation.js +6 -3
  34. package/dist/functions/Navigation.js.map +1 -1
  35. package/dist/functions/Plugins.js +4 -2
  36. package/dist/functions/Plugins.js.map +1 -1
  37. package/dist/hooks/MonitorBackgroundTask.js +10 -8
  38. package/dist/hooks/MonitorBackgroundTask.js.map +1 -1
  39. package/dist/hooks/MonitorDataOutput.js +4 -3
  40. package/dist/hooks/MonitorDataOutput.js.map +1 -1
  41. package/dist/hooks/UseFilterSet.js +45 -7
  42. package/dist/hooks/UseFilterSet.js.map +1 -1
  43. package/dist/hooks/UseTable.js +1 -1
  44. package/dist/index.d.ts +6 -1
  45. package/dist/index.js +20 -11
  46. package/dist/index.js.map +1 -1
  47. package/dist/node_modules/@mantine/hooks/esm/use-debounced-value/use-debounced-value.js +40 -15
  48. package/dist/node_modules/@mantine/hooks/esm/use-debounced-value/use-debounced-value.js.map +1 -1
  49. package/dist/node_modules/@mantine/hooks/esm/use-document-visibility/use-document-visibility.js +1 -1
  50. package/dist/node_modules/@mantine/hooks/esm/use-document-visibility/use-document-visibility.js.map +1 -1
  51. package/dist/node_modules/@mantine/hooks/esm/use-local-storage/create-storage.js +57 -62
  52. package/dist/node_modules/@mantine/hooks/esm/use-local-storage/create-storage.js.map +1 -1
  53. package/dist/node_modules/@mantine/hooks/esm/use-local-storage/use-local-storage.js.map +1 -1
  54. package/dist/node_modules/@mantine/hooks/esm/use-window-event/use-window-event.js +5 -3
  55. package/dist/node_modules/@mantine/hooks/esm/use-window-event/use-window-event.js.map +1 -1
  56. package/dist/node_modules/@mantine/hooks/esm/utils/random-id/random-id.js.map +1 -1
  57. package/dist/node_modules/@remix-run/router/dist/router.js +10 -0
  58. package/dist/node_modules/@remix-run/router/dist/router.js.map +1 -1
  59. package/dist/node_modules/@sentry/browser/build/npm/esm/prod/report-dialog.js +2 -2
  60. package/dist/node_modules/@sentry/browser/build/npm/esm/prod/report-dialog.js.map +1 -1
  61. package/dist/node_modules/@sentry/core/build/esm/scope.js +6 -5
  62. package/dist/node_modules/@sentry/core/build/esm/scope.js.map +1 -1
  63. package/dist/node_modules/@sentry/core/build/esm/utils/chain-and-copy-promiselike.js +1 -1
  64. package/dist/node_modules/@sentry/core/build/esm/utils/chain-and-copy-promiselike.js.map +1 -1
  65. package/dist/node_modules/@sentry/core/build/esm/utils/is.js +1 -1
  66. package/dist/node_modules/@sentry/core/build/esm/utils/is.js.map +1 -1
  67. package/dist/node_modules/@sentry/core/build/esm/utils/misc.js +1 -1
  68. package/dist/node_modules/@sentry/core/build/esm/utils/misc.js.map +1 -1
  69. package/dist/node_modules/@sentry/core/build/esm/utils/randomSafeContext.js +1 -1
  70. package/dist/node_modules/@sentry/core/build/esm/utils/randomSafeContext.js.map +1 -1
  71. package/dist/node_modules/@sentry/core/build/esm/utils/time.js +1 -1
  72. package/dist/node_modules/@sentry/core/build/esm/utils/time.js.map +1 -1
  73. package/dist/node_modules/@tabler/icons-react/dist/esm/createReactComponent.js +6 -0
  74. package/dist/node_modules/@tabler/icons-react/dist/esm/createReactComponent.js.map +1 -1
  75. package/dist/node_modules/@tabler/icons-react/dist/esm/defaultAttributes.js +6 -0
  76. package/dist/node_modules/@tabler/icons-react/dist/esm/defaultAttributes.js.map +1 -1
  77. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconAdjustments.js +6 -0
  78. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconAdjustments.js.map +1 -1
  79. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowRight.js +6 -0
  80. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconArrowRight.js.map +1 -1
  81. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.js +6 -0
  82. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCheck.js.map +1 -1
  83. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.js +6 -0
  84. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconChevronLeft.js.map +1 -1
  85. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleCheck.js +6 -0
  86. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleCheck.js.map +1 -1
  87. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleX.js +6 -0
  88. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCircleX.js.map +1 -1
  89. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.js +6 -0
  90. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconCopy.js.map +1 -1
  91. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconDots.js +6 -0
  92. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconDots.js.map +1 -1
  93. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconEdit.js +6 -0
  94. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconEdit.js.map +1 -1
  95. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconExclamationCircle.js +6 -0
  96. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconExclamationCircle.js.map +1 -1
  97. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.js +6 -0
  98. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconPlus.js.map +1 -1
  99. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconSearch.js +6 -0
  100. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconSearch.js.map +1 -1
  101. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconTag.js +14 -0
  102. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconTag.js.map +1 -0
  103. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconTrash.js +6 -0
  104. package/dist/node_modules/@tabler/icons-react/dist/esm/icons/IconTrash.js.map +1 -1
  105. package/dist/node_modules/@tanstack/query-core/build/modern/focusManager.js +31 -20
  106. package/dist/node_modules/@tanstack/query-core/build/modern/focusManager.js.map +1 -1
  107. package/dist/node_modules/@tanstack/query-core/build/modern/onlineManager.js +27 -17
  108. package/dist/node_modules/@tanstack/query-core/build/modern/onlineManager.js.map +1 -1
  109. package/dist/node_modules/@tanstack/query-core/build/modern/queryObserver.js +179 -177
  110. package/dist/node_modules/@tanstack/query-core/build/modern/queryObserver.js.map +1 -1
  111. package/dist/node_modules/@tanstack/query-core/build/modern/timeoutManager.js +31 -21
  112. package/dist/node_modules/@tanstack/query-core/build/modern/timeoutManager.js.map +1 -1
  113. package/dist/node_modules/@tanstack/react-query/build/modern/errorBoundaryUtils.js +1 -1
  114. package/dist/node_modules/@tanstack/react-query/build/modern/errorBoundaryUtils.js.map +1 -1
  115. package/dist/node_modules/@tanstack/react-query/build/modern/suspense.js +1 -1
  116. package/dist/node_modules/@tanstack/react-query/build/modern/suspense.js.map +1 -1
  117. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js +7 -4
  118. package/dist/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js.map +1 -1
  119. package/dist/node_modules/react/cjs/react-jsx-runtime.development.js +10 -1
  120. package/dist/node_modules/react/cjs/react-jsx-runtime.development.js.map +1 -1
  121. package/dist/node_modules/react/cjs/react-jsx-runtime.production.js +10 -1
  122. package/dist/node_modules/react/cjs/react-jsx-runtime.production.js.map +1 -1
  123. package/dist/node_modules/react-router/dist/index.js +11 -1
  124. package/dist/node_modules/react-router/dist/index.js.map +1 -1
  125. package/dist/node_modules/react-router-dom/dist/index.js +10 -0
  126. package/dist/node_modules/react-router-dom/dist/index.js.map +1 -1
  127. package/dist/plugin/InventreeHmrPlugin.d.ts +8 -0
  128. package/dist/plugin/InventreeHmrPlugin.js +21 -0
  129. package/dist/plugin/InventreeHmrPlugin.js.map +1 -0
  130. package/dist/plugin/LocalizedComponent.d.ts +9 -0
  131. package/dist/plugin/LocalizedComponent.js +57 -0
  132. package/dist/plugin/LocalizedComponent.js.map +1 -0
  133. package/dist/states/StoredTableState.js +2 -1
  134. package/dist/states/StoredTableState.js.map +1 -1
  135. package/dist/states/types.d.ts +3 -0
  136. package/dist/types/Filters.d.ts +11 -0
  137. package/dist/types/Forms.d.ts +6 -1
  138. package/dist/types/Panel.d.ts +26 -0
  139. package/dist/types/Plugins.d.ts +14 -2
  140. package/dist/types/Plugins.js +2 -2
  141. package/dist/types/Plugins.js.map +1 -1
  142. package/dist/types/Rendering.d.ts +54 -0
  143. package/dist/types/Tables.d.ts +7 -3
  144. package/lib/components/Boundary.tsx +7 -3
  145. package/lib/components/RowActions.tsx +2 -2
  146. package/lib/components/TableColumnSelect.tsx +1 -1
  147. package/lib/components/TagsList.tsx +27 -0
  148. package/lib/components/nav/DetailDrawer.tsx +1 -1
  149. package/lib/enums/ApiEndpoints.tsx +18 -4
  150. package/lib/enums/ModelInformation.tsx +26 -2
  151. package/lib/enums/ModelType.tsx +4 -1
  152. package/lib/enums/Roles.tsx +3 -0
  153. package/lib/functions/Navigation.tsx +1 -1
  154. package/lib/hooks/UseFilterSet.tsx +62 -11
  155. package/lib/index.ts +14 -1
  156. package/lib/plugin/InventreeHmrPlugin.tsx +40 -0
  157. package/lib/plugin/LocalizedComponent.tsx +85 -0
  158. package/lib/states/types.tsx +7 -0
  159. package/lib/types/Filters.tsx +19 -0
  160. package/lib/types/Forms.tsx +7 -1
  161. package/lib/types/Panel.tsx +30 -0
  162. package/lib/types/Plugins.tsx +20 -1
  163. package/lib/types/Rendering.tsx +61 -0
  164. package/lib/types/Tables.tsx +8 -3
  165. package/package.json +19 -18
@@ -0,0 +1,85 @@
1
+ import { i18n } from '@lingui/core';
2
+ import { I18nProvider } from '@lingui/react';
3
+ import { Skeleton } from '@mantine/core';
4
+ import { useEffect, useState } from 'react';
5
+
6
+ /**
7
+ * Attempt to load the locale file for the given locale, returning null if it fails
8
+ */
9
+ async function tryLoadLocale(locale: string): Promise<any> {
10
+ try {
11
+ const messages = await import(`./locales/${locale}/messages.ts`);
12
+ return messages;
13
+ } catch (error) {
14
+ console.warn(`Failed to load locale ${locale}`);
15
+ return null;
16
+ }
17
+ }
18
+
19
+ /**
20
+ * Helper function to dynamically load frontend translations,
21
+ * based on the provided locale.
22
+ */
23
+ async function loadPluginLocale(locale: string) {
24
+ let messages = null;
25
+
26
+ // Find the most specific locale file possible, with fallbacks to less specific locales if necessary
27
+ messages = await tryLoadLocale(locale);
28
+
29
+ if (!messages && locale.includes('-')) {
30
+ const fallbackLocale = locale.split('-')[0];
31
+ console.debug(
32
+ `Locale ${locale} not found, trying fallback locale ${fallbackLocale}`
33
+ );
34
+ messages = await tryLoadLocale(fallbackLocale);
35
+ }
36
+
37
+ if (!messages && locale.includes('_')) {
38
+ const fallbackLocale = locale.split('_')[0];
39
+ console.debug(
40
+ `Locale ${locale} not found, trying fallback locale ${fallbackLocale}`
41
+ );
42
+ messages = await tryLoadLocale(fallbackLocale);
43
+ }
44
+
45
+ if (!messages && locale !== 'en') {
46
+ console.debug(`Locale ${locale} not found, trying fallback locale en`);
47
+ messages = await tryLoadLocale('en');
48
+ }
49
+
50
+ if (messages?.messages) {
51
+ i18n.load(locale, messages.messages);
52
+ i18n.activate(locale);
53
+ } else {
54
+ console.error(`Failed to load any locale for ${locale}`);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Wrapper function for a plugin-defined component which needs to support dynamic locale loading.
60
+ *
61
+ * This is primarily designed for usage by the InvenTree plugin creator tool
62
+ */
63
+ export default function LocalizedComponent({
64
+ locale,
65
+ children
66
+ }: {
67
+ locale: string;
68
+ children: React.ReactNode;
69
+ }) {
70
+ const [loaded, setLoaded] = useState(false);
71
+
72
+ // Reload the component when the locale changes
73
+ useEffect(() => {
74
+ setLoaded(false);
75
+ loadPluginLocale(locale).then(() => {
76
+ setLoaded(true);
77
+ });
78
+ }, [locale]);
79
+
80
+ return loaded ? (
81
+ <I18nProvider i18n={i18n}>{children}</I18nProvider>
82
+ ) : (
83
+ <Skeleton w='100%' animate />
84
+ );
85
+ }
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { InstanceRenderInterface } from '../types/Rendering';
3
+
4
+ export type setRenderProps = (
5
+ model: string,
6
+ renderer: (props: Readonly<InstanceRenderInterface>) => ReactNode
7
+ ) => void;
@@ -41,6 +41,7 @@ export type TableFilter = {
41
41
  name: string;
42
42
  label?: string;
43
43
  description?: string;
44
+ placeholder?: string;
44
45
  type?: TableFilterType;
45
46
  choices?: TableFilterChoice[];
46
47
  choiceFunction?: () => TableFilterChoice[];
@@ -52,6 +53,16 @@ export type TableFilter = {
52
53
  apiFilter?: Record<string, any>;
53
54
  model?: ModelType;
54
55
  modelRenderer?: (instance: any) => string;
56
+ transform?: (item: any) => TableFilterChoice;
57
+ multi?: boolean;
58
+ };
59
+
60
+ /*
61
+ * A named snapshot of a set of active filters, saved to local storage.
62
+ */
63
+ export type NamedFilterSet = {
64
+ name: string;
65
+ filters: Pick<TableFilter, 'name' | 'value' | 'displayValue'>[];
55
66
  };
56
67
 
57
68
  /*
@@ -62,10 +73,18 @@ export type TableFilter = {
62
73
  * activeFilters: An array of active filters
63
74
  * setActiveFilters: A function to set the active filters
64
75
  * clearActiveFilters: A function to clear all active filters
76
+ * savedFilterSets: Named filter set snapshots persisted to local storage
77
+ * saveFilterSet: Save the current active filters under a given name
78
+ * loadFilterSet: Replace active filters with a previously saved named set
79
+ * deleteFilterSet: Remove a saved named filter set by name
65
80
  */
66
81
  export type FilterSetState = {
67
82
  filterKey: string;
68
83
  activeFilters: TableFilter[];
69
84
  setActiveFilters: (filters: TableFilter[]) => void;
70
85
  clearActiveFilters: () => void;
86
+ savedFilterSets: NamedFilterSet[];
87
+ saveFilterSet: (name: string) => void;
88
+ loadFilterSet: (name: string) => void;
89
+ deleteFilterSet: (name: string) => void;
71
90
  };
@@ -2,6 +2,7 @@ import type { DefaultMantineColor, MantineStyleProp } from '@mantine/core';
2
2
  import type { UseFormReturnType } from '@mantine/form';
3
3
  import type { JSX, ReactNode } from 'react';
4
4
  import type { FieldValues, UseFormReturn } from 'react-hook-form';
5
+ import type { NavigateFunction } from 'react-router-dom';
5
6
  import type { ApiEndpoints } from '../enums/ApiEndpoints';
6
7
  import type { ModelType } from '../enums/ModelType';
7
8
  import type { PathParams, UiSizeType } from './Core';
@@ -45,6 +46,7 @@ export type ApiFormFieldHeader = {
45
46
  * @param api_url : The API endpoint to fetch data from (for related fields)
46
47
  * @param pk_field : The primary key field for the related field (default = "pk")
47
48
  * @param model : The model to use for related fields
49
+ * @param custom_model : Optional custom model name (plugins may register renderers for custom models)
48
50
  * @param modelRenderer : Optional function to render the related model instance (for related fields)
49
51
  * @param filters : Optional API filters to apply to related fields
50
52
  * @param child: Optional definition of a child field (for nested objects)
@@ -97,10 +99,12 @@ export type ApiFormFieldType = {
97
99
  | 'file upload'
98
100
  | 'nested object'
99
101
  | 'dependent field'
100
- | 'table';
102
+ | 'table'
103
+ | 'tags';
101
104
  api_url?: string;
102
105
  pk_field?: string;
103
106
  model?: ModelType;
107
+ custom_model?: string;
104
108
  modelRenderer?: (instance: any) => ReactNode;
105
109
  filters?: any;
106
110
  child?: ApiFormFieldType;
@@ -158,6 +162,7 @@ export type ApiFormFieldSet = Record<string, ApiFormFieldType>;
158
162
  * @param modelType : Define a model type for this form
159
163
  * @param follow : Boolean, follow the result of the form (if possible)
160
164
  * @param table : Table to update on success (if provided)
165
+ * @param navigate : Optional navigate function to use for following results (if follow is true)
161
166
  */
162
167
  export interface ApiFormProps {
163
168
  url: ApiEndpoints | string;
@@ -187,6 +192,7 @@ export interface ApiFormProps {
187
192
  follow?: boolean;
188
193
  actions?: ApiFormAction[];
189
194
  timeout?: number;
195
+ navigate?: NavigateFunction;
190
196
  keepOpenOption?: boolean;
191
197
  onKeepOpenChange?: (keepOpen: boolean) => void;
192
198
  }
@@ -0,0 +1,30 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ // The type of indicator dot to be shown against a panel
4
+ export type PanelIndicatorType = 'info' | 'warning' | 'danger' | null;
5
+
6
+ /**
7
+ * Type used to specify a single panel in a panel group
8
+ */
9
+ export type PanelType = {
10
+ name: string;
11
+ label: string;
12
+ controls?: ReactNode;
13
+ icon?: ReactNode;
14
+ notification_dot?: PanelIndicatorType | (() => Promise<PanelIndicatorType>);
15
+ content?: ReactNode;
16
+ hidden?: boolean;
17
+ disabled?: boolean;
18
+ showHeadline?: boolean;
19
+ supportsDirty?: boolean;
20
+ };
21
+
22
+ /**
23
+ * Type used to specify a group of panels
24
+ */
25
+ export type PanelGroupType = {
26
+ id: string;
27
+ label: string;
28
+ panelIDs?: string[];
29
+ panels?: PanelType[];
30
+ };
@@ -2,16 +2,24 @@ import type { I18n } from '@lingui/core';
2
2
  import type { MantineColorScheme, MantineTheme } from '@mantine/core';
3
3
  import type { QueryClient } from '@tanstack/react-query';
4
4
  import type { AxiosInstance } from 'axios';
5
+ import type { JSX } from 'react';
5
6
  import type { NavigateFunction } from 'react-router-dom';
6
7
  import type { ModelDict } from '../enums/ModelInformation';
7
8
  import type { ModelType } from '../enums/ModelType';
9
+ import type { setRenderProps } from '../states/types';
8
10
  import type {
9
11
  ApiFormModalProps,
12
+ ApiFormProps,
10
13
  BulkEditApiFormModalProps,
11
14
  StockOperationProps
12
15
  } from './Forms';
13
16
  import type { UseModalReturn } from './Modals';
14
- import type { RenderInstanceProps } from './Rendering';
17
+ import type {
18
+ RemoteInstanceProps,
19
+ RenderInlineModelProps,
20
+ RenderInstanceProps,
21
+ ThumbnailProps
22
+ } from './Rendering';
15
23
  import type { SettingsStateProps } from './Settings';
16
24
  import type { InvenTreeTableRenderProps } from './Tables';
17
25
  import type { UserStateProps } from './User';
@@ -46,6 +54,7 @@ export type InvenTreeFormsContext = {
46
54
  create: (props: ApiFormModalProps) => UseModalReturn;
47
55
  delete: (props: ApiFormModalProps) => UseModalReturn;
48
56
  edit: (props: ApiFormModalProps) => UseModalReturn;
57
+ editApiForm: (props: { id?: string; props: ApiFormProps }) => React.ReactNode;
49
58
  stockActions: StockAdjustmentFormsContext;
50
59
  };
51
60
 
@@ -97,6 +106,13 @@ export type InvenTreePluginContext = {
97
106
  globalSettings: SettingsStateProps;
98
107
  modelInformation: ModelDict;
99
108
  renderInstance: (props: Readonly<RenderInstanceProps>) => React.ReactNode;
109
+ renderRemoteInstance: (
110
+ props: Readonly<RemoteInstanceProps>
111
+ ) => React.ReactNode;
112
+ renderInlineModel: (
113
+ props: Readonly<RenderInlineModelProps>
114
+ ) => React.ReactNode;
115
+ thumbnail: (props: Readonly<ThumbnailProps>) => JSX.Element;
100
116
  host: string;
101
117
  i18n: I18n;
102
118
  locale: string;
@@ -104,6 +120,9 @@ export type InvenTreePluginContext = {
104
120
  theme: MantineTheme;
105
121
  colorScheme: MantineColorScheme;
106
122
  forms: InvenTreeFormsContext;
123
+ stateFnc: {
124
+ setRenderer: setRenderProps;
125
+ };
107
126
  tables: InvenTreeTablesContext<any>;
108
127
  importer: ImporterDrawerContext;
109
128
  model?: ModelType | string;
@@ -1,4 +1,11 @@
1
+ import type {
2
+ QueryObserverResult,
3
+ UseQueryResult
4
+ } from '@tanstack/react-query';
5
+ import type { ReactNode } from 'react';
6
+ import type { ApiEndpoints } from '..';
1
7
  import type { ModelType } from '../enums/ModelType';
8
+ import type { PathParams } from './Core';
2
9
 
3
10
  /**
4
11
  * Interface for rendering a model instance.
@@ -8,6 +15,7 @@ export interface InstanceRenderInterface {
8
15
  link?: boolean;
9
16
  navigate?: any;
10
17
  showSecondary?: boolean;
18
+ showHover?: boolean;
11
19
  extra?: Record<string, any>;
12
20
  }
13
21
 
@@ -22,4 +30,57 @@ export type ModelRendererDict = EnumDictionary<
22
30
 
23
31
  export type RenderInstanceProps = {
24
32
  model: ModelType | undefined;
33
+ custom_model?: string;
25
34
  } & InstanceRenderInterface;
35
+
36
+ export interface UseInstanceResult {
37
+ instance: any;
38
+ setInstance: (instance: any) => void;
39
+ refreshInstance: () => void;
40
+ refreshInstancePromise: () => Promise<QueryObserverResult<any, any>>;
41
+ instanceQuery: UseQueryResult;
42
+ isLoaded: boolean;
43
+ }
44
+
45
+ export interface useInstanceProps {
46
+ endpoint: ApiEndpoints;
47
+ pk?: string | number | undefined;
48
+ hasPrimaryKey?: boolean;
49
+ params?: any;
50
+ pathParams?: PathParams;
51
+ disabled?: boolean;
52
+ defaultValue?: any;
53
+ refetchOnMount?: boolean;
54
+ refetchOnWindowFocus?: boolean;
55
+ updateInterval?: number;
56
+ }
57
+
58
+ export interface RemoteInstanceProps {
59
+ model: ModelType;
60
+ modelUrl?: string;
61
+ modelRenderer?: (instance: any) => ReactNode;
62
+ pk: number;
63
+ }
64
+ export interface ThumbnailProps {
65
+ src?: string;
66
+ alt?: string;
67
+ size?: number;
68
+ text?: ReactNode;
69
+ align?: string;
70
+ link?: string;
71
+ hover?: boolean;
72
+ hoverSize?: number;
73
+ }
74
+
75
+ export interface RenderInlineModelProps {
76
+ primary: ReactNode;
77
+ secondary?: ReactNode;
78
+ showSecondary?: boolean;
79
+ prefix?: ReactNode;
80
+ suffix?: ReactNode;
81
+ image?: string;
82
+ labels?: string[];
83
+ url?: string;
84
+ navigate?: any;
85
+ tooltip?: string;
86
+ }
@@ -84,7 +84,7 @@ export type TableState = {
84
84
  * @param editable - Whether the value of this column can be edited
85
85
  * @param definition - Optional field definition for the column
86
86
  * @param render - A custom render function
87
- * @param filter - A custom filter function
87
+ * @param filter - Filter name (string) to look up from tableFilters and attach an inline icon, or a custom render function for the filter popover
88
88
  * @param filtering - Whether the column is filterable
89
89
  * @param width - The width of the column
90
90
  * @param minWidth - The minimum width of the column
@@ -100,7 +100,7 @@ export type TableState = {
100
100
  */
101
101
  export type TableColumnProps<T = any> = {
102
102
  accessor?: string;
103
- title?: string;
103
+ title?: string | ReactNode;
104
104
  ordering?: string;
105
105
  sortable?: boolean;
106
106
  switchable?: boolean;
@@ -109,7 +109,10 @@ export type TableColumnProps<T = any> = {
109
109
  editable?: boolean;
110
110
  definition?: ApiFormFieldType;
111
111
  render?: (record: T, index?: number) => any;
112
- filter?: any;
112
+ filter?:
113
+ | string
114
+ | string[]
115
+ | (({ close }: { close: () => void }) => ReactNode);
113
116
  filtering?: boolean;
114
117
  width?: number;
115
118
  minWidth?: string | number;
@@ -173,6 +176,7 @@ export type RowViewProps = RowAction & RowModelProps;
173
176
  * @param barcodeActions : any[] - List of barcode actions
174
177
  * @param tableFilters : TableFilter[] - List of custom filters
175
178
  * @param tableActions : any[] - List of custom action groups
179
+ * @param isRecordSelectable : (record: any, index: number) => boolean - Callback function to determine if a row is selectable
176
180
  * @param detailAction: boolean - Enable detail action for each row (default = true)
177
181
  * @param dataFormatter : (data: any) => any - Callback function to reformat data returned by server (if not in default format)
178
182
  * @param rowActions : (record: any) => RowAction[] - Callback function to generate row actions
@@ -203,6 +207,7 @@ export type InvenTreeTableProps<T = any> = {
203
207
  barcodeActions?: React.ReactNode[];
204
208
  tableFilters?: TableFilter[];
205
209
  tableActions?: React.ReactNode[];
210
+ isRecordSelectable?: (record: T, index: number) => boolean;
206
211
  rowExpansion?: DataTableRowExpansionProps<T>;
207
212
  dataFormatter?: (data: any) => any;
208
213
  rowActions?: (record: T) => RowAction[];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@inventreedb/ui",
3
3
  "description": "UI components for the InvenTree project",
4
- "version": "0.11.3",
4
+ "version": "1.4.1",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -60,17 +60,17 @@
60
60
  "@github/webauthn-json": "^2.1.1",
61
61
  "@lingui/core": "^5.9.2",
62
62
  "@lingui/react": "^5.9.2",
63
- "@mantine/carousel": "^8.2.7",
64
- "@mantine/charts": "^8.2.7",
65
- "@mantine/core": "^8.2.7",
66
- "@mantine/dates": "^8.2.7",
67
- "@mantine/dropzone": "^8.2.7",
68
- "@mantine/form": "^8.2.7",
69
- "@mantine/hooks": "^8.2.7",
70
- "@mantine/modals": "^8.2.7",
71
- "@mantine/notifications": "^8.2.7",
72
- "@mantine/spotlight": "^8.2.7",
73
- "@mantine/vanilla-extract": "^8.2.7",
63
+ "@mantine/carousel": "^9.2.1",
64
+ "@mantine/charts": "^9.2.1",
65
+ "@mantine/core": "^9.2.1",
66
+ "@mantine/dates": "^9.2.1",
67
+ "@mantine/dropzone": "^9.2.1",
68
+ "@mantine/form": "^9.2.1",
69
+ "@mantine/hooks": "^9.2.1",
70
+ "@mantine/modals": "^9.2.1",
71
+ "@mantine/notifications": "^9.2.1",
72
+ "@mantine/spotlight": "^9.2.1",
73
+ "@mantine/vanilla-extract": "^9.2.1",
74
74
  "@messageformat/date-skeleton": "^1.1.0",
75
75
  "@sentry/react": "^10.43.0",
76
76
  "@tabler/icons-react": "^3.17.0",
@@ -84,12 +84,13 @@
84
84
  "codemirror": "^6.0.2",
85
85
  "dayjs": "^1.11.13",
86
86
  "dompurify": "^3.2.4",
87
- "easymde": "^2.18.0",
87
+ "easymde": "^2.20.0",
88
+ "embla-carousel": "^8.5.2",
88
89
  "embla-carousel-react": "^8.5.2",
89
90
  "fuse.js": "^7.0.0",
90
91
  "html5-qrcode": "^2.3.8",
91
- "mantine-contextmenu": "^8.2.0",
92
- "mantine-datatable": "^8.2.0",
92
+ "mantine-contextmenu": "^9.2.1",
93
+ "mantine-datatable": "^9.2.0",
93
94
  "qrcode": "^1.5.4",
94
95
  "react": "^19.2.4",
95
96
  "react-dom": "^19.2.4",
@@ -114,7 +115,7 @@
114
115
  "@lingui/babel-plugin-lingui-macro": "^5.9.2",
115
116
  "@lingui/cli": "^5.9.2",
116
117
  "@lingui/macro": "^5.9.2",
117
- "@playwright/test": "^1.58.2",
118
+ "@playwright/test": "^1.16.0",
118
119
  "@types/node": "^25.5.0",
119
120
  "@types/qrcode": "^1.5.5",
120
121
  "@types/react": "^19.2.14",
@@ -131,7 +132,7 @@
131
132
  "rollup": "^4.59.0",
132
133
  "rollup-plugin-license": "^3.7.0",
133
134
  "typescript": "^5.9.3",
134
- "vite": "7.3.2",
135
+ "vite": "^6.4.2",
135
136
  "vite-plugin-babel-macros": "^1.0.6",
136
137
  "vite-plugin-dts": "^4.5.4",
137
138
  "vite-plugin-externals": "^0.6.2",
@@ -139,6 +140,6 @@
139
140
  },
140
141
  "resolutions": {
141
142
  "undici": "^6.24.0",
142
- "vite": "^8.0.5"
143
+ "vite": "^6.4.2"
143
144
  }
144
145
  }