@jigx/core-sdk 1.0.0 → 1.2.0-rc
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/README.md +2 -0
- package/dist/action/ja.generate-pdf.d.ts +17 -1
- package/dist/action/ja.generate-pdf.d.ts.map +1 -1
- package/dist/action/ja.generate-pdf.js +4 -1
- package/dist/action/ja.in-background.d.ts +3 -2
- package/dist/action/ja.in-background.d.ts.map +1 -1
- package/dist/action/ja.in-background.js +1 -1
- package/dist/assets/example-extraction-cache.json +3 -3
- package/dist/assets/extracted-core-sdk-examples.yaml +18 -0
- package/dist/assets/extracted-core-sdk-types.yaml +58 -0
- package/dist/assets/type-extraction-cache.json +3 -3
- package/docs/array-fields.md +371 -0
- package/docs/conditional-logic.md +178 -0
- package/docs/convention-naming.md +102 -0
- package/docs/date-field.md +92 -0
- package/docs/dropdown-fields.md +879 -0
- package/docs/field-state.md +131 -0
- package/docs/field-types-overview.md +132 -0
- package/docs/formatting.md +421 -0
- package/docs/icons.md +142 -0
- package/docs/index.md +23 -0
- package/docs/jsonata-expressions.md +200 -0
- package/docs/media-fields.md +107 -0
- package/docs/overview.md +467 -0
- package/docs/pattern-build-deploy.md +91 -0
- package/docs/pattern-datasources.md +459 -0
- package/docs/pattern-forms.md +528 -0
- package/docs/pattern-global-actions.md +92 -0
- package/docs/pattern-javascript-functions.md +452 -0
- package/docs/pattern-navigation.md +304 -0
- package/docs/pattern-pdf-generation.md +391 -0
- package/docs/pattern-rest-acumatica.md +660 -0
- package/docs/pattern-sync-progress.md +96 -0
- package/docs/pattern-sync.md +653 -0
- package/docs/pattern-tabs-form.md +293 -0
- package/docs/recipe-index.md +64 -0
- package/docs/runtime-variables.md +127 -0
- package/docs/sections.md +81 -0
- package/docs/validation-patterns.md +150 -0
- package/package.json +5 -4
- package/CHANGELOG.md +0 -95
package/docs/overview.md
ADDED
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
# Expert SDK Overview
|
|
2
|
+
|
|
3
|
+
Available documentation resources for Core SDK forms and wizards.
|
|
4
|
+
|
|
5
|
+
## Field Types
|
|
6
|
+
|
|
7
|
+
Expert SDK provides these field types:
|
|
8
|
+
|
|
9
|
+
| Type | Purpose | Default Required |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `text` | Single/multi-line text input | Yes |
|
|
12
|
+
| `email` | Email with format validation | Yes |
|
|
13
|
+
| `phone` | Phone with phone-pad keyboard | Yes |
|
|
14
|
+
| `number` | Numeric input | Yes |
|
|
15
|
+
| `checkbox` | Boolean toggle | **No** |
|
|
16
|
+
| `date` | Date/time picker (mode: date/time/datetime) | Yes |
|
|
17
|
+
| `dropdown` | Single/multi selection from list | Yes |
|
|
18
|
+
| `choice-field` | Radio buttons or chips | Yes |
|
|
19
|
+
| `media` | File/image upload | Yes |
|
|
20
|
+
| `signature` | Signature capture pad | Yes |
|
|
21
|
+
| `duration-picker` | Time duration selector | Yes |
|
|
22
|
+
| `avatar-field` | Profile picture selector | Yes |
|
|
23
|
+
| `location` | GPS coordinate capture | Yes |
|
|
24
|
+
| `rating` | Star rating scale | Yes |
|
|
25
|
+
| `slider` | Range selection with min/max | Yes |
|
|
26
|
+
|
|
27
|
+
**Common properties** (all fields): `icon`, `helperText`, `errorText`, `value`, `isDisabled`, `isRequired`, `isVisible`
|
|
28
|
+
|
|
29
|
+
**Ref:** `./dropdown-fields.md` for dropdown patterns
|
|
30
|
+
**Ref:** `./choice-fields.md` for choice vs dropdown decision
|
|
31
|
+
|
|
32
|
+
**Details:** [Field Types Overview](./field-types-overview.md)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Field State
|
|
37
|
+
|
|
38
|
+
Every field has `.state.value` that provides live access to the current field value. Updates immediately as user types.
|
|
39
|
+
|
|
40
|
+
**Scope:** Current step only - not accessible from other steps.
|
|
41
|
+
|
|
42
|
+
**Use for:**
|
|
43
|
+
|
|
44
|
+
- Same-step conditional visibility
|
|
45
|
+
- Same-step validation
|
|
46
|
+
- Real-time field dependencies within one step
|
|
47
|
+
|
|
48
|
+
**For cross-step data:** Use `step.data.getFieldData()` instead.
|
|
49
|
+
|
|
50
|
+
**Dropdown special case:** Dropdowns also expose `dropdownField.state.selected` for full object access in the same step.
|
|
51
|
+
|
|
52
|
+
**Details:** [Field State](./field-state.md)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## About JSONata
|
|
57
|
+
|
|
58
|
+
The Expert SDK uses [JSONata](https://jsonata.org/) (v1.8) as its expression language. JSONata is a lightweight query and transformation language for JSON data, similar to XPath for XML.
|
|
59
|
+
|
|
60
|
+
**Key characteristics and rules:**
|
|
61
|
+
|
|
62
|
+
- Functional expression language (no side effects)
|
|
63
|
+
- Path navigation with dot notation
|
|
64
|
+
- Built-in functions for string, array, date manipulation
|
|
65
|
+
- Single `=` for equality (not `==`)
|
|
66
|
+
- `&` for string concatenation (not `+`)
|
|
67
|
+
- `$now()` returns ISO string — use `$millis()` for date comparisons/diffs
|
|
68
|
+
- `null` can't be used in math, string concat, comparisons, or array operations — always check first: `$x ? $x > 0 : false`
|
|
69
|
+
|
|
70
|
+
Official docs: [jsonata.org](https://jsonata.org/)
|
|
71
|
+
|
|
72
|
+
## Value Types
|
|
73
|
+
|
|
74
|
+
Field properties support two modes:
|
|
75
|
+
|
|
76
|
+
| Mode | API | Use When |
|
|
77
|
+
| --- | --- | --- |
|
|
78
|
+
| **Static** | Constructor arg or `.with()` | Constant values that never change |
|
|
79
|
+
| **Dynamic** | `new JsonataBuilder(body, variables)` | Values dependent on other data |
|
|
80
|
+
|
|
81
|
+
## JSONata Reference
|
|
82
|
+
|
|
83
|
+
| Operator | Example | ⚠️ Never Use |
|
|
84
|
+
| --- | --- | --- |
|
|
85
|
+
| `=` | `$x = "value"` | `==` |
|
|
86
|
+
| `!=` | `$x != "value"` | `!==`, `<>` |
|
|
87
|
+
| `and` | `$a and $b` | `&&` |
|
|
88
|
+
| `or` | `$a or $b` | `\|\|` |
|
|
89
|
+
| `$not()` | `$not($a)` | `!`, `not` |
|
|
90
|
+
| `&` | `$a & " " & $b` | `+` (except math) |
|
|
91
|
+
| `? :` | `$x ? "yes" : "no"` | (ternary conditional) |
|
|
92
|
+
| `:=` | `$temp := $x * 2` | (assignment) |
|
|
93
|
+
| `..` | `1..10` | (range → array) |
|
|
94
|
+
| `~>` | `$x ~> $uppercase` | (pipe/transform) |
|
|
95
|
+
|
|
96
|
+
**Fallback pattern** (use ternary instead of elvis/null coalesce):
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
$x ? $x : "default"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Functions:**
|
|
103
|
+
|
|
104
|
+
| Category | Functions |
|
|
105
|
+
| --- | --- |
|
|
106
|
+
| String | `$uppercase` `$lowercase` `$substring` `$length` `$trim` `$contains` `$split` `$join` |
|
|
107
|
+
| Array | `$count` `$sum` `$max` `$min` `$distinct` `$sort` `$reverse` `$filter` `$map` `$in` |
|
|
108
|
+
| Date | `$now` `$millis` `$toMillis` `$fromMillis` |
|
|
109
|
+
| Type | `$string` `$number` `$boolean` `$type` |
|
|
110
|
+
|
|
111
|
+
**Details:** [JSONata Expressions](./jsonata-expressions.md)
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Conditional Logic
|
|
116
|
+
|
|
117
|
+
Make fields conditionally visible or required based on other field values using `JsonataBuilder`.
|
|
118
|
+
|
|
119
|
+
**Common patterns:**
|
|
120
|
+
|
|
121
|
+
- Show field when another has specific value
|
|
122
|
+
- Require field only when relevant
|
|
123
|
+
- Combine multiple conditions
|
|
124
|
+
|
|
125
|
+
**Details:** [Conditional Logic](./conditional-logic.md)
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Field Validation
|
|
130
|
+
|
|
131
|
+
Use `errorText` with `JsonataBuilder` to show validation messages based on field values. Messages appear when expression returns non-null string.
|
|
132
|
+
|
|
133
|
+
**Pattern:** Expression returns error message string when invalid, `null` when valid.
|
|
134
|
+
|
|
135
|
+
**Details:** [Validation Patterns](./validation-patterns.md)
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Sections
|
|
140
|
+
|
|
141
|
+
Use `addSection()` to group related fields visually within a step. Improves form organization and user experience.
|
|
142
|
+
|
|
143
|
+
**When to use:**
|
|
144
|
+
|
|
145
|
+
- Group 3+ related fields together
|
|
146
|
+
- Separate different types of information (personal vs professional)
|
|
147
|
+
- Create visual hierarchy in longer forms
|
|
148
|
+
- Improve scannability
|
|
149
|
+
|
|
150
|
+
**Details:** [Sections](./sections.md)
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Dropdown Fields
|
|
155
|
+
|
|
156
|
+
Four data source patterns for dropdown options:
|
|
157
|
+
|
|
158
|
+
| Source | Use When | Data Type |
|
|
159
|
+
| --- | --- | --- |
|
|
160
|
+
| **Static** | Fixed list <20 items (priorities, statuses) | `{label, value, icon?}[]` |
|
|
161
|
+
| **Dynamic** | Database-backed data (products, customers) | `DatasourceBuilder` |
|
|
162
|
+
| **ArrayField** | Cross-step data from arrayField | `step.data.getArrayFieldData()` |
|
|
163
|
+
| **Package** | ERP/CRM data via data packages (Acumatica, etc.) | `PackageDataBuilder` |
|
|
164
|
+
|
|
165
|
+
**Dropdown vs Choice:**
|
|
166
|
+
|
|
167
|
+
- Dropdown: >6 options OR long option labels
|
|
168
|
+
- Choice: ≤6 options AND short labels
|
|
169
|
+
|
|
170
|
+
**Multi-selection:** Set `isMultiple: true` for multiple selections.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Static vs Dynamic Decision
|
|
175
|
+
|
|
176
|
+
**Use static options when:**
|
|
177
|
+
|
|
178
|
+
- Small fixed sets unlikely to change (Yes/No, gender, true/false)
|
|
179
|
+
- Values tied to app logic (status enums where code branches on specific values)
|
|
180
|
+
- Fewer than ~8 items that are universal across deployments
|
|
181
|
+
|
|
182
|
+
**Use dynamic (lookup table) when:**
|
|
183
|
+
|
|
184
|
+
- User says "managed", "from database", "editable", "configurable"
|
|
185
|
+
- Domain/reference data that may grow (countries, products, customers, categories)
|
|
186
|
+
- User provides a large list (>10 items)
|
|
187
|
+
- Values that different orgs/deployments would customize
|
|
188
|
+
- Data that non-developers should be able to edit in management portal
|
|
189
|
+
|
|
190
|
+
**If uncertain**, ask the user whether the options are fixed or may change over time.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### Value Collection
|
|
195
|
+
|
|
196
|
+
If values are clear from context, suggest initial values and ask for confirmation. If unclear, ask the user what values to populate.
|
|
197
|
+
|
|
198
|
+
When ambiguous (e.g., "add a status field" without specifying values), ask the user whether the values should be static or managed dynamically.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### Displaying Lookup Data
|
|
203
|
+
|
|
204
|
+
When showing lookup table contents to the user, format as a markdown table:
|
|
205
|
+
|
|
206
|
+
| Value | Label | Sort |
|
|
207
|
+
| --- | --- | ---: |
|
|
208
|
+
| high | High | 1 |
|
|
209
|
+
| medium | Medium | 2 |
|
|
210
|
+
| low | Low | 3 |
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Choice Fields
|
|
215
|
+
|
|
216
|
+
Use choice fields for small, fixed option sets displayed as radio buttons or chips.
|
|
217
|
+
|
|
218
|
+
**When to use:**
|
|
219
|
+
|
|
220
|
+
- ≤6 options with short labels
|
|
221
|
+
- Visual selection (user sees all options at once)
|
|
222
|
+
- Grid layout desired
|
|
223
|
+
|
|
224
|
+
**Choice vs Dropdown:**
|
|
225
|
+
|
|
226
|
+
| Criteria | Choice | Dropdown |
|
|
227
|
+
| --- | --- | --- |
|
|
228
|
+
| Options count | ≤6 | >6 |
|
|
229
|
+
| Label length | Short | Any |
|
|
230
|
+
| Display | All visible | Collapsed list |
|
|
231
|
+
|
|
232
|
+
**Choice vs Checkbox for yes/no:**
|
|
233
|
+
|
|
234
|
+
- Required yes/no: Use choice (checkbox fails validation when unchecked)
|
|
235
|
+
- 3-state logic: Use choice (Yes/No/NA, True/False/Unknown)
|
|
236
|
+
- Optional toggle: Use checkbox
|
|
237
|
+
|
|
238
|
+
**Details:** [Choice Fields](./choice-fields.md)
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Array Fields
|
|
243
|
+
|
|
244
|
+
**Use ArrayField when you need a "form within a form"** - a repeatable group of fields where users can add/remove multiple entries of the same structure.
|
|
245
|
+
|
|
246
|
+
**When to use:**
|
|
247
|
+
|
|
248
|
+
- Invoice/order with multiple line items (product, quantity, price per item)
|
|
249
|
+
- Team registration with multiple members (name, email, role per person)
|
|
250
|
+
- Inspection checklist with multiple items (item name, status, notes per check)
|
|
251
|
+
- Any scenario requiring "Add another [X]" functionality
|
|
252
|
+
|
|
253
|
+
**How it works:** ArrayField creates a nested, repeatable form section. Each item contains the same field structure. Users tap "Add" to create new items and can remove existing ones.
|
|
254
|
+
|
|
255
|
+
| Property | Type | Description |
|
|
256
|
+
| --- | --- | --- |
|
|
257
|
+
| `name` | string | Field identifier (required) |
|
|
258
|
+
| `label` | string | Display label (required) |
|
|
259
|
+
| `title` | TextValueBuilder | Item title in the array list (required) |
|
|
260
|
+
| `subtitle` | TextValueBuilder | Item subtitle in the array list |
|
|
261
|
+
| `description` | TextValueBuilder | Item description in the array list |
|
|
262
|
+
| `addButtonLabel` | string | Custom "Add" button text |
|
|
263
|
+
| `value` | ArrayFieldValue[] \| JsonataBuilder | Initial data for fixed-size arrays (hides add/delete) |
|
|
264
|
+
| `keyField` | string | Field to match init items with saved data (required with `value`) |
|
|
265
|
+
|
|
266
|
+
**Three ways to use ArrayField:**
|
|
267
|
+
|
|
268
|
+
| Mode | `value` | Behavior |
|
|
269
|
+
| --- | --- | --- |
|
|
270
|
+
| **User-managed** | (not set) | Users add/remove items freely |
|
|
271
|
+
| **Static** | Array literal | Fixed items (subform, checklist) |
|
|
272
|
+
| **Dynamic** | Expression/field ref | Items regenerate from source |
|
|
273
|
+
|
|
274
|
+
**Ref:** `./predefined-array-items.md` for static and dynamic initialization
|
|
275
|
+
|
|
276
|
+
**Title is required** - identifies items in the list and delete confirmation.
|
|
277
|
+
|
|
278
|
+
**Ref:** `./cross-step-data.md` for accessing array data in other steps
|
|
279
|
+
|
|
280
|
+
**Recognize repeated data patterns:**
|
|
281
|
+
|
|
282
|
+
| User describes... | Use |
|
|
283
|
+
| --- | --- |
|
|
284
|
+
| "3 passengers on booking" | ArrayField + 3 predefined items |
|
|
285
|
+
| "5 emergency contacts" | ArrayField + 5 predefined items |
|
|
286
|
+
| "Add ingredients to recipe" | ArrayField (user-managed) |
|
|
287
|
+
| "Track project milestones" | ArrayField (user-managed) |
|
|
288
|
+
|
|
289
|
+
**Anti-pattern:** Creating multiple sections with duplicated fields (e.g., "Contact 1 Name", "Contact 1 Phone", "Contact 2 Name"...). This creates longer forms and inconsistent data structure.
|
|
290
|
+
|
|
291
|
+
**Default rule:** Same data type captured multiple times → ArrayField, not duplicated sections.
|
|
292
|
+
|
|
293
|
+
**Details:** [Array Fields](./array-fields.md)
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Array Initialization
|
|
298
|
+
|
|
299
|
+
Use ArrayField with `value` to initialize items. Add/delete buttons hidden automatically.
|
|
300
|
+
|
|
301
|
+
| Mode | `value` | Regenerates | Use Case |
|
|
302
|
+
| --- | --- | --- | --- |
|
|
303
|
+
| **Subform** | 1 static item | No | Nested details (vehicle, address) |
|
|
304
|
+
| **Fixed list** | N static items | No | Scorecards, checklists |
|
|
305
|
+
| **Dynamic** | Expression/field ref | Yes | Date ranges, count from field |
|
|
306
|
+
|
|
307
|
+
**Key properties:**
|
|
308
|
+
|
|
309
|
+
| Property | Description |
|
|
310
|
+
| --- | --- |
|
|
311
|
+
| `value` | Initial items (static array or JsonataBuilder expression) |
|
|
312
|
+
| `keyField` | Field to match items with saved data (required for dynamic, optional for static) |
|
|
313
|
+
|
|
314
|
+
**Ref:** `./array-fields.md` for full ArrayField API
|
|
315
|
+
|
|
316
|
+
**Details:** [Array Initialization](./predefined-array-items.md)
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Date Field
|
|
321
|
+
|
|
322
|
+
Use `addDate()` to capture dates, times, or both with a native picker.
|
|
323
|
+
|
|
324
|
+
| Property | Type | Description |
|
|
325
|
+
| --- | --- | --- |
|
|
326
|
+
| `mode` | `'date'` \| `'time'` \| `'datetime'` | Picker type (default: 'date') |
|
|
327
|
+
| `minimum` | `string` \| `number` \| `JsonataBuilder` | Earliest selectable date |
|
|
328
|
+
| `maximum` | `string` \| `number` \| `JsonataBuilder` | Latest selectable date |
|
|
329
|
+
|
|
330
|
+
| Mode | Picker | Use Case |
|
|
331
|
+
| --- | --- | --- |
|
|
332
|
+
| `'date'` | Date only | Birthdays, deadlines |
|
|
333
|
+
| `'time'` | Time only | Meeting times, schedules |
|
|
334
|
+
| `'datetime'` | Both | Appointments, events |
|
|
335
|
+
|
|
336
|
+
**Details:** [Date Field](./date-field.md)
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Formatting
|
|
341
|
+
|
|
342
|
+
Two ways to format values:
|
|
343
|
+
|
|
344
|
+
| Approach | Use Case |
|
|
345
|
+
| --- | --- |
|
|
346
|
+
| **Field `format` property** | Format numbers in disabled (read-only) fields |
|
|
347
|
+
| **`FormatBuilder` class** | Format any value for text display: `submissionItemTitle`, `submissionItemSubtitle`, arrayField `title`/`subtitle`/`description`, step `title` |
|
|
348
|
+
|
|
349
|
+
**Details:** [Formatting](./formatting.md)
|
|
350
|
+
|
|
351
|
+
---
|
|
352
|
+
|
|
353
|
+
**Read the YAML schemas before writing any SQL query.** They document available tables, fields, nullable columns, relationships, and common query patterns.
|
|
354
|
+
|
|
355
|
+
### When to Use Custom Sync Parameters
|
|
356
|
+
|
|
357
|
+
| Use Case | Parameters |
|
|
358
|
+
| --- | --- |
|
|
359
|
+
| Fetch all records | None (uses package defaults) |
|
|
360
|
+
| Only sync active records | Custom filter to limit fetched records |
|
|
361
|
+
| Reduce sync volume | Filter expression |
|
|
362
|
+
| Different expand per screen | Expand override |
|
|
363
|
+
|
|
364
|
+
### Handling Null Values (COALESCE)
|
|
365
|
+
|
|
366
|
+
External data fields can be null. **Use COALESCE** for display fields to prevent empty UI labels. Check the package's schema files for which fields are nullable and their recommended fallbacks.
|
|
367
|
+
|
|
368
|
+
### JOIN Queries (Multiple Tables)
|
|
369
|
+
|
|
370
|
+
**Always wrap `json_extract()` in `TRIM()` for JOIN conditions.** External data often contains leading/trailing whitespace that breaks equality comparisons.
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## Media & Specialized Fields
|
|
375
|
+
|
|
376
|
+
Core SDK provides these media capture fields:
|
|
377
|
+
|
|
378
|
+
| Type | Purpose |
|
|
379
|
+
| --- | --- |
|
|
380
|
+
| `media` | File/image upload (single or multiple) |
|
|
381
|
+
| `signature` | Signature capture pad |
|
|
382
|
+
| `avatar-field` | Profile picture selector |
|
|
383
|
+
| `duration-picker` | Time duration selector |
|
|
384
|
+
|
|
385
|
+
**Details:** [Media Fields](./media-fields.md)
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## Location Field
|
|
390
|
+
|
|
391
|
+
The `addLocation()` method creates a field that auto-captures GPS coordinates as "lat,lng" format.
|
|
392
|
+
|
|
393
|
+
**Two patterns:**
|
|
394
|
+
|
|
395
|
+
| Pattern | Use Case | isDisabled |
|
|
396
|
+
| --- | --- | --- |
|
|
397
|
+
| Current location (readonly) | Check-ins, service visits, asset tagging | `true` |
|
|
398
|
+
| Generic location (editable) | Delivery addresses, event venues | `false` (default) |
|
|
399
|
+
|
|
400
|
+
**Details:** [Location Field](./location-field.md)
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## Icons
|
|
405
|
+
|
|
406
|
+
Expert SDK includes 18,000+ icons. Icon names are validated at build time - invalid names cause build failures.
|
|
407
|
+
|
|
408
|
+
**Never guess icon names** - always search via MCP.
|
|
409
|
+
|
|
410
|
+
**Details:** [Icons](./icons.md)
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
## Runtime Variables
|
|
415
|
+
|
|
416
|
+
Access runtime context using `System` and `Auth.user` from Expert SDK:
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
import { Auth, System, JsonataBuilder } from '@jigx/expert-sdk'
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
| Namespace | Purpose |
|
|
423
|
+
| --- | --- |
|
|
424
|
+
| `System.*` | Device info, network status, location |
|
|
425
|
+
| `Auth.user.*` | Authenticated user data |
|
|
426
|
+
|
|
427
|
+
**Details:** [Runtime Variables](./runtime-variables.md)
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
## Internationalization (i18n)
|
|
432
|
+
|
|
433
|
+
Build multi-language forms using the `I18nBuilder` class. Supports:
|
|
434
|
+
|
|
435
|
+
- Translation keys with fallback messages
|
|
436
|
+
- Placeholder interpolation with `JsonataBuilder`
|
|
437
|
+
- Formatted values with `FormatBuilder` class
|
|
438
|
+
- Formatted strings combining multiple values
|
|
439
|
+
|
|
440
|
+
**Priority:** `I18nBuilder` > `format property` > `direct value`
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
**When to use I18nBuilder:**
|
|
444
|
+
- Combining multiple field values with text
|
|
445
|
+
- Formatting dates, currencies, numbers, or percentages
|
|
446
|
+
- Multi-language support needed
|
|
447
|
+
- Complex string interpolation
|
|
448
|
+
|
|
449
|
+
**Details:** [Internationalization](./i18n.md)
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## Submission Display
|
|
454
|
+
|
|
455
|
+
Use `step.data.getFieldData()` to configure what information appears in the submission list. Shows meaningful data instead of generic IDs.
|
|
456
|
+
|
|
457
|
+
**Properties (both required):**
|
|
458
|
+
- `submissionItemTitle` — primary text shown for each submission
|
|
459
|
+
- `submissionItemSubtitle` — secondary text shown below the title
|
|
460
|
+
|
|
461
|
+
**Important:** Both `submissionItemTitle` and `submissionItemSubtitle` must be defined. Form validation will fail if either is missing.
|
|
462
|
+
|
|
463
|
+
**Date/number formatting:** Use `FormatBuilder` when displaying date, currency, or number values in `submissionItemTitle` or `submissionItemSubtitle`. See `./formatting.md` for details.
|
|
464
|
+
|
|
465
|
+
**Details:** [Submission Display](./submission-display.md)
|
|
466
|
+
|
|
467
|
+
---
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Pattern: Build and Deploy
|
|
2
|
+
|
|
3
|
+
## Build order matters
|
|
4
|
+
|
|
5
|
+
Register in this order in `app.ts`:
|
|
6
|
+
|
|
7
|
+
1. Database tables
|
|
8
|
+
2. App-scoped datasources
|
|
9
|
+
3. Functions (before actions that reference them)
|
|
10
|
+
4. Global actions (before screens that reference them)
|
|
11
|
+
5. Tab content screens (before the tabs screen that embeds them)
|
|
12
|
+
6. Tabs screen
|
|
13
|
+
7. Other screens
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
Core SDK must be compiled before workspace projects can build (tsx imports compiled output):
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
yarn workspace @jigx/core-sdk build
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Commands
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Typecheck
|
|
27
|
+
npx tsc --noEmit --strict --target es2022 --module esnext \
|
|
28
|
+
--moduleResolution bundler --customConditions source \
|
|
29
|
+
--esModuleInterop --skipLibCheck workspace/acumatica-apps/create-customer/src/app.ts
|
|
30
|
+
|
|
31
|
+
# Build JSON + YAML
|
|
32
|
+
npx tsx workspace/build.ts workspace/acumatica-apps/create-customer
|
|
33
|
+
npx tsx workspace/build-yaml.ts workspace/acumatica-apps/create-customer
|
|
34
|
+
|
|
35
|
+
# Deploy (env vars or .env)
|
|
36
|
+
STAMP=PROD ORGANIZATION_ID="..." JIGX_API_KEY="..." \
|
|
37
|
+
./workspace/acumatica-apps/create-customer/build-publish.sh
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Build scripts
|
|
41
|
+
|
|
42
|
+
| Script | Output | Location |
|
|
43
|
+
| ---: | --- | --- |
|
|
44
|
+
| `workspace/build.ts` | `build/output.json` + `build/output.yaml` | Single merged file |
|
|
45
|
+
| `workspace/build-yaml.ts` | `build/jigx-project/` | Individual `.jigx` files matching standard Jigx YAML project structure |
|
|
46
|
+
| `build-publish.sh` | Builds + publishes to Jigx API | Per-project script |
|
|
47
|
+
|
|
48
|
+
## YAML project output
|
|
49
|
+
|
|
50
|
+
The `build-yaml.ts` script decomposes the single JSON output into individual files:
|
|
51
|
+
|
|
52
|
+
| JSON key | Output |
|
|
53
|
+
| ---: | --- |
|
|
54
|
+
| `name`, `title`, `category`, `tabs` | `index.jigx` |
|
|
55
|
+
| `databases["default"]` | `databases/default.jigx` |
|
|
56
|
+
| `datasources["<id>"]` | `datasources/<id>.jigx` |
|
|
57
|
+
| `jigs["<id>"]` | `jigs/<id>.jigx` (screen-scoped datasources stay inline) |
|
|
58
|
+
| `actions["<id>"]` | `actions/<id>.jigx` |
|
|
59
|
+
| `functions["<id>"]` | `functions/<id>.jigx` |
|
|
60
|
+
|
|
61
|
+
Internal IDs (`jigId`, `datasourceId`, `instanceId`, `databaseId`) are stripped — they're implied by the filename.
|
|
62
|
+
|
|
63
|
+
## Deploy script (`build-publish.sh`)
|
|
64
|
+
|
|
65
|
+
Each project has a `build-publish.sh` that builds and publishes to the Jigx API. Required env vars (from `.env` or inline):
|
|
66
|
+
|
|
67
|
+
| Variable | Description |
|
|
68
|
+
| ---: | --- |
|
|
69
|
+
| `ORGANIZATION_ID` | Jigx organization UUID |
|
|
70
|
+
| `JIGX_API_KEY` | PAT for Jigx API (store in `.env`, never commit) |
|
|
71
|
+
| `STAMP` | `DEV` (default) or `PROD` |
|
|
72
|
+
|
|
73
|
+
API base URLs:
|
|
74
|
+
|
|
75
|
+
- DEV: `https://us-west-2.dev-api.jigx.com/v2.0`
|
|
76
|
+
- PROD: `https://us-east-1.api.jigx.com/v2.0`
|
|
77
|
+
|
|
78
|
+
Deploy flow:
|
|
79
|
+
|
|
80
|
+
1. Build `output.json` via `workspace/build.ts`
|
|
81
|
+
2. `GET /strata/organizations/{orgId}/solutions/{appName}` — look up existing solution
|
|
82
|
+
3. If 404: `POST /strata/organizations/{orgId}/solutions/` — create new solution
|
|
83
|
+
4. `PUT /strata/organizations/{orgId}/solutions/{solutionId}/content` — publish full `output.json` as body
|
|
84
|
+
|
|
85
|
+
All calls use `Authorization: Bearer {JIGX_API_KEY}`.
|
|
86
|
+
|
|
87
|
+
Inline env vars override `.env` defaults — pass credentials on the command line to avoid storing prod keys:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
STAMP=PROD ORGANIZATION_ID="..." JIGX_API_KEY="..." ./workspace/acumatica-apps/create-customer/build-publish.sh
|
|
91
|
+
```
|