12 KiB
12 KiB
React-UI Spezifikation für PowerOn Frontend
Übersicht
Diese Spezifikation definiert die strukturellen und architektonischen Prinzipien für das React-UI für PowerOn und weitere UI's.
1. Architektur-Übersicht
1.1 Generische UI-Anforderungen
Das UI soll:
- Modular und erweiterbar sein: Neue Module können einfach hinzugefügt werden ohne bestehenden Code zu ändern
- Konsistent und einheitlich sein: Alle Module folgen den gleichen Design-Patterns und Verhaltensweisen
- Responsive und zugänglich sein: Funktioniert auf allen Geräten und ist barrierefrei
- Performance-optimiert sein: Schnelle Ladezeiten und flüssige Interaktionen
- Wartbar und testbar sein: Klare Struktur, umfassende Tests und Dokumentation
- Sicher und robust sein: Fehlerbehandlung, Input-Validierung und sichere API-Kommunikation
- Internationalisierbar sein: Mehrsprachige Unterstützung für alle UI-Elemente
- Konfigurierbar sein: Verhalten und Aussehen können über Konfiguration angepasst werden
1.2 React-Architektur-Spezifikation
Das React-UI MUSS folgende Kernelemente implementieren:
1.2.1 FormGeneric-Komponente
- EINE zentrale CRUD-Komponente für alle Module
- Automatische Formular-Generierung basierend auf Backend-Modell-Definitionen
- Einheitliche Validierung und Fehlerbehandlung
- Unterstützung für alle Standard-Feldtypen (Text, Number, Date, Select, etc.)
1.2.2 Modul-Management-System
- Zentrale Klasse für Modul-Loading, -Aktivierung und -Deaktivierung
- Dynamisches Laden von Modulen zur Laufzeit
- Modul-spezifische Konfiguration und State-Isolation
- Einheitliche Modul-Lifecycle-Verwaltung
1.2.3 Globaler State-Management
- EINE zentrale State-Management-Lösung für alle Module
- Konsistente Datenhaltung und -synchronisation
- Modul-übergreifende Datenfreigabe
- Optimistic Updates und Rollback-Mechanismen
1.2.4 Timezone-Aware Timestamp-System
- Alle Timestamps MÜSSEN timezone-aware sein
- Konsistente Darstellung in allen Modulen
- Automatische Konvertierung zwischen Zeitzonen
- Integration mit Backend-Timestamp-Format
1.2.5 Zentrale API-Kommunikation
- Einheitliche API-Call-Verwaltung
- Automatische Error-Handling und Retry-Mechanismen
- Request/Response-Interceptoren
- Caching-Strategien für Performance
1.2.6 Konfigurationsverwaltung
- Globale Konfiguration für UI-Verhalten
- Umgebungs-spezifische Konfiguration (dev/prod)
- Feature-Flags für modulare Aktivierung
- Zentrale Validierungsregeln
2. Konfigurationsverwaltung
2.1 Konfigurationsarchitektur
Das UI verwendet eine zweistufige Konfigurationsverwaltung:
Globale Konfiguration (config.js)
// Zentrale Konfigurationsverwaltung für globale Variablen
interface GlobalConfig {
// API-Konfiguration
apiBaseUrl: string;
apiTimeout: number;
// UI-Konfiguration
defaultLanguage: string;
theme: 'light' | 'dark' | 'auto';
pageSize: number;
// Feature-Flags
features: {
enableAdvancedSearch: boolean;
enableBulkOperations: boolean;
enableRealTimeUpdates: boolean;
};
// Validierung
validation: {
maxFileSize: number;
allowedFileTypes: string[];
passwordMinLength: number;
};
}
// Konfigurationsservice
class ConfigService {
private config: GlobalConfig;
get(key: string): any;
set(key: string, value: any): void;
getApiBaseUrl(): string;
getFeatureFlag(flag: string): boolean;
}
Umgebungs-spezifische Konfiguration (env)
// Umgebungsvariablen für spezifische Konfigurationen
interface EnvironmentConfig {
// Umgebung
NODE_ENV: 'development' | 'production' | 'test';
APP_ENV: 'dev' | 'int' | 'prod';
// API-Endpunkte
API_BASE_URL: string;
API_TIMEOUT: number;
// Debugging
DEBUG_MODE: boolean;
LOG_LEVEL: 'debug' | 'info' | 'warn' | 'error';
// Externe Services
GOOGLE_CLIENT_ID?: string;
MICROSOFT_CLIENT_ID?: string;
// Build-spezifisch
BUILD_VERSION: string;
BUILD_TIMESTAMP: string;
}
// Environment Service
class EnvironmentService {
get(key: keyof EnvironmentConfig): string | undefined;
isDevelopment(): boolean;
isProduction(): boolean;
getApiBaseUrl(): string;
}
2.2 Konfigurationshierarchie
// Konfigurationspriorität (höchste zu niedrigste):
// 1. Umgebungsvariablen (env)
// 2. Globale Konfiguration (config.js)
// 3. Standardwerte (defaults)
class ConfigurationManager {
private envConfig: EnvironmentConfig;
private globalConfig: GlobalConfig;
private defaults: GlobalConfig;
get(key: string): any {
// Prüfe Umgebungsvariablen zuerst
if (this.envConfig[key]) {
return this.envConfig[key];
}
// Dann globale Konfiguration
if (this.globalConfig[key]) {
return this.globalConfig[key];
}
// Schließlich Standardwerte
return this.defaults[key];
}
}
2.3 React-Integration
// React Hook für Konfiguration
const useConfig = () => {
const [config, setConfig] = useState<GlobalConfig>();
useEffect(() => {
// Lade Konfiguration beim Mount
const loadConfig = async () => {
const configData = await configService.load();
setConfig(configData);
};
loadConfig();
}, []);
return {
config,
get: (key: string) => config?.[key],
isFeatureEnabled: (feature: string) => config?.features?.[feature] || false,
getApiBaseUrl: () => config?.apiBaseUrl || envService.getApiBaseUrl()
};
};
// Verwendung in Komponenten
const MyComponent = () => {
const { config, isFeatureEnabled, getApiBaseUrl } = useConfig();
return (
<div>
{isFeatureEnabled('enableAdvancedSearch') && <AdvancedSearch />}
<ApiClient baseUrl={getApiBaseUrl()} />
</div>
);
};
3. Strukturelle Prinzipien
3.1 Modulare Architektur
Jedes Modul folgt einer einheitlichen Struktur:
ModuleName/
├── index.tsx // Hauptkomponente
├── ModuleName.tsx // Haupt-UI-Komponente
├── ModuleName.types.ts // TypeScript-Definitionen
├── ModuleName.hooks.ts // Custom Hooks
├── ModuleName.service.ts // API-Service
└── ModuleName.styles.css // Modul-spezifische Styles
3.2 State Management
// Zustand-Management mit React Context + useReducer
interface ModuleState {
items: any[];
currentItem: any | null;
isEditing: boolean;
isCreating: boolean;
lifecycleState: 'active' | 'background' | 'unloaded' | 'stale';
lastActivated: number | null;
lastDataLoad: number | null;
}
// Zentrale Module-Management-Klasse
class ModuleManager {
private modules: Map<string, ModuleState> = new Map();
load(moduleName: string): Promise<boolean>;
unload(moduleName: string): boolean;
activate(moduleName: string): Promise<boolean>;
deactivate(moduleName: string): boolean;
}
4. FormGeneric React-Implementierung
4.1 Generische CRUD-Komponente
interface FormGenericProps<T> {
entityType: string;
apiEndpoint: {
get: () => Promise<T[]>;
create: (data: Partial<T>) => Promise<T>;
update: (id: string, data: Partial<T>) => Promise<T>;
delete: (id: string) => Promise<void>;
};
config: {
fields: FieldDefinition[];
table: TableConfig;
ui: UIConfig;
};
events?: {
beforeActivation?: () => Promise<void>;
onActivation?: () => Promise<void>;
onDeactivation?: () => Promise<void>;
};
}
const FormGeneric = <T extends Record<string, any>>({
entityType,
apiEndpoint,
config,
events
}: FormGenericProps<T>) => {
// React-Implementierung der aktuellen formGeneric-Logik
};
4.2 Field-Definitionen aus Backend
interface FieldDefinition {
name: string;
label: Record<string, string>; // Multi-language support
type: 'text' | 'email' | 'password' | 'checkbox' | 'select' | 'textarea' | 'timestamp';
required: boolean;
readonly: boolean;
options?: Array<{
value: string;
label: Record<string, string>;
}>;
}
5. Timezone-Aware Timestamps
5.1 Konsistente Timestamp-Behandlung
// React Hook für Timestamp-Utilities
const useTimezoneUtils = () => {
const formatUtcForDisplay = (timestamp: number): string => {
// UTC timestamp in seconds -> formatted display string
};
const isExpiredUtc = (expiresAt: number): boolean => {
// Check if timestamp is expired
};
return { formatUtcForDisplay, isExpiredUtc, /* ... */ };
};
5.2 Backend-Model-Integration
// Automatische Generierung von TypeScript-Interfaces aus Backend-Modellen
interface User {
id: string;
username: string;
email: string;
fullName?: string;
language: string;
enabled: boolean;
privilege: 'user' | 'admin' | 'sysadmin';
authenticationAuthority: 'local' | 'google' | 'msft';
mandateId?: string;
}
interface UserConnection {
id: string;
userId: string;
authority: 'local' | 'google' | 'msft';
externalUsername: string;
externalEmail?: string;
status: 'active' | 'expired' | 'revoked' | 'pending';
connectedAt: number; // UTC timestamp
lastChecked: number; // UTC timestamp
expiresAt?: number; // UTC timestamp
}
6. Fehlerbehandlung
6.1 Zentrale Error-Boundary
class ErrorBoundary extends React.Component {
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
// Logging und Benutzer-Benachrichtigung
console.error('Module Error:', error, errorInfo);
// Toast-Benachrichtigung anzeigen
}
}
6.2 API-Error-Handling
// Service-Klasse für API-Aufrufe
class ApiService {
async request<T>(endpoint: string, options?: RequestInit): Promise<T> {
try {
const response = await fetch(endpoint, options);
if (!response.ok) {
throw new ApiError(response.status, await response.text());
}
return await response.json();
} catch (error) {
// Zentrale Fehlerbehandlung
this.handleError(error);
throw error;
}
}
}
7. Styling-Ansatz
6.1 CSS-in-JS oder CSS-Module
// Empfehlung: CSS-Module für bessere Performance
import styles from './FormGeneric.module.css';
const FormGeneric = () => (
<div className={styles.entityTable}>
<table className={styles.table}>
{/* ... */}
</table>
</div>
);
6.2 Design-System
/* Design-Tokens */
:root {
--color-primary: #3b82f6;
--color-secondary: #6b7280;
--color-success: #10b981;
--color-warning: #f59e0b;
--color-error: #ef4444;
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--border-radius: 0.375rem;
--box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
7. Performance-Optimierungen
7.1 Lazy Loading
// Lazy Loading für Module
const UsersModule = React.lazy(() => import('./modules/Users'));
const ConnectionsModule = React.lazy(() => import('./modules/Connections'));
// Suspense-Wrapper
<Suspense fallback={<LoadingSpinner />}>
<UsersModule />
</Suspense>
7.2 Memoization
// Optimierte Komponenten mit React.memo
const DataTable = React.memo<DataTableProps>(({ data, columns }) => {
// Komponente wird nur neu gerendert wenn sich data oder columns ändern
});
8. Testing-Strategie
8.1 Unit Tests
// Jest + React Testing Library
describe('FormGeneric', () => {
it('should render table with data', () => {
render(<FormGeneric {...mockProps} />);
expect(screen.getByRole('table')).toBeInTheDocument();
});
});
8.2 Integration Tests
// API-Integration Tests
describe('UserService', () => {
it('should fetch users from API', async () => {
const users = await userService.getUsers();
expect(users).toHaveLength(2);
});
});
9. Implementierungsrichtlinien
9.1 Code-Qualität
- TypeScript: Strikte Typisierung für alle Komponenten und Services
- ESLint: Code-Qualitätsregeln und Konsistenz
9.2 Dokumentation
- Storybook: Komponenten-Dokumentation
- README: Setup und Entwicklungsanweisungen