Files
directus/app/src/utils/render-string-template.ts
Nicola Krumschmidt 7bf90efa62 Add support for a package extension bundle type (#15672)
* Add bundle type to constants and types

* Add support for API bundle extensions

* Rename generateExtensionsEntry to generateExtensionsEntrypoint

* Add support for App bundle extensions

* Refactor App extension registration

* Replace extensions inject with useExtensions()

* Replace getInterfaces() with useExtensions()

* Replace getDisplays() with useExtensions()

* Replace getLayouts() with useExtensions()

* Replace getModules() with useExtensions()

* Replace getPanels() with useExtensions()

* Replace getOperations() with useExtensions()

* Add useExtension() composable

* Replace useExtensions() with useExtension() where applicable

* Remove interface getters

* Remove display getters

* Remove layout getters

* Remove module getter

* Remove panel getters

* Remove operation getters

* Rename extension register.ts files to index.ts

* Perform module pre register check in parallel

* Remove Refs from AppExtensionConfigs type

* Remove old extension shims

* Ensure registration of modules is awaited when hydrating

* Add support for scaffolding package extensions

* Add support for building bundle extensions

* Add JsonValue type

* Use json for complex command line flags

* Load internal extensions if custom ones are not available

* Fix extension manifest validation for pack extensions

* Fix tests in shared

* Add SplitEntrypoint type

* Move command specific utils to helpers

* Add SDK version getter

* Move extension dev deps generation to helpers

* Move template path to getter util

* Move template copying to a helper

* Only rename copied template files

* Add directus-extension add command

* Convert provided extension source path to url

* Replace deprecated import.meta.globEager

* Mock URL.createObjectURL to make App unit tests pass

* Update rollup-plugin-typescript2

* indentation

* sort vite glob imported modules

* fix unintentional wrong commit

* Simplify app extension import logic

* reinstall @rollup/plugin-virtual

* add test for getInterfaces() expected sort order

Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com>
Co-authored-by: Azri Kahar <42867097+azrikahar@users.noreply.github.com>
2022-11-16 11:28:52 -05:00

104 lines
2.8 KiB
TypeScript

import { useAliasFields } from '@/composables/use-alias-fields';
import { useFieldsStore } from '@/stores/fields';
import { Field } from '@directus/shared/types';
import { getFieldsFromTemplate } from '@directus/shared/utils';
import { render, renderFn } from 'micromustache';
import { computed, ComputedRef, Ref, ref, unref } from 'vue';
import { get, set } from 'lodash';
import { useExtension } from '@/composables/use-extension';
type StringTemplate = {
fieldsInTemplate: ComputedRef<string[]>;
displayValue: ComputedRef<string | false>;
};
function resolve(path: string, scope: any) {
const value = get(scope, path);
return typeof value === 'object' ? JSON.stringify(value) : value;
}
export function renderStringTemplate(
template: Ref<string | null> | string,
item: Record<string, any> | undefined | null | Ref<Record<string, any> | undefined | null>
): StringTemplate {
const values = unref(item);
const templateString = unref(template);
const fieldsInTemplate = computed(() => getFieldsFromTemplate(templateString));
const displayValue = computed(() => {
if (!values || !templateString || !fieldsInTemplate.value) return false;
try {
return renderFn(templateString, resolve, values, { propsExist: true });
} catch {
return false;
}
});
return { fieldsInTemplate, displayValue };
}
export function renderPlainStringTemplate(template: string, item?: Record<string, any> | null): string | null {
const fieldsInTemplate = getFieldsFromTemplate(template);
if (!item || !template || !fieldsInTemplate) return null;
try {
return render(template, item, { propsExist: true });
} catch {
return null;
}
}
export function renderDisplayStringTemplate(
collection: string,
template: string,
item: Record<string, any>
): string | null {
const fieldsStore = useFieldsStore();
const fields = getFieldsFromTemplate(template);
const fieldsUsed: Record<string, Field | null> = {};
for (const key of fields) {
set(fieldsUsed, key, fieldsStore.getField(collection, key));
}
const { aliasFields } = useAliasFields(ref(fields));
const parsedItem: Record<string, any> = {};
for (const key of fields) {
const value =
!aliasFields.value?.[key] || get(item, key) !== undefined
? get(item, key)
: get(item, aliasFields.value[key].fullAlias);
const display = useExtension(
'display',
computed(() => fieldsUsed[key]?.meta?.display ?? null)
);
if (value !== undefined && value !== null) {
set(
parsedItem,
key,
display.value?.handler
? display.value.handler(value, fieldsUsed[key]?.meta?.display_options ?? {}, {
interfaceOptions: fieldsUsed[key]?.meta?.options ?? {},
field: fieldsUsed[key] ?? undefined,
collection: collection,
})
: value
);
} else {
set(parsedItem, key, value);
}
}
return renderPlainStringTemplate(template, parsedItem);
}