diff --git a/frontend/src/js/core/templating.ts b/frontend/src/js/core/templating.ts index 0f2edf1..db5ebc5 100644 --- a/frontend/src/js/core/templating.ts +++ b/frontend/src/js/core/templating.ts @@ -2,6 +2,7 @@ import { cloneDeep } from 'lodash-es'; import hash from 'object-hash'; +import entry from 'js/types/entry'; import Settings from 'js/types/settings'; // @ts-ignore import TemplatingWorker from 'js/workers/templating-worker?worker'; @@ -226,3 +227,22 @@ export const render = ( */ export const containsAi = (template: string) => (template.includes('ai') && template.includes('endai') && template.includes('user')) || template.includes('aiPrompt('); + +/** + * Add entry meta to the state it object. + * @param entry Entry object. + * @param it State it object. + * @returns State it object with entry meta. + */ +export const addEntryMeta = (entry: entry | null, it: any) => { + if (!it) { + return it; + } + return { + ...it, + snd: { + id: entry?.id ?? 'skeleton-entry-id', + name: entry?.name ?? 'Skeleton Entry Name', + }, + }; +}; diff --git a/frontend/src/js/ui/components/editor/template.ts b/frontend/src/js/ui/components/editor/template.ts index 22411ee..3aecd23 100644 --- a/frontend/src/js/ui/components/editor/template.ts +++ b/frontend/src/js/ui/components/editor/template.ts @@ -8,7 +8,7 @@ import { fillConfigValues } from 'src/js/types/config'; import * as API from 'js/core/api'; import { createNunjucksCompletionProvider } from 'js/core/monaco/completion-nunjucks'; import { settings } from 'js/core/store'; -import { render } from 'js/core/templating'; +import { addEntryMeta, render } from 'js/core/templating'; import Button from 'js/ui/spectre/button'; import Label from 'js/ui/spectre/label'; @@ -31,6 +31,7 @@ import { dialogWarning, error } from 'js/ui/toast'; type TemplateEditorProps = { template: Template; onChange: (updated: Template) => void; + onJSONError?: (error: any | null) => void; editMode?: boolean; }; @@ -41,6 +42,7 @@ type TemplateEditorState = { entriesKey: string; entries: Entry[]; listPreview: string; + jsonSkeleton: string; errorsPrint: PrintPreviewError[]; errorsList: PrintPreviewError[]; }; @@ -53,6 +55,7 @@ export default (): m.Component => { entriesKey: '', entries: [], listPreview: '', + jsonSkeleton: '{}', errorsPrint: [], errorsList: [], }; @@ -88,7 +91,7 @@ export default (): m.Component => { render( val, { - it: attrs.template.skeletonData, + it: addEntryMeta(null, attrs.template.skeletonData), sources: attrs.template.dataSources, config: state.config, settings: settings.value, @@ -171,6 +174,7 @@ export default (): m.Component => { return { oninit({ attrs }) { renderListPreview(attrs.template.listTemplate, attrs); + state.jsonSkeleton = JSON.stringify(attrs.template.skeletonData, null, 2); fetchEntries(attrs); }, onupdate({ attrs }) { @@ -318,14 +322,16 @@ export default (): m.Component => { m(Monaco, { key: 'data-skeleton-monaco', language: 'json', - value: JSON.stringify(attrs.template.skeletonData, null, 2), + value: state.jsonSkeleton, className: '.flex-grow-1', wordWrap: 'on', onChange: (value) => { + state.jsonSkeleton = value; try { attrs.onChange({ ...attrs.template, skeletonData: JSON.parse(value) }); + if (attrs.onJSONError) attrs.onJSONError(null); } catch (e) { - // Monaco will show the error + if (attrs.onJSONError) attrs.onJSONError(e); } }, }), @@ -346,7 +352,7 @@ export default (): m.Component => { className: '.flex-grow-1', errors: state.errorsPrint, completion: createNunjucksCompletionProvider({ - it: attrs.template.skeletonData, + it: addEntryMeta(null, attrs.template.skeletonData), images: attrs.template.images, settings: settings.value, sources: attrs.template.dataSources, diff --git a/frontend/src/js/ui/components/print-preview-template.ts b/frontend/src/js/ui/components/print-preview-template.ts index c0f416c..39b0e99 100644 --- a/frontend/src/js/ui/components/print-preview-template.ts +++ b/frontend/src/js/ui/components/print-preview-template.ts @@ -1,10 +1,11 @@ import m from 'mithril'; import { cloneDeep, debounce, isEqual } from 'lodash-es'; +import Entry from 'js/types/entry'; import Generator from 'js/types/generator'; import Template from 'js/types/template'; import store, { settings } from 'js/core/store'; -import { containsAi, render } from 'js/core/templating'; +import { addEntryMeta, containsAi, render } from 'js/core/templating'; import Button from 'js/ui/spectre/button'; @@ -24,6 +25,7 @@ export type PrintPreviewTemplateProps = { generator?: Generator; useListTemplate?: boolean; it?: any; + entry?: Entry; config?: any; hideAiNotice?: boolean; width?: number; @@ -54,7 +56,8 @@ export default (): m.Component => { isEqual(lastProps.template, attrs.template) && isEqual(lastProps.it, attrs.it) && isEqual(lastProps.generator, attrs.generator) && - isEqual(lastProps.config, attrs.config) + isEqual(lastProps.config, attrs.config) && + isEqual(lastProps.entry, attrs.entry) ) { return; } @@ -65,7 +68,7 @@ export default (): m.Component => { if (attrs.template === null && attrs.generator === null) return; const printTemplate = getTemplate(attrs); - const it = attrs.it ?? attrs.template?.skeletonData; + const it = addEntryMeta(attrs.entry ?? null, attrs.it) ?? addEntryMeta(null, attrs.template?.skeletonData); render(printTemplate ?? '', { it: it ?? {}, diff --git a/frontend/src/js/ui/components/view-layout/sidebar-print-page.ts b/frontend/src/js/ui/components/view-layout/sidebar-print-page.ts index 07aa7e0..5bd949a 100644 --- a/frontend/src/js/ui/components/view-layout/sidebar-print-page.ts +++ b/frontend/src/js/ui/components/view-layout/sidebar-print-page.ts @@ -1,5 +1,6 @@ import m from 'mithril'; +import Entry from 'js/types/entry'; import Generator from 'js/types/generator'; import Template from 'js/types/template'; @@ -17,6 +18,7 @@ type SidebarPrintProps = { template?: Template; generator?: Generator; it?: any; + entry?: Entry; config?: any; tabs: TabDefinition[]; content: Record m.Component>; @@ -55,6 +57,7 @@ export default (): m.Component => { template: vnode.attrs.template, generator: vnode.attrs.generator, it: vnode.attrs.it, + entry: vnode.attrs.entry, config: vnode.attrs.config, width: 380, className: '.bg-black-05.ph1.ba.b--black-10', diff --git a/frontend/src/js/ui/views/extern-print/template.ts b/frontend/src/js/ui/views/extern-print/template.ts index 3f96258..e599405 100644 --- a/frontend/src/js/ui/views/extern-print/template.ts +++ b/frontend/src/js/ui/views/extern-print/template.ts @@ -3,7 +3,7 @@ import m from 'mithril'; import Template from 'js/types/template'; import * as API from 'js/core/api'; import { settings } from 'js/core/store'; -import { render } from 'js/core/templating'; +import { addEntryMeta, render } from 'js/core/templating'; type ExternPrintProps = { id: string; @@ -34,7 +34,7 @@ export default (): m.Component => { API.exec