2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-05-12 04:28:45 +00:00

feat(frontend): expose inline render helpers (#11917)

* expose RenderInlineModel

* expose Thumbnail

* add changelog / lib entry

* move thumbnail back; use context

* move to context

* reduce diff

* add better type

* reduce diff more
This commit is contained in:
Matthias Mair
2026-05-12 05:46:58 +02:00
committed by GitHub
parent 98f1ae53a3
commit 34a9f1e10c
6 changed files with 48 additions and 27 deletions
+3
View File
@@ -8,11 +8,14 @@ Adds additional functions in the plugin context related to form rendering and AP
- `useInstance` - `useInstance`
- `renderRemoteInstance` - `renderRemoteInstance`
- `EditApiForm` - `EditApiForm`
- `RenderInlineModel`
- `Thumbnail`
Exposes sub-components related to DetailDrawer rendering: Exposes sub-components related to DetailDrawer rendering:
- `DetailDrawerComponent` - `DetailDrawerComponent`
- `useLocalLibState` - `useLocalLibState`
### 0.11.3 - April 2026 ### 0.11.3 - April 2026
Exposes additional type definitions related to rendering drawers from tables: Exposes additional type definitions related to rendering drawers from tables:
+11 -1
View File
@@ -2,6 +2,7 @@ import type { I18n } from '@lingui/core';
import type { MantineColorScheme, MantineTheme } from '@mantine/core'; import type { MantineColorScheme, MantineTheme } from '@mantine/core';
import type { QueryClient } from '@tanstack/react-query'; import type { QueryClient } from '@tanstack/react-query';
import type { AxiosInstance } from 'axios'; import type { AxiosInstance } from 'axios';
import type { JSX } from 'react';
import type { NavigateFunction } from 'react-router-dom'; import type { NavigateFunction } from 'react-router-dom';
import type { ModelDict } from '../enums/ModelInformation'; import type { ModelDict } from '../enums/ModelInformation';
import type { ModelType } from '../enums/ModelType'; import type { ModelType } from '../enums/ModelType';
@@ -12,7 +13,12 @@ import type {
StockOperationProps StockOperationProps
} from './Forms'; } from './Forms';
import type { UseModalReturn } from './Modals'; import type { UseModalReturn } from './Modals';
import type { RemoteInstanceProps, RenderInstanceProps } from './Rendering'; import type {
RemoteInstanceProps,
RenderInlineModelProps,
RenderInstanceProps,
ThumbnailProps
} from './Rendering';
import type { SettingsStateProps } from './Settings'; import type { SettingsStateProps } from './Settings';
import type { InvenTreeTableRenderProps } from './Tables'; import type { InvenTreeTableRenderProps } from './Tables';
import type { UserStateProps } from './User'; import type { UserStateProps } from './User';
@@ -102,6 +108,10 @@ export type InvenTreePluginContext = {
renderRemoteInstance: ( renderRemoteInstance: (
props: Readonly<RemoteInstanceProps> props: Readonly<RemoteInstanceProps>
) => React.ReactNode; ) => React.ReactNode;
renderInlineModel: (
props: Readonly<RenderInlineModelProps>
) => React.ReactNode;
thumbnail: (props: Readonly<ThumbnailProps>) => JSX.Element;
host: string; host: string;
i18n: I18n; i18n: I18n;
locale: string; locale: string;
+23
View File
@@ -60,3 +60,26 @@ export interface RemoteInstanceProps {
modelRenderer?: (instance: any) => ReactNode; modelRenderer?: (instance: any) => ReactNode;
pk: number; pk: number;
} }
export interface ThumbnailProps {
src?: string;
alt?: string;
size?: number;
text?: ReactNode;
align?: string;
link?: string;
hover?: boolean;
hoverSize?: number;
}
export interface RenderInlineModelProps {
primary: ReactNode;
secondary?: ReactNode;
showSecondary?: boolean;
prefix?: ReactNode;
suffix?: ReactNode;
image?: string;
labels?: string[];
url?: string;
navigate?: any;
tooltip?: string;
}
@@ -1,7 +1,8 @@
import { t } from '@lingui/core/macro'; import { t } from '@lingui/core/macro';
import { Anchor, Group, HoverCard, Image } from '@mantine/core'; import { Anchor, Group, HoverCard, Image } from '@mantine/core';
import { type ReactNode, useMemo } from 'react'; import { useMemo } from 'react';
import type { ThumbnailProps } from '@lib/types/Rendering';
import { ApiImage } from './ApiImage'; import { ApiImage } from './ApiImage';
/* /*
@@ -16,16 +17,7 @@ export function Thumbnail({
align, align,
hover, hover,
hoverSize = 128 hoverSize = 128
}: Readonly<{ }: Readonly<ThumbnailProps>) {
src?: string;
alt?: string;
size?: number;
text?: ReactNode;
align?: string;
link?: string;
hover?: boolean;
hoverSize?: number;
}>) {
const backup_image = '/static/img/blank_image.png'; const backup_image = '/static/img/blank_image.png';
const inner = useMemo(() => { const inner = useMemo(() => {
@@ -48,7 +48,9 @@ import {
import { useServerApiState } from '../../states/ServerApiState'; import { useServerApiState } from '../../states/ServerApiState';
import { InvenTreeTableInternal } from '../../tables/InvenTreeTable'; import { InvenTreeTableInternal } from '../../tables/InvenTreeTable';
import { EditApiForm } from '../forms/ApiForm'; import { EditApiForm } from '../forms/ApiForm';
import { Thumbnail } from '../images/Thumbnail';
import { RenderInstance, RenderRemoteInstance } from '../render/Instance'; import { RenderInstance, RenderRemoteInstance } from '../render/Instance';
import { RenderInlineModel } from '../render/Instance';
export const useInvenTreeContext = () => { export const useInvenTreeContext = () => {
const [locale, host] = useLocalState(useShallow((s) => [s.language, s.host])); const [locale, host] = useLocalState(useShallow((s) => [s.language, s.host]));
@@ -82,6 +84,8 @@ export const useInvenTreeContext = () => {
useInstance: useInstance, useInstance: useInstance,
renderInstance: RenderInstance, renderInstance: RenderInstance,
renderRemoteInstance: RenderRemoteInstance, renderRemoteInstance: RenderRemoteInstance,
renderInlineModel: RenderInlineModel,
thumbnail: Thumbnail,
theme: theme, theme: theme,
colorScheme: colorScheme, colorScheme: colorScheme,
importer: { importer: {
@@ -15,14 +15,15 @@ import { type ReactNode, useCallback } from 'react';
import { ModelInformationDict } from '@lib/enums/ModelInformation'; import { ModelInformationDict } from '@lib/enums/ModelInformation';
import { ModelType } from '@lib/enums/ModelType'; import { ModelType } from '@lib/enums/ModelType';
import { apiUrl } from '@lib/functions/Api'; import { apiUrl } from '@lib/functions/Api';
import { getBaseUrl, navigateToLink } from '@lib/functions/Navigation';
import type { import type {
ModelRendererDict, ModelRendererDict,
RemoteInstanceProps, RemoteInstanceProps,
RenderInlineModelProps,
RenderInstanceProps RenderInstanceProps
} from '@lib/types/Rendering'; } from '@lib/types/Rendering';
export type { InstanceRenderInterface } from '@lib/types/Rendering'; export type { InstanceRenderInterface } from '@lib/types/Rendering';
import { shortenString } from '@lib/functions/String'; import { getBaseUrl, navigateToLink, shortenString } from '@lib/index';
import { useApi } from '../../contexts/ApiContext'; import { useApi } from '../../contexts/ApiContext';
import { Thumbnail } from '../images/Thumbnail'; import { Thumbnail } from '../images/Thumbnail';
import { RenderBuildItem, RenderBuildLine, RenderBuildOrder } from './Build'; import { RenderBuildItem, RenderBuildLine, RenderBuildOrder } from './Build';
@@ -172,20 +173,8 @@ export function RenderInlineModel({
navigate, navigate,
showSecondary = true, showSecondary = true,
tooltip tooltip
}: Readonly<{ }: Readonly<RenderInlineModelProps>): ReactNode {
primary: ReactNode;
secondary?: ReactNode;
showSecondary?: boolean;
prefix?: ReactNode;
suffix?: ReactNode;
image?: string;
labels?: string[];
url?: string;
navigate?: any;
tooltip?: string;
}>): ReactNode {
// TODO: Handle labels // TODO: Handle labels
const onClick = useCallback( const onClick = useCallback(
(event: any) => { (event: any) => {
if (url && navigate) { if (url && navigate) {