203 lines
6.5 KiB
TypeScript
203 lines
6.5 KiB
TypeScript
/**
|
|
* FeatureView Page
|
|
*
|
|
* Generische Feature-View-Komponente.
|
|
* Rendert den entsprechenden Content basierend auf Feature-Code und View.
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { useCurrentInstance } from '../hooks/useCurrentInstance';
|
|
import { useCanViewFeatureView } from '../hooks/useInstancePermissions';
|
|
import { getLabel, FEATURE_REGISTRY } from '../types/mandate';
|
|
|
|
// Trustee Views
|
|
// Note: TrusteeOrganisationsView and TrusteeContractsView removed - Feature-Instanz = Organisation
|
|
import { TrusteeDocumentsView } from './views/trustee/TrusteeDocumentsView';
|
|
import { TrusteePositionsView } from './views/trustee/TrusteePositionsView';
|
|
import { TrusteePositionDocumentsView } from './views/trustee/TrusteePositionDocumentsView';
|
|
import { TrusteeDashboardView } from './views/trustee/TrusteeDashboardView';
|
|
import { TrusteeInstanceRolesView } from './views/trustee/TrusteeInstanceRolesView';
|
|
import { TrusteeExpenseImportView } from './views/trustee/TrusteeExpenseImportView';
|
|
|
|
// Chatbot Views
|
|
import { ChatbotConversationsView } from './views/chatbot/ChatbotConversationsView';
|
|
|
|
// RealEstate Views
|
|
import { RealEstatePekView, RealEstateInstanceRolesPlaceholder } from './views/realestate';
|
|
|
|
// Chat Playground Views (reusing existing workflow pages)
|
|
import { PlaygroundPage, WorkflowsPage } from './workflows';
|
|
|
|
// Automation Views (reusing existing workflow pages)
|
|
import { AutomationsPage, AutomationTemplatesPage } from './workflows';
|
|
|
|
// Teamsbot Views
|
|
import { TeamsbotDashboardView } from './views/teamsbot/TeamsbotDashboardView';
|
|
import { TeamsbotSessionView } from './views/teamsbot/TeamsbotSessionView';
|
|
import { TeamsbotSettingsView } from './views/teamsbot/TeamsbotSettingsView';
|
|
|
|
import styles from './FeatureView.module.css';
|
|
|
|
// =============================================================================
|
|
// PLACEHOLDER VIEWS (für nicht implementierte Features)
|
|
// =============================================================================
|
|
|
|
const PlaceholderView: React.FC<{ title: string; description: string }> = ({ title, description }) => (
|
|
<div className={styles.placeholder}>
|
|
<h2>{title}</h2>
|
|
<p>{description}</p>
|
|
</div>
|
|
);
|
|
|
|
// Chatworkflow Views
|
|
const ChatworkflowDashboard: React.FC = () => (
|
|
<PlaceholderView title="Workflow Dashboard" description="Übersicht der Workflows" />
|
|
);
|
|
|
|
const ChatworkflowRuns: React.FC = () => (
|
|
<PlaceholderView title="Runs" description="Workflow-Ausführungen" />
|
|
);
|
|
|
|
const ChatworkflowFiles: React.FC = () => (
|
|
<PlaceholderView title="Dateien" description="Workflow-Dateien" />
|
|
);
|
|
|
|
// Chatbot Views
|
|
// ChatbotConversationsView is imported above
|
|
|
|
const ChatbotSettings: React.FC = () => (
|
|
<PlaceholderView title="Chatbot Einstellungen" description="Konfiguration des Chatbots" />
|
|
);
|
|
|
|
// Generic/Fallback
|
|
const NotFound: React.FC = () => (
|
|
<div className={styles.notFound}>
|
|
<h2>Seite nicht gefunden</h2>
|
|
<p>Diese View existiert nicht oder wurde noch nicht implementiert.</p>
|
|
</div>
|
|
);
|
|
|
|
const AccessDenied: React.FC = () => (
|
|
<div className={styles.accessDenied}>
|
|
<h2>Zugriff verweigert</h2>
|
|
<p>Du hast keine Berechtigung für diese Ansicht.</p>
|
|
</div>
|
|
);
|
|
|
|
// =============================================================================
|
|
// VIEW REGISTRY
|
|
// =============================================================================
|
|
|
|
type ViewComponent = React.FC;
|
|
|
|
const VIEW_COMPONENTS: Record<string, Record<string, ViewComponent>> = {
|
|
trustee: {
|
|
dashboard: TrusteeDashboardView,
|
|
documents: TrusteeDocumentsView,
|
|
positions: TrusteePositionsView,
|
|
'position-documents': TrusteePositionDocumentsView,
|
|
'instance-roles': TrusteeInstanceRolesView,
|
|
'expense-import': TrusteeExpenseImportView,
|
|
},
|
|
chatworkflow: {
|
|
dashboard: ChatworkflowDashboard,
|
|
runs: ChatworkflowRuns,
|
|
files: ChatworkflowFiles,
|
|
},
|
|
chatbot: {
|
|
conversations: ChatbotConversationsView,
|
|
settings: ChatbotSettings,
|
|
},
|
|
realestate: {
|
|
dashboard: RealEstatePekView,
|
|
'instance-roles': RealEstateInstanceRolesPlaceholder,
|
|
},
|
|
chatplayground: {
|
|
playground: PlaygroundPage,
|
|
workflows: WorkflowsPage,
|
|
},
|
|
automation: {
|
|
definitions: AutomationsPage,
|
|
templates: AutomationTemplatesPage,
|
|
logs: () => <PlaceholderView title="Execution Logs" description="Automatisierungs-Ausführungsprotokolle" />,
|
|
},
|
|
teamsbot: {
|
|
dashboard: TeamsbotDashboardView,
|
|
sessions: TeamsbotSessionView,
|
|
settings: TeamsbotSettingsView,
|
|
},
|
|
};
|
|
|
|
// =============================================================================
|
|
// FEATURE VIEW PAGE
|
|
// =============================================================================
|
|
|
|
interface FeatureViewPageProps {
|
|
view: string;
|
|
}
|
|
|
|
export const FeatureViewPage: React.FC<FeatureViewPageProps> = ({ view }) => {
|
|
const { instance, featureCode, isValid } = useCurrentInstance();
|
|
|
|
// Berechtigungs-Check
|
|
const viewCode = `${featureCode}-${view}`;
|
|
const canView = useCanViewFeatureView(viewCode);
|
|
|
|
// DEBUG: Log permission check for chatbot
|
|
if (featureCode === 'chatbot') {
|
|
console.log('🔍 [DEBUG] FeatureView Permission Check:', {
|
|
featureCode,
|
|
view,
|
|
viewCode,
|
|
instanceId: instance?.id,
|
|
instanceLabel: instance?.instanceLabel,
|
|
isValid,
|
|
canView,
|
|
permissions: instance?.permissions,
|
|
views: instance?.permissions?.views,
|
|
viewKeys: instance?.permissions?.views ? Object.keys(instance.permissions.views) : [],
|
|
hasLegacyView: instance?.permissions?.views?.[viewCode],
|
|
hasFullObjectKey: instance?.permissions?.views?.[`ui.feature.${featureCode}.${view}`],
|
|
hasWildcard: instance?.permissions?.views?.['_all'],
|
|
});
|
|
}
|
|
|
|
// Nicht valider Kontext
|
|
if (!isValid || !featureCode || !instance) {
|
|
return <NotFound />;
|
|
}
|
|
|
|
// Keine Berechtigung
|
|
if (!canView && view !== 'not-found') {
|
|
return <AccessDenied />;
|
|
}
|
|
|
|
// View-Komponente finden
|
|
const featureViews = VIEW_COMPONENTS[featureCode];
|
|
if (!featureViews) {
|
|
return <NotFound />;
|
|
}
|
|
|
|
const ViewComponent = featureViews[view];
|
|
if (!ViewComponent) {
|
|
return <NotFound />;
|
|
}
|
|
|
|
// View-Info aus Registry
|
|
const featureConfig = FEATURE_REGISTRY[featureCode];
|
|
const viewConfig = featureConfig?.views?.find(v => v.code === view);
|
|
const viewLabel = viewConfig ? getLabel(viewConfig.label) : view;
|
|
|
|
return (
|
|
<div className={styles.featureView}>
|
|
<header className={styles.viewHeader}>
|
|
<h1 className={styles.viewTitle}>{viewLabel}</h1>
|
|
</header>
|
|
<main className={styles.viewContent}>
|
|
<ViewComponent />
|
|
</main>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default FeatureViewPage;
|