diff --git a/client/src/api/client.ts b/client/src/api/client.ts index 20ee2b9cf..aa96c6b9f 100644 --- a/client/src/api/client.ts +++ b/client/src/api/client.ts @@ -460,6 +460,7 @@ export const adminApi = { updateOidc: (data: Record) => apiClient.put('/admin/oidc', data).then(r => r.data), addons: () => apiClient.get('/admin/addons').then(r => r.data), updateAddon: (id: number | string, data: Record) => apiClient.put(`/admin/addons/${id}`, data).then(r => r.data), + plugins: () => apiClient.get('/admin/plugins').then(r => r.data), // Local LLM (Ollama) management for the AI-parsing addon. llmLocalModels: (baseUrl: string): Promise<{ models: { name: string; size: number }[] }> => apiClient.get('/admin/llm/local/models', { params: { baseUrl } }).then(r => r.data), diff --git a/client/src/components/Admin/AdminPluginsPanel.tsx b/client/src/components/Admin/AdminPluginsPanel.tsx new file mode 100644 index 000000000..b80519509 --- /dev/null +++ b/client/src/components/Admin/AdminPluginsPanel.tsx @@ -0,0 +1,113 @@ +import { useEffect, useState } from 'react' +import { Blocks, AlertTriangle, PackageOpen } from 'lucide-react' +import { adminApi } from '../../api/client' +import { useTranslation } from '../../i18n' + +/** + * Admin → Plugins (#plugins), M0 read-only scaffold. Lists installed plugins + * from the registry table and shows whether the runtime is enabled + * (TREK_PLUGINS_ENABLED). Install, activation and the registry browser arrive in + * later milestones; this panel is intentionally inert. + */ + +interface PluginRow { + id: string + name: string + description: string | null + type: string + icon: string | null + version: string | null + status: string + reviewed_at: string | null + source_repo: string | null +} + +const STATUS_CLASS: Record = { + active: 'bg-emerald-500/15 text-emerald-600', + inactive: 'bg-surface-tertiary text-content-muted', + disabled: 'bg-amber-500/15 text-amber-600', + error: 'bg-rose-500/15 text-rose-600', + incompatible: 'bg-orange-500/15 text-orange-600', +} + +export default function AdminPluginsPanel() { + const { t } = useTranslation() + const [enabled, setEnabled] = useState(false) + const [plugins, setPlugins] = useState([]) + const [loading, setLoading] = useState(true) + const [error, setError] = useState(false) + + useEffect(() => { + let alive = true + adminApi.plugins() + .then((d: { enabled: boolean; plugins: PluginRow[] }) => { + if (!alive) return + setEnabled(!!d.enabled) + setPlugins(d.plugins || []) + }) + .catch(() => { if (alive) setError(true) }) + .finally(() => { if (alive) setLoading(false) }) + return () => { alive = false } + }, []) + + return ( +
+
+
+ +
+
+

{t('admin.plugins.title')}

+

{t('admin.plugins.subtitle')}

+
+
+ + {!enabled && !loading && !error && ( +
+ +
+

{t('admin.plugins.disabledTitle')}

+

{t('admin.plugins.disabledBody')}

+
+
+ )} + +
+ {loading ? ( +
{t('common.loading')}
+ ) : error ? ( +
{t('admin.plugins.loadError')}
+ ) : plugins.length === 0 ? ( +
+ +

{t('admin.plugins.empty')}

+
+ ) : ( +
+ {plugins.map(p => ( +
+
+ +
+
+
+ {p.name} + {p.version && v{p.version}} +
+ {p.description &&

{p.description}

} +
+ + {t(`admin.plugins.status.${p.status}` as never)} + +
+ ))} +
+ )} +
+ +
+

{t('admin.plugins.scaffoldNote')}

+
+
+ ) +} diff --git a/client/src/pages/AdminPage.tsx b/client/src/pages/AdminPage.tsx index 8719ad8b7..c7334ffb2 100644 --- a/client/src/pages/AdminPage.tsx +++ b/client/src/pages/AdminPage.tsx @@ -11,7 +11,8 @@ import AddonManager from '../components/Admin/AddonManager' import PackingTemplateManager from '../components/Admin/PackingTemplateManager' import AuditLogPanel from '../components/Admin/AuditLogPanel' import AdminMcpTokensPanel from '../components/Admin/AdminMcpTokensPanel' -import { Users, Map, Briefcase, Shield, FileText, SlidersHorizontal, UserCog, Puzzle, Settings as SettingsIcon, Bell, Database, ScrollText, KeyRound, GitBranch, Bug } from 'lucide-react' +import AdminPluginsPanel from '../components/Admin/AdminPluginsPanel' +import { Users, Map, Briefcase, Shield, FileText, SlidersHorizontal, UserCog, Puzzle, Blocks, Settings as SettingsIcon, Bell, Database, ScrollText, KeyRound, GitBranch, Bug } from 'lucide-react' import PageSidebar, { type PageSidebarTab } from '../components/Layout/PageSidebar' import { useAdmin } from './admin/useAdmin' import AdminUpdateBanner from './admin/AdminUpdateBanner' @@ -45,6 +46,7 @@ export default function AdminPage(): React.ReactElement { { id: 'config', label: t('admin.tabs.config'), icon: SlidersHorizontal, group: gConfig }, { id: 'settings', label: t('admin.tabs.settings'), icon: SettingsIcon, group: gConfig }, { id: 'addons', label: t('admin.tabs.addons'), icon: Puzzle, group: gConfig }, + { id: 'plugins', label: t('admin.tabs.plugins'), icon: Blocks, group: gConfig }, { id: 'notifications', label: t('admin.tabs.notifications'), icon: Bell, group: gIntegration }, ...(mcpEnabled ? [{ id: 'mcp-tokens', label: t('admin.tabs.mcpTokens'), icon: KeyRound, group: gIntegration }] : []), { id: 'github', label: t('admin.tabs.github'), icon: GitBranch, group: gIntegration }, @@ -157,6 +159,8 @@ export default function AdminPage(): React.ReactElement { {activeTab === 'mcp-tokens' && } + {activeTab === 'plugins' && } + {activeTab === 'github' && } {activeTab === 'defaults' && } diff --git a/server/src/config.ts b/server/src/config.ts index 8c7ab68f1..54d43f0f8 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -174,3 +174,14 @@ export const SESSION_DURATION_REMEMBER = export const SESSION_DURATION_REMEMBER_MS = parsedRememberMs ?? parseDurationMs(DEFAULT_SESSION_DURATION_REMEMBER)!; /** "Remember me" session length in seconds — passed to `jwt.sign({ expiresIn })`. */ export const SESSION_DURATION_REMEMBER_SECONDS = Math.floor(SESSION_DURATION_REMEMBER_MS / 1000); + +/** + * Plugin-system kill switch (#plugins). Off by default — a brand-new, high-risk + * surface an instance owner must deliberately opt into. When false, the plugin + * module serves its admin listing (so the tab isn't a dead end) but never spawns + * a plugin process and refuses install/activate. Read at call time so tests and + * runtime env changes take effect without re-import. + */ +export function pluginsEnabled(): boolean { + return (process.env.TREK_PLUGINS_ENABLED || '').trim().toLowerCase() === 'true'; +} diff --git a/server/src/db/migrations.ts b/server/src/db/migrations.ts index 2d6e7b30a..a098e97a7 100644 --- a/server/src/db/migrations.ts +++ b/server/src/db/migrations.ts @@ -3289,6 +3289,69 @@ function runMigrations(db: Database.Database): void { () => { try { db.exec('ALTER TABLE invite_tokens ADD COLUMN trip_id INTEGER REFERENCES trips(id) ON DELETE SET NULL'); } catch (err) { console.warn('[migrations] Non-fatal migration step failed:', err); } }, + // Migration 155: plugin system scaffold (#plugins). A plugin is a row here; + // its code lives on the /plugins volume and (once the runtime lands) runs in + // an isolated child process. This migration only lays down the registry + // tables — nothing executes yet. Own data lives in a per-plugin sqlite file + // under /plugins-data, never in these tables. + () => { + db.exec(` + CREATE TABLE IF NOT EXISTS plugins ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + description TEXT, + type TEXT NOT NULL DEFAULT 'integration', + icon TEXT DEFAULT 'Blocks', + version TEXT, + api_version INTEGER DEFAULT 1, + min_trek_version TEXT, + permissions TEXT DEFAULT '[]', + granted_permissions TEXT DEFAULT '[]', + status TEXT NOT NULL DEFAULT 'inactive', + config TEXT DEFAULT '{}', + source_repo TEXT, + source_commit TEXT, + sha256 TEXT, + crash_count INTEGER NOT NULL DEFAULT 0, + last_error TEXT, + reviewed_at TEXT, + sort_order INTEGER NOT NULL DEFAULT 0, + installed_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP + ); + CREATE TABLE IF NOT EXISTS plugin_meta_migrations ( + plugin_id TEXT NOT NULL, + migration_id TEXT NOT NULL, + applied_at DATETIME DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (plugin_id, migration_id) + ); + CREATE TABLE IF NOT EXISTS plugin_error_log ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + plugin_id TEXT NOT NULL, + ts DATETIME DEFAULT CURRENT_TIMESTAMP, + level TEXT NOT NULL DEFAULT 'error', + message TEXT, + stack TEXT + ); + CREATE INDEX IF NOT EXISTS idx_plugin_error_log_plugin ON plugin_error_log(plugin_id, ts); + CREATE TABLE IF NOT EXISTS plugin_settings_fields ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + plugin_id TEXT NOT NULL, + field_key TEXT NOT NULL, + label TEXT, + input_type TEXT NOT NULL DEFAULT 'text', + placeholder TEXT, + hint TEXT, + required INTEGER NOT NULL DEFAULT 0, + secret INTEGER NOT NULL DEFAULT 0, + scope TEXT NOT NULL DEFAULT 'instance', + options TEXT, + oauth_config TEXT, + sort_order INTEGER NOT NULL DEFAULT 0, + UNIQUE (plugin_id, field_key) + ); + `); + }, ]; if (currentVersion < migrations.length) { diff --git a/server/src/nest/app.module.ts b/server/src/nest/app.module.ts index d3f6a9d41..603aeb21e 100644 --- a/server/src/nest/app.module.ts +++ b/server/src/nest/app.module.ts @@ -41,6 +41,7 @@ import { OidcModule } from './oidc/oidc.module'; import { OauthModule } from './oauth/oauth.module'; import { AdminModule } from './admin/admin.module'; import { AddonsModule } from './addons/addons.module'; +import { PluginsModule } from './plugins/plugins.module'; import { TrekExceptionFilter } from './common/trek-exception.filter'; import { SpaFallbackFilter } from './platform/spa-fallback.filter'; import { IdempotencyInterceptor } from './common/idempotency.interceptor'; @@ -51,7 +52,7 @@ import { IdempotencyInterceptor } from './common/idempotency.interceptor'; * migrated. */ @Module({ - imports: [DatabaseModule, WeatherModule, HelpModule, AirportsModule, ConfigModule, SystemNoticesModule, MapsModule, CategoriesModule, TagsModule, NotificationsModule, AtlasModule, VacayModule, PackingModule, TodoModule, BudgetModule, ReservationsModule, DaysModule, AssignmentsModule, PlacesModule, TripsModule, CollabModule, FilesModule, PhotosModule, MemoriesModule, AirtrailModule, JourneyModule, CollectionsModule, ShareModule, TripInviteModule, TransitModule, FeedsModule, SettingsModule, BackupModule, AuthModule, OidcModule, OauthModule, AdminModule, AddonsModule, BookingImportModule], + imports: [DatabaseModule, WeatherModule, HelpModule, AirportsModule, ConfigModule, SystemNoticesModule, MapsModule, CategoriesModule, TagsModule, NotificationsModule, AtlasModule, VacayModule, PackingModule, TodoModule, BudgetModule, ReservationsModule, DaysModule, AssignmentsModule, PlacesModule, TripsModule, CollabModule, FilesModule, PhotosModule, MemoriesModule, AirtrailModule, JourneyModule, CollectionsModule, ShareModule, TripInviteModule, TransitModule, FeedsModule, SettingsModule, BackupModule, AuthModule, OidcModule, OauthModule, AdminModule, AddonsModule, PluginsModule, BookingImportModule], controllers: [HealthController], providers: [ HealthService, diff --git a/server/src/nest/plugins/plugins.controller.ts b/server/src/nest/plugins/plugins.controller.ts new file mode 100644 index 000000000..fdbc4ef8e --- /dev/null +++ b/server/src/nest/plugins/plugins.controller.ts @@ -0,0 +1,24 @@ +import { Controller, Get, UseGuards } from '@nestjs/common'; +import { PluginsService } from './plugins.service'; +import { JwtAuthGuard } from '../auth/jwt-auth.guard'; +import { AdminGuard } from '../auth/admin.guard'; + +/** + * /api/admin/plugins — admin-only plugin control surface (#plugins). + * + * M0 scaffold: read-only listing + the runtime-enabled flag. Install, activate, + * disable, uninstall and the registry browser are added in later milestones. + * Admin-gated like the rest of /api/admin. The proxy namespace /api/plugins/:id + * is reserved for the (future) runtime and is intentionally NOT part of this + * admin controller. + */ +@Controller('api/admin/plugins') +@UseGuards(JwtAuthGuard, AdminGuard) +export class PluginsController { + constructor(private readonly plugins: PluginsService) {} + + @Get() + list() { + return this.plugins.list(); + } +} diff --git a/server/src/nest/plugins/plugins.module.ts b/server/src/nest/plugins/plugins.module.ts new file mode 100644 index 000000000..462a21f05 --- /dev/null +++ b/server/src/nest/plugins/plugins.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common'; +import { PluginsController } from './plugins.controller'; +import { PluginsService } from './plugins.service'; + +/** + * Plugin system (#plugins). M0 registers only the read side; the isolated + * runtime supervisor, install pipeline and registry service are added in later + * milestones under this same module. + */ +@Module({ + controllers: [PluginsController], + providers: [PluginsService], +}) +export class PluginsModule {} diff --git a/server/src/nest/plugins/plugins.service.ts b/server/src/nest/plugins/plugins.service.ts new file mode 100644 index 000000000..1e88b9c3d --- /dev/null +++ b/server/src/nest/plugins/plugins.service.ts @@ -0,0 +1,36 @@ +import { Injectable } from '@nestjs/common'; +import { db } from '../../db/database'; +import { pluginsEnabled } from '../../config'; + +/** + * Read side of the plugin system (#plugins), M0 scaffold. Lists installed + * plugins from the `plugins` registry table and reports whether the runtime is + * enabled (TREK_PLUGINS_ENABLED). No execution here — the isolated runtime, + * install pipeline and registry fetch land in later milestones. + */ + +export interface PluginListItem { + id: string; + name: string; + description: string | null; + type: string; + icon: string | null; + version: string | null; + status: string; + reviewed_at: string | null; + source_repo: string | null; +} + +@Injectable() +export class PluginsService { + list(): { enabled: boolean; plugins: PluginListItem[] } { + const plugins = db + .prepare( + `SELECT id, name, description, type, icon, version, status, reviewed_at, source_repo + FROM plugins + ORDER BY sort_order, name`, + ) + .all() as PluginListItem[]; + return { enabled: pluginsEnabled(), plugins }; + } +} diff --git a/shared/src/i18n/ar/admin.ts b/shared/src/i18n/ar/admin.ts index b3522ddad..21eb874e5 100644 --- a/shared/src/i18n/ar/admin.ts +++ b/shared/src/i18n/ar/admin.ts @@ -177,6 +177,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'فشل حذف القالب', 'admin.packingTemplates.saveError': 'فشل الحفظ', 'admin.tabs.addons': 'الإضافات', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'الإضافات', 'admin.addons.subtitle': 'فعّل أو عطّل الميزات لتخصيص تجربة TREK.', 'admin.addons.catalog.packing.name': 'القوائم', diff --git a/shared/src/i18n/br/admin.ts b/shared/src/i18n/br/admin.ts index 162bceef6..82b0d402c 100644 --- a/shared/src/i18n/br/admin.ts +++ b/shared/src/i18n/br/admin.ts @@ -156,6 +156,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Falha ao excluir modelo', 'admin.packingTemplates.saveError': 'Falha ao salvar', 'admin.tabs.addons': 'Complementos', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Complementos', 'admin.addons.subtitle': 'Ative ou desative recursos para personalizar sua experiência no TREK.', 'admin.addons.catalog.memories.name': 'Memórias', diff --git a/shared/src/i18n/cs/admin.ts b/shared/src/i18n/cs/admin.ts index c1b8edb95..b3d1e72ad 100644 --- a/shared/src/i18n/cs/admin.ts +++ b/shared/src/i18n/cs/admin.ts @@ -157,6 +157,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Nepodařilo se smazat šablonu', 'admin.packingTemplates.saveError': 'Uložení se nezdařilo', 'admin.tabs.addons': 'Doplňky', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Doplňky', 'admin.addons.subtitle': 'Zapněte nebo vypněte funkce a přizpůsobte si TREK.', 'admin.addons.catalog.memories.name': 'Fotky (Immich)', diff --git a/shared/src/i18n/de/admin.ts b/shared/src/i18n/de/admin.ts index a94a5d84b..a1c129c00 100644 --- a/shared/src/i18n/de/admin.ts +++ b/shared/src/i18n/de/admin.ts @@ -159,6 +159,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Vorlage konnte nicht gelöscht werden', 'admin.packingTemplates.saveError': 'Fehler beim Speichern', 'admin.tabs.addons': 'Addons', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Plugins von Drittanbietern auf deiner Instanz installieren und verwalten.', + 'admin.plugins.disabledTitle': 'Plugins sind deaktiviert', + 'admin.plugins.disabledBody': 'Die Plugin-Laufzeit ist ausgeschaltet (TREK_PLUGINS_ENABLED). Es kann kein Plugin laufen, bis ein Admin sie in der Serverkonfiguration aktiviert.', + 'admin.plugins.empty': 'Noch keine Plugins installiert.', + 'admin.plugins.loadError': 'Plugins konnten nicht geladen werden.', + 'admin.plugins.scaffoldNote': 'Installation und Aktivierung von Plugins folgen in einem späteren Update. Dieses Panel zeigt derzeit nur installierte Plugins an.', + 'admin.plugins.status.active': 'Aktiv', + 'admin.plugins.status.inactive': 'Inaktiv', + 'admin.plugins.status.disabled': 'Deaktiviert', + 'admin.plugins.status.error': 'Fehler', + 'admin.plugins.status.incompatible': 'Inkompatibel', 'admin.addons.title': 'Addons', 'admin.addons.subtitle': 'Aktiviere oder deaktiviere Funktionen, um TREK nach deinen Wünschen anzupassen.', 'admin.addons.catalog.packing.name': 'Listen', diff --git a/shared/src/i18n/en/admin.ts b/shared/src/i18n/en/admin.ts index 52354aad5..06cb42e2f 100644 --- a/shared/src/i18n/en/admin.ts +++ b/shared/src/i18n/en/admin.ts @@ -211,6 +211,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Failed to delete template', 'admin.packingTemplates.saveError': 'Failed to save', 'admin.tabs.addons': 'Addons', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Addons', 'admin.addons.subtitle': 'Enable or disable features to customize your TREK experience.', 'admin.addons.catalog.packing.name': 'Lists', diff --git a/shared/src/i18n/es/admin.ts b/shared/src/i18n/es/admin.ts index d79a1dbd0..4ed79c170 100644 --- a/shared/src/i18n/es/admin.ts +++ b/shared/src/i18n/es/admin.ts @@ -158,6 +158,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Error al eliminar plantilla', 'admin.packingTemplates.saveError': 'Error al guardar', 'admin.tabs.addons': 'Complementos', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Complementos', 'admin.addons.subtitle': 'Activa o desactiva funciones para personalizar tu experiencia en TREK.', 'admin.addons.subtitleBefore': 'Activa o desactiva funciones para personalizar tu experiencia en ', diff --git a/shared/src/i18n/fr/admin.ts b/shared/src/i18n/fr/admin.ts index d21862bae..7ce4fdf60 100644 --- a/shared/src/i18n/fr/admin.ts +++ b/shared/src/i18n/fr/admin.ts @@ -160,6 +160,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Erreur de suppression du modèle', 'admin.packingTemplates.saveError': 'Erreur de sauvegarde', 'admin.tabs.addons': 'Extensions', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Extensions', 'admin.addons.subtitle': 'Activez ou désactivez des fonctionnalités pour personnaliser votre expérience TREK.', 'admin.addons.catalog.memories.name': 'Photos (Immich)', diff --git a/shared/src/i18n/gr/admin.ts b/shared/src/i18n/gr/admin.ts index 0039872db..481fe7f38 100644 --- a/shared/src/i18n/gr/admin.ts +++ b/shared/src/i18n/gr/admin.ts @@ -205,6 +205,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Αποτυχία διαγραφής προτύπου', 'admin.packingTemplates.saveError': 'Αποτυχία αποθήκευσης', 'admin.tabs.addons': 'Πρόσθετα', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Πρόσθετα', 'admin.addons.subtitle': 'Ενεργοποιήστε ή απενεργοποιήστε λειτουργίες για να εξατομικεύσετε την εμπειρία σας στο TREK.', diff --git a/shared/src/i18n/hu/admin.ts b/shared/src/i18n/hu/admin.ts index 38879b312..43ec8bdca 100644 --- a/shared/src/i18n/hu/admin.ts +++ b/shared/src/i18n/hu/admin.ts @@ -159,6 +159,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Nem sikerült törölni a sablont', 'admin.packingTemplates.saveError': 'Nem sikerült menteni', 'admin.tabs.addons': 'Bővítmények', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Bővítmények', 'admin.addons.subtitle': 'Funkciók engedélyezése vagy letiltása a TREK testreszabásához.', 'admin.addons.catalog.packing.name': 'Listák', diff --git a/shared/src/i18n/id/admin.ts b/shared/src/i18n/id/admin.ts index 06890b6c2..83d8c22dd 100644 --- a/shared/src/i18n/id/admin.ts +++ b/shared/src/i18n/id/admin.ts @@ -201,6 +201,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Gagal menghapus template', 'admin.packingTemplates.saveError': 'Gagal menyimpan', 'admin.tabs.addons': 'Addon', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Addon', 'admin.addons.subtitle': 'Aktifkan atau nonaktifkan fitur untuk menyesuaikan pengalaman TREK kamu.', 'admin.addons.catalog.packing.name': 'Daftar', diff --git a/shared/src/i18n/it/admin.ts b/shared/src/i18n/it/admin.ts index 9df405b47..720fce4a7 100644 --- a/shared/src/i18n/it/admin.ts +++ b/shared/src/i18n/it/admin.ts @@ -158,6 +158,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Impossibile eliminare il modello', 'admin.packingTemplates.saveError': 'Impossibile salvare', 'admin.tabs.addons': 'Moduli', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Moduli', 'admin.addons.subtitle': 'Abilita o disabilita le funzionalità per personalizzare la tua esperienza TREK.', 'admin.addons.catalog.packing.name': 'Liste', diff --git a/shared/src/i18n/ja/admin.ts b/shared/src/i18n/ja/admin.ts index 4d740c7cb..d1c37e5c9 100644 --- a/shared/src/i18n/ja/admin.ts +++ b/shared/src/i18n/ja/admin.ts @@ -190,6 +190,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'テンプレートの削除に失敗しました', 'admin.packingTemplates.saveError': '保存に失敗しました', 'admin.tabs.addons': 'アドオン', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'アドオン', 'admin.addons.subtitle': '機能を有効/無効にしてTREKをカスタマイズします。', 'admin.addons.catalog.packing.name': 'リスト', diff --git a/shared/src/i18n/ko/admin.ts b/shared/src/i18n/ko/admin.ts index f26e9616a..58cc45cfd 100644 --- a/shared/src/i18n/ko/admin.ts +++ b/shared/src/i18n/ko/admin.ts @@ -196,6 +196,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': '템플릿 삭제 실패', 'admin.packingTemplates.saveError': '저장 실패', 'admin.tabs.addons': '애드온', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': '애드온', 'admin.addons.subtitle': '기능을 활성화 또는 비활성화하여 TREK 경험을 맞춤 설정하세요.', 'admin.addons.catalog.packing.name': '목록', diff --git a/shared/src/i18n/nl/admin.ts b/shared/src/i18n/nl/admin.ts index 609cd30ce..e1670d261 100644 --- a/shared/src/i18n/nl/admin.ts +++ b/shared/src/i18n/nl/admin.ts @@ -159,6 +159,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Fout bij verwijderen van sjabloon', 'admin.packingTemplates.saveError': 'Fout bij opslaan', 'admin.tabs.addons': 'Add-ons', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Add-ons', 'admin.addons.subtitle': 'Schakel functies in of uit om je TREK-ervaring aan te passen.', 'admin.addons.catalog.memories.name': "Foto's (Immich)", diff --git a/shared/src/i18n/pl/admin.ts b/shared/src/i18n/pl/admin.ts index 762d824ed..9bac2077c 100644 --- a/shared/src/i18n/pl/admin.ts +++ b/shared/src/i18n/pl/admin.ts @@ -152,6 +152,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Nie udało się usunąć szablonu', 'admin.packingTemplates.saveError': 'Nie udało się zapisać szablonu', 'admin.tabs.addons': 'Dodatki', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Dodatki', 'admin.addons.subtitle': 'Włączaj lub wyłączaj funkcje, aby dostosować swoje doświadczenie w TREK.', 'admin.addons.catalog.packing.name': 'Listy', diff --git a/shared/src/i18n/ru/admin.ts b/shared/src/i18n/ru/admin.ts index 4c9413dda..6d1a2c711 100644 --- a/shared/src/i18n/ru/admin.ts +++ b/shared/src/i18n/ru/admin.ts @@ -159,6 +159,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Ошибка удаления шаблона', 'admin.packingTemplates.saveError': 'Ошибка сохранения', 'admin.tabs.addons': 'Дополнения', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Дополнения', 'admin.addons.subtitle': 'Включайте или отключайте функции для настройки TREK под себя.', 'admin.addons.catalog.memories.name': 'Фото (Immich)', diff --git a/shared/src/i18n/sv/admin.ts b/shared/src/i18n/sv/admin.ts index 9ed39ec06..64e796503 100644 --- a/shared/src/i18n/sv/admin.ts +++ b/shared/src/i18n/sv/admin.ts @@ -211,6 +211,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Det gick inte att ta bort mallen', 'admin.packingTemplates.saveError': 'Det gick inte att spara', 'admin.tabs.addons': 'Tillägg', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Tillägg', 'admin.addons.subtitle': 'Aktivera eller inaktivera funktioner för att anpassa din TREK-upplevelse.', 'admin.addons.catalog.packing.name': 'Listor', diff --git a/shared/src/i18n/tr/admin.ts b/shared/src/i18n/tr/admin.ts index bcd44f6e6..c58cff34f 100644 --- a/shared/src/i18n/tr/admin.ts +++ b/shared/src/i18n/tr/admin.ts @@ -203,6 +203,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Şablon silinemedi', 'admin.packingTemplates.saveError': 'Kaydedilemedi', 'admin.tabs.addons': 'Eklentiler', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Eklentiler', 'admin.addons.subtitle': 'TREK deneyiminizi özelleştirmek için özellikleri etkinleştirin veya devre dışı bırakın.', 'admin.addons.catalog.packing.name': 'Listeler', diff --git a/shared/src/i18n/uk/admin.ts b/shared/src/i18n/uk/admin.ts index 73deaca20..b6a6576b0 100644 --- a/shared/src/i18n/uk/admin.ts +++ b/shared/src/i18n/uk/admin.ts @@ -159,6 +159,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Помилка видалення шаблону', 'admin.packingTemplates.saveError': 'Помилка збереження', 'admin.tabs.addons': 'Дополнения', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Доповнення', 'admin.addons.subtitle': 'Увімкніть або вимкніть функції, щоб налаштувати TREK під себе.', 'admin.addons.catalog.memories.name': 'Фото (Immich)', diff --git a/shared/src/i18n/vi/admin.ts b/shared/src/i18n/vi/admin.ts index 868cf9600..3712e0fcc 100644 --- a/shared/src/i18n/vi/admin.ts +++ b/shared/src/i18n/vi/admin.ts @@ -211,6 +211,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': 'Không xóa được mẫu', 'admin.packingTemplates.saveError': 'Không lưu được', 'admin.tabs.addons': 'Tiện ích bổ sung', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': 'Tiện ích bổ sung', 'admin.addons.subtitle': 'Bật hoặc tắt các tính năng để tùy chỉnh trải nghiệm TREK của bạn.', 'admin.addons.catalog.packing.name': 'Danh sách', diff --git a/shared/src/i18n/zh-TW/admin.ts b/shared/src/i18n/zh-TW/admin.ts index 5f237df89..556184d2f 100644 --- a/shared/src/i18n/zh-TW/admin.ts +++ b/shared/src/i18n/zh-TW/admin.ts @@ -193,6 +193,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': '刪除模板失敗', 'admin.packingTemplates.saveError': '儲存失敗', 'admin.tabs.addons': '擴充套件', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': '擴充套件', 'admin.addons.subtitle': '啟用或停用功能以自定義你的 TREK 體驗。', 'admin.addons.catalog.memories.name': '照片 (Immich)', diff --git a/shared/src/i18n/zh/admin.ts b/shared/src/i18n/zh/admin.ts index b6cd6d2c6..45c11209d 100644 --- a/shared/src/i18n/zh/admin.ts +++ b/shared/src/i18n/zh/admin.ts @@ -154,6 +154,19 @@ const admin: TranslationStrings = { 'admin.packingTemplates.deleteError': '删除模板失败', 'admin.packingTemplates.saveError': '保存失败', 'admin.tabs.addons': '扩展', + 'admin.tabs.plugins': 'Plugins', + 'admin.plugins.title': 'Plugins', + 'admin.plugins.subtitle': 'Install and manage third-party plugins on your instance.', + 'admin.plugins.disabledTitle': 'Plugins are disabled', + 'admin.plugins.disabledBody': 'The plugin runtime is turned off (TREK_PLUGINS_ENABLED). No plugin can run until an admin enables it in the server configuration.', + 'admin.plugins.empty': 'No plugins installed yet.', + 'admin.plugins.loadError': 'Could not load plugins.', + 'admin.plugins.scaffoldNote': 'Plugin installation and activation are coming in a later update. This panel currently lists installed plugins only.', + 'admin.plugins.status.active': 'Active', + 'admin.plugins.status.inactive': 'Inactive', + 'admin.plugins.status.disabled': 'Disabled', + 'admin.plugins.status.error': 'Error', + 'admin.plugins.status.incompatible': 'Incompatible', 'admin.addons.title': '扩展', 'admin.addons.subtitle': '启用或禁用功能以自定义你的 TREK 体验。', 'admin.addons.catalog.memories.name': '照片 (Immich)',