UNPKG

@mindmakr/gs-websdk

Version:

Web SDK for Guru SaaS System - Complete JavaScript/TypeScript SDK for building applications with dynamic schema management

707 lines (588 loc) 16.1 kB
# Field Properties & UI Enhancement Guide This guide provides comprehensive information about the field properties and UI enhancements available in the Guru SaaS dynamic schema system. These properties allow you to create rich, interactive forms with backend-driven UI configuration. ## Table of Contents - [Overview](#overview) - [Field Enhancement Properties](#field-enhancement-properties) - [Layout Properties](#layout-properties) - [Styling Properties](#styling-properties) - [Validation Properties](#validation-properties) - [Conditional Properties](#conditional-properties) - [Widget-Specific Properties](#widget-specific-properties) - [Theme Integration](#theme-integration) - [Real Backend Examples](#real-backend-examples) ## Overview The Guru SaaS field properties system allows you to define rich UI configurations directly in your schema templates. These properties are stored in the `enhanced_properties` field of schema templates and can be applied using the fluent API builder or directly through the schema management APIs. ### Field Enhancement Structure ```typescript interface FieldEnhancement { // Visual properties icon?: string; image?: string; // Style properties style?: { variant?: 'default' | 'outline' | 'ghost' | 'destructive' | 'secondary'; size?: 'sm' | 'md' | 'lg' | 'xl'; className?: string; }; // Layout properties layout?: { width?: 'quarter' | 'half' | 'three-quarter' | 'full'; height?: 'small' | 'medium' | 'large'; group?: string; order?: number; conditional?: ConditionalConfig; }; // Validation rules validation?: ValidationRule[]; // UI behavior placeholder?: Record<string, string>; helpText?: Record<string, string>; options?: Record<string, any>; } ``` ## Field Enhancement Properties ### Icon Properties Add visual icons to fields for better UX: ```typescript // Using the fluent API .text('email', 'Email Address') .icon('mail') // Direct API call await client.schema.updateFieldEnhancement(templateId, 'email', { icon: 'mail' }); // Backend API endpoint PUT /api/schema-templates/{id}/field-enhancement { "field_key": "email", "enhancement": { "icon": "mail" } } ``` **Available Icons:** - `user`, `mail`, `phone`, `lock`, `calendar`, `clock`, `upload`, `image`, `video`, `audio` - `star`, `heart`, `check`, `x`, `plus`, `minus`, `edit`, `delete`, `save` - `home`, `building`, `map-pin`, `credit-card`, `shield`, `settings` ### Image Properties Add images or visual indicators: ```typescript .text('company', 'Company Name') .image('https://example.com/company-icon.png') // Or using enhancement API { "image": "https://example.com/company-icon.png" } ``` ### Multi-language Support Support multiple languages for labels and help text: ```typescript .text('name', 'Name') .placeholder({ en: 'Enter your full name', es: 'Ingrese su nombre completo', fr: 'Entrez votre nom complet' }) .help({ en: 'Your legal name as it appears on documents', es: 'Su nombre legal tal como aparece en los documentos', fr: 'Votre nom légal tel qu\'il apparaît sur les documents' }) ``` ## Layout Properties ### Width Configuration Control field width using CSS Grid system: ```typescript // Using fluent API .text('firstName', 'First Name') .layout({ width: 'half' }) .text('lastName', 'Last Name') .layout({ width: 'half' }) .textarea('bio', 'Biography') .layout({ width: 'full' }) // Available widths - 'quarter' (25% width) - 'half' (50% width) - 'three-quarter' (75% width) - 'full' (100% width) ``` ### Height Configuration Control field height for textareas and complex widgets: ```typescript .textarea('description', 'Description') .layout({ width: 'full', height: 'large' // 'small', 'medium', 'large' }) ``` ### Field Grouping Group related fields together: ```typescript .section('Contact Information') .text('email', 'Email') .layout({ width: 'half', group: 'contact' }) .phone('phone', 'Phone') .layout({ width: 'half', group: 'contact' }) .text('address', 'Address') .layout({ width: 'full', group: 'contact' }) ``` ### Field Ordering Control the display order of fields: ```typescript .text('priority', 'Priority') .layout({ order: 1 }) .text('title', 'Title') .layout({ order: 0 }) // Will appear first ``` ## Styling Properties ### Variants Control the visual style of form fields: ```typescript .text('username', 'Username') .style({ variant: 'outline', // 'default', 'outline', 'ghost', 'destructive', 'secondary' size: 'lg' // 'sm', 'md', 'lg', 'xl' }) .text('error_field', 'Error Field') .style({ variant: 'destructive' }) // Red styling for errors ``` ### Custom CSS Classes Add custom CSS classes for advanced styling: ```typescript .text('featured', 'Featured Item') .style({ className: 'featured-field highlight-border' }) ``` ### Real Backend Implementation The backend stores these in the `enhanced_properties` field: ```sql -- Schema template table structure CREATE TABLE schema_templates ( id SERIAL PRIMARY KEY, enhanced_properties JSONB, -- other fields... ); -- Example stored data { "username": { "style": { "variant": "outline", "size": "lg" }, "icon": "user" } } ``` ## Validation Properties ### Custom Validation Rules Add complex validation beyond JSON Schema: ```typescript .text('password', 'Password') .validation([ { type: 'min_length', value: 8, message: { en: 'Password must be at least 8 characters', es: 'La contraseña debe tener al menos 8 caracteres' } }, { type: 'regex', value: '^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])', message: { en: 'Password must contain uppercase, lowercase, number, and special character', es: 'La contraseña debe contener mayúsculas, minúsculas, números y caracteres especiales' } } ]) ``` ### Field Dependencies Validate based on other field values: ```typescript .text('confirmPassword', 'Confirm Password') .validation([ { type: 'field_equals', value: 'password', message: { en: 'Passwords must match', es: 'Las contraseñas deben coincidir' } } ]) ``` ### Available Validation Types ```typescript type ValidationType = | 'required' | 'min_length' | 'max_length' | 'min' | 'max' | 'regex' | 'pattern' | 'equals' | 'not_equals' | 'field_equals' | 'field_not_equals' | 'contains' | 'not_contains' | 'in_array' | 'not_in_array' | 'email' | 'url' | 'phone' | 'date' | 'datetime' | 'time' | 'numeric' | 'alpha' | 'alphanumeric'; ``` ## Conditional Properties ### Conditional Display Show/hide fields based on other field values: ```typescript .boolean('hasPhone', 'I have a phone number') .phone('phoneNumber', 'Phone Number') .conditional({ field: 'hasPhone', operator: 'equals', value: true }) // This field will only show when hasPhone is true ``` ### Advanced Conditional Logic ```typescript .select('userType', 'User Type') .options(['individual', 'business'], ['Individual', 'Business']) .text('companyName', 'Company Name') .conditional({ field: 'userType', operator: 'equals', value: 'business' }) .text('taxId', 'Tax ID') .conditional({ field: 'userType', operator: 'equals', value: 'business' }) ``` ### Multiple Conditions ```typescript .text('managerName', 'Manager Name') .conditional([ { field: 'userType', operator: 'equals', value: 'business' }, { field: 'hasManager', operator: 'equals', value: true } ]) ``` ## Widget-Specific Properties ### Text Input Widgets ```typescript .text('search', 'Search') .options({ autocomplete: 'off', spellcheck: false, maxLength: 100 }) ``` ### File Upload Widgets ```typescript .image('profilePicture', 'Profile Picture') .options({ accept: 'image/*', maxSize: 5242880, // 5MB in bytes preview: true, cropRatio: '1:1' }) .file('document', 'Upload Document') .options({ accept: '.pdf,.doc,.docx', maxSize: 10485760, // 10MB multiple: false }) ``` ### Select Widgets ```typescript .select('country', 'Country') .options(['US', 'CA', 'UK'], ['United States', 'Canada', 'United Kingdom']) .uiOptions({ searchable: true, placeholder: 'Select a country', clearable: true }) ``` ### Rich Text Widgets ```typescript .richText('content', 'Content') .options({ toolbar: ['bold', 'italic', 'underline', 'link', 'image'], maxLength: 5000, placeholder: 'Enter your content here...' }) ``` ### Reference Field Widgets ```typescript .reference('relatedProduct', 'Related Product') .options({ entityType: 'product', displayField: 'name', searchFields: ['name', 'sku'], allowEmpty: true, filterBy: { category: 'electronics' }, limit: 10 }) ``` ## Theme Integration ### Automatic Theme Application The SDK automatically applies theme variables to all fields: ```typescript // Theme is automatically applied from backend configuration const layoutConfig = generateLayoutFromSchema(template, currentTheme); // Fields receive theme props automatically <TextInput theme={{ colors: theme.colors, typography: theme.typography, spacing: theme.spacing, borderRadius: theme.borderRadius }} /> ``` ### Custom Theme Overrides Override theme for specific fields: ```typescript .text('highlightedField', 'Important Field') .style({ className: 'custom-theme-override', variant: 'outline' }) .options({ customTheme: { primaryColor: '#ff6b35', borderRadius: '12px' } }) ``` ## Real Backend Examples ### Creating Enhanced Template via API ```javascript // POST /api/schema-templates const templateData = { name: 'Enhanced Customer Form', code: 'enhanced_customer', category: 'customer_management', schema_definition: { type: 'object', title: 'Customer Information', properties: { firstName: { type: 'string', title: 'First Name', minLength: 1, maxLength: 50 }, email: { type: 'string', format: 'email', title: 'Email Address' }, phone: { type: 'string', format: 'phone', title: 'Phone Number' }, priority: { type: 'string', title: 'Priority Level', enum: ['low', 'medium', 'high'], enumNames: ['Low', 'Medium', 'High'] } }, required: ['firstName', 'email'] }, enhanced_properties: { firstName: { icon: 'user', style: { variant: 'outline', size: 'lg' }, layout: { width: 'half' }, validation: [ { type: 'min_length', value: 2, message: { en: 'Name must be at least 2 characters', es: 'El nombre debe tener al menos 2 caracteres' } } ] }, email: { icon: 'mail', style: { variant: 'outline', size: 'lg' }, layout: { width: 'half' }, placeholder: { en: 'Enter your email address', es: 'Ingrese su dirección de correo' } }, phone: { icon: 'phone', layout: { width: 'half' }, options: { format: '(###) ###-####', mask: true } }, priority: { style: { variant: 'outline' }, layout: { width: 'half' }, helpText: { en: 'Select the priority level for this customer', es: 'Seleccione el nivel de prioridad para este cliente' } } } }; const template = await fetch('/api/schema-templates', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(templateData) }); ``` ### Updating Field Enhancement via API ```javascript // PUT /api/schema-templates/{id}/field-enhancement await fetch(`/api/schema-templates/${templateId}/field-enhancement`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ field_key: 'email', enhancement: { icon: 'mail-check', style: { variant: 'outline', size: 'xl' }, validation: [ { type: 'email', message: { en: 'Please enter a valid email address', es: 'Por favor ingrese una dirección de correo válida' } } ] } }) }); ``` ### Getting Field Rendering Configuration ```javascript // GET /api/schema-templates/{id}/field-rendering/{fieldKey} const fieldConfig = await fetch( `/api/schema-templates/${templateId}/field-rendering/email`, { headers: { 'Authorization': `Bearer ${token}` } } ); // Response includes complete rendering configuration { "field_key": "email", "component": "EmailInput", "props": { "label": "Email Address", "placeholder": "Enter your email address", "required": true, "icon": "mail", "variant": "outline", "size": "lg", "validation": [...], "theme": {...} }, "layout": { "width": "half", "order": 1 } } ``` ### Using with SDK ```typescript import { GuruSaaS, TemplateBuilder } from '@mindmakr/gs-websdk'; const client = new GuruSaaS({ baseUrl: 'http://localhost', authUrl: 'http://localhost:4000', globalDataUrl: 'http://localhost:5010', debug: true }); // Using fluent API const template = new TemplateBuilder('customer_profile', 'Customer Profile') .category('customer_management') .section('Personal Information') .text('firstName', 'First Name') .required() .icon('user') .style({ variant: 'outline', size: 'lg' }) .layout({ width: 'half' }) .validation([ { type: 'min_length', value: 2, message: { en: 'Name too short', es: 'Nombre muy corto' } } ]) .email('email', 'Email Address') .required() .icon('mail') .style({ variant: 'outline', size: 'lg' }) .layout({ width: 'half' }) .placeholder({ en: 'your@email.com', es: 'su@email.com' }) .section('Contact Details') .phone('phone', 'Phone Number') .icon('phone') .layout({ width: 'half' }) .options({ format: '(###) ###-####', mask: true }) .select('priority', 'Priority Level') .options(['low', 'medium', 'high'], ['Low', 'Medium', 'High']) .layout({ width: 'half' }) .help({ en: 'Customer priority level', es: 'Nivel de prioridad del cliente' }) .build(); // Create the enhanced template const createdTemplate = await client.schema.createSchemaTemplate(template); // Get enhanced field properties const enhancements = await client.schema.getEnhancedFieldProperties(createdTemplate.id); // Generate layout configuration const layoutConfig = generateLayoutFromSchema(createdTemplate, currentTheme); ``` This comprehensive field properties system allows you to create rich, interactive forms that are completely driven by backend configuration, making your applications highly flexible and customizable without requiring frontend code changes.