2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-05-01 13:06:45 +00:00

Template Editor Improvements (#9434)

* add unmount hook and context to report editor ui feature

* Fix tests

* Update pui_printing.spec.ts

* Update pui_printing.spec.ts

* try fix tests

* retrigger ci

* remove debug messages
This commit is contained in:
Lukas 2025-04-02 00:01:12 +02:00 committed by GitHub
parent 6a964a4e2b
commit ba703cf58a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 30 additions and 22 deletions

View File

@ -175,7 +175,7 @@ class SampleUserInterfacePlugin(SettingsMixin, UserInterfaceMixin, InvenTreePlug
{
'key': 'sample-template-editor',
'title': 'Sample Template Editor',
'icon': 'keywords',
'icon': 'ti:tags:outline',
'source': self.plugin_static_file(
'sample_template.js:getTemplateEditor'
),
@ -190,7 +190,7 @@ class SampleUserInterfacePlugin(SettingsMixin, UserInterfaceMixin, InvenTreePlug
{
'key': 'sample-template-preview',
'title': 'Sample Template Preview',
'icon': 'category',
'icon': 'ti:category:outline',
'source': self.plugin_static_file(
'sample_preview.js:getTemplatePreview'
),

View File

@ -4,7 +4,7 @@ export function getTemplatePreview({ featureContext, pluginContext }) {
featureContext.registerHandlers({
updatePreview: (...args) => {
console.log("updatePreview", args);
console.log("updatePreview", args[0]);
}
});

View File

@ -7,6 +7,6 @@ import { CodeEditorComponent } from './CodeEditor';
export const CodeEditor: Editor = {
key: 'code',
name: t`Code`,
icon: IconCode,
icon: <IconCode size={18} />,
component: CodeEditorComponent
};

View File

@ -7,6 +7,6 @@ import { PdfPreviewComponent } from './PdfPreview';
export const PdfPreview: PreviewArea = {
key: 'pdf-preview',
name: t`PDF Preview`,
icon: IconFileTypePdf,
icon: <IconFileTypePdf size={18} />,
component: PdfPreviewComponent
};

View File

@ -26,7 +26,6 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { api } from '../../../App';
import { ModelType } from '../../../enums/ModelType';
import type { TablerIconType } from '../../../functions/icons';
import { apiUrl } from '../../../states/ApiState';
import type { TemplateI } from '../../../tables/settings/TemplateTable';
import { Boundary } from '../../Boundary';
@ -50,7 +49,7 @@ export type EditorComponent = React.ForwardRefExoticComponent<
export type Editor = {
key: string;
name: string;
icon?: TablerIconType;
icon?: React.ReactNode;
component: EditorComponent;
};
@ -72,7 +71,7 @@ export type PreviewAreaComponent = React.ForwardRefExoticComponent<
export type PreviewArea = {
key: string;
name: string;
icon: TablerIconType;
icon: React.ReactNode;
component: PreviewAreaComponent;
};
@ -272,7 +271,7 @@ export function TemplateEditor(props: Readonly<TemplateEditorProps>) {
<Tabs.Tab
key={Editor.key}
value={Editor.key}
leftSection={Editor.icon && <Editor.icon size='0.8rem' />}
leftSection={Editor.icon}
>
{Editor.name}
</Tabs.Tab>
@ -336,9 +335,7 @@ export function TemplateEditor(props: Readonly<TemplateEditorProps>) {
<Tabs.Tab
key={PreviewArea.key}
value={PreviewArea.key}
leftSection={
PreviewArea.icon && <PreviewArea.icon size='0.8rem' />
}
leftSection={PreviewArea.icon}
>
{PreviewArea.name}
</Tabs.Tab>

View File

@ -82,9 +82,10 @@ export const getPluginTemplateEditor = (
}));
useEffect(() => {
let unmountHandler: (() => void) | undefined;
(async () => {
try {
func({
unmountHandler = await func({
ref: elRef.current!,
registerHandlers: ({ getCode, setCode }) => {
setCodeRef.current = setCode;
@ -101,6 +102,12 @@ export const getPluginTemplateEditor = (
console.error(error);
}
})();
return () => {
if (typeof unmountHandler === 'function') {
unmountHandler();
}
};
}, []);
return (

View File

@ -14,9 +14,13 @@ export type BaseUIFeature = {
featureReturnType: any;
};
export type PluginUIGetFeatureType<T extends BaseUIFeature> = (params: {
export type PluginUIGetFeatureType<
T extends BaseUIFeature,
ServerContext extends Record<string, unknown>
> = (params: {
featureContext: T['featureContext'];
inventreeContext: InvenTreeContext;
serverContext: ServerContext;
}) => T['featureReturnType'];
export type PluginUIFuncWithoutInvenTreeContextType<T extends BaseUIFeature> = (
@ -25,9 +29,8 @@ export type PluginUIFuncWithoutInvenTreeContextType<T extends BaseUIFeature> = (
export type PluginUIFeatureAPIResponse<T extends BaseUIFeature> = {
feature_type: T['featureType'];
options: T['responseOptions'];
source: string;
};
} & T['responseOptions'];
// #region Types
export type TemplateEditorUIFeature = {
@ -45,7 +48,7 @@ export type TemplateEditorUIFeature = {
}) => void;
template: TemplateI;
};
featureReturnType: undefined;
featureReturnType: (() => void) | undefined;
};
export type TemplatePreviewUIFeature = {

View File

@ -84,7 +84,8 @@ export function usePluginUIFeature<UIFeatureT extends BaseUIFeature>({
return func({
featureContext,
inventreeContext
inventreeContext,
serverContext: feature.context
});
}) as PluginUIFuncWithoutInvenTreeContextType<UIFeatureT>
};

View File

@ -16,6 +16,7 @@ import type {
PreviewArea
} from '../../components/editors/TemplateEditor/TemplateEditor';
import type { ApiFormFieldSet } from '../../components/forms/fields/ApiFormField';
import { ApiIcon } from '../../components/items/ApiIcon';
import { AttachmentLink } from '../../components/items/AttachmentLink';
import { DetailDrawer } from '../../components/nav/DetailDrawer';
import {
@ -29,7 +30,6 @@ import type {
import type { ApiEndpoints } from '../../enums/ApiEndpoints';
import type { ModelType } from '../../enums/ModelType';
import { identifierString } from '../../functions/conversion';
import { GetIcon } from '../../functions/icons';
import { notYetImplemented } from '../../functions/notifications';
import { useFilters } from '../../hooks/UseFilter';
import {
@ -115,7 +115,7 @@ export function TemplateDrawer({
`${editor.options.plugin_name}-${editor.options.key}`
),
name: editor.options.title,
icon: GetIcon(editor.options.icon || 'plugin'),
icon: <ApiIcon name={editor.options.icon || 'plugin'} size={18} />,
component: getPluginTemplateEditor(editor.func, template)
} as Editor;
}) || [])
@ -143,7 +143,7 @@ export function TemplateDrawer({
({
key: preview.options.key,
name: preview.options.title,
icon: GetIcon(preview.options.icon || 'plugin'),
icon: <ApiIcon name={preview.options.icon || 'plugin'} size={18} />,
component: getPluginTemplatePreview(preview.func, template)
}) as PreviewArea
) || [])

View File

@ -138,7 +138,7 @@ test('Report Editing', async ({ browser, request }) => {
.click();
const msg = (await consoleLogPromise).args();
expect(await msg[0].jsonValue()).toBe('updatePreview');
expect((await msg[1].jsonValue())[0]).toBe(newTextareaValue);
expect(await msg[1].jsonValue()).toBe(newTextareaValue);
// deactivate the sample plugin again after the test
await setPluginState({