@almadar/std 16.221.0 → 16.223.0

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.
@@ -1,6 +1,7 @@
1
1
  app std-data-import "1.0.0"
2
2
  "std-data-import — staged CSV import run, source-agnostic: upload → staged review → confirm → parse+map → handoff. UPLOAD_CSV opens a run and persists an ImportBatch row (status uploaded, fieldMappingJson recorded verbatim for provenance); the host's file UI parses the CSV and answers with STAGE_ROWS, one JSON string per raw row, which the atom bulk-persists into import_rows against the batch id and presents as a staged review (row/error counts + Confirm/Discard). CONFIRM_IMPORT marks the batch confirmed, emits IMPORT_CONFIRMED { batchId, sourceName, rowCount }, and fetches the batch's staged rows; on fetch success the atom parses each rowJson via json/parse, remaps keys through the batch's mappingJson, and emits IMPORT_ROWS_PARSED { batchId, rows, failed } — the persist half is the CONSUMER organism's: it listens for IMPORT_ROWS_PARSED and persists the mapped rows into its own target entity (cross-atom persist into a consumer's entity is not expressible from here). This is deliberately the CSV-file path: the atom never calls a source service — sourceName/fieldMappingJson/targetEntity/historyWindowDays are declarative consumer configs, and any persist failure marks the batch row failed and fires IMPORT_FAILED, never a silent swallow. Compose with std-import for the file-picker menu."
