@dforge-core/dforge-mcp 0.1.0-rc.9 → 0.1.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.
- package/CHANGELOG.md +132 -0
- package/README.md +84 -27
- package/dist/server.js +2957 -616
- package/docs/creating-modules.md +11 -4
- package/package.json +11 -6
- package/resources/docs/conventions.md +22 -16
- package/resources/docs/dsl-reference.md +767 -0
- package/resources/schemas/entity.schema.json +8 -1
- package/resources/schemas/print-templates.schema.json +82 -0
- package/resources/schemas/reports.schema.json +4 -0
- package/resources/schemas/triggers.schema.json +59 -0
- package/skills/dforge-mcp-author/SKILL.md +269 -69
- package/skills/dforge-mcp-author/examples/matrix-budget/README.md +43 -0
- package/skills/dforge-mcp-author/examples/matrix-budget/entities/budget_category.json +24 -0
- package/skills/dforge-mcp-author/examples/matrix-budget/entities/budget_line.json +56 -0
- package/skills/dforge-mcp-author/examples/matrix-budget/manifest.json +30 -0
- package/skills/dforge-mcp-author/examples/matrix-budget/security/roles.json +9 -0
- package/skills/dforge-mcp-author/examples/matrix-budget/seed-data/01-categories.json +8 -0
- package/skills/dforge-mcp-author/examples/matrix-budget/ui/data_views.json +42 -0
- package/skills/dforge-mcp-author/examples/simple-todo/README.md +38 -0
- package/skills/dforge-mcp-author/examples/simple-todo/entities/todo_item.json +83 -0
- package/skills/dforge-mcp-author/examples/simple-todo/entities/todo_list.json +43 -0
- package/skills/dforge-mcp-author/examples/simple-todo/logic/actions/mark_done.dsl +6 -0
- package/skills/dforge-mcp-author/examples/simple-todo/manifest.json +32 -0
- package/skills/dforge-mcp-author/examples/simple-todo/security/roles.json +10 -0
- package/skills/dforge-mcp-author/examples/simple-todo/seed-data/01-lists.json +17 -0
- package/skills/dforge-mcp-author/examples/simple-todo/ui/actions.json +11 -0
- package/skills/dforge-mcp-author/examples/simple-todo/ui/data_views.json +35 -0
- package/skills/dforge-mcp-author/examples/simple-todo/ui/menus.json +28 -0
- package/skills/dforge-mcp-author/references/action-dsl.md +397 -0
- package/skills/dforge-mcp-author/references/column-types.md +168 -0
- package/skills/dforge-mcp-author/references/conventions.md +177 -0
- package/skills/dforge-mcp-author/references/data-migration.md +270 -0
- package/skills/dforge-mcp-author/references/data-views.md +243 -0
- package/skills/dforge-mcp-author/references/excel-import.md +61 -0
- package/skills/dforge-mcp-author/references/field-types.md +144 -0
- package/skills/dforge-mcp-author/references/filters.md +326 -0
- package/skills/dforge-mcp-author/references/flags.md +73 -0
- package/skills/dforge-mcp-author/references/formulas.md +206 -0
- package/skills/dforge-mcp-author/references/jobs.md +149 -0
- package/skills/dforge-mcp-author/references/manifest.md +123 -0
- package/skills/dforge-mcp-author/references/menus.md +164 -0
- package/skills/dforge-mcp-author/references/number-sequences.md +117 -0
- package/skills/dforge-mcp-author/references/print-templates.md +159 -0
- package/skills/dforge-mcp-author/references/queries.md +312 -0
- package/skills/dforge-mcp-author/references/reports.md +398 -0
- package/skills/dforge-mcp-author/references/schema-import.md +331 -0
- package/skills/dforge-mcp-author/references/security.md +244 -0
- package/skills/dforge-mcp-author/references/settings.md +120 -0
- package/skills/dforge-mcp-author/references/traits.md +153 -0
- package/skills/dforge-mcp-author/references/translations.md +158 -0
- package/skills/dforge-mcp-author/references/validation-checklist.md +183 -0
- package/skills/dforge-mcp-author/scripts/xlsx_to_model.py +198 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
# Reports Reference
|
|
2
|
+
|
|
3
|
+
Reports are **query-driven visualizations** — charts, KPIs, pivot tables, grids — backed by datasets. Unlike data views (which target one entity), reports can combine multiple datasets and render any layout.
|
|
4
|
+
|
|
5
|
+
Lives in: `ui/reports.json` or `ui/reports/<report_code>.json`
|
|
6
|
+
SP files: `logic/reports/rpt_*.sql`
|
|
7
|
+
|
|
8
|
+
## Structure
|
|
9
|
+
|
|
10
|
+
```json
|
|
11
|
+
{
|
|
12
|
+
"sales_pipeline": {
|
|
13
|
+
"description": "Open opportunities by stage",
|
|
14
|
+
"datasets": {
|
|
15
|
+
"ds_pipeline": {
|
|
16
|
+
"caption": "Pipeline Data",
|
|
17
|
+
"entityCode": "opportunity",
|
|
18
|
+
"columns": ["stage", "total_amount", "account"],
|
|
19
|
+
"filter": {
|
|
20
|
+
"g": "and",
|
|
21
|
+
"i": [
|
|
22
|
+
{ "c": "stage", "o": "!in", "v": ["Closed Won", "Closed Lost"] }
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"groupBy": ["stage"],
|
|
26
|
+
"aggregations": {
|
|
27
|
+
"opp_count": { "func": "count", "column": "*" },
|
|
28
|
+
"total_value": { "func": "sum", "column": "total_amount" }
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"layout": [
|
|
33
|
+
{
|
|
34
|
+
"vizType": "bar",
|
|
35
|
+
"datasetCd": "ds_pipeline",
|
|
36
|
+
"title": "Pipeline Value by Stage",
|
|
37
|
+
"config": {
|
|
38
|
+
"categoryCol": "stage",
|
|
39
|
+
"valueCol": "total_value",
|
|
40
|
+
"agg": "sum"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"vizType": "grid",
|
|
45
|
+
"datasetCd": "ds_pipeline",
|
|
46
|
+
"title": "Pipeline Detail"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"params": {
|
|
50
|
+
"owner_filter": {
|
|
51
|
+
"fieldTypeCd": "user",
|
|
52
|
+
"label": "Filter by Owner",
|
|
53
|
+
"required": false
|
|
54
|
+
},
|
|
55
|
+
"start_date": {
|
|
56
|
+
"fieldTypeCd": "date",
|
|
57
|
+
"label": "Start Date",
|
|
58
|
+
"required": false,
|
|
59
|
+
"default": "=STARTMONTH()"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Dataset types
|
|
67
|
+
|
|
68
|
+
### Entity query dataset (most common)
|
|
69
|
+
|
|
70
|
+
Queries an entity's data using the platform's query builder. Filters use the standard JSON filter format (see `references/filters.md`).
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
"ds_sales": {
|
|
74
|
+
"caption": "Sales Data",
|
|
75
|
+
"entityCode": "opportunity",
|
|
76
|
+
"columns": ["stage", "total_amount", "close_date", "account"],
|
|
77
|
+
"filter": { "c": "stage", "o": "!=", "v": "Closed Lost" },
|
|
78
|
+
"sort": [{ "column_cd": "close_date", "direction": "desc" }],
|
|
79
|
+
"groupBy": ["stage"],
|
|
80
|
+
"aggregations": {
|
|
81
|
+
"deal_count": { "func": "count", "column": "*" },
|
|
82
|
+
"total_value": { "func": "sum", "column": "total_amount" },
|
|
83
|
+
"avg_value": { "func": "avg", "column": "total_amount" }
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Aggregation functions: `count`, `sum`, `avg`, `min`, `max`.
|
|
89
|
+
|
|
90
|
+
### Stored procedure dataset (developer path)
|
|
91
|
+
|
|
92
|
+
For complex SQL that the entity query can't express — window functions, CTEs, cross-schema joins, conditional aggregation, multi-result sets.
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
"aging_data": {
|
|
96
|
+
"caption": "AR Aging",
|
|
97
|
+
"datasetType": "S",
|
|
98
|
+
"sp": "rpt_ar_aging",
|
|
99
|
+
"params": {
|
|
100
|
+
"as_of_date": {
|
|
101
|
+
"fieldTypeCd": "date",
|
|
102
|
+
"label": "As of Date",
|
|
103
|
+
"required": true,
|
|
104
|
+
"default": "=NOW()"
|
|
105
|
+
},
|
|
106
|
+
"customer_id": {
|
|
107
|
+
"fieldTypeCd": "lookup",
|
|
108
|
+
"label": "Customer",
|
|
109
|
+
"required": false,
|
|
110
|
+
"params": { "entityCd": "customer" }
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
"columnsDef": {
|
|
114
|
+
"customer_name": {
|
|
115
|
+
"label": "Customer",
|
|
116
|
+
"fieldTypeCd": "text",
|
|
117
|
+
"baseDatatypeCd": "string",
|
|
118
|
+
"width": 200
|
|
119
|
+
},
|
|
120
|
+
"current_amount": {
|
|
121
|
+
"label": "Current",
|
|
122
|
+
"fieldTypeCd": "number",
|
|
123
|
+
"baseDatatypeCd": "number",
|
|
124
|
+
"format": "#,##0.00",
|
|
125
|
+
"width": 120
|
|
126
|
+
},
|
|
127
|
+
"days_30": {
|
|
128
|
+
"label": "1-30 Days",
|
|
129
|
+
"fieldTypeCd": "number",
|
|
130
|
+
"baseDatatypeCd": "number",
|
|
131
|
+
"format": "#,##0.00",
|
|
132
|
+
"width": 120
|
|
133
|
+
},
|
|
134
|
+
"total": {
|
|
135
|
+
"label": "Total",
|
|
136
|
+
"fieldTypeCd": "number",
|
|
137
|
+
"baseDatatypeCd": "number",
|
|
138
|
+
"format": "#,##0.00",
|
|
139
|
+
"width": 130
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Key differences from entity datasets:
|
|
146
|
+
- `datasetType: "S"` (instead of default entity query)
|
|
147
|
+
- `sp` — the stored procedure function name (without schema — uses the module's schema)
|
|
148
|
+
- `columnsDef` — **required** — explicitly defines columns since the platform can't infer them from entity metadata
|
|
149
|
+
- Params can be defined per-dataset (dataset-level) or per-report (report-level)
|
|
150
|
+
|
|
151
|
+
### The PostgreSQL function
|
|
152
|
+
|
|
153
|
+
SP files live in `logic/reports/` and follow this convention:
|
|
154
|
+
|
|
155
|
+
```sql
|
|
156
|
+
CREATE OR REPLACE FUNCTION crm.rpt_ar_aging(
|
|
157
|
+
p_folder_uid uuid, -- REQUIRED: injected by platform (folder context)
|
|
158
|
+
p_user_id bigint, -- REQUIRED: injected by platform (current user)
|
|
159
|
+
p_as_of_date date DEFAULT NULL, -- User parameter
|
|
160
|
+
p_customer_id bigint DEFAULT NULL -- User parameter (optional)
|
|
161
|
+
)
|
|
162
|
+
RETURNS TABLE (
|
|
163
|
+
customer_name text,
|
|
164
|
+
current_amount numeric,
|
|
165
|
+
days_30 numeric,
|
|
166
|
+
days_60 numeric,
|
|
167
|
+
days_90 numeric,
|
|
168
|
+
over_90 numeric,
|
|
169
|
+
total numeric
|
|
170
|
+
)
|
|
171
|
+
LANGUAGE sql STABLE
|
|
172
|
+
AS $$
|
|
173
|
+
SELECT
|
|
174
|
+
c.account_name AS customer_name,
|
|
175
|
+
SUM(CASE WHEN age <= 30 THEN i.amount_due ELSE 0 END) AS current_amount,
|
|
176
|
+
SUM(CASE WHEN age BETWEEN 31 AND 60 THEN i.amount_due ELSE 0 END) AS days_30,
|
|
177
|
+
-- ... more columns ...
|
|
178
|
+
SUM(i.amount_due) AS total
|
|
179
|
+
FROM fin.invoice i
|
|
180
|
+
JOIN crm.account c ON c.account_id = i.customer_id
|
|
181
|
+
WHERE i.status != 'Paid'
|
|
182
|
+
AND (p_customer_id IS NULL OR i.customer_id = p_customer_id)
|
|
183
|
+
GROUP BY c.account_name
|
|
184
|
+
ORDER BY total DESC;
|
|
185
|
+
$$;
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Rules for SP functions:**
|
|
189
|
+
- First two params are **always** `p_folder_uid uuid` and `p_user_id bigint` — injected by the platform
|
|
190
|
+
- User params come after, with `DEFAULT NULL` for optional ones
|
|
191
|
+
- Use `RETURNS TABLE (...)` for single result sets
|
|
192
|
+
- Use `RETURNS SETOF refcursor` for multiple result sets (advanced)
|
|
193
|
+
- Use the module's schema prefix: `crm.rpt_*`, `fin.rpt_*`, etc.
|
|
194
|
+
- Use `STABLE` volatility (read-only, enables PostgreSQL optimization)
|
|
195
|
+
- **Security is your responsibility** — filter by `p_folder_uid` and `p_user_id` where needed
|
|
196
|
+
|
|
197
|
+
### Multi-result-set SPs
|
|
198
|
+
|
|
199
|
+
For reports with multiple related datasets from one query:
|
|
200
|
+
|
|
201
|
+
```json
|
|
202
|
+
"datasets": {
|
|
203
|
+
"summary": {
|
|
204
|
+
"caption": "Department Summary",
|
|
205
|
+
"datasetType": "S",
|
|
206
|
+
"sp": "rpt_department_overview",
|
|
207
|
+
"spCursor": "department_summary",
|
|
208
|
+
"columnsDef": { /* ... */ }
|
|
209
|
+
},
|
|
210
|
+
"by_role": {
|
|
211
|
+
"caption": "By Role",
|
|
212
|
+
"datasetType": "S",
|
|
213
|
+
"sp": "rpt_department_overview",
|
|
214
|
+
"spCursor": "employee_breakdown",
|
|
215
|
+
"columnsDef": { /* ... */ }
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Multiple datasets share the same `sp` (function called once). `spCursor` maps each dataset to a named refcursor returned by the function.
|
|
221
|
+
|
|
222
|
+
## Parameters
|
|
223
|
+
|
|
224
|
+
Parameters prompt the user for input before running the report (or action). Both reports and actions use the same parameter system.
|
|
225
|
+
|
|
226
|
+
### Report-level parameters
|
|
227
|
+
|
|
228
|
+
Defined in the report's `params` object:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
"params": {
|
|
232
|
+
"start_date": {
|
|
233
|
+
"fieldTypeCd": "date",
|
|
234
|
+
"label": "Start Date",
|
|
235
|
+
"required": true,
|
|
236
|
+
"default": "=STARTMONTH()"
|
|
237
|
+
},
|
|
238
|
+
"end_date": {
|
|
239
|
+
"fieldTypeCd": "date",
|
|
240
|
+
"label": "End Date",
|
|
241
|
+
"required": true,
|
|
242
|
+
"default": "=NOW()"
|
|
243
|
+
},
|
|
244
|
+
"region": {
|
|
245
|
+
"fieldTypeCd": "dropdown",
|
|
246
|
+
"label": "Region",
|
|
247
|
+
"required": false,
|
|
248
|
+
"params": {
|
|
249
|
+
"options": ["All", "North", "South", "East", "West"]
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
"customer": {
|
|
253
|
+
"fieldTypeCd": "lookup",
|
|
254
|
+
"label": "Customer",
|
|
255
|
+
"required": false,
|
|
256
|
+
"params": { "entityCd": "account" }
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Parameter properties
|
|
262
|
+
|
|
263
|
+
| Property | Description |
|
|
264
|
+
|---|---|
|
|
265
|
+
| `fieldTypeCd` | UI control type: `date`, `datetime`, `text`, `number`, `dropdown`, `lookup`, `user`, `checkbox` |
|
|
266
|
+
| `label` | Display label in the parameter dialog |
|
|
267
|
+
| `required` | Whether the user must fill this before running |
|
|
268
|
+
| `default` | Default value — plain value or formula with `=` prefix (e.g. `"=NOW()"`, `"=STARTMONTH()"`, `"=TODAY()"`) |
|
|
269
|
+
| `params` | Additional config — `options` for dropdowns, `entityCd` for lookups |
|
|
270
|
+
|
|
271
|
+
### Using parameters in entity query filters
|
|
272
|
+
|
|
273
|
+
Reference parameters with `@param_code` in filter values:
|
|
274
|
+
|
|
275
|
+
```json
|
|
276
|
+
"filter": {
|
|
277
|
+
"g": "and",
|
|
278
|
+
"i": [
|
|
279
|
+
{ "c": "created_date", "o": ">=", "v": "@start_date" },
|
|
280
|
+
{ "c": "created_date", "o": "<=", "v": "@end_date" }
|
|
281
|
+
]
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Using parameters in SP datasets
|
|
286
|
+
|
|
287
|
+
Parameters are passed to the PostgreSQL function as positional arguments (after the two required system params). The order matches `params` declaration order in the dataset definition.
|
|
288
|
+
|
|
289
|
+
### Action parameters (DSL)
|
|
290
|
+
|
|
291
|
+
Actions declare parameters in the `params:` block of the DSL file:
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
params:
|
|
295
|
+
new_stage: dropdown required "New Stage"
|
|
296
|
+
note: textarea "Note"
|
|
297
|
+
amount: number required "Amount"
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
Access in execute block: `params[param_name]`
|
|
301
|
+
|
|
302
|
+
See `references/action-dsl.md` for full syntax.
|
|
303
|
+
|
|
304
|
+
### Named parameter sets (saved combos)
|
|
305
|
+
|
|
306
|
+
Users can save frequently-used parameter combinations for quick reuse. These are stored per-report or per-action and appear in a dropdown at the top of the parameter dialog. Defined at runtime (not in the module package).
|
|
307
|
+
|
|
308
|
+
### Cross-parameter validation
|
|
309
|
+
|
|
310
|
+
Parameters can have cross-validation rules (e.g. `end_date >= start_date`). This is configured via a `validate` formula on the parameter set. For module packages, validation is typically handled by sensible defaults rather than explicit cross-validation formulas.
|
|
311
|
+
|
|
312
|
+
## Layout
|
|
313
|
+
|
|
314
|
+
The `layout` array defines how datasets are visualized:
|
|
315
|
+
|
|
316
|
+
```json
|
|
317
|
+
"layout": [
|
|
318
|
+
{
|
|
319
|
+
"vizType": "bar",
|
|
320
|
+
"datasetCd": "ds_pipeline",
|
|
321
|
+
"title": "Pipeline by Stage",
|
|
322
|
+
"config": {
|
|
323
|
+
"categoryCol": "stage",
|
|
324
|
+
"valueCol": "total_value",
|
|
325
|
+
"agg": "sum",
|
|
326
|
+
"chartSize": "l"
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"vizType": "grid",
|
|
331
|
+
"datasetCd": "ds_pipeline",
|
|
332
|
+
"title": "Detail"
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
"vizType": "kpi",
|
|
336
|
+
"datasetCd": "ds_pipeline",
|
|
337
|
+
"title": "Total Value",
|
|
338
|
+
"config": {
|
|
339
|
+
"valueCol": "total_value",
|
|
340
|
+
"format": "currency"
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"vizType": "pie",
|
|
345
|
+
"datasetCd": "ds_pipeline",
|
|
346
|
+
"title": "Distribution",
|
|
347
|
+
"config": {
|
|
348
|
+
"categoryCol": "stage",
|
|
349
|
+
"valueCol": "opp_count"
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
]
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Visualization types
|
|
356
|
+
|
|
357
|
+
| `vizType` | Description | Config |
|
|
358
|
+
|---|---|---|
|
|
359
|
+
| `grid` | Tabular data with sort/filter | — |
|
|
360
|
+
| `bar` | Vertical bar chart | `categoryCol`, `valueCol`, `agg` |
|
|
361
|
+
| `bar-stacked` | Stacked vertical bar | `categoryCol`, `valueCol`, `stackCol`, `agg` |
|
|
362
|
+
| `h-bar` | Horizontal bar | Same as `bar` |
|
|
363
|
+
| `line` | Line chart | `categoryCol`, `valueCol`, `agg` |
|
|
364
|
+
| `area` | Area chart | Same as `line` |
|
|
365
|
+
| `pie` | Pie chart | `categoryCol`, `valueCol` |
|
|
366
|
+
| `doughnut` | Doughnut chart | Same as `pie` |
|
|
367
|
+
| `scatter` | Scatter plot | `xCol`, `yCol` |
|
|
368
|
+
| `combo` | Combined bar + line | `categoryCol`, `barCol`, `lineCol` |
|
|
369
|
+
| `kpi` | Single value card | `valueCol`, `format` (optional: gauge, progress, sparkline, icon variants) |
|
|
370
|
+
| `pivot` | Pivot table | `rowCols`, `colCols`, `valueCols`, `aggFunc` |
|
|
371
|
+
|
|
372
|
+
### Chart size
|
|
373
|
+
|
|
374
|
+
Chart visualizations support an optional `config.chartSize` property to control the default display height.
|
|
375
|
+
|
|
376
|
+
| Field | Type | Allowed values | Description |
|
|
377
|
+
|---|---|---|---|
|
|
378
|
+
| `config.chartSize` | string | `sm`, `m`, `l`, `xl` | Optional size preset for chart height. When omitted, the default is `m`. |
|
|
379
|
+
|
|
380
|
+
## Grants
|
|
381
|
+
|
|
382
|
+
Report access is granted via the `E` right:
|
|
383
|
+
|
|
384
|
+
```json
|
|
385
|
+
"rights": {
|
|
386
|
+
"report.sales_pipeline": "E"
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## Common mistakes
|
|
391
|
+
|
|
392
|
+
- Mixing `entityCode` + SP fields (`datasetType`, `sp`, `columnsDef`) in the same dataset — pick one source type.
|
|
393
|
+
- Forgetting `columnsDef` on SP datasets — **required** (platform can't infer columns from a function).
|
|
394
|
+
- Forgetting to grant `E` access in at least one role — report becomes invisible.
|
|
395
|
+
- Forgetting `p_folder_uid` and `p_user_id` as first two SP function params — call will fail.
|
|
396
|
+
- Using `panels` instead of `layout` for the visualization array — use `layout`.
|
|
397
|
+
- Using `widget` instead of `vizType` — use `vizType`.
|
|
398
|
+
- Referencing a parameter as `$param` — use `@param_code` in filters.
|