============================================================================================ NOW.JS FRAMEWORK - ARCHITECTURE DIAGRAM ============================================================================================ ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ BROWSER / CLIENT SIDE │ ├─────────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ HTML TEMPLATES (/templates/) │ │ ├─ users.html │ │ ├─ profile.html │ │ ├─ settings/ │ │ │ ├─ categories.html ┌─ Settings form with editable table │ │ │ ├─ languages.html │ │ │ │ └─ general.html └─ Complex settings forms with multiple fieldsets │ │ │ │ DATA BINDING LAYER (HTML Attributes) │ │ ├─ data-table="identifier" ← Activates TableManager │ │ ├─ data-form="identifier" ← Activates FormManager │ │ ├─ data-component="name" ← Activates ComponentManager │ │ ├─ data-source="api/..." ← API endpoint for data │ │ ├─ data-load-api="api/..." ← API endpoint for form loading │ │ ├─ data-attr="value:field" ← Bind attributes with expressions │ │ ├─ data-i18n ← Translation key │ │ ├─ data-if="condition" ← Conditional rendering │ │ ├─ data-template="${...}" ← Custom cell rendering │ │ └─ data-format="datetime" ← Built-in formatters │ │ │ │ JAVASCRIPT MANAGERS (Now/js/) │ │ ┌──────────────────────────────────────────────────────────────────────────────────┐ │ │ │ CORE MANAGERS │ │ │ ├──────────────────────────────────────────────────────────────────────────────────┤ │ │ │ │ │ │ │ ┌─────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │ │ │ │ FormManager │ │ TableManager │ │ ApiService │ │ │ │ │ │ (141 KB) │ │ (236 KB) │ │ (43 KB) │ │ │ │ │ ├─────────────────┤ ├──────────────────┤ ├──────────────────┤ │ │ │ │ │ • Validation │ │ • Sorting │ │ • HTTP requests │ │ │ │ │ │ • Data binding │ │ • Filtering │ │ • Caching │ │ │ │ │ │ • AJAX submit │ │ • Pagination │ │ • Auth headers │ │ │ │ │ │ • File upload │ │ • Row actions │ │ • Retries │ │ │ │ │ │ • Error display │ │ • Bulk actions │ │ • CSRF token │ │ │ │ │ │ • Loading state │ │ • Cell templates │ │ • Deduplication │ │ │ │ │ └─────────────────┘ └──────────────────┘ └──────────────────┘ │ │ │ │ │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │ │ │ │ AuthManager │ │ RouterManager │ │ ComponentManager │ │ │ │ │ │ (41 KB) │ │ (55 KB) │ │ (34 KB) │ │ │ │ │ ├──────────────────┤ ├──────────────────┤ ├──────────────────┤ │ │ │ │ │ • Login/logout │ │ • History API │ │ • Mount/unmount │ │ │ │ │ │ • Token mgmt │ │ • Route guards │ │ • Lifecycle │ │ │ │ │ │ • RBAC │ │ • Auth checks │ │ • Templates │ │ │ │ │ │ • Permissions │ │ • Redirects │ │ • i18n │ │ │ │ │ │ • JWT refresh │ │ • URL params │ │ • Props binding │ │ │ │ │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ │ │ │ │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ │ │ │ │ReactiveManager │ │TemplateManager │ │ Other Managers │ │ │ │ │ │ (26 KB) │ │ (127 KB) │ │ │ │ │ │ │ ├──────────────────┤ ├──────────────────┤ ├──────────────────┤ │ │ │ │ │ • Proxies │ │ • Load templates │ │ • MenuManager │ │ │ │ │ │ • Effects │ │ • Directives │ │ • EventManager │ │ │ │ │ │ • Computed props │ │ • Sanitize │ │ • StateManager │ │ │ │ │ │ • Batched update │ │ • Parse expr. │ │ • I18nManager │ │ │ │ │ │ • Dependency trk │ │ • Event binding │ │ • CoreObserver │ │ │ │ │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ELEMENT FACTORIES (Input Field Management) │ │ ├─ TextElementFactory (Text input + autocomplete) │ │ ├─ SelectElementFactory (Dropdowns + cascading) │ │ ├─ FileElementFactory (File upload + preview) │ │ ├─ DateElementFactory (Date/datetime picker) │ │ ├─ NumberElementFactory (Number input) │ │ ├─ MultiSelectElementFactory (Multi-value select) │ │ ├─ PasswordElementFactory (Password strength) │ │ ├─ RangeElementFactory (Slider) │ │ ├─ ColorElementFactory (Color picker) │ │ ├─ TagsElementFactory (Tag input) │ │ └─ Other specialized factories │ │ │ │ SUPPORT SERVICES │ │ ├─ HttpClient (Low-level HTTP) │ │ ├─ TokenService (Auth token storage) │ │ ├─ ResponseHandler (API response processing) │ │ ├─ EventManager (Event emission/listening) │ │ ├─ NotificationManager (Toast/alerts) │ │ ├─ AuthGuard (Route protection) │ │ └─ Others (ScrollManager, MediaViewer, etc.) │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────┘ ⬇ HTTP ⬇ JSON API REQUEST ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │ SERVER SIDE (PHP) │ ├─────────────────────────────────────────────────────────────────────────────────────────┤ │ │ │ API ROUTING │ │ /api/index/{controller}/{action} [QueryString/FormData] │ │ │ │ │ ├─ GET /api/index/users → Controller::get() │ │ ├─ GET /api/index/users?id=123 → Controller::get() [single] │ │ ├─ GET /api/index/profile/get?id=123 → Controller::get() [profile] │ │ ├─ POST /api/index/profile/save → Controller::save() │ │ ├─ POST /api/index/users/action → Controller::action() [bulk] │ │ └─ POST /api/index/profile/remove-{file}→ Controller::removeFile() │ │ │ │ CONTROLLERS (/modules/index/controllers/) │ │ ┌──────────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ users.php profile.php categories.php │ │ │ │ ├─ get() ├─ get() ├─ get() │ │ │ │ ├─ save() ├─ save() ├─ save() │ │ │ │ ├─ action() └─ removeFile() └─ action() │ │ │ │ └─ ... │ │ │ │ │ │ │ │ All extend: \Gcms\Api (base controller) │ │ │ │ Key methods: │ │ │ │ • authenticateRequest($request) → Verify JWT token │ │ │ │ • isSuperAdmin($login) → Check admin role │ │ │ │ • successResponse($msg, $data) → JSON success │ │ │ │ • errorResponse($msg, $code) → JSON error │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────────────┴─────────────────────────┐ │ │ │ Reads from Request object │ │ │ │ ├─ Query params (page, sort, search, filters) │ │ │ │ ├─ POST data (form fields, files) │ │ │ │ ├─ Authentication header/cookie │ │ │ │ └─ CSRF token │ │ │ └─────────────────────────────────────────────────────┘ │ │ ⬇ │ │ │ │ MODELS (/modules/index/models/) │ │ ┌──────────────────────────────────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ users.php profile.php categories.php │ │ │ │ ├─ toDataTable() ├─ get() ├─ toDataTable() │ │ │ │ │ ├─ Build query ├─ Query user ├─ Query list │ │ │ │ │ ├─ Apply filters ├─ Format response ├─ Apply filters │ │ │ │ │ ├─ Apply search ├─ Load options ├─ Apply search │ │ │ │ │ ├─ Apply sort └─ Load metas ├─ Apply sort │ │ │ │ │ └─ Apply pagination └─ Apply pagination │ │ │ │ ├─ get($id) ├─ save() ├─ save() │ │ │ │ │ └─ Single user │ ├─ Validate input │ ├─ Validate │ │ │ │ ├─ save() │ ├─ Update DB │ ├─ Insert/update │ │ │ │ │ └─ Insert/update │ ├─ Handle files │ └─ Return success │ │ │ │ ├─ performAction() │ └─ Return success │ │ │ │ │ │ ├─ Activate └─ validate() └─ performAction() │ │ │ │ │ ├─ Deactivate └─ Check all fields │ │ │ │ │ ├─ Delete │ │ │ │ │ └─ ... │ │ │ │ └─ validate() │ │ │ │ ├─ Check required │ │ │ │ ├─ Check format (email, phone) │ │ │ │ ├─ Check lengths │ │ │ │ └─ Return errors array │ │ │ │ │ │ │ │ All extend: \Kotchasan\Model (base model) │ │ │ │ Key methods: │ │ │ │ • createQuery() → Database query builder │ │ │ │ • select(...) → SELECT columns │ │ │ │ • from(...) → FROM table │ │ │ │ • where(...) → WHERE conditions │ │ │ │ • orderBy(...) → ORDER BY │ │ │ │ • limit/offset → PAGINATION │ │ │ │ • execute() → Run query │ │ │ │ │ │ │ └──────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────────────┴──────────────────────────────┐ │ │ │ Database Queries (Protected) │ │ │ │ ├─ Parameterized queries (SQL injection safe) │ │ │ │ ├─ Input validation │ │ │ │ ├─ Transaction support │ │ │ │ └─ Error handling │ │ │ └──────────────────────────────────────────────────────────┘ │ │ ⬇ │ │ │ │ DATABASE (MySQL/MariaDB) │ │ ├─ user table ← User records │ │ ├─ user_meta table ← User metadata (department, etc.) │ │ ├─ category table ← Categories │ │ ├─ language table ← Languages │ │ └─ other tables ← Settings, permissions, logs, etc. │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────┘ ⬇ JSON ⬇ API RESPONSE RESPONSE FORMAT (Standard JSON) ┌─────────────────────────────────────────────────────────────────┐ │ { │ │ "success": true, ← Operation result │ │ "data": { ← Response payload │ │ "id": 1, │ │ "name": "John", │ │ "rows": [...], ← For tables │ │ "meta": { ← Pagination info │ │ "total": 100, │ │ "page": 1, │ │ "pageSize": 25 │ │ }, │ │ "options": { ← For form dropdowns │ │ "status": [ │ │ {"value": "0", "text": "Inactive"}, │ │ {"value": "1", "text": "Active"} │ │ ] │ │ } │ │ }, │ │ "message": "Success", │ │ "error": null, │ │ "formErrors": null, ← Validation errors │ │ "redirect": "/dashboard" ← Optional redirect │ │ } │ └─────────────────────────────────────────────────────────────────┘ ============================================================================================ KEY DATA FLOW SEQUENCES ============================================================================================ TABLE LOADING SEQUENCE: ───────────────────── 1. HTML:
2. TableManager.initTable() reads HTML attributes 3. ApiService.get('api/index/users?page=1&sort=id desc&search=') 4. Controller::get() validates auth, gets params 5. Model::toDataTable() builds SQL with filters/sort/pagination 6. Database executes query 7. JSON Response: {success: true, data: [rows], meta: {total, page}} 8. TableManager.renderTable() creates HTML rows 9. Apply data-template and data-format 10. Insert HTML into 11. Attach row action handlers 12. Display table FORM LOADING SEQUENCE: ────────────────────── 1. HTML: 2. FormManager.initForm() triggers load 3. ApiService.get('api/index/profile/get?id=123') 4. Controller::get() validates auth, gets profile data 5. Model::get(123) queries database 6. JSON Response: {success: true, data: {id, name, email, ...}, options: {...}} 7. FormManager._bindFormData() iterates elements 8. For each element with data-attr="value:fieldname" - element.value = response.data.fieldname 9. For selects with data-options-key="status" - Populate options from response.options.status 10. Form displayed with loaded data 11. Form marked as "clean" (no changes) FORM SUBMISSION SEQUENCE: ──────────────────────── 1. User modifies form fields 2. User clicks submit button 3. FormManager captures submit event 4. Run client-side validators (validateOnInput, validateOnBlur) 5. Serialize form data (all field values) 6. FormManager.serializeFormData() → FormData or JSON object 7. Add CSRF token from response or meta tag 8. Add Authorization header (JWT token) 9. ApiService.post('api/index/profile/save', formData) 10. POST /api/index/profile/save 11. Controller::save() receives form data 12. Model::validate() checks input - If errors: return {success: false, formErrors: {...}} 13. Model::save() inserts/updates database 14. Return {success: true, data: {...}, message: "Saved", redirect: "/dashboard"} 15. FormManager.handleResponse() - If success: show notification, reset form, redirect - If error: show field errors, highlight invalid fields 16. Display result to user BULK ACTION SEQUENCE: ──────────────────── 1. User selects rows with checkboxes 2. User chooses bulk action (e.g., "delete") 3. TableManager.performBulkAction() 4. Collect selected row IDs 5. ApiService.post('api/index/users/action', {action: 'delete', id: [1,2,3]}) 6. POST /api/index/users/action 7. Controller::action() receives action name and IDs 8. Model::performAction(id, 'delete') for each row 9. Database updates/deletes rows 10. Return {success: true, message: "Deleted 3 rows"} 11. Notification shown to user 12. TableManager.refresh() - reload table data 13. Table displays updated data ============================================================================================