3
3
  orbital DataImportOrbital {
4
+ type DataImportFile = { name : string!, size : number, type : string, content : string }
4
5
 
5
6
  entity ImportBatch [persistent: import_batches] {
6
7
  id : string!
@@ -30,6 +31,24 @@ orbital DataImportOrbital {
30
31
  (set @entity.errorCount 0)
31
32
  (set @entity.mappingJson @config.fieldMappingJson)
32
33
  (set @entity.createdAt 0)
34
+ (render-ui main {
35
+ children: [{
36
+ content: (str/concat "Import " @entity.sourceName)
37
+ type: typography
38
+ variant: h3
39
+ }, {
40
+ accept: ".csv,text/csv"
41
+ action: UPLOAD_CSV
42
+ description: "Drop a CSV file here or click to browse"
43
+ icon: upload
44
+ label: "Upload CSV file"
45
+ maxFiles: 1
46
+ type: upload-drop-zone
47
+ }]
48
+ direction: vertical
49
+ gap: md
50
+ type: stack
51
+ })
33
52
  UPLOAD_CSV -> uploaded
34
53
  (set @entity.id ?batchId)
35
54
  (set @entity.sourceName (or ?sourceName @config.sourceName))
@@ -52,8 +71,17 @@ orbital DataImportOrbital {
52
71
  }
53
72
 
54
73
  state uploaded {
74
+ ;; STAGE_ROWS has no emitter yet (host-side CSV-content parsing is a
75
+ ;; still-open substrate gap, R-DATA-IMPORT-PAGES-BLANK-NO-UPLOAD-UI) —
76
+ ;; render something here too so `uploaded` is never a second blank
77
+ ;; dead end after the upload affordance's UPLOAD_CSV succeeds.
55
78
  BATCH_CREATED -> uploaded
56
79
  (set @entity.id ?id)
80
+ (render-ui main {
81
+ message: (str/concat "Import started — " @entity.sourceName ". Waiting for the file's rows to be staged.")
82
+ type: alert
83
+ variant: info
84
+ })
57
85
  STAGE_ROWS -> staged when [">", (array/len ?rows), 0]
58
86
  (set @entity.rowCount (array/len ?rows))
59
87
  (set @entity.errorCount (or ?errorCount 0))
@@ -273,8 +301,9 @@ orbital DataImportOrbital {
273
301
  UPLOAD_CSV {
274
302
  batchId : string
275
303
  sourceName : string
304
+ files : [DataImportFile]!
276
305
  }
277
- @description "Starts an import run for a CSV file upload. batchId is the client-minted batch id (idempotent upload — the host generates it so a retry never double-creates a batch); when omitted, the server-issued id is bound on BATCH_CREATED instead. The host's file UI (e.g. a sibling std-import menu) only announces the upload — parsing is host work and arrives as STAGE_ROWS."
306
+ @description "Starts an import run for a CSV file upload, fired by the idle state's own upload-drop-zone affordance. batchId is the client-minted batch id (idempotent upload — the host generates it so a retry never double-creates a batch); when omitted, the server-issued id is bound on BATCH_CREATED instead. files carries the picked file(s) (name/size/type/content) but the atom does not read content from it yet — no runtime capability exists to decode/parse it into rows (tracked: R-DATA-IMPORT-PAGES-BLANK-NO-UPLOAD-UI); STAGE_ROWS is the still-open handoff for a future host-side parser to answer with real row data."
278
307
  @synonyms "upload csv, import csv, start import, import file, bulk import"
279
308
  @tier "domain"
280
309
  STAGE_ROWS {
@@ -146,15 +146,34 @@ orbital GlobalSearchOrbital {
146
146
  event: SEARCH
147
147
  placeholder: @config.placeholder
148
148
  type: search-input
149
- }, (array/map (array/filter @entity.results (fn g (!= @g.resultsJson ""))) (fn g {
150
- type: stack
151
- direction: vertical
152
- gap: sm
153
- children: [
154
- <Typography.traits.TypographyRender content={@g.moduleKey} linkedEntity={SearchQuery} variant={h4} />,
155
- (array/map (array/filter (str/split @g.resultsJson ", ") (fn item (!= @item ""))) (fn item <Typography.traits.TypographyRender content={@item} linkedEntity={SearchQuery} variant={body} />))
156
- ]
157
- }))]
149
+ }, (if (> (array/len (array/filter @entity.results (fn g (!= @g.resultsJson "")))) 0)
150
+ {
151
+ type: stack
152
+ direction: vertical
153
+ gap: sm
154
+ children: (array/map (array/filter @entity.results (fn g (!= @g.resultsJson ""))) (fn g {
155
+ type: stack
156
+ direction: vertical
157
+ gap: sm
158
+ ;; a bare array/map result as a sibling of a static element in the SAME children list mis-renders as "Unknown pattern" in @almadar/ui (confirmed live via play_scene) — wrap it in its own container so every children element is a single node
159
+ children: [
160
+ <Typography.traits.TypographyRender content={@g.moduleKey} linkedEntity={SearchQuery} variant={h4} />,
161
+ {
162
+ type: stack
163
+ direction: vertical
164
+ gap: xs
165
+ children: (array/map (array/filter (str/split @g.resultsJson ", ") (fn item (!= @item ""))) (fn item <Typography.traits.TypographyRender content={@item} linkedEntity={SearchQuery} variant={body} />))
166
+ }
167
+ ]
168
+ }))
169
+ }
170
+ ;; children[1] must never be a bare empty array (renders nothing, and was observed to blank the whole slot) — always a single well-formed node instead; the two "no results yet" sub-cases share one empty-state node, distinguished only by its string props
171
+ {
172
+ description: (if (and @entity.fanOutDone (>= @entity.respondedCount @entity.requestedCount)) "Try a different search term or module." "Waiting for the rest of the results…")
173
+ icon: search-x
174
+ title: (if (and @entity.fanOutDone (>= @entity.respondedCount @entity.requestedCount)) "No results found" "Searching…")
175
+ type: empty-state
176
+ })]
158
177
  direction: vertical
159
178
  gap: md
160
179
  type: stack
@@ -26,7 +26,7 @@ orbital ModQueueItemOrbital {
26
26
  reviewedBy : string @description "The user who performed the review action." @synonyms "reviewer, reviewerId, assignedTo"
27
27
  reviewedAt : datetime @description "Timestamp indicating when the item was last reviewed." @synonyms "review date, review time, last reviewed"
28
28
  notes : string @description "Free-text comments or observations related to the item." @synonyms "comment, remark, observation, details"
29
- seedRow : ModQueueItem @intrinsic @description "The row an edit-mode modal pre-fills from when its payload carries no row (a scalar-only action event still opens a fully seeded form)." = {}
29
+ seedRow : Map string scalar @intrinsic @description "The row an edit-mode modal pre-fills from when its payload carries no row (a scalar-only action event still opens a fully seeded form)." = {}
30
30
  }
31
31
 
32
32
  trait LoadingSpinner = Spinner.traits.SpinnerRender -> ModQueueItem {
@@ -110,7 +110,7 @@ orbital BoardOrbital {
110
110
  (set @entity.currentTitle ?title)
111
111
  (set @entity.currentDescription ?description)
112
112
  (set @entity.currentStage ?stage)
113
- (set @entity.currentNotes ?row.notes)
113
+ (set @entity.currentNotes ?notes)
114
114
  (set @entity.currentRow ?row)
115
115
  (render-ui main {
116
116
  children: [{
@@ -423,6 +423,7 @@ orbital BoardOrbital {
423
423
  title : string
424
424
  description : string
425
425
  stage : string
426
+ notes : string
426
427
  }
427
428
  @description "A card within the board has been selected or activated."
428
429
  @synonyms "select, activate, view, show"
@@ -581,6 +582,10 @@ orbital BoardOrbital {
581
582
  @label "Card id binding"
582
583
  @description "Per-card binding for the id used in action payloads."
583
584
  @tier "presentation"
585
+ cardNotesBinding : string = @item.notes
586
+ @label "Card notes binding"
587
+ @description "Per-card binding for the notes slot shown in the card detail view. Set to an empty string for hosts with no notes-equivalent field — declared as 'no notes capture', never inferred."
588
+ @tier "presentation"
584
589
  groupByField : string = stage
585
590
  @label "Group-by field"
586
591
  @description "Entity field whose value matches a column key — items are filtered into columns by it. Default 'stage'; set to 'status' (or any field) for entities that track state under a different name."
@@ -717,7 +722,7 @@ orbital BoardOrbital {
717
722
  align: center
718
723
  children: [{
719
724
  action: OPEN_CARD
720
- actionPayload: { description: @config.cardDescriptionBinding, id: @config.cardIdBinding, row: @item, stage: @config.cardStageBinding, title: @config.cardTitleBinding }
725
+ actionPayload: { description: @config.cardDescriptionBinding, id: @config.cardIdBinding, notes: @config.cardNotesBinding, row: @item, stage: @config.cardStageBinding, title: @config.cardTitleBinding }
721
726
  icon: arrow-right
722
727
  label: Open
723
728
  type: button
@@ -861,7 +866,7 @@ orbital BoardOrbital {
861
866
  variant: @col.variant
862
867
  }, {
863
868
  action: OPEN_CARD
864
- actionPayload: { description: @config.cardDescriptionBinding, id: @config.cardIdBinding, row: @item, stage: @config.cardStageBinding, title: @config.cardTitleBinding }
869
+ actionPayload: { description: @config.cardDescriptionBinding, id: @config.cardIdBinding, notes: @config.cardNotesBinding, row: @item, stage: @config.cardStageBinding, title: @config.cardTitleBinding }
865
870
  className: ml-auto
866
871
  icon: arrow-right
867
872
  label: Open
@@ -24,7 +24,7 @@ orbital ModalRecordOrbital {
24
24
  name : string @description "A user-facing identifier for the modal." @synonyms "title, label, identifier"
25
25
  description : string @description "A textual explanation of the modal's content or function." @synonyms "details, explanation, notes, summary"
26
26
  status : "active" | "inactive" | "pending" @description "Current operational state of the record." @synonyms "state, condition, flag" = active
27
- seedRow : ModalRecord @intrinsic @description "The row an edit-mode OPEN pre-fills from when its payload carries no row. Stashed by SEED — hosts route the surface's loaded event here (e.g. a document look's RecordItemLoaded) so scalar-only action events ({ id }) can still open a fully seeded settings form." = {}
27
+ seedRow : Map string scalar @intrinsic @description "The row an edit-mode OPEN pre-fills from when its payload carries no row. Stashed by SEED — hosts route the surface's loaded event here (e.g. a document look's RecordItemLoaded) so scalar-only action events ({ id }) can still open a fully seeded settings form." = {}
28
28
  createdAt : string
29
29
  }
30
30
 
@@ -536,7 +536,7 @@
536
536
  "name": "Initialize"
537
537
  },
538
538
  {
539
- "description": "Starts an import run for a CSV file upload. batchId is the client-minted batch id (idempotent upload — the host generates it so a retry never double-creates a batch); when omitted, the server-issued id is bound on BATCH_CREATED instead. The host's file UI (e.g. a sibling std-import menu) only announces the upload — parsing is host work and arrives as STAGE_ROWS.",
539
+ "description": "Starts an import run for a CSV file upload, fired by the idle state's own upload-drop-zone affordance. batchId is the client-minted batch id (idempotent upload — the host generates it so a retry never double-creates a batch); when omitted, the server-issued id is bound on BATCH_CREATED instead. files carries the picked file(s) (name/size/type/content) but the atom does not read content from it yet — no runtime capability exists to decode/parse it into rows (tracked: R-DATA-IMPORT-PAGES-BLANK-NO-UPLOAD-UI); STAGE_ROWS is the still-open handoff for a future host-side parser to answer with real row data.",
540
540
  "id": "evt_01M2HEYJ1V2E7BSYFFZDPQB5DM",
541
541
  "key": "UPLOAD_CSV",
542
542
  "name": "Upload Csv",
@@ -548,6 +548,30 @@
548
548
  {
549
549
  "name": "sourceName",
550
550
  "type": "string"
551
+ },
552
+ {
553
+ "name": "files",
554
+ "properties": [
555
+ {
556
+ "name": "name",
557
+ "required": true,
558
+ "type": "string"
559
+ },
560
+ {
561
+ "name": "size",
562
+ "type": "number"
563
+ },
564
+ {
565
+ "name": "type",
566
+ "type": "string"
567
+ },
568
+ {
569
+ "name": "content",
570
+ "type": "string"
571
+ }
572
+ ],
573
+ "required": true,
574
+ "type": "[object]"
551
575
  }
552
576
  ],
553
577
  "synonyms": "upload csv, import csv, start import, import file, bulk import",
@@ -777,6 +801,35 @@
777
801
  "set",
778
802
  "@entity.createdAt",
779
803
  0.0
804
+ ],
805
+ [
806
+ "render-ui",
807
+ "main",
808
+ {
809
+ "children": [
810
+ {
811
+ "content": [
812
+ "str/concat",
813
+ "Import ",
814
+ "@entity.sourceName"
815
+ ],
816
+ "type": "typography",
817
+ "variant": "h3"
818
+ },
819
+ {
820
+ "accept": ".csv,text/csv",
821
+ "action": "UPLOAD_CSV",
822
+ "description": "Drop a CSV file here or click to browse",
823
+ "icon": "upload",
824
+ "label": "Upload CSV file",
825
+ "maxFiles": 1.0,
826
+ "type": "upload-drop-zone"
827
+ }
828
+ ],
829
+ "direction": "vertical",
830
+ "gap": "md",
831
+ "type": "stack"
832
+ }
780
833
  ]
781
834
  ],
782
835
  "event": "INIT",
@@ -859,6 +912,20 @@
859
912
  "set",
860
913
  "@entity.id",
861
914
  "@payload.id"
915
+ ],
916
+ [
917
+ "render-ui",
918
+ "main",
919
+ {
920
+ "message": [
921
+ "str/concat",
922
+ "Import started — ",
923
+ "@entity.sourceName",
924
+ ". Waiting for the file's rows to be staged."
925
+ ],
926
+ "type": "alert",
927
+ "variant": "info"
928
+ }
862
929
  ]
863
930
  ],
864
931
  "event": "BATCH_CREATED",
@@ -1479,7 +1546,28 @@
1479
1546
  ]
1480
1547
  }
1481
1548
  }
1482
- ]
1549
+ ],
1550
+ "types": {
1551
+ "DataImportFile": [
1552
+ {
1553
+ "name": "name",
1554
+ "required": true,
1555
+ "type": "string"
1556
+ },
1557
+ {
1558
+ "name": "size",
1559
+ "type": "number"
1560
+ },
1561
+ {
1562
+ "name": "type",
1563
+ "type": "string"
1564
+ },
1565
+ {
1566
+ "name": "content",
1567
+ "type": "string"
1568
+ }
1569
+ ]
1570
+ }
1483
1571
  }
1484
1572
  ],
1485
1573
  "schemaVersion": 1,
@@ -1243,57 +1243,122 @@
1243
1243
  "type": "search-input"
1244
1244
  },
1245
1245
  [
1246
- "array/map",
1246
+ "if",
1247
1247
  [
1248
- "array/filter",
1249
- "@entity.results",
1248
+ ">",
1250
1249
  [
1251
- "fn",
1252
- "g",
1250
+ "array/len",
1253
1251
  [
1254
- "!=",
1255
- "@g.resultsJson",
1256
- ""
1252
+ "array/filter",
1253
+ "@entity.results",
1254
+ [
1255
+ "fn",
1256
+ "g",
1257
+ [
1258
+ "!=",
1259
+ "@g.resultsJson",
1260
+ ""
1261
+ ]
1262
+ ]
1257
1263
  ]
1258
- ]
1264
+ ],
1265
+ 0.0
1259
1266
  ],
1260
- [
1261
- "fn",
1262
- "g",
1263
- {
1264
- "children": [
1265
- "@trait.InlineTypographyRender4",
1267
+ {
1268
+ "children": [
1269
+ "array/map",
1270
+ [
1271
+ "array/filter",
1272
+ "@entity.results",
1266
1273
  [
1267
- "array/map",
1268
- [
1269
- "array/filter",
1270
- [
1271
- "str/split",
1272
- "@g.resultsJson",
1273
- ", "
1274
- ],
1275
- [
1276
- "fn",
1277
- "item",
1278
- [
1279
- "!=",
1280
- "@item",
1281
- ""
1282
- ]
1283
- ]
1284
- ],
1274
+ "fn",
1275
+ "g",
1285
1276
  [
1286
- "fn",
1287
- "item",
1288
- "@trait.InlineTypographyRender5"
1277
+ "!=",
1278
+ "@g.resultsJson",
1279
+ ""
1289
1280
  ]
1290
1281
  ]
1291
1282
  ],
1292
- "direction": "vertical",
1293
- "gap": "sm",
1294
- "type": "stack"
1295
- }
1296
- ]
1283
+ [
1284
+ "fn",
1285
+ "g",
1286
+ {
1287
+ "children": [
1288
+ "@trait.InlineTypographyRender4",
1289
+ {
1290
+ "children": [
1291
+ "array/map",
1292
+ [
1293
+ "array/filter",
1294
+ [
1295
+ "str/split",
1296
+ "@g.resultsJson",
1297
+ ", "
1298
+ ],
1299
+ [
1300
+ "fn",
1301
+ "item",
1302
+ [
1303
+ "!=",
1304
+ "@item",
1305
+ ""
1306
+ ]
1307
+ ]
1308
+ ],
1309
+ [
1310
+ "fn",
1311
+ "item",
1312
+ "@trait.InlineTypographyRender5"
1313
+ ]
1314
+ ],
1315
+ "direction": "vertical",
1316
+ "gap": "xs",
1317
+ "type": "stack"
1318
+ }
1319
+ ],
1320
+ "direction": "vertical",
1321
+ "gap": "sm",
1322
+ "type": "stack"
1323
+ }
1324
+ ]
1325
+ ],
1326
+ "direction": "vertical",
1327
+ "gap": "sm",
1328
+ "type": "stack"
1329
+ },
1330
+ {
1331
+ "description": [
1332
+ "if",
1333
+ [
1334
+ "and",
1335
+ "@entity.fanOutDone",
1336
+ [
1337
+ ">=",
1338
+ "@entity.respondedCount",
1339
+ "@entity.requestedCount"
1340
+ ]
1341
+ ],
1342
+ "Try a different search term or module.",
1343
+ "Waiting for the rest of the results…"
1344
+ ],
1345
+ "icon": "search-x",
1346
+ "title": [
1347
+ "if",
1348
+ [
1349
+ "and",
1350
+ "@entity.fanOutDone",
1351
+ [
1352
+ ">=",
1353
+ "@entity.respondedCount",
1354
+ "@entity.requestedCount"
1355
+ ]
1356
+ ],
1357
+ "No results found",
1358
+ "Searching…"
1359
+ ],
1360
+ "type": "empty-state"
1361
+ }
1297
1362
  ]
1298
1363
  ],
