@rglabs/butterfly 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CLAUDE.md +201 -0
  2. package/README.md +371 -0
  3. package/dist/commands/add.d.ts +23 -0
  4. package/dist/commands/add.js +303 -0
  5. package/dist/commands/code.d.ts +11 -0
  6. package/dist/commands/code.js +72 -0
  7. package/dist/commands/create-object.d.ts +6 -0
  8. package/dist/commands/create-object.js +293 -0
  9. package/dist/commands/create-report.d.ts +6 -0
  10. package/dist/commands/create-report.js +154 -0
  11. package/dist/commands/diff.d.ts +4 -0
  12. package/dist/commands/diff.js +238 -0
  13. package/dist/commands/download.d.ts +4 -0
  14. package/dist/commands/download.js +374 -0
  15. package/dist/commands/layout.d.ts +12 -0
  16. package/dist/commands/layout.js +83 -0
  17. package/dist/commands/record.d.ts +21 -0
  18. package/dist/commands/record.js +483 -0
  19. package/dist/commands/run-poc.d.ts +3 -0
  20. package/dist/commands/run-poc.js +18 -0
  21. package/dist/commands/setup.d.ts +3 -0
  22. package/dist/commands/setup.js +66 -0
  23. package/dist/commands/start-poc.d.ts +3 -0
  24. package/dist/commands/start-poc.js +55 -0
  25. package/dist/commands/sync-docs.d.ts +3 -0
  26. package/dist/commands/sync-docs.js +27 -0
  27. package/dist/commands/translate.d.ts +13 -0
  28. package/dist/commands/translate.js +401 -0
  29. package/dist/commands/upload.d.ts +3 -0
  30. package/dist/commands/upload.js +150 -0
  31. package/dist/commands/workflow-info.d.ts +13 -0
  32. package/dist/commands/workflow-info.js +161 -0
  33. package/dist/components/ConflictResolver.d.ts +12 -0
  34. package/dist/components/ConflictResolver.js +77 -0
  35. package/dist/components/DiffView.d.ts +11 -0
  36. package/dist/components/DiffView.js +101 -0
  37. package/dist/components/DownloadProgress.d.ts +11 -0
  38. package/dist/components/DownloadProgress.js +29 -0
  39. package/dist/components/RecordPreview.d.ts +11 -0
  40. package/dist/components/RecordPreview.js +91 -0
  41. package/dist/components/SetupForm.d.ts +8 -0
  42. package/dist/components/SetupForm.js +56 -0
  43. package/dist/components/UploadProgress.d.ts +13 -0
  44. package/dist/components/UploadProgress.js +42 -0
  45. package/dist/diff/adapters/index.d.ts +8 -0
  46. package/dist/diff/adapters/index.js +18 -0
  47. package/dist/diff/adapters/objectsAdapter.d.ts +13 -0
  48. package/dist/diff/adapters/objectsAdapter.js +177 -0
  49. package/dist/diff/adapters/reportsAdapter.d.ts +14 -0
  50. package/dist/diff/adapters/reportsAdapter.js +212 -0
  51. package/dist/diff/adapters/types.d.ts +19 -0
  52. package/dist/diff/adapters/types.js +2 -0
  53. package/dist/diff/engine.d.ts +19 -0
  54. package/dist/diff/engine.js +57 -0
  55. package/dist/diff/types.d.ts +34 -0
  56. package/dist/diff/types.js +110 -0
  57. package/dist/index.d.ts +3 -0
  58. package/dist/index.js +117 -0
  59. package/dist/types/index.d.ts +18 -0
  60. package/dist/types/index.js +2 -0
  61. package/dist/utils/api.d.ts +85 -0
  62. package/dist/utils/api.js +1031 -0
  63. package/dist/utils/auth.d.ts +4 -0
  64. package/dist/utils/auth.js +22 -0
  65. package/dist/utils/bfySplitter.d.ts +12 -0
  66. package/dist/utils/bfySplitter.js +151 -0
  67. package/dist/utils/docs.d.ts +16 -0
  68. package/dist/utils/docs.js +186 -0
  69. package/dist/utils/errorLogger.d.ts +6 -0
  70. package/dist/utils/errorLogger.js +29 -0
  71. package/dist/utils/files.d.ts +14 -0
  72. package/dist/utils/files.js +772 -0
  73. package/dist/utils/lockManager.d.ts +15 -0
  74. package/dist/utils/lockManager.js +126 -0
  75. package/dist/utils/resourceHandlers.d.ts +50 -0
  76. package/dist/utils/resourceHandlers.js +684 -0
  77. package/dist/utils/resourceMapping.d.ts +32 -0
  78. package/dist/utils/resourceMapping.js +210 -0
  79. package/dist/utils/singleResourceDownload.d.ts +14 -0
  80. package/dist/utils/singleResourceDownload.js +261 -0
  81. package/dist/utils/summaryGenerator.d.ts +2 -0
  82. package/dist/utils/summaryGenerator.js +183 -0
  83. package/dist/utils/uploadHandler.d.ts +31 -0
  84. package/dist/utils/uploadHandler.js +263 -0
  85. package/docs/AI_API.md +93 -0
  86. package/docs/CLAUDE.md +216 -0
  87. package/docs/PROJECT_SPECIFIC.md +1 -0
  88. package/docs/RECORD_COMMAND.md +262 -0
  89. package/docs/WORKFLOW_API.md +480 -0
  90. package/docs/bfy-splitting.md +126 -0
  91. package/docs/cli-commands.md +333 -0
  92. package/docs/examples/README.md +95 -0
  93. package/docs/examples/order-system.md +147 -0
  94. package/docs/examples/product-catalog.md +195 -0
  95. package/docs/examples/reports.md +187 -0
  96. package/docs/excel-export.md +216 -0
  97. package/docs/field-types/README.md +29 -0
  98. package/docs/field-types/calculated.md +147 -0
  99. package/docs/field-types/code-mappings.md +84 -0
  100. package/docs/field-types/custom.md +340 -0
  101. package/docs/object-specs/README.md +136 -0
  102. package/docs/object-specs/code-parameters.md +151 -0
  103. package/docs/object-specs/creating.md +203 -0
  104. package/docs/object-specs/js-code-examples.md +208 -0
  105. package/docs/object-specs/js-field-updates.md +168 -0
  106. package/docs/objects/README.md +89 -0
  107. package/docs/objects/creating.md +127 -0
  108. package/docs/page-layout.md +361 -0
  109. package/docs/permissions.md +260 -0
  110. package/docs/reports.md +197 -0
  111. package/docs/state-machines.md +544 -0
  112. package/docs/tasks/create-object.md +81 -0
  113. package/docs/translations.md +346 -0
  114. package/docs/twig-helpers.md +283 -0
  115. package/docs/webservices.md +159 -0
  116. package/docs/workspaces.md +176 -0
  117. package/package.json +59 -0
