diff --git a/src/frontend/CHANGELOG.md b/src/frontend/CHANGELOG.md index 7068a287b0..4e62d3cfc3 100644 --- a/src/frontend/CHANGELOG.md +++ b/src/frontend/CHANGELOG.md @@ -8,11 +8,14 @@ Adds additional functions in the plugin context related to form rendering and AP - `useInstance` - `renderRemoteInstance` - `EditApiForm` +- `RenderInlineModel` +- `Thumbnail` Exposes sub-components related to DetailDrawer rendering: - `DetailDrawerComponent` - `useLocalLibState` + ### 0.11.3 - April 2026 Exposes additional type definitions related to rendering drawers from tables: diff --git a/src/frontend/lib/types/Plugins.tsx b/src/frontend/lib/types/Plugins.tsx index 25066cb354..0628eda9e9 100644 --- a/src/frontend/lib/types/Plugins.tsx +++ b/src/frontend/lib/types/Plugins.tsx @@ -2,6 +2,7 @@ import type { I18n } from '@lingui/core'; import type { MantineColorScheme, MantineTheme } from '@mantine/core'; import type { QueryClient } from '@tanstack/react-query'; import type { AxiosInstance } from 'axios'; +import type { JSX } from 'react'; import type { NavigateFunction } from 'react-router-dom'; import type { ModelDict } from '../enums/ModelInformation'; import type { ModelType } from '../enums/ModelType'; @@ -12,7 +13,12 @@ import type { StockOperationProps } from './Forms'; 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 { InvenTreeTableRenderProps } from './Tables'; import type { UserStateProps } from './User'; @@ -102,6 +108,10 @@ export type InvenTreePluginContext = { renderRemoteInstance: ( props: Readonly ) => React.ReactNode; + renderInlineModel: ( + props: Readonly + ) => React.ReactNode; + thumbnail: (props: Readonly) => JSX.Element; host: string; i18n: I18n; locale: string; diff --git a/src/frontend/lib/types/Rendering.tsx b/src/frontend/lib/types/Rendering.tsx index 0fa3b5abb1..2ad427c519 100644 --- a/src/frontend/lib/types/Rendering.tsx +++ b/src/frontend/lib/types/Rendering.tsx @@ -60,3 +60,26 @@ export interface RemoteInstanceProps { modelRenderer?: (instance: any) => ReactNode; 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; +} diff --git a/src/frontend/src/components/images/Thumbnail.tsx b/src/frontend/src/components/images/Thumbnail.tsx index c24e7671a0..2d3e0d094f 100644 --- a/src/frontend/src/components/images/Thumbnail.tsx +++ b/src/frontend/src/components/images/Thumbnail.tsx @@ -1,7 +1,8 @@ import { t } from '@lingui/core/macro'; 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'; /* @@ -16,16 +17,7 @@ export function Thumbnail({ align, hover, hoverSize = 128 -}: Readonly<{ - src?: string; - alt?: string; - size?: number; - text?: ReactNode; - align?: string; - link?: string; - hover?: boolean; - hoverSize?: number; -}>) { +}: Readonly) { const backup_image = '/static/img/blank_image.png'; const inner = useMemo(() => { diff --git a/src/frontend/src/components/plugins/PluginContext.tsx b/src/frontend/src/components/plugins/PluginContext.tsx index 0fbb0b7763..a39de16bb6 100644 --- a/src/frontend/src/components/plugins/PluginContext.tsx +++ b/src/frontend/src/components/plugins/PluginContext.tsx @@ -48,7 +48,9 @@ import { import { useServerApiState } from '../../states/ServerApiState'; import { InvenTreeTableInternal } from '../../tables/InvenTreeTable'; import { EditApiForm } from '../forms/ApiForm'; +import { Thumbnail } from '../images/Thumbnail'; import { RenderInstance, RenderRemoteInstance } from '../render/Instance'; +import { RenderInlineModel } from '../render/Instance'; export const useInvenTreeContext = () => { const [locale, host] = useLocalState(useShallow((s) => [s.language, s.host])); @@ -82,6 +84,8 @@ export const useInvenTreeContext = () => { useInstance: useInstance, renderInstance: RenderInstance, renderRemoteInstance: RenderRemoteInstance, + renderInlineModel: RenderInlineModel, + thumbnail: Thumbnail, theme: theme, colorScheme: colorScheme, importer: { diff --git a/src/frontend/src/components/render/Instance.tsx b/src/frontend/src/components/render/Instance.tsx index e81803aaa5..dff59e022c 100644 --- a/src/frontend/src/components/render/Instance.tsx +++ b/src/frontend/src/components/render/Instance.tsx @@ -15,14 +15,15 @@ import { type ReactNode, useCallback } from 'react'; import { ModelInformationDict } from '@lib/enums/ModelInformation'; import { ModelType } from '@lib/enums/ModelType'; import { apiUrl } from '@lib/functions/Api'; -import { getBaseUrl, navigateToLink } from '@lib/functions/Navigation'; import type { ModelRendererDict, RemoteInstanceProps, + RenderInlineModelProps, RenderInstanceProps } 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 { Thumbnail } from '../images/Thumbnail'; import { RenderBuildItem, RenderBuildLine, RenderBuildOrder } from './Build'; @@ -172,20 +173,8 @@ export function RenderInlineModel({ navigate, showSecondary = true, tooltip -}: Readonly<{ - primary: ReactNode; - secondary?: ReactNode; - showSecondary?: boolean; - prefix?: ReactNode; - suffix?: ReactNode; - image?: string; - labels?: string[]; - url?: string; - navigate?: any; - tooltip?: string; -}>): ReactNode { +}: Readonly): ReactNode { // TODO: Handle labels - const onClick = useCallback( (event: any) => { if (url && navigate) {