1299
1364
  "direction": "vertical",
@@ -271,13 +271,11 @@
271
271
  "default": {},
272
272
  "description": "The row an edit-mode modal pre-fills from when its payload carries no row (a scalar-only action event still opens a fully seeded form).",
273
273
  "intrinsic": true,
274
- "name": "seedRow",
275
- "relation": {
276
- "cardinality": "one",
277
- "entity": "ModQueueItem",
278
- "entityId": "ent_01KXG04FDN3D78Z39RX2F9T16W"
274
+ "items": {
275
+ "type": "scalar"
279
276
  },
280
- "type": "relation"
277
+ "name": "seedRow",
278
+ "type": "object"
281
279
  }
282
280
  ],
283
281
  "id": "ent_01KXG04FDN3D78Z39RX2F9T16W",
@@ -545,7 +543,7 @@
545
543
  },
546
544
  {
547
545
  "name": "seedRow",
548
- "type": "ModQueueItem"
546
+ "type": "Map<string,scalar>"
549
547
  }
550
548
  ],
551
549
  "type": "object"
@@ -609,7 +607,7 @@
609
607
  },
610
608
  {
611
609
  "name": "seedRow",
612
- "type": "ModQueueItem"
610
+ "type": "Map<string,scalar>"
613
611
  }