@@ -0,0 +1,195 @@
1
+ # Product Catalog Example
2
+
3
+ Complete example for creating an e-commerce product catalog.
4
+
5
+ ## Step 1: Create Categories Object
6
+
7
+ ```bash
8
+ # Create object
9
+ butterfly-cli record add objects --data '{
10
+ "name": "Product Categories",
11
+ "table_name": "product_categories",
12
+ "has_order": 1
13
+ }'
14
+ # Note the ID (e.g., 150)
15
+
16
+ # Add fields
17
+ butterfly-cli record add object_specs --data '{"object_id":150,"name":"Name","column_name":"name","type":"string","required":1,"list_column":1,"edit_order_no":1}'
18
+ butterfly-cli record add object_specs --data '{"object_id":150,"name":"Slug","column_name":"slug","type":"slug","edit_order_no":2}'
19
+ butterfly-cli record add object_specs --data '{"object_id":150,"name":"Parent","column_name":"parent_id","type":"dropdown","val_1":"product_categories","val_2":"id","val_3":"name","edit_order_no":3}'
20
+ butterfly-cli record add object_specs --data '{"object_id":150,"name":"Active","column_name":"is_active","type":"checkbox","default_value":"1","edit_order_no":4}'
21
+ ```
22
+
23
+ ## Step 2: Create Products Object
24
+
25
+ ```bash
26
+ # Create object
27
+ butterfly-cli record add objects --data '{
28
+ "name": "Products",
29
+ "table_name": "products",
30
+ "has_trash": 1
31
+ }'
32
+ # Note the ID (e.g., 151)
33
+
34
+ # Basic Info Section
35
+ butterfly-cli record add object_specs --data '{
36
+ "object_id": 151,
37
+ "name": "Title",
38
+ "column_name": "title",
39
+ "type": "string",
40
+ "required": 1,
41
+ "list_column": 1,
42
+ "search_column": 1,
43
+ "section_title": "Basic Information",
44
+ "edit_order_no": 1
45
+ }'
46
+
47
+ butterfly-cli record add object_specs --data '{
48
+ "object_id": 151,
49
+ "name": "SKU",
50
+ "column_name": "sku",
51
+ "type": "string",
52
+ "list_column": 1,
53
+ "column_size": "col-md-6",
54
+ "edit_order_no": 2
55
+ }'
56
+
57
+ butterfly-cli record add object_specs --data '{
58
+ "object_id": 151,
59
+ "name": "Category",
60
+ "column_name": "category_id",
61
+ "type": "dropdown",
62
+ "val_1": "product_categories",
63
+ "val_2": "id",
64
+ "val_3": "name",
65
+ "val_4": "is_active = 1",
66
+ "column_size": "col-md-6",
67
+ "edit_order_no": 3
68
+ }'
69
+
70
+ butterfly-cli record add object_specs --data '{
71
+ "object_id": 151,
72
+ "name": "Description",
73
+ "column_name": "description",
74
+ "type": "textarea",
75
+ "height": 150,
76
+ "edit_order_no": 4
77
+ }'
78
+
79
+ # Pricing Section
80
+ butterfly-cli record add object_specs --data '{
81
+ "object_id": 151,
82
+ "name": "Price",
83
+ "column_name": "price",
84
+ "type": "decimal",
85
+ "required": 1,
86
+ "section_title": "Pricing",
87
+ "column_size": "col-md-4",
88
+ "edit_order_no": 5
89
+ }'
90
+
91
+ butterfly-cli record add object_specs --data '{
92
+ "object_id": 151,
93
+ "name": "Sale Price",
94
+ "column_name": "sale_price",
95
+ "type": "decimal",
96
+ "column_size": "col-md-4",
97
+ "edit_order_no": 6
98
+ }'
99
+
100
+ butterfly-cli record add object_specs --data '{
101
+ "object_id": 151,
102
+ "name": "Tax Rate %",
103
+ "column_name": "tax_rate",
104
+ "type": "decimal",
105
+ "default_value": "18",
106
+ "column_size": "col-md-4",
107
+ "edit_order_no": 7
108
+ }'
109
+
110
+ # Inventory Section
111
+ butterfly-cli record add object_specs --data '{
112
+ "object_id": 151,
113
+ "name": "Stock",
114
+ "column_name": "stock",
115
+ "type": "integer",
116
+ "default_value": "0",
117
+ "section_title": "Inventory",
118
+ "column_size": "col-md-6",
119
+ "edit_order_no": 8
120
+ }'
121
+
122
+ butterfly-cli record add object_specs --data '{
123
+ "object_id": 151,
124
+ "name": "Low Stock Alert",
125
+ "column_name": "low_stock_threshold",
126
+ "type": "integer",
127
+ "default_value": "5",
128
+ "column_size": "col-md-6",
129
+ "edit_order_no": 9
130
+ }'
131
+
132
+ # Media
133
+ butterfly-cli record add object_specs --data '{
134
+ "object_id": 151,
135
+ "name": "Image",
136
+ "column_name": "image",
137
+ "type": "image",
138
+ "section_title": "Media",
139
+ "edit_order_no": 10
140
+ }'
141
+
142
+ # Sidebar fields
143
+ butterfly-cli record add object_specs --data '{
144
+ "object_id": 151,
145
+ "name": "Status",
146
+ "column_name": "status",
147
+ "type": "from_list",
148
+ "val_1": "draft:Draft,active:Active,archived:Archived",
149
+ "default_value": "draft",
150
+ "edit_position": 1,
151
+ "edit_order_no": 1
152
+ }'
153
+
154
+ butterfly-cli record add object_specs --data '{
155
+ "object_id": 151,
156
+ "name": "Featured",
157
+ "column_name": "is_featured",
158
+ "type": "checkbox",
159
+ "edit_position": 1,
160
+ "edit_order_no": 2
161
+ }'
162
+
163
+ # Calculated field
164
+ butterfly-cli record add object_specs --data '{
165
+ "object_id": 151,
166
+ "name": "Final Price",
167
+ "column_name": "final_price",
168
+ "type": "calculated",
169
+ "val_1": "{% set base = info.sale_price > 0 ? info.sale_price : info.price %}{{ base * (1 + info.tax_rate/100) }}",
170
+ "edit_position": 1,
171
+ "edit_order_no": 3
172
+ }'
173
+ ```
174
+
175
+ ## Step 3: Verify
176
+
177
+ ```bash
178
+ # Check products object
179
+ butterfly-cli record get objects --column table_name --value "products"
180
+
181
+ # List all product specs
182
+ butterfly-cli record get object_specs --column object_id --value 151
183
+ ```
184
+
185
+ ## Result
186
+
187
+ You now have:
188
+ - **Product Categories** with hierarchical structure
189
+ - **Products** with:
190
+ - Basic info (title, SKU, category, description)
191
+ - Pricing (price, sale price, tax rate)
192
+ - Inventory tracking
193
+ - Image upload
194
+ - Status workflow
195
+ - Calculated final price with tax
@@ -0,0 +1,187 @@
1
+ # Reports Example
2
+
3
+ Complete example for creating reports with queries and specs via CLI.
4
+
5
+ ## Overview
6
+
7
+ Reports in Butterfly consist of three related tables:
8
+ - `cms_reports` - Main report definition
9
+ - `cms_report_queries` - Sub-queries for the report
10
+ - `cms_report_specs` - Field specifications/columns for display
11
+
12
+ ## Step 1: Create a Report
13
+
14
+ ```bash
15
+ # Create the main report
16
+ butterfly-cli record add cms_reports --data '{
17
+ "name": "Sales Summary",
18
+ "alias": "sales_summary",
19
+ "query": "SELECT o.id, o.order_number, o.total, o.created_at, c.name as customer_name FROM orders o LEFT JOIN customers c ON o.customer_id = c.id WHERE 1=1 {% if filters.date_from %}AND o.created_at >= \"{{ filters.date_from }}\"{% endif %} {% if filters.date_to %}AND o.created_at <= \"{{ filters.date_to }}\"{% endif %}"
20
+ }'
21
+ # Response: SUCCESS (ID: 50)
22
+ ```
23
+
24
+ ### Report Fields
25
+
26
+ | Field | Description |
27
+ |-------|-------------|
28
+ | `name` | Display name of the report |
29
+ | `alias` | URL-friendly identifier (used in file structure) |
30
+ | `query` | Main Twig/SQL query |
31
+ | `cms_report_category_id` | Category ID for grouping |
32
+
33
+ ## Step 2: Add Report Queries
34
+
35
+ Report queries are sub-queries that can be used within the report.
36
+
37
+ ```bash
38
+ # Add a summary query
39
+ butterfly-cli record add cms_report_queries --data '{
40
+ "cms_report_id": 50,
41
+ "name": "totals",
42
+ "system_name": "totals",
43
+ "query": "SELECT COUNT(*) as order_count, SUM(total) as total_revenue FROM orders WHERE 1=1 {% if filters.date_from %}AND created_at >= \"{{ filters.date_from }}\"{% endif %}"
44
+ }'
45
+ # Response: SUCCESS (ID: 101)
46
+
47
+ # Add a query with JavaScript processing
48
+ butterfly-cli record add cms_report_queries --data '{
49
+ "cms_report_id": 50,
50
+ "name": "monthly_breakdown",
51
+ "system_name": "monthly_breakdown",
52
+ "query": "SELECT DATE_FORMAT(created_at, \"%Y-%m\") as month, SUM(total) as revenue FROM orders GROUP BY month ORDER BY month",
53
+ "js_code": "// Process results\ndata.forEach(row => { row.revenue_formatted = \"$\" + parseFloat(row.revenue).toFixed(2); });\nreturn data;"
54
+ }'
55
+ # Response: SUCCESS (ID: 102)
56
+ ```
57
+
58
+ ### Report Query Fields
59
+
60
+ | Field | Description |
61
+ |-------|-------------|
62
+ | `cms_report_id` | Foreign key to parent report |
63
+ | `name` | Display name (used for folder naming) |
64
+ | `system_name` | System identifier |
65
+ | `query` | Twig/SQL query code |
66
+ | `js_code` | JavaScript for post-processing results |
67
+
68
+ ## Step 3: Add Report Specs
69
+
70
+ Report specs define the columns/fields displayed in the report output.
71
+
72
+ ```bash
73
+ # Add column specs
74
+ butterfly-cli record add cms_report_specs --data '{
75
+ "cms_report_id": 50,
76
+ "field_name": "order_number",
77
+ "title": "Order #",
78
+ "order_no": 1
79
+ }'
80
+
81
+ butterfly-cli record add cms_report_specs --data '{
82
+ "cms_report_id": 50,
83
+ "field_name": "customer_name",
84
+ "title": "Customer",
85
+ "order_no": 2
86
+ }'
87
+
88
+ butterfly-cli record add cms_report_specs --data '{
89
+ "cms_report_id": 50,
90
+ "field_name": "total",
91
+ "title": "Total",
92
+ "order_no": 3,
93
+ "js_code": "return \"$\" + parseFloat(value).toFixed(2);"
94
+ }'
95
+
96
+ butterfly-cli record add cms_report_specs --data '{
97
+ "cms_report_id": 50,
98
+ "field_name": "created_at",
99
+ "title": "Date",
100
+ "order_no": 4
101
+ }'
102
+ ```
103
+
104
+ ### Report Spec Fields
105
+
106
+ | Field | Description |
107
+ |-------|-------------|
108
+ | `cms_report_id` | Foreign key to parent report |
109
+ | `field_name` | Column name from query results |
110
+ | `title` | Display title for the column |
111
+ | `order_no` | Display order |
112
+ | `js_code` | JavaScript for formatting the field value |
113
+
114
+ ## Complete Example: Inventory Report
115
+
116
+ ```bash
117
+ # 1. Create the report
118
+ butterfly-cli record add cms_reports --data '{
119
+ "name": "Inventory Status",
120
+ "alias": "inventory_status",
121
+ "query": "SELECT p.id, p.sku, p.title, p.stock, p.low_stock_threshold, (p.stock <= p.low_stock_threshold) as is_low_stock FROM products p WHERE p.status = \"active\" ORDER BY p.stock ASC"
122
+ }'
123
+ # Note the ID (e.g., 51)
124
+
125
+ # 2. Add a summary query
126
+ butterfly-cli record add cms_report_queries --data '{
127
+ "cms_report_id": 51,
128
+ "name": "summary",
129
+ "system_name": "summary",
130
+ "query": "SELECT COUNT(*) as total_products, SUM(CASE WHEN stock <= low_stock_threshold THEN 1 ELSE 0 END) as low_stock_count, SUM(stock) as total_stock FROM products WHERE status = \"active\""
131
+ }'
132
+
133
+ # 3. Add report specs
134
+ butterfly-cli record add cms_report_specs --data '{"cms_report_id":51,"field_name":"sku","title":"SKU","order_no":1}'
135
+ butterfly-cli record add cms_report_specs --data '{"cms_report_id":51,"field_name":"title","title":"Product","order_no":2}'
136
+ butterfly-cli record add cms_report_specs --data '{"cms_report_id":51,"field_name":"stock","title":"Stock","order_no":3}'
137
+ butterfly-cli record add cms_report_specs --data '{
138
+ "cms_report_id": 51,
139
+ "field_name": "is_low_stock",
140
+ "title": "Status",
141
+ "order_no": 4,
142
+ "js_code": "return value == 1 ? \"<span class=badge-danger>Low Stock</span>\" : \"<span class=badge-success>OK</span>\";"
143
+ }'
144
+ ```
145
+
146
+ ## Verify Reports
147
+
148
+ ```bash
149
+ # Get report by alias
150
+ butterfly-cli record get cms_reports --column alias --value "inventory_status"
151
+
152
+ # List all queries for a report
153
+ butterfly-cli record get cms_report_queries --column cms_report_id --value 51
154
+
155
+ # List all specs for a report
156
+ butterfly-cli record get cms_report_specs --column cms_report_id --value 51
157
+ ```
158
+
159
+ ## File Structure After Download
160
+
161
+ When you run `butterfly-cli download -t reports`, reports are saved as:
162
+
163
+ ```
164
+ data/reports/
165
+ ├── categories.json
166
+ └── inventory_status/
167
+ ├── report.json
168
+ ├── main_query.bfy
169
+ ├── queries/
170
+ │ └── summary/
171
+ │ ├── query.json
172
+ │ └── query_code.bfy
173
+ └── specs/
174
+ └── is_low_stock/
175
+ ├── spec.json
176
+ └── code.js
177
+ ```
178
+
179
+ ## Editing Reports
180
+
181
+ After downloading, you can edit report files locally and upload changes using `butterfly-cli upload <path>`:
182
+
183
+ 1. Edit `report.json` - Updates report metadata
184
+ 2. Edit `main_query.bfy` - Updates main query
185
+ 3. Edit `queries/*/query_code.bfy` - Updates query code
186
+ 4. Edit `queries/*/script.js` - Updates query JS processing
187
+ 5. Edit `specs/*/code.js` - Updates spec JS formatting
@@ -0,0 +1,216 @@
1
+ # Excel Export
2
+
3
+ Butterfly provides a built-in Excel export function for generating downloadable spreadsheets from Twig code.
4
+
5
+ ## Where It Works
6
+
7
+ Excel export only works in:
8
+ - **Custom fields** (`template_code.bfy` / `processing_code.bfy`)
9
+ - **Calculated fields** (`code.bfy`)
10
+ - **Reports** (`query_code.bfy`)
11
+ - **Webservices** (`page_code.bfy`)
12
+
13
+ It does **NOT** work in state machine transition codes, even though they use Twig.
14
+
15
+ ## Recommended Pattern: Query Parameter Trigger
16
+
17
+ The best approach is to add a query parameter to the current URL and check for it in the same Twig template:
18
+
19
+ ```twig
20
+ {# Check if export is requested #}
21
+ {% if getParameter('download_excel') %}
22
+ {% set data = db().table('orders').where('status', 'completed').get() %}
23
+ {% do excel().sheet('Orders').autoTable(data).download('orders.xlsx') %}
24
+ {% endif %}
25
+
26
+ {# Display export button - preserves existing URL parameters #}
27
+ <a href="{{ currentUrlWith({'download_excel': 1}) }}" class="btn btn-primary">Export to Excel</a>
28
+ ```
29
+
30
+ ### Preserving URL Parameters with currentUrlWith()
31
+
32
+ Use `currentUrlWith()` to merge new parameters with existing query string parameters. This ensures filters, pagination, and other URL parameters are preserved when triggering the export.
33
+
34
+ ```twig
35
+ {{ currentUrlWith({'download_excel': 1}) }}
36
+ {# If current URL is ?page=2&sort=asc, result is ?page=2&sort=asc&download_excel=1 #}
37
+
38
+ {{ currentUrlWith({'page': 2, 'sort': 'desc'}) }}
39
+ {# New params override existing ones with the same key #}
40
+ ```
41
+
42
+ ## Quick Export (autoTable)
43
+
44
+ ```twig
45
+ {% do excel().sheet('Sheet Name').autoTable(data).download('filename.xlsx') %}
46
+ ```
47
+
48
+ ## With Options
49
+
50
+ ```twig
51
+ {% do excel().sheet('Report').autoTable(data, 'A1', {
52
+ labels: {field_name: 'Custom Label'},
53
+ types: {amount: 'currency', qty: 'number', date: 'date'},
54
+ widths: {description: 40},
55
+ decimals: {price: 2},
56
+ symbols: {amount: '€'},
57
+ exclude: ['id', 'password'],
58
+ only: ['name', 'email', 'total']
59
+ }).download('report.xlsx') %}
60
+ ```
61
+
62
+ ### autoTable Options
63
+
64
+ | Option | Description | Example |
65
+ |----------|--------------------------------------------------|----------------------------------|
66
+ | labels | Custom column headers | `{field_name: 'Custom Label'}` |
67
+ | types | Column data types | `{amount: 'currency'}` |
68
+ | widths | Column widths | `{description: 40}` |
69
+ | decimals | Decimal places for number types | `{price: 2}` |
70
+ | symbols | Currency symbols | `{amount: '€'}` |
71
+ | aligns | Column alignment (overrides type defaults) | `{status: 'center'}` |
72
+ | exclude | Fields to exclude from export | `['id', 'password']` |
73
+ | only | Only include these fields (whitelist) | `['name', 'email', 'total']` |
74
+
75
+ ## Column Types
76
+
77
+ | Type | Output | Default Alignment | Options |
78
+ |----------|------------------|-------------------|------------------------|
79
+ | text | Plain text | left | - |
80
+ | currency | ₺ 1,234.56 | right | symbols: {field: '€'} |
81
+ | number | 1,234 | right | decimals: {field: 0} |
82
+ | decimal | 1,234.56 | right | decimals: {field: 2} |
83
+ | percent | 12.34% | right | - |
84
+ | date | 25.01.2025 | left | - |
85
+ | datetime | 25.01.2025 14:30 | left | - |
86
+
87
+ ## Column Alignment
88
+
89
+ The `aligns` option allows you to override the default alignment for any column.
90
+
91
+ ### Available Alignment Values
92
+
93
+ | Value | Description |
94
+ |--------|---------------------------------------------------------------|
95
+ | left | Align text to the left (default for text, date columns) |
96
+ | center | Center align text |
97
+ | right | Align text to the right (default for number/currency columns) |
98
+
99
+ ### Example
100
+
101
+ ```twig
102
+ {% set orders = db().table('orders').get() %}
103
+
104
+ {% do excel().sheet('Orders').autoTable(orders, 'A1', {
105
+ labels: {
106
+ id: 'Order ID',
107
+ status: 'Status',
108
+ total: 'Total'
109
+ },
110
+ types: {
111
+ total: 'currency'
112
+ },
113
+ aligns: {
114
+ id: 'center',
115
+ status: 'center'
116
+ }
117
+ }).download('orders.xlsx') %}
118
+ ```
119
+
120
+ ## Manual Column Definitions (table)
121
+
122
+ For more control over columns, use the `table()` method:
123
+
124
+ ```twig
125
+ {% do excel().sheet('Sales').table([
126
+ {key: 'product', label: 'Product', width: 30},
127
+ {key: 'qty', label: 'Quantity', type: 'number'},
128
+ {key: 'price', label: 'Price', type: 'currency', symbol: '₺'}
129
+ ], data).download('sales.xlsx') %}
130
+ ```
131
+
132
+ ### Column Definition Properties
133
+
134
+ | Property | Description |
135
+ |----------|--------------------------------|
136
+ | key | Field name in data |
137
+ | label | Column header text |
138
+ | width | Column width |
139
+ | type | Data type (see Column Types) |
140
+ | symbol | Currency symbol for currency type |
141
+
142
+ ## Multi-Sheet Export
143
+
144
+ ```twig
145
+ {% do excel()
146
+ .sheet('Summary').autoTable(summaryData)
147
+ .sheet('Details').autoTable(detailData)
148
+ .download('report.xlsx')
149
+ %}
150
+ ```
151
+
152
+ ## Styling Methods
153
+
154
+ ```twig
155
+ {% set e = excel().sheet('Report').autoTable(data) %}
156
+ {% do e.bold('A1:D1') %}
157
+ {% do e.background('A1:D1', 'FFFF00') %}
158
+ {% do e.border('A1:D10', 'medium') %}
159
+ {% do e.freeze('A2') %}
160
+ {% do e.download('styled.xlsx') %}
161
+ ```
162
+
163
+ ## Available Methods
164
+
165
+ | Method | Description |
166
+ |----------------------------------------|------------------------------|
167
+ | `.sheet(name)` | Create/switch sheet |
168
+ | `.autoTable(data, startCell, options)` | Auto-generate table |
169
+ | `.table(columns, data, startCell)` | Manual column table |
170
+ | `.bold(range)` | Bold text |
171
+ | `.background(range, color)` | Background color (hex) |
172
+ | `.border(range, type)` | Borders: thin, medium, thick |
173
+ | `.freeze(cell)` | Freeze panes |
174
+ | `.merge(range)` | Merge cells |
175
+ | `.width(col, width)` | Set column width |
176
+ | `.wrapText(range)` | Enable text wrap |
177
+ | `.download(filename)` | Download file |
178
+
179
+ ## Complete Example
180
+
181
+ ```twig
182
+ {# In a report query or custom field template_code #}
183
+
184
+ {% if getParameter('export_orders') %}
185
+ {% set orders = db()
186
+ .table('orders')
187
+ .join('customers', 'customers.id', '=', 'orders.customer_id')
188
+ .select(['orders.*', 'customers.name as customer_name'])
189
+ .where('orders.status', 'completed')
190
+ .get()
191
+ %}
192
+
193
+ {% set e = excel().sheet('Orders') %}
194
+ {% do e.autoTable(orders, 'A1', {
195
+ labels: {
196
+ customer_name: 'Customer',
197
+ order_date: 'Date',
198
+ total_amount: 'Total'
199
+ },
200
+ types: {
201
+ order_date: 'date',
202
+ total_amount: 'currency'
203
+ },
204
+ symbols: {total_amount: '₺'},
205
+ exclude: ['id', 'customer_id', 'created_at', 'updated_at']
206
+ }) %}
207
+ {% do e.bold('A1:D1') %}
208
+ {% do e.freeze('A2') %}
209
+ {% do e.download('orders_export.xlsx') %}
210
+ {% endif %}
211
+
212
+ {# Export button - preserves existing URL parameters like filters #}
213
+ <a href="{{ currentUrlWith({'export_orders': 1}) }}" class="btn btn-success">
214
+ <i class="lucide-download"></i> Export to Excel
215
+ </a>
216
+ ```
@@ -0,0 +1,29 @@
1
+ # Field Types
2
+
3
+ ## Basic Types
4
+ string, textarea, integer, float, decimal, money, date, datetime, time, checkbox, yes_no, status, code, password, slug, color_picker, hidden_string, hidden_integer
5
+
6
+ ## Selection Types
7
+ | Type | val_1 | val_2 | val_3 | val_4 | val_5 |
8
+ |------|-------|-------|-------|-------|-------|
9
+ | dropdown | table_name | title_column | value_column | where | - |
10
+ | autocomplete | table_name | search_column | value_column | where | additional_columns |
11
+ | from_list | options (pipe-separated) | edit_on_list | other_value | - | - |
12
+
13
+ ## Multi-Select Types
14
+ multidropdown, multicheckbox, multicheckbox_from_list, tag, hierarchy, tree
15
+
16
+ ## File Types
17
+ file_upload, file_upload_multiple, image_upload, image_upload_multiple, image_upload_extended
18
+
19
+ ## Advanced Types
20
+ | Type | val_1 | val_2 | val_3 |
21
+ |------|-------|-------|-------|
22
+ | [calculated](./calculated.md) | twig_code | - | - |
23
+ | [custom](./custom.md) | template_code | processing_code | - |
24
+ | filter | - | - | filter_code |
25
+ | nested | yaml_config | multiple | sortable |
26
+ | nested_single | yaml_config | - | - |
27
+
28
+ ## Column Sizes
29
+ `1` `1/2` `1/3` `1/4` `2/3` `3/4`