Add comprehensive features.json schema with translations, layouts, actions, and component configurations

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-08 13:31:21 +00:00
parent a8ee69e133
commit be1b6f02d3
3 changed files with 728 additions and 0 deletions

View File

@@ -1,4 +1,330 @@
{
"translations": {
"en": {
"features": {
"database-crud": {
"name": "Database CRUD Operations",
"description": "Create, read, update, and delete database records"
},
"table-management": {
"name": "Table Management",
"description": "Create and manage database tables"
},
"column-management": {
"name": "Column Management",
"description": "Add, modify, and delete table columns"
},
"sql-query": {
"name": "SQL Query Interface",
"description": "Execute custom SQL queries"
},
"constraint-management": {
"name": "Constraint Management",
"description": "Add and manage table constraints (PRIMARY KEY, UNIQUE, CHECK)"
},
"query-builder": {
"name": "Query Builder",
"description": "Visual query builder for creating SELECT queries"
},
"index-management": {
"name": "Index Management",
"description": "Create and manage database indexes for performance optimization"
}
},
"actions": {
"create": "Create",
"read": "Read",
"update": "Update",
"delete": "Delete",
"add": "Add",
"modify": "Modify",
"execute": "Execute",
"list": "List",
"build": "Build"
},
"tables": {
"users": {
"name": "Users",
"description": "User accounts and profiles"
},
"products": {
"name": "Products",
"description": "Product catalog"
}
},
"columns": {
"id": "ID",
"name": "Name",
"email": "Email",
"created_at": "Created At",
"updated_at": "Updated At"
}
},
"fr": {
"features": {
"database-crud": {
"name": "Opérations CRUD de base de données",
"description": "Créer, lire, mettre à jour et supprimer des enregistrements de base de données"
},
"table-management": {
"name": "Gestion des tables",
"description": "Créer et gérer des tables de base de données"
},
"column-management": {
"name": "Gestion des colonnes",
"description": "Ajouter, modifier et supprimer des colonnes de table"
},
"sql-query": {
"name": "Interface de requête SQL",
"description": "Exécuter des requêtes SQL personnalisées"
},
"constraint-management": {
"name": "Gestion des contraintes",
"description": "Ajouter et gérer les contraintes de table (PRIMARY KEY, UNIQUE, CHECK)"
},
"query-builder": {
"name": "Constructeur de requêtes",
"description": "Constructeur de requêtes visuel pour créer des requêtes SELECT"
},
"index-management": {
"name": "Gestion des index",
"description": "Créer et gérer des index de base de données pour l'optimisation des performances"
}
},
"actions": {
"create": "Créer",
"read": "Lire",
"update": "Mettre à jour",
"delete": "Supprimer",
"add": "Ajouter",
"modify": "Modifier",
"execute": "Exécuter",
"list": "Lister",
"build": "Construire"
},
"tables": {
"users": {
"name": "Utilisateurs",
"description": "Comptes et profils utilisateur"
},
"products": {
"name": "Produits",
"description": "Catalogue de produits"
}
},
"columns": {
"id": "ID",
"name": "Nom",
"email": "E-mail",
"created_at": "Créé le",
"updated_at": "Mis à jour le"
}
}
},
"actions": {
"database-crud": {
"create": "createRecord",
"read": "readRecords",
"update": "updateRecord",
"delete": "deleteRecord"
},
"table-management": {
"create": "createTable",
"delete": "dropTable"
},
"column-management": {
"add": "addColumn",
"modify": "modifyColumn",
"delete": "dropColumn"
},
"sql-query": {
"execute": "executeQuery"
},
"constraint-management": {
"list": "listConstraints",
"add": "addConstraint",
"delete": "deleteConstraint"
},
"query-builder": {
"build": "buildQuery",
"execute": "executeBuiltQuery"
},
"index-management": {
"list": "listIndexes",
"create": "createIndex",
"delete": "deleteIndex"
}
},
"tableLayouts": {
"users": {
"columns": ["id", "name", "email", "created_at", "updated_at"],
"columnWidths": {
"id": 80,
"name": 200,
"email": 250,
"created_at": 180,
"updated_at": 180
},
"defaultSort": {
"column": "created_at",
"direction": "desc"
},
"hiddenColumns": [],
"frozenColumns": ["id"]
},
"products": {
"columns": ["id", "name", "price", "stock", "created_at"],
"columnWidths": {
"id": 80,
"name": 250,
"price": 120,
"stock": 100,
"created_at": 180
},
"defaultSort": {
"column": "name",
"direction": "asc"
},
"hiddenColumns": [],
"frozenColumns": ["id"]
}
},
"columnLayouts": {
"id": {
"align": "left",
"format": "number",
"editable": false
},
"name": {
"align": "left",
"format": "text",
"editable": true
},
"email": {
"align": "left",
"format": "email",
"editable": true
},
"created_at": {
"align": "left",
"format": "datetime",
"editable": false
},
"updated_at": {
"align": "left",
"format": "datetime",
"editable": false
},
"price": {
"align": "right",
"format": "currency",
"editable": true
},
"stock": {
"align": "right",
"format": "number",
"editable": true
}
},
"tableFeatures": {
"users": {
"enablePagination": true,
"enableSearch": true,
"enableExport": true,
"enableFilters": true,
"rowsPerPage": 25,
"allowedActions": ["create", "read", "update", "delete"]
},
"products": {
"enablePagination": true,
"enableSearch": true,
"enableExport": true,
"enableFilters": true,
"rowsPerPage": 50,
"allowedActions": ["create", "read", "update", "delete"]
}
},
"columnFeatures": {
"id": {
"searchable": true,
"sortable": true,
"filterable": true,
"required": true
},
"name": {
"searchable": true,
"sortable": true,
"filterable": true,
"required": true
},
"email": {
"searchable": true,
"sortable": true,
"filterable": true,
"required": true,
"validation": "email"
},
"created_at": {
"searchable": false,
"sortable": true,
"filterable": true,
"required": false
},
"updated_at": {
"searchable": false,
"sortable": true,
"filterable": true,
"required": false
},
"price": {
"searchable": true,
"sortable": true,
"filterable": true,
"required": true,
"validation": "number"
},
"stock": {
"searchable": true,
"sortable": true,
"filterable": true,
"required": true,
"validation": "number"
}
},
"componentLayouts": {
"DataGrid": {
"headerHeight": 56,
"rowHeight": 48,
"density": "standard",
"showBorders": true,
"alternateRowColors": false,
"hoverHighlight": true
},
"FormDialog": {
"width": "md",
"fullScreen": false,
"showCloseButton": true,
"disableBackdropClick": false
},
"ConfirmDialog": {
"width": "sm",
"showCloseButton": true,
"confirmButtonColor": "primary",
"cancelButtonColor": "default"
},
"Sidebar": {
"width": 240,
"collapsible": true,
"defaultOpen": true,
"variant": "permanent"
},
"Toolbar": {
"height": 64,
"showSearch": true,
"showUserMenu": true,
"elevation": 2
}
},
"features": [
{
"id": "database-crud",

View File

@@ -6,6 +6,17 @@ import {
getFeatureById,
getFeatures,
getNavItems,
getTranslations,
getFeatureTranslation,
getActionTranslation,
getTableTranslation,
getColumnTranslation,
getActionFunctionName,
getTableLayout,
getColumnLayout,
getTableFeatures,
getColumnFeatures,
getComponentLayout,
} from './featureConfig';
describe('FeatureConfig', () => {
@@ -385,4 +396,286 @@ describe('FeatureConfig', () => {
});
});
});
describe('getTranslations', () => {
it('should return English translations by default', () => {
const translations = getTranslations();
expect(translations).toBeDefined();
expect(translations).toHaveProperty('features');
expect(translations).toHaveProperty('actions');
expect(translations).toHaveProperty('tables');
expect(translations).toHaveProperty('columns');
});
it('should return French translations when locale is fr', () => {
const translations = getTranslations('fr');
expect(translations).toBeDefined();
expect(translations).toHaveProperty('features');
expect(translations).toHaveProperty('actions');
});
});
describe('getFeatureTranslation', () => {
it('should return English translation for database-crud', () => {
const translation = getFeatureTranslation('database-crud', 'en');
expect(translation).toBeDefined();
expect(translation?.name).toBe('Database CRUD Operations');
expect(translation?.description).toContain('Create, read, update, and delete');
});
it('should return French translation for database-crud', () => {
const translation = getFeatureTranslation('database-crud', 'fr');
expect(translation).toBeDefined();
expect(translation?.name).toBe('Opérations CRUD de base de données');
});
it('should return undefined for non-existent feature', () => {
const translation = getFeatureTranslation('non-existent', 'en');
expect(translation).toBeUndefined();
});
});
describe('getActionTranslation', () => {
it('should return English translation for create action', () => {
const translation = getActionTranslation('create', 'en');
expect(translation).toBe('Create');
});
it('should return French translation for create action', () => {
const translation = getActionTranslation('create', 'fr');
expect(translation).toBe('Créer');
});
it('should return English translation for delete action', () => {
const translation = getActionTranslation('delete', 'en');
expect(translation).toBe('Delete');
});
it('should return French translation for delete action', () => {
const translation = getActionTranslation('delete', 'fr');
expect(translation).toBe('Supprimer');
});
});
describe('getTableTranslation', () => {
it('should return English translation for users table', () => {
const translation = getTableTranslation('users', 'en');
expect(translation).toBeDefined();
expect(translation?.name).toBe('Users');
expect(translation?.description).toBe('User accounts and profiles');
});
it('should return French translation for users table', () => {
const translation = getTableTranslation('users', 'fr');
expect(translation).toBeDefined();
expect(translation?.name).toBe('Utilisateurs');
});
});
describe('getColumnTranslation', () => {
it('should return English translation for name column', () => {
const translation = getColumnTranslation('name', 'en');
expect(translation).toBe('Name');
});
it('should return French translation for name column', () => {
const translation = getColumnTranslation('name', 'fr');
expect(translation).toBe('Nom');
});
it('should return English translation for email column', () => {
const translation = getColumnTranslation('email', 'en');
expect(translation).toBe('Email');
});
});
describe('getActionFunctionName', () => {
it('should return function name for database-crud create action', () => {
const functionName = getActionFunctionName('database-crud', 'create');
expect(functionName).toBe('createRecord');
});
it('should return function name for table-management create action', () => {
const functionName = getActionFunctionName('table-management', 'create');
expect(functionName).toBe('createTable');
});
it('should return function name for column-management add action', () => {
const functionName = getActionFunctionName('column-management', 'add');
expect(functionName).toBe('addColumn');
});
it('should return undefined for non-existent feature', () => {
const functionName = getActionFunctionName('non-existent', 'create');
expect(functionName).toBeUndefined();
});
});
describe('getTableLayout', () => {
it('should return layout configuration for users table', () => {
const layout = getTableLayout('users');
expect(layout).toBeDefined();
expect(layout?.columns).toContain('id');
expect(layout?.columns).toContain('name');
expect(layout?.columns).toContain('email');
expect(layout?.columnWidths).toHaveProperty('id');
expect(layout?.defaultSort).toHaveProperty('column');
expect(layout?.defaultSort).toHaveProperty('direction');
});
it('should return layout configuration for products table', () => {
const layout = getTableLayout('products');
expect(layout).toBeDefined();
expect(layout?.columns).toContain('id');
expect(layout?.columns).toContain('name');
expect(layout?.defaultSort.column).toBe('name');
expect(layout?.defaultSort.direction).toBe('asc');
});
it('should return undefined for non-existent table', () => {
const layout = getTableLayout('non-existent');
expect(layout).toBeUndefined();
});
});
describe('getColumnLayout', () => {
it('should return layout configuration for id column', () => {
const layout = getColumnLayout('id');
expect(layout).toBeDefined();
expect(layout?.align).toBe('left');
expect(layout?.format).toBe('number');
expect(layout?.editable).toBe(false);
});
it('should return layout configuration for email column', () => {
const layout = getColumnLayout('email');
expect(layout).toBeDefined();
expect(layout?.align).toBe('left');
expect(layout?.format).toBe('email');
expect(layout?.editable).toBe(true);
});
it('should return layout configuration for price column', () => {
const layout = getColumnLayout('price');
expect(layout).toBeDefined();
expect(layout?.align).toBe('right');
expect(layout?.format).toBe('currency');
});
});
describe('getTableFeatures', () => {
it('should return features configuration for users table', () => {
const features = getTableFeatures('users');
expect(features).toBeDefined();
expect(features?.enablePagination).toBe(true);
expect(features?.enableSearch).toBe(true);
expect(features?.enableExport).toBe(true);
expect(features?.enableFilters).toBe(true);
expect(features?.rowsPerPage).toBe(25);
expect(features?.allowedActions).toContain('create');
expect(features?.allowedActions).toContain('read');
});
it('should return features configuration for products table', () => {
const features = getTableFeatures('products');
expect(features).toBeDefined();
expect(features?.rowsPerPage).toBe(50);
});
it('should return undefined for non-existent table', () => {
const features = getTableFeatures('non-existent');
expect(features).toBeUndefined();
});
});
describe('getColumnFeatures', () => {
it('should return features configuration for id column', () => {
const features = getColumnFeatures('id');
expect(features).toBeDefined();
expect(features?.searchable).toBe(true);
expect(features?.sortable).toBe(true);
expect(features?.filterable).toBe(true);
expect(features?.required).toBe(true);
});
it('should return features configuration for email column with validation', () => {
const features = getColumnFeatures('email');
expect(features).toBeDefined();
expect(features?.validation).toBe('email');
expect(features?.required).toBe(true);
});
it('should return features configuration for created_at column', () => {
const features = getColumnFeatures('created_at');
expect(features).toBeDefined();
expect(features?.searchable).toBe(false);
expect(features?.sortable).toBe(true);
});
});
describe('getComponentLayout', () => {
it('should return layout configuration for DataGrid component', () => {
const layout = getComponentLayout('DataGrid');
expect(layout).toBeDefined();
expect(layout?.headerHeight).toBe(56);
expect(layout?.rowHeight).toBe(48);
expect(layout?.density).toBe('standard');
expect(layout?.showBorders).toBe(true);
});
it('should return layout configuration for FormDialog component', () => {
const layout = getComponentLayout('FormDialog');
expect(layout).toBeDefined();
expect(layout?.width).toBe('md');
expect(layout?.fullScreen).toBe(false);
expect(layout?.showCloseButton).toBe(true);
});
it('should return layout configuration for Sidebar component', () => {
const layout = getComponentLayout('Sidebar');
expect(layout).toBeDefined();
expect(layout?.width).toBe(240);
expect(layout?.collapsible).toBe(true);
expect(layout?.defaultOpen).toBe(true);
});
it('should return undefined for non-existent component', () => {
const layout = getComponentLayout('NonExistentComponent');
expect(layout).toBeUndefined();
});
});
});