614
612
  ],
615
613
  "type": "object"
@@ -673,7 +671,7 @@
673
671
  },
674
672
  {
675
673
  "name": "seedRow",
676
- "type": "ModQueueItem"
674
+ "type": "Map<string,scalar>"
677
675
  }
678
676
  ],
679
677
  "type": "object"
@@ -739,7 +737,7 @@
739
737
  },
740
738
  {
741
739
  "name": "seedRow",
742
- "type": "ModQueueItem"
740
+ "type": "Map<string,scalar>"
743
741
  }
744
742
  ],
745
743
  "type": "[object]"
@@ -812,7 +810,7 @@
812
810
  },
813
811
  {
814
812
  "name": "seedRow",
815
- "type": "ModQueueItem"
813
+ "type": "Map<string,scalar>"
816
814
  }
817
815
  ],
818
816
  "scope": "internal",
@@ -916,7 +914,7 @@
916
914
  },
917
915
  {
918
916
  "name": "seedRow",
919
- "type": "ModQueueItem"
917
+ "type": "Map<string,scalar>"
920
918
  }
921
919
  ],
922
920
  "type": "[object]"
@@ -1015,7 +1013,7 @@
1015
1013
  },
1016
1014
  {
1017
1015
  "name": "seedRow",
1018
- "type": "ModQueueItem"
1016
+ "type": "Map<string,scalar>"
1019
1017
  }
