@@ -7,6 +7,36 @@ import { TableInformation } from './ai-data-entities/types/ai-module-types.js';
77import { TableSettingsEntity } from '../table-settings/common-table-settings/table-settings.entity.js' ;
88import { AICoreService , AIProviderType , cleanAIJsonResponse } from '../../ai-core/index.js' ;
99
10+ interface AIGeneratedWidgetParams {
11+ options ?: Array < { value : string ; label : string ; background_color ?: string } > ;
12+ allow_null ?: boolean ;
13+ unit ?: string ;
14+ threshold_min ?: number ;
15+ threshold_max ?: number ;
16+ height ?: number ;
17+ prefix ?: string ;
18+ encrypt ?: boolean ;
19+ algorithm ?: string ;
20+ min ?: number ;
21+ max ?: number ;
22+ step ?: number ;
23+ formatDistanceWithinHours ?: number ;
24+ language ?: string ;
25+ rows ?: number ;
26+ invert_colors ?: boolean ;
27+ validate ?: string ;
28+ regex ?: string ;
29+ type ?: string ;
30+ format ?: string ;
31+ show_flag ?: boolean ;
32+ preferred_countries ?: string [ ] ;
33+ enable_placeholder ?: boolean ;
34+ phone_validation ?: boolean ;
35+ version ?: string ;
36+ namespace ?: string ;
37+ name ?: string ;
38+ }
39+
1040interface AIGeneratedTableSettings {
1141 table_name : string ;
1242 display_name : string ;
@@ -18,6 +48,7 @@ interface AIGeneratedTableSettings {
1848 widgets : Array < {
1949 field_name : string ;
2050 widget_type : string ;
51+ widget_params ?: AIGeneratedWidgetParams ;
2152 name : string ;
2253 description : string ;
2354 } > ;
@@ -106,29 +137,96 @@ For each table, provide:
1061377. widgets: For each column, suggest the best widget type from: ${ widgetTypes }
107138
108139Available widget types and when to use them:
109- - Password: for password fields
110- - Boolean: for boolean/bit columns
111- - Date: for date columns
112- - Time: for time-only columns
113- - DateTime: for datetime/timestamp columns
114- - JSON: for JSON/JSONB columns
115- - Textarea: for long text fields (description, content, etc.)
116- - String: for short text fields (name, title, etc.)
117- - Readonly: for auto-generated fields
118- - Number: for numeric columns
119- - Select: for columns with limited options
120- - UUID: for UUID columns
121- - Enum: for enum columns
122- - Foreign_key: for foreign key columns
123- - File: for file path columns
124- - Image: for image URL columns
125- - URL: for URL columns
126- - Code: for code snippets
127- - Phone: for phone number columns
128- - Country: for country columns
129- - Color: for color columns (hex values)
130- - Range: for range values
131- - Timezone: for timezone columns
140+
141+ PASSWORD WIDGET:
142+ - Use for: password, secret, hash columns
143+ - REQUIRED params: {"encrypt": true, "algorithm": "bcrypt"}
144+ - Algorithms: sha1, sha3, sha224, sha256, sha512, sha384, bcrypt (recommended), scrypt, argon2, pbkdf2
145+ - Detect existing hash by pattern:
146+ * bcrypt: starts with "$2a$", "$2b$", or "$2y$" (60 chars)
147+ * argon2: starts with "$argon2"
148+ * scrypt: starts with "$scrypt$"
149+ * pbkdf2: starts with "$pbkdf2"
150+ * sha1: 40 hex characters
151+ * sha256: 64 hex characters (most common)
152+ * sha512: 128 hex characters
153+
154+ BOOLEAN WIDGET:
155+ - Use for: boolean, bit, tinyint(1) columns, is_*, has_*, can_* columns
156+ - Params: {"allow_null": false, "invert_colors": false}
157+
158+ DATE/TIME WIDGETS:
159+ - Date: for date columns (params: {"formatDistanceWithinHours": 24} - shows "2 hours ago" for recent)
160+ - Time: for time-only columns (no params needed)
161+ - DateTime: for datetime/timestamp columns (params: {"formatDistanceWithinHours": 24})
162+
163+ TEXT WIDGETS:
164+ - String: for short text (name, title, email) - params: {"validate": "isEmail"} for email validation
165+ Validators: isEmail, isURL, isUUID, isAlpha, isNumeric, isMobilePhone, isPostalCode, isCreditCard
166+ - Textarea: for long text (description, content, bio) - params: {"rows": 5}
167+ - JSON: for JSON/JSONB columns (no params needed)
168+ - Code: for code/script columns - params: {"language": "html|css|typescript|yaml|markdown|sql"}
169+ - Readonly: for auto-generated, computed fields (no params needed)
170+
171+ NUMBER WIDGET:
172+ - Use for: int, decimal, float columns
173+ - Params: {"unit": "bytes|meters|seconds|kg", "threshold_min": 0, "threshold_max": 1000}
174+ - Unit examples: bytes, KB, MB, meters, km, seconds, minutes, kg, USD
175+
176+ SELECT WIDGET:
177+ - Use for: status, type, category columns with known/limited values
178+ - REQUIRED params: {"allow_null": true, "options": [{"value": "db_value", "label": "Display Label", "background_color": "#hex"}]}
179+ - Infer options from column name (status: active/inactive, type: user/admin, priority: low/medium/high)
180+
181+ RANGE WIDGET:
182+ - Use for: rating, progress, percentage columns
183+ - Params: {"min": 0, "max": 100, "step": 1}
184+
185+ UUID WIDGET:
186+ - Use for: uuid columns
187+ - Params: {"version": "v4"} - versions: v1, v3, v4 (default), v5, v7
188+
189+ IMAGE WIDGET:
190+ - Use for: avatar, photo, image_url, thumbnail columns
191+ - Params: {"height": 100, "prefix": "https://cdn.example.com/"}
192+
193+ FILE WIDGET:
194+ - Use for: file_path, document, attachment columns
195+ - Params: {"type": "file|hex|base64"}
196+
197+ URL WIDGET:
198+ - Use for: website, link, url columns
199+ - Params: {"prefix": "https://"} if values don't include protocol
200+
201+ PHONE WIDGET:
202+ - Use for: phone, mobile, telephone columns
203+ - Params: {"preferred_countries": ["US", "GB"], "phone_validation": true}
204+
205+ COUNTRY WIDGET:
206+ - Use for: country, country_code columns
207+ - Params: {"show_flag": true, "allow_null": false}
208+
209+ COLOR WIDGET:
210+ - Use for: color, hex_color columns
211+ - Params: {"format": "hex_hash"} - formats: hex, hex_hash, rgb, hsl
212+
213+ TIMEZONE WIDGET:
214+ - Use for: timezone, tz columns
215+ - Params: {"allow_null": false}
216+
217+ FOREIGN_KEY WIDGET:
218+ - Use ONLY for columns that reference another table but are NOT detected as foreign keys
219+ - Skip if foreign key is already detected in table structure
220+ - Params: {"column_name": "user_id", "referenced_table_name": "users", "referenced_column_name": "id"}
221+
222+ WIDGET SELECTION RULES:
223+ 1. Match widget type to column data type AND column name semantics
224+ 2. For password/hash columns: Always use Password with encrypt:true and detect algorithm from hash pattern
225+ 3. For status/type/category columns: Use Select with sensible options inferred from column name
226+ 4. For columns ending in _id that aren't foreign keys: Consider Foreign_key widget
227+ 5. For columns named email, phone, url, etc.: Use specialized widgets (String with isEmail validator, Phone, URL)
228+ 6. For auto_increment or primary key columns: Use Readonly
229+ 7. Provide widget_params only when the widget type benefits from configuration
132230
133231Database tables to analyze:
134232${ tablesDescription }
@@ -146,15 +244,39 @@ Respond ONLY with valid JSON in this exact format (no markdown, no explanations)
146244 "ordering_field": "created_at",
147245 "widgets": [
148246 {
149- "field_name": "column_name",
247+ "field_name": "id",
248+ "widget_type": "Readonly",
249+ "widget_params": {},
250+ "name": "ID",
251+ "description": "Unique identifier"
252+ },
253+ {
254+ "field_name": "email",
150255 "widget_type": "String",
151- "name": "Column Display Name",
152- "description": "Description of what this column contains"
256+ "widget_params": {"validate": "isEmail"},
257+ "name": "Email Address",
258+ "description": "User email for login and communication"
259+ },
260+ {
261+ "field_name": "password_hash",
262+ "widget_type": "Password",
263+ "widget_params": {"encrypt": true, "algorithm": "bcrypt"},
264+ "name": "Password",
265+ "description": "Encrypted user password"
266+ },
267+ {
268+ "field_name": "status",
269+ "widget_type": "Select",
270+ "widget_params": {"options": [{"value": "active", "label": "Active"}, {"value": "inactive", "label": "Inactive"}], "allow_null": true},
271+ "name": "Status",
272+ "description": "Current status of the record"
153273 }
154274 ]
155275 }
156276 ]
157- }` ;
277+ }
278+
279+ IMPORTANT: For each widget, include appropriate widget_params based on the column name, type, and semantics. Use empty {} for widgets that don't need special configuration.` ;
158280 }
159281
160282 private parseAIResponse ( aiResponse : string , tablesInformation : Array < TableInformation > ) : AIResponse {
@@ -189,13 +311,21 @@ Respond ONLY with valid JSON in this exact format (no markdown, no explanations)
189311 settings . table_widgets = tableSettings . widgets
190312 . filter ( ( w ) => validColumnNames . includes ( w . field_name ) )
191313 . map ( ( widgetData ) => {
314+ const widgetType = this . mapWidgetType ( widgetData . widget_type ) ;
315+ if ( ! widgetType || widgetType === WidgetTypeEnum . Foreign_key ) {
316+ return null ;
317+ }
192318 const widget = new TableWidgetEntity ( ) ;
193319 widget . field_name = widgetData . field_name ;
194- widget . widget_type = this . mapWidgetType ( widgetData . widget_type ) ;
320+ widget . widget_type = widgetType ;
195321 widget . name = widgetData . name ;
196322 widget . description = widgetData . description ;
323+ if ( widgetData . widget_params && Object . keys ( widgetData . widget_params ) . length > 0 ) {
324+ widget . widget_params = JSON . stringify ( widgetData . widget_params ) ;
325+ }
197326 return widget ;
198- } ) ;
327+ } )
328+ . filter ( ( w ) : w is TableWidgetEntity => w !== null ) ;
199329
200330 return settings ;
201331 } ) ;
@@ -225,7 +355,6 @@ Respond ONLY with valid JSON in this exact format (no markdown, no explanations)
225355 [ 'Number' , WidgetTypeEnum . Number ] ,
226356 [ 'Select' , WidgetTypeEnum . Select ] ,
227357 [ 'UUID' , WidgetTypeEnum . UUID ] ,
228- [ 'Enum' , WidgetTypeEnum . Enum ] ,
229358 [ 'Foreign_key' , WidgetTypeEnum . Foreign_key ] ,
230359 [ 'File' , WidgetTypeEnum . File ] ,
231360 [ 'Image' , WidgetTypeEnum . Image ] ,
0 commit comments