View File

@@ -51,8 +51,73 @@ export type IndexType = {
description: string;
};
export type Translation = {
name: string;
description: string;
};
export type Translations = {
en: {
features: Record<string, Translation>;
actions: Record<string, string>;
tables: Record<string, Translation>;
columns: Record<string, string>;
};
fr: {
features: Record<string, Translation>;
actions: Record<string, string>;
tables: Record<string, Translation>;
columns: Record<string, string>;
};
};
export type TableLayout = {
columns: string[];
columnWidths: Record<string, number>;
defaultSort: {
column: string;
direction: 'asc' | 'desc';
};
hiddenColumns: string[];
frozenColumns: string[];
};
export type ColumnLayout = {
align: 'left' | 'right' | 'center';
format: string;
editable: boolean;
};
export type TableFeatures = {
enablePagination: boolean;
enableSearch: boolean;
enableExport: boolean;
enableFilters: boolean;
rowsPerPage: number;
allowedActions: string[];
};
export type ColumnFeatures = {
searchable: boolean;
sortable: boolean;
filterable: boolean;
required: boolean;
validation?: string;
};
export type ComponentLayout = {
[key: string]: any;
};
// Type definition for the features config structure
type FeaturesConfig = {
translations?: Translations;
actions?: Record<string, Record<string, string>>;
tableLayouts?: Record<string, TableLayout>;
columnLayouts?: Record<string, ColumnLayout>;
tableFeatures?: Record<string, TableFeatures>;
columnFeatures?: Record<string, ColumnFeatures>;
componentLayouts?: Record<string, ComponentLayout>;
features: Feature[];
dataTypes: DataType[];
constraintTypes?: ConstraintType[];
@@ -99,3 +164,47 @@ export function getEnabledFeaturesByPriority(priority: string): Feature[] {
f => f.enabled && f.priority === priority,
);
}
export function getTranslations(locale: 'en' | 'fr' = 'en'): Translations[typeof locale] | undefined {
return config.translations?.[locale];
}
export function getFeatureTranslation(featureId: string, locale: 'en' | 'fr' = 'en'): Translation | undefined {
return config.translations?.[locale]?.features[featureId];
}
export function getActionTranslation(actionName: string, locale: 'en' | 'fr' = 'en'): string | undefined {
return config.translations?.[locale]?.actions[actionName];
}
export function getTableTranslation(tableName: string, locale: 'en' | 'fr' = 'en'): Translation | undefined {
return config.translations?.[locale]?.tables[tableName];
}
export function getColumnTranslation(columnName: string, locale: 'en' | 'fr' = 'en'): string | undefined {
return config.translations?.[locale]?.columns[columnName];
}
export function getActionFunctionName(featureId: string, actionName: string): string | undefined {
return config.actions?.[featureId]?.[actionName];
}
export function getTableLayout(tableName: string): TableLayout | undefined {
return config.tableLayouts?.[tableName];
}
export function getColumnLayout(columnName: string): ColumnLayout | undefined {
return config.columnLayouts?.[columnName];
}
export function getTableFeatures(tableName: string): TableFeatures | undefined {
return config.tableFeatures?.[tableName];
}
export function getColumnFeatures(columnName: string): ColumnFeatures | undefined {
return config.columnFeatures?.[columnName];
}
export function getComponentLayout(componentName: string): ComponentLayout | undefined {
return config.componentLayouts?.[componentName];
}