1020
1018
  ],
1021
1019
  "type": "object"
@@ -1080,7 +1078,7 @@
1080
1078
  },
1081
1079
  {
1082
1080
  "name": "seedRow",
1083
- "type": "ModQueueItem"
1081
+ "type": "Map<string,scalar>"
1084
1082
  }
1085
1083
  ],
1086
1084
  "type": "object"
@@ -1145,7 +1143,7 @@
1145
1143
  },
1146
1144
  {
1147
1145
  "name": "seedRow",
1148
- "type": "ModQueueItem"
1146
+ "type": "Map<string,scalar>"
1149
1147
  }
1150
1148
  ],
1151
1149
  "type": "object"
@@ -1202,7 +1200,7 @@
1202
1200
  },
1203
1201
  {
1204
1202
  "name": "seedRow",
1205
- "type": "ModQueueItem"
1203
+ "type": "Map<string,scalar>"
1206
1204
  }
1207
1205
  ],
1208
1206
  "synonyms": "reviewed, processed, judged, completed",
@@ -569,6 +569,7 @@
569
569
  "actionPayload": {
570
570
  "description": "@config.cardDescriptionBinding",
571
571
  "id": "@config.cardIdBinding",
572
+ "notes": "@config.cardNotesBinding",
572
573
  "row": "@item",
573
574
  "stage": "@config.cardStageBinding",
574
575
  "title": "@config.cardTitleBinding"
@@ -688,6 +689,13 @@
688
689
  "tile-image-first"
689
690
  ]
