feat(dms): fix upload response_model, add content_hash migration, storage settings tab, roadmap external storage
Check Cross-Plugin Imports / check (push) Has been cancelled
Check Cross-Plugin Imports / check (push) Has been cancelled
This commit is contained in:
@@ -27,7 +27,7 @@ export interface DmsFile {
|
||||
mime_type: string;
|
||||
size_bytes?: number;
|
||||
storage_path: string;
|
||||
checksum?: string | null;
|
||||
content_hash?: string | null;
|
||||
deleted_at: string | null;
|
||||
uploaded_by?: string;
|
||||
created_at?: string | null;
|
||||
@@ -39,6 +39,8 @@ export interface DmsFile {
|
||||
size?: number;
|
||||
/** @deprecated Use uploaded_by instead */
|
||||
created_by?: string;
|
||||
/** @deprecated Use content_hash instead */
|
||||
checksum?: string | null;
|
||||
}
|
||||
|
||||
export interface FilePermission {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Code, BookOpen, FileJson } from 'lucide-react';
|
||||
import { Code, BookOpen, FileJson, HardDrive } from 'lucide-react';
|
||||
import { SettingsMenuOrderPage } from './SettingsMenuOrder';
|
||||
import { SettingsThemePage } from './SettingsTheme';
|
||||
import { SettingsPluginsPage } from './SettingsPlugins';
|
||||
@@ -13,6 +13,7 @@ export function SettingsSystemPage() {
|
||||
{ key: 'menu', label: t('settings.menuOrder', 'Menü') },
|
||||
{ key: 'theme', label: t('settings.theme', 'Theme') },
|
||||
{ key: 'plugins', label: t('settings.plugins', 'Plugins') },
|
||||
{ key: 'storage', label: t('settings.storage', 'Storage') },
|
||||
{ key: 'entwickler', label: t('settings.developer', 'Entwickler') },
|
||||
];
|
||||
|
||||
@@ -44,6 +45,76 @@ export function SettingsSystemPage() {
|
||||
{activeTab === 'menu' && <SettingsMenuOrderPage />}
|
||||
{activeTab === 'theme' && <SettingsThemePage />}
|
||||
{activeTab === 'plugins' && <SettingsPluginsPage />}
|
||||
{activeTab === 'storage' && (
|
||||
<div className="space-y-6" data-testid="settings-storage-section">
|
||||
<div className="bg-white rounded-lg border border-secondary-200 p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="w-10 h-10 rounded-lg bg-primary-50 text-primary-600 flex items-center justify-center">
|
||||
<HardDrive className="w-5 h-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-secondary-900">{t('settings.storage.local', 'Lokaler Storage')}</h3>
|
||||
<p className="text-xs text-secondary-500">/data/storage</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-sm text-secondary-600 mb-4">
|
||||
{t('settings.storage.localDesc', 'Dateien werden lokal im Docker-Volume gespeichert. Bei Bedarf auf S3 oder externe Storage-Provider umstellbar.')}
|
||||
</p>
|
||||
<div className="grid grid-cols-2 gap-4 text-sm">
|
||||
<div>
|
||||
<span className="text-secondary-500">Backend:</span>
|
||||
<span className="ml-2 font-medium text-secondary-900">Local</span>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-secondary-500">Pfad:</span>
|
||||
<span className="ml-2 font-medium text-secondary-900">/data/storage</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg border border-secondary-200 p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="w-10 h-10 rounded-lg bg-warning-50 text-warning-600 flex items-center justify-center">
|
||||
<HardDrive className="w-5 h-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-secondary-900">{t('settings.storage.s3', 'S3 Storage')}</h3>
|
||||
<p className="text-xs text-secondary-500">{t('settings.storage.s3Desc', 'S3-kompatibler Storage (AWS S3, MinIO, etc.)')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-3 text-sm">
|
||||
<div className="flex items-center justify-between p-3 bg-secondary-50 rounded-md">
|
||||
<span className="text-secondary-600">Status</span>
|
||||
<span className="font-medium text-secondary-400">{t('settings.storage.notConfigured', 'Nicht konfiguriert')}</span>
|
||||
</div>
|
||||
<p className="text-xs text-secondary-500">
|
||||
{t('settings.storage.s3Hint', 'S3 wird via Environment-Variablen konfiguriert: STORAGE_BACKEND=s3, S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY, S3_SECRET_KEY')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-lg border border-secondary-200 p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="w-10 h-10 rounded-lg bg-success-50 text-success-600 flex items-center justify-center">
|
||||
<HardDrive className="w-5 h-5" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-sm font-semibold text-secondary-900">{t('settings.storage.external', 'Externe Storage-Provider')}</h3>
|
||||
<p className="text-xs text-secondary-500">{t('settings.storage.externalDesc', 'WebDAV, Nextcloud, Google Drive, Dropbox')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center justify-between p-3 bg-secondary-50 rounded-md">
|
||||
<span className="text-sm text-secondary-600">{t('settings.storage.webdav', 'WebDAV')}</span>
|
||||
<span className="text-xs font-medium text-secondary-400">{t('settings.storage.comingSoon', 'In Entwicklung')}</span>
|
||||
</div>
|
||||
<p className="text-xs text-secondary-500">
|
||||
{t('settings.storage.externalHint', 'Externe Storage-Provider werden als Plugins implementiert. In Zukunft hier konfigurierbar.')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{activeTab === 'entwickler' && (
|
||||
<div className="space-y-4" data-testid="settings-developer-section">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
|
||||
Reference in New Issue
Block a user