added basic plugin support

This commit is contained in:
vabene1111
2025-07-17 15:34:51 +02:00
parent 01c4974507
commit 5fcfe09bb6
6 changed files with 68 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
import {createApp} from "vue";
import {createRouter, createWebHashHistory, createWebHistory} from 'vue-router'
import {createRouter, createWebHistory} from 'vue-router'
import {createPinia} from 'pinia'
// @ts-ignore
import App from './Tandoor.vue'
@@ -12,8 +12,9 @@ import { createRulesPlugin } from 'vuetify/labs/rules'
import {setupI18n} from "@/i18n";
import MealPlanPage from "@/pages/MealPlanPage.vue";
import {TandoorPlugin} from "@/types/Plugins.ts";
const routes = [
let routes = [
{path: '/', component: () => import("@/pages/StartPage.vue"), name: 'StartPage'},
{path: '/search', redirect: {name: 'StartPage'}},
{path: '/test', component: () => import("@/pages/TestPage.vue"), name: 'view_test'},
@@ -55,6 +56,13 @@ const routes = [
{path: '/space-setup', component: () => import("@/pages/SpaceSetupPage.vue"), name: 'SpaceSetupPage'},
]
const pluginModules = import.meta.glob('@/plugins/*/plugin.ts', { eager: true })
const tandoorPlugins = [] as TandoorPlugin[]
Object.values(pluginModules).forEach(module => {
tandoorPlugins.push(module.plugin)
routes = routes.concat(module.plugin.routes)
})
const router = createRouter({
history: createWebHistory(),
routes,

View File

@@ -28,7 +28,7 @@ const props = defineProps({
closeAfterDelete: {default: true},
})
const editorComponent = shallowRef(defineAsyncComponent(() => import(`@/components/model_editors/${getGenericModelFromString(props.model, t).model.name}Editor.vue`)))
const editorComponent = shallowRef(getGenericModelFromString(props.model, t).model.editorComponent)
const dialog = defineModel<Boolean|undefined>({default: undefined})
const dialogActivator = (dialog.value !== undefined) ? undefined : props.activator
@@ -40,7 +40,7 @@ const editingObjChangedState = ref(false)
* because of this watch prop changes and update manually if prop is changed
*/
watch(() => props.model, () => {
editorComponent.value = defineAsyncComponent(() => import(`@/components/model_editors/${getGenericModelFromString(props.model, t).model.name}Editor.vue`))
editorComponent.value = getGenericModelFromString(props.model, t).model.editorComponent
})
/**

View File

@@ -32,7 +32,7 @@ const props = defineProps({
id: {type: String, required: false, default: undefined},
})
const editorComponent = shallowRef(defineAsyncComponent(() => import(`@/components/model_editors/${getGenericModelFromString(props.model, t).model.name}Editor.vue`)))
const editorComponent = shallowRef(getGenericModelFromString(props.model, t).model.editorComponent)
const router = useRouter()

View File

@@ -1,8 +0,0 @@
import {DateTime} from "luxon";
export default {
install: (app: any) => {
// inject a globally available luxon DateTime
app.config.globalProperties.$luxon = DateTime
}
}

View File

@@ -18,6 +18,7 @@ import {
import {VDataTable} from "vuetify/components";
import {getNestedProperty} from "@/utils/utils";
import {useUserPreferenceStore} from "@/stores/UserPreferenceStore";
import {defineAsyncComponent, shallowRef} from "vue";
type VDataTableProps = InstanceType<typeof VDataTable>['$props']
@@ -40,7 +41,7 @@ export function getGenericModelFromString(modelName: EditorSupportedModels, t: a
* register a given model instance in the supported models list
* @param model model to register
*/
function registerModel(model: Model) {
export function registerModel(model: Model) {
SUPPORTED_MODELS.set(model.name.toLowerCase(), model)
}
@@ -90,6 +91,8 @@ export type Model = {
icon: string,
toStringKeys: Array<string>,
editorComponent?: any,
itemValue: string | undefined,
itemLabel: string | undefined,
@@ -184,6 +187,8 @@ export const TFood = {
localizationKeyDescription: 'FoodHelp',
icon: 'fa-solid fa-carrot',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/FoodEditor.vue`)),
isPaginated: true,
isMerge: true,
mergeAutomation: 'FOOD_ALIAS',
@@ -204,6 +209,8 @@ export const TUnit = {
localizationKeyDescription: 'UnitHelp',
icon: 'fa-solid fa-scale-balanced',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/UnitEditor.vue`)),
isPaginated: true,
isMerge: true,
mergeAutomation: 'UNIT_ALIAS',
@@ -223,6 +230,8 @@ export const TKeyword = {
localizationKeyDescription: 'KeywordHelp',
icon: 'fa-solid fa-tags',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/KeywordEditor.vue`)),
isPaginated: true,
isMerge: true,
mergeAutomation: 'KEYWORD_ALIAS',
@@ -241,6 +250,8 @@ export const TRecipe = {
localizationKeyDescription: 'RecipeHelp',
icon: 'fa-solid fa-book',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/RecipeEditor.vue`)),
isPaginated: true,
toStringKeys: ['name'],
@@ -295,6 +306,8 @@ export const TMealType = {
localizationKeyDescription: 'MealTypeHelp',
icon: 'fa-solid fa-utensils',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/MealTypeEditor.vue`)),
isPaginated: true,
toStringKeys: ['name'],
@@ -311,6 +324,8 @@ export const TMealPlan = {
localizationKeyDescription: 'MealPlanHelp',
icon: 'fa-solid fa-calendar-days',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/MealPlanEditor.vue`)),
isPaginated: true,
toStringKeys: ['title', 'recipe.name'],
@@ -330,6 +345,8 @@ export const TRecipeBook = {
localizationKeyDescription: 'RecipeBookHelp',
icon: 'fa-solid fa-book-bookmark',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/RecipeBookEditor.vue`)),
isPaginated: true,
toStringKeys: ['name'],
@@ -367,6 +384,8 @@ export const TCustomFilter = {
localizationKeyDescription: 'SavedSearchHelp',
icon: 'fa-solid fa-filter',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/CustomFilterEditor.vue`)),
isPaginated: true,
toStringKeys: ['name'],
@@ -405,6 +424,8 @@ export const TSupermarket = {
localizationKeyDescription: 'SupermarketHelp',
icon: 'fa-solid fa-store',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/SupermarketEditor.vue`)),
isPaginated: true,
toStringKeys: ['name'],
@@ -421,6 +442,8 @@ export const TSupermarketCategory = {
localizationKeyDescription: 'SupermarketCategoryHelp',
icon: 'fa-solid fa-boxes-stacked',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/SupermarketCategoryEditor.vue`)),
isPaginated: true,
isMerge: true,
toStringKeys: ['name'],
@@ -438,6 +461,8 @@ export const TShoppingListEntry = {
localizationKeyDescription: 'ShoppingListEntryHelp',
icon: 'fa-solid fa-list-check',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/ShoppingListEntryEditor.vue`)),
disableListView: true,
isPaginated: true,
toStringKeys: ['amount', 'unit.name', 'food.name'],
@@ -457,6 +482,8 @@ export const TPropertyType = {
localizationKeyDescription: 'PropertyTypeHelp',
icon: 'fa-solid fa-database',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/PropertyTypeEditor.vue`)),
isPaginated: true,
toStringKeys: ['name'],
@@ -473,6 +500,8 @@ export const TProperty = {
localizationKeyDescription: 'PropertyHelp',
icon: 'fa-solid fa-database',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/PropertyEditor.vue`)),
disableListView: true,
isPaginated: true,
toStringKeys: ['propertyAmount', 'propertyType.name'],
@@ -491,6 +520,8 @@ export const TUnitConversion = {
localizationKeyDescription: 'UnitConversionHelp',
icon: 'fa-solid fa-exchange-alt',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/UnitConversionEditor.vue`)),
isPaginated: true,
toStringKeys: ['food.name', 'baseUnit.name', 'convertedUnit.name'],
@@ -511,6 +542,8 @@ export const TUserFile = {
localizationKeyDescription: 'UserFileHelp',
icon: 'fa-solid fa-file',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/UserFileEditor.vue`)),
isPaginated: true,
toStringKeys: ['name'],
@@ -527,6 +560,8 @@ export const TAutomation = {
localizationKeyDescription: 'AutomationHelp',
icon: 'fa-solid fa-robot',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/AutomationEditor.vue`)),
isPaginated: true,
toStringKeys: ['name'],
@@ -584,6 +619,8 @@ export const TAccessToken = {
localizationKeyDescription: 'AccessTokenHelp',
icon: 'fa-solid fa-key',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/AccessTokenEditor.vue`)),
disableListView: true,
isPaginated: true,
toStringKeys: ['token'],
@@ -602,6 +639,8 @@ export const TUserSpace = {
localizationKeyDescription: 'SpaceMembersHelp',
icon: 'fa-solid fa-users',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/UserSpaceEditor.vue`)),
disableListView: true,
isPaginated: true,
toStringKeys: ['user.displayName'],
@@ -621,6 +660,8 @@ export const TInviteLink = {
localizationKeyDescription: 'InviteLinkHelp',
icon: 'fa-solid fa-link',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/InviteLinkEditor.vue`)),
disableListView: true,
isPaginated: true,
toStringKeys: ['email', 'role'],
@@ -640,6 +681,8 @@ export const TStorage = {
localizationKeyDescription: 'StorageHelp',
icon: 'fa-solid fa-cloud',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/StorageEditor.vue`)),
disableListView: false,
toStringKeys: ['name'],
isPaginated: true,
@@ -657,6 +700,8 @@ export const TSync = {
localizationKeyDescription: 'SyncedPathHelp',
icon: 'fa-solid fa-folder-plus',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/SyncEditor.vue`)),
disableListView: false,
toStringKeys: ['path'],
isPaginated: true,
@@ -722,6 +767,8 @@ export const TConnectorConfig = {
localizationKeyDescription: 'ConnectorConfigHelp',
icon: 'fa-solid fa-arrows-turn-to-dots',
editorComponent: defineAsyncComponent(() => import(`@/components/model_editors/ConnectorConfigEditor.vue`)),
disableListView: false,
toStringKeys: ['name'],
isPaginated: true,

View File

@@ -0,0 +1,7 @@
import {RouteRecordRaw} from "vue-router";
import {Model, registerModel} from "@/types/Models.ts";
export type TandoorPlugin = {
name: string,
routes: RouteRecordRaw[]
}