690
691
  },
692
+ "cardNotesBinding": {
693
+ "default": "@item.notes",
694
+ "description": "Per-card binding for the notes slot shown in the card detail view. Set to an empty string for hosts with no notes-equivalent field — declared as 'no notes capture', never inferred.",
695
+ "label": "Card notes binding",
696
+ "tier": "presentation",
697
+ "type": "string"
698
+ },
691
699
  "cardStageBinding": {
692
700
  "default": "@item.stage",
693
701
  "description": "Per-card binding for the stage/status slot.",
@@ -990,6 +998,7 @@
990
998
  "actionPayload": {
991
999
  "description": "@config.cardDescriptionBinding",
992
1000
  "id": "@config.cardIdBinding",
1001
+ "notes": "@config.cardNotesBinding",
993
1002
  "row": "@item",
994
1003
  "stage": "@config.cardStageBinding",
995
1004
  "title": "@config.cardTitleBinding"
@@ -1513,6 +1522,10 @@
1513
1522
  {
1514
1523
  "name": "stage",
1515
1524
  "type": "string"
1525
+ },
1526
+ {
1527
+ "name": "notes",
1528
+ "type": "string"
1516
1529
  }
1517
1530
  ],
1518
1531
  "synonyms": "select, choose, activate, display",
@@ -2025,7 +2038,7 @@
2025
2038
  [
2026
2039
  "set",
2027
2040
  "@entity.currentNotes",
2028
- "@payload.row.notes"
2041
+ "@payload.notes"
2029
2042
  ],
2030
2043
  [
2031
2044
  "set",