Metadata Components
The MetadataEntity system provides a comprehensive solution for managing and displaying entity metadata, API documentation, field information, and schema details. This powerful functionality helps developers understand entity structures, relationships, and available operations.
Overview
The metadata system consists of several interconnected components that work together to provide complete entity documentation:
- OverviewTab: Basic entity information and statistics
- FieldsTab: Detailed field information with types and relationships
- APITab: Generated API documentation for the entity
- InterfacesTab: Interface and schema documentation
OverviewTab Component
Displays basic entity information, statistics, and summary data.
Props
interface OverviewTabProps {
entity: EntityData; // Entity data object
getFieldsByType: () => { // Field type statistics function
scalar: number;
relation: number;
other: number;
};
locale?: string; // Locale for translations
}Features
- Entity Information: Class name, resource name, parent class, role prefix
- Statistics Dashboard: Field counts, API operations, relations, interfaces
- Trait Information: Lists used traits in the entity
- Property Types: Required, writable, and displayable properties count
- Visual Cards: Statistics displayed in responsive card layout
Usage Example
import { OverviewTab } from "@phpcreation/frontend-crud-react-nextjs-bundle/components";
function EntityOverview({ entity }: { entity: EntityData }) {
const getFieldsByType = () => ({
scalar: Object.values(entity.fields).filter(f => f.type === 'scalar').length,
relation: Object.values(entity.fields).filter(f => f.type === 'relation').length,
other: Object.values(entity.fields).filter(f => !['scalar', 'relation'].includes(f.type)).length
});
return (
<OverviewTab
entity={entity}
getFieldsByType={getFieldsByType}
locale="en"
/>
);
}FieldsTab Component
Shows detailed field information including types, relationships, and constraints.
Props
interface FieldsTabProps {
entity: EntityData; // Entity data object
fields: Field[]; // Array of field metadata
onFieldEdit?: (field: Field) => void; // Field edit handler
locale?: string; // Locale for translations
}
interface Field {
fieldName: string; // Field name
type: string; // Field type
scale?: number | null; // Scale for decimal types
length?: number | null; // Field length
unique?: boolean; // Is unique field
nullable: boolean; // Whether field can be null
precision?: number | null; // Precision for decimal types
columnName?: string; // Database column name
constraints?: Record<string, any>; // Field constraints
id?: boolean; // Is primary key
options?: Record<string, any>; // Field options
joinColumns?: any[]; // Join columns for relations
cascade?: string[]; // Cascade options
inversedBy?: string; // Inverse relation field
targetEntity?: string; // Target entity for relations
fetch?: string; // Fetch strategy
mappedBy?: string; // Mapped by field
isOwningSide?: boolean; // Is owning side of relation
sourceEntity?: string; // Source entity
isCascadeRemove?: boolean; // Cascade remove
isCascadePersist?: boolean; // Cascade persist
isCascadeRefresh?: boolean; // Cascade refresh
isCascadeMerge?: boolean; // Cascade merge
isCascadeDetach?: boolean; // Cascade detach
orphanRemoval?: boolean; // Orphan removal
orderBy?: Record<string, string>; // Order by clause
targetEntityResourceName?: string; // Target entity resource name
targetEntityResourceIri?: string; // Target entity resource IRI
}Features
- Field Listing: Comprehensive table of all entity fields
- Type Information: Display field types with visual indicators
- Relationship Details: Show entity relationships with target information
- Constraint Display: Field validation rules and constraints
- Interactive Editing: Optional field editing capabilities
- Filtering: Filter fields by type, required status, etc.
Usage Example
Basic Usage
import { FieldsTab } from "@phpcreation/frontend-crud-react-nextjs-bundle/components";
function EntityFields({ entity }: { entity: EntityData }) {
return (
<FieldsTab
entity={entity}
fields={Object.values(entity.fields)}
locale="en"
/>
);
}APITab Component
Generates comprehensive API documentation for the entity including all available endpoints.
Props
interface APITabProps {
entity: EntityData; // Entity data object
endpoints: APIEndpoint[]; // Available API endpoints
baseUrl: string; // API base URL
locale?: string; // Locale for translations
}
interface APIEndpoint {
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; // HTTP method
path: string; // Endpoint path
description: string; // Endpoint description
parameters?: { // Request parameters
name: string;
type: string;
required: boolean;
description: string;
}[];
requestBody?: { // Request body schema
required: boolean;
content: Record<string, any>;
};
responses: { // Response schemas
[statusCode: string]: {
description: string;
content?: Record<string, any>;
};
};
examples?: { // Usage examples
request?: any;
response?: any;
};
}Features
- Endpoint Documentation: Complete list of available API operations
- Request/Response Schemas: Detailed schema information with examples
- Interactive Examples: Copy-paste ready code examples
- Authentication Info: Required permissions and authentication details
- Rate Limiting: API usage limits and guidelines
- Error Codes: Complete error response documentation
Usage Example
Basic API Docs
import { APITab } from "@phpcreation/frontend-crud-react-nextjs-bundle/components";
function EntityAPI({ entity }: { entity: EntityData }) {
const endpoints: APIEndpoint[] = [
{
method: 'GET',
path: `/api/v1/${entity.resourceName}`,
description: 'List all entities with pagination',
parameters: [
{ name: 'page', type: 'integer', required: false, description: 'Page number' },
{ name: 'limit', type: 'integer', required: false, description: 'Items per page' }
],
responses: {
'200': {
description: 'Success',
content: { 'application/json': { data: [], meta: {} } }
}
}
},
{
method: 'POST',
path: `/api/v1/${entity.resourceName}`,
description: 'Create new entity',
requestBody: {
required: true,
content: { 'application/json': entity.createSchema }
},
responses: {
'201': { description: 'Created successfully' },
'422': { description: 'Validation errors' }
}
}
];
return (
<APITab
entity={entity}
endpoints={endpoints}
baseUrl="/api/v1"
locale="en"
/>
);
}InterfacesTab Component
Documents entity interfaces, schemas, and data structures.
Props
interface InterfacesTabProps {
entity: EntityData; // Entity data object
interfaces: InterfaceDefinition[]; // Interface definitions
locale?: string; // Locale for translations
}
interface InterfaceDefinition {
name: string; // Interface name
methods: { // Interface methods
name: string;
parameters: { name: string; type: string }[];
returnType: string;
description: string;
}[];
properties?: { // Interface properties
name: string;
type: string;
readonly: boolean;
description: string;
}[];
extends?: string[]; // Extended interfaces
implemented_by: string[]; // Classes implementing interface
}Features
- Interface Documentation: Complete interface definitions with methods and properties
- Schema Visualization: Visual representation of data structures
- Implementation Details: Classes that implement each interface
- Type Definitions: TypeScript/PHP type definitions
- Inheritance Chain: Interface inheritance and extension relationships
Usage Example
import { InterfacesTab } from "@phpcreation/frontend-crud-react-nextjs-bundle/components";
function EntityInterfaces({ entity }: { entity: EntityData }) {
const interfaces: InterfaceDefinition[] = [
{
name: 'EntityInterface',
methods: [
{
name: 'getId',
parameters: [],
returnType: 'int|null',
description: 'Get entity ID'
},
{
name: 'toArray',
parameters: [],
returnType: 'array',
description: 'Convert entity to array'
}
],
properties: [
{
name: 'id',
type: 'int',
readonly: true,
description: 'Entity identifier'
}
],
implemented_by: [entity.entity]
}
];
return (
<InterfacesTab
entity={entity}
interfaces={interfaces}
locale="en"
/>
);
}Complete Metadata System Integration
Here’s how to integrate all metadata components into a complete entity metadata management system:
import {
OverviewTab,
FieldsTab,
APITab,
InterfacesTab
} from "@phpcreation/frontend-crud-react-nextjs-bundle/components";
function CompleteMetadataSystem({ entity }: { entity: EntityData }) {
const [activeTab, setActiveTab] = useState("overview");
const getFieldsByType = () => ({
scalar: Object.values(entity.fields).filter(f => f.type === 'scalar').length,
relation: Object.values(entity.fields).filter(f => f.type === 'relation').length,
other: Object.values(entity.fields).filter(f => !['scalar', 'relation'].includes(f.type)).length
});
const generateEndpoints = (entity: EntityData): APIEndpoint[] => {
return [
{
method: 'GET',
path: `/api/v1/${entity.resourceName}`,
description: `List all ${entity.resourceName}`,
responses: { '200': { description: 'Success' } }
},
{
method: 'POST',
path: `/api/v1/${entity.resourceName}`,
description: `Create new ${entity.resourceName}`,
responses: { '201': { description: 'Created' } }
},
{
method: 'PUT',
path: `/api/v1/${entity.resourceName}/{id}`,
description: `Update ${entity.resourceName}`,
responses: { '200': { description: 'Updated' } }
},
{
method: 'DELETE',
path: `/api/v1/${entity.resourceName}/{id}`,
description: `Delete ${entity.resourceName}`,
responses: { '204': { description: 'Deleted' } }
}
];
};
const handleFieldEdit = (field: Field) => {
console.log('Editing field:', field.name);
// Implement field editing logic
};
return (
<div className="bg-white rounded-lg shadow-lg">
{/* Tab Navigation */}
<div className="border-b border-gray-200">
<nav className="flex space-x-8 px-6">
{[
{ id: "overview", label: "Overview", icon: "📊" },
{ id: "fields", label: "Fields", icon: "🏗️" },
{ id: "api", label: "API Documentation", icon: "📡" },
{ id: "interfaces", label: "Interfaces", icon: "🔌" }
].map(tab => (
<button
key={tab.id}
className={`py-4 px-1 border-b-2 font-medium text-sm flex items-center gap-2 ${
activeTab === tab.id
? 'border-blue-500 text-blue-600'
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
}`}
onClick={() => setActiveTab(tab.id)}
>
<span>{tab.icon}</span>
{tab.label}
</button>
))}
</nav>
</div>
{/* Tab Content */}
<div className="p-6">
{activeTab === "overview" && (
<OverviewTab
entity={entity}
getFieldsByType={getFieldsByType}
locale="en"
/>
)}
{activeTab === "fields" && (
<FieldsTab
entity={entity}
fields={Object.values(entity.fields)}
onFieldEdit={handleFieldEdit}
locale="en"
/>
)}
{activeTab === "api" && (
<APITab
entity={entity}
endpoints={generateEndpoints(entity)}
baseUrl="/api/v1"
locale="en"
/>
)}
{activeTab === "interfaces" && (
<InterfacesTab
entity={entity}
interfaces={entity.class_object_data?.implemented_interfaces || []}
locale="en"
/>
)}
</div>
</div>
);
}Best Practices
Advanced Features
Metadata Synchronization
function MetadataSync({ entity }: { entity: EntityData }) {
const [syncing, setSyncing] = useState(false);
const syncMetadata = async () => {
setSyncing(true);
try {
// Sync with backend metadata
await fetch(`/api/metadata/sync/${entity.resourceName}`, {
method: 'POST'
});
// Refresh metadata
window.location.reload();
} finally {
setSyncing(false);
}
};
return (
<Button onClick={syncMetadata} disabled={syncing}>
{syncing ? 'Syncing...' : 'Sync Metadata'}
</Button>
);
}Export Metadata
function MetadataExport({ entity }: { entity: EntityData }) {
const exportMetadata = (format: 'json' | 'yaml' | 'markdown') => {
const data = {
entity: entity.entity,
fields: Object.values(entity.fields),
operations: entity.operations,
interfaces: entity.class_object_data?.implemented_interfaces
};
let content = '';
let mimeType = '';
switch (format) {
case 'json':
content = JSON.stringify(data, null, 2);
mimeType = 'application/json';
break;
case 'yaml':
content = yaml.dump(data);
mimeType = 'application/x-yaml';
break;
case 'markdown':
content = generateMarkdownDocs(data);
mimeType = 'text/markdown';
break;
}
const blob = new Blob([content], { type: mimeType });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${entity.resourceName}-metadata.${format}`;
a.click();
};
return (
<div className="flex gap-2">
<Button onClick={() => exportMetadata('json')}>Export JSON</Button>
<Button onClick={() => exportMetadata('yaml')}>Export YAML</Button>
<Button onClick={() => exportMetadata('markdown')}>Export Docs</Button>
</div>
);
}This comprehensive metadata system provides complete documentation and management capabilities for your entities, making it easy for developers to understand and work with your data structures.