@almadar/std 14.8.0 → 14.9.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.
Files changed (57) hide show
  1. package/behaviors/registry/app/organisms/std-api-gateway.orb +1167 -4114
  2. package/behaviors/registry/app/organisms/std-booking-system.orb +2627 -4281
  3. package/behaviors/registry/app/organisms/std-cicd-pipeline.orb +1313 -3724
  4. package/behaviors/registry/app/organisms/std-cms.orb +1658 -4903
  5. package/behaviors/registry/app/organisms/std-coding-academy.orb +686 -1238
  6. package/behaviors/registry/app/organisms/std-crm.orb +1778 -5995
  7. package/behaviors/registry/app/organisms/std-devops-dashboard.orb +1918 -5539
  8. package/behaviors/registry/app/organisms/std-finance-tracker.orb +1064 -3721
  9. package/behaviors/registry/app/organisms/std-healthcare.orb +2810 -7215
  10. package/behaviors/registry/app/organisms/std-helpdesk.orb +1065 -4161
  11. package/behaviors/registry/app/organisms/std-hr-portal.orb +2300 -6322
  12. package/behaviors/registry/app/organisms/std-iot-dashboard.orb +1582 -3721
  13. package/behaviors/registry/app/organisms/std-lms.orb +1885 -3952
  14. package/behaviors/registry/app/organisms/std-project-manager.orb +1226 -5123
  15. package/behaviors/registry/app/organisms/std-realtime-chat.orb +1147 -3794
  16. package/behaviors/registry/app/organisms/std-social-feed.orb +1044 -1728
  17. package/behaviors/registry/app/organisms/std-trading-dashboard.orb +1208 -3186
  18. package/behaviors/registry/core/atoms/std-graphs.orb +40 -41
  19. package/behaviors/registry/core/atoms/std-stats.orb +131 -110
  20. package/behaviors/registry/service/atoms/std-service-custom-bearer.orb +351 -345
  21. package/behaviors/registry/service/atoms/std-service-email.orb +334 -328
  22. package/behaviors/registry/service/atoms/std-service-github.orb +308 -365
  23. package/behaviors/registry/service/atoms/std-service-llm.orb +329 -437
  24. package/behaviors/registry/service/atoms/std-service-oauth.orb +261 -564
  25. package/behaviors/registry/service/atoms/std-service-redis.orb +299 -405
  26. package/behaviors/registry/service/atoms/std-service-storage.orb +293 -505
  27. package/behaviors/registry/service/atoms/std-service-twilio.orb +315 -393
  28. package/behaviors/registry/service/atoms/std-service-youtube.orb +266 -547
  29. package/dist/behaviors/registry/app/organisms/std-api-gateway.orb +1167 -4114
  30. package/dist/behaviors/registry/app/organisms/std-booking-system.orb +2627 -4281
  31. package/dist/behaviors/registry/app/organisms/std-cicd-pipeline.orb +1313 -3724
  32. package/dist/behaviors/registry/app/organisms/std-cms.orb +1658 -4903
  33. package/dist/behaviors/registry/app/organisms/std-coding-academy.orb +686 -1238
  34. package/dist/behaviors/registry/app/organisms/std-crm.orb +1778 -5995
  35. package/dist/behaviors/registry/app/organisms/std-devops-dashboard.orb +1918 -5539
  36. package/dist/behaviors/registry/app/organisms/std-finance-tracker.orb +1064 -3721
  37. package/dist/behaviors/registry/app/organisms/std-healthcare.orb +2810 -7215
  38. package/dist/behaviors/registry/app/organisms/std-helpdesk.orb +1065 -4161
  39. package/dist/behaviors/registry/app/organisms/std-hr-portal.orb +2300 -6322
  40. package/dist/behaviors/registry/app/organisms/std-iot-dashboard.orb +1582 -3721
  41. package/dist/behaviors/registry/app/organisms/std-lms.orb +1885 -3952
  42. package/dist/behaviors/registry/app/organisms/std-project-manager.orb +1226 -5123
  43. package/dist/behaviors/registry/app/organisms/std-realtime-chat.orb +1147 -3794
  44. package/dist/behaviors/registry/app/organisms/std-social-feed.orb +1044 -1728
  45. package/dist/behaviors/registry/app/organisms/std-trading-dashboard.orb +1208 -3186
  46. package/dist/behaviors/registry/core/atoms/std-graphs.orb +40 -41
  47. package/dist/behaviors/registry/core/atoms/std-stats.orb +131 -110
  48. package/dist/behaviors/registry/service/atoms/std-service-custom-bearer.orb +351 -345
  49. package/dist/behaviors/registry/service/atoms/std-service-email.orb +334 -328
  50. package/dist/behaviors/registry/service/atoms/std-service-github.orb +308 -365
  51. package/dist/behaviors/registry/service/atoms/std-service-llm.orb +329 -437
  52. package/dist/behaviors/registry/service/atoms/std-service-oauth.orb +261 -564
  53. package/dist/behaviors/registry/service/atoms/std-service-redis.orb +299 -405
  54. package/dist/behaviors/registry/service/atoms/std-service-storage.orb +293 -505
  55. package/dist/behaviors/registry/service/atoms/std-service-twilio.orb +315 -393
  56. package/dist/behaviors/registry/service/atoms/std-service-youtube.orb +266 -547
  57. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "std-social-feed",
3
- "version": "1.0.0",
4
- "description": "Social feed: posts with comments. Pick for Twitter/Instagram-style timelines with replies.",
3
+ "version": "2.0.0",
4
+ "description": "Social feed: posts with images, likes, and threaded comments. Pick for Twitter/Instagram-style timelines.",
5
5
  "orbitals": [
6
6
  {
7
7
  "name": "PostOrbital",
@@ -9,11 +9,36 @@
9
9
  {
10
10
  "from": "std/behaviors/std-app-layout",
11
11
  "as": "AppShell"
12
+ },
13
+ {
14
+ "from": "std/behaviors/std-modal",
15
+ "as": "Modal"
16
+ },
17
+ {
18
+ "from": "std/behaviors/std-confirmation",
19
+ "as": "Confirmation"
20
+ },
21
+ {
22
+ "from": "std/behaviors/std-search",
23
+ "as": "Search"
24
+ },
25
+ {
26
+ "from": "std/behaviors/std-stats",
27
+ "as": "Stats"
28
+ },
29
+ {
30
+ "from": "std/behaviors/std-browse",
31
+ "as": "Browse"
32
+ },
33
+ {
34
+ "from": "std/behaviors/std-service-storage",
35
+ "as": "Storage"
12
36
  }
13
37
  ],
14
38
  "entity": {
15
39
  "name": "Post",
16
- "persistence": "runtime",
40
+ "collection": "posts",
41
+ "persistence": "persistent",
17
42
  "fields": [
18
43
  {
19
44
  "name": "id",
@@ -21,9 +46,9 @@
21
46
  "required": true
22
47
  },
23
48
  {
24
- "name": "title",
49
+ "name": "author",
25
50
  "type": "string",
26
- "default": ""
51
+ "required": true
27
52
  },
28
53
  {
29
54
  "name": "content",
@@ -31,12 +56,12 @@
31
56
  "default": ""
32
57
  },
33
58
  {
34
- "name": "author",
59
+ "name": "image",
35
60
  "type": "string",
36
61
  "default": ""
37
62
  },
38
63
  {
39
- "name": "createdAt",
64
+ "name": "timestamp",
40
65
  "type": "datetime",
41
66
  "default": ""
42
67
  },
@@ -44,6 +69,16 @@
44
69
  "name": "likes",
45
70
  "type": "number",
46
71
  "default": 0.0
72
+ },
73
+ {
74
+ "name": "tag",
75
+ "type": "string",
76
+ "default": ""
77
+ },
78
+ {
79
+ "name": "pendingId",
80
+ "type": "string",
81
+ "default": ""
47
82
  }
48
83
  ]
49
84
  },
@@ -52,23 +87,23 @@
52
87
  "ref": "AppShell.traits.AppLayout",
53
88
  "name": "PostAppLayout",
54
89
  "config": {
55
- "searchEvent": "POST_SEARCH",
56
- "notificationClickEvent": "POST_NOTIFICATIONS_OPEN",
57
90
  "navItems": [
58
91
  {
59
- "href": "/feed",
60
- "icon": "layout-list",
61
- "label": "Feed"
92
+ "icon": "rss",
93
+ "label": "Feed",
94
+ "href": "/feed"
62
95
  },
63
96
  {
64
97
  "icon": "message-circle",
65
- "label": "Messages",
66
- "href": "/messages"
98
+ "label": "Comments",
99
+ "href": "/comments"
67
100
  }
68
101
  ],
69
- "contentTrait": "@trait.PostBrowse",
102
+ "contentTrait": "@trait.FeedCatalog",
103
+ "searchEvent": "POST_SEARCH",
104
+ "appName": "SocialFeed",
70
105
  "notifications": [],
71
- "appName": "SocialFeed"
106
+ "notificationClickEvent": "POST_NOTIFICATIONS_OPEN"
72
107
  },
73
108
  "events": {
74
109
  "NOTIFY_CLICK": "POST_NOTIFICATIONS_OPEN",
@@ -76,128 +111,15 @@
76
111
  }
77
112
  },
78
113
  {
79
- "name": "PostBrowse",
114
+ "name": "FeedCatalog",
80
115
  "category": "interaction",
81
- "linkedEntity": "Post",
82
116
  "emits": [
83
117
  {
84
- "event": "COMMENT",
118
+ "event": "CREATE",
85
119
  "scope": "external",
86
120
  "payloadSchema": [
87
121
  {
88
- "name": "id",
89
- "type": "string"
90
- }
91
- ]
92
- },
93
- {
94
- "event": "CREATE"
95
- },
96
- {
97
- "event": "VIEW",
98
- "payloadSchema": [
99
- {
100
- "name": "id",
101
- "type": "string",
102
- "required": true
103
- },
104
- {
105
- "name": "row.id",
106
- "type": "string",
107
- "required": true
108
- },
109
- {
110
- "name": "row.title",
111
- "type": "string"
112
- },
113
- {
114
- "name": "row.content",
115
- "type": "string"
116
- },
117
- {
118
- "name": "row.author",
119
- "type": "string"
120
- },
121
- {
122
- "name": "row.createdAt",
123
- "type": "datetime"
124
- },
125
- {
126
- "name": "row.likes",
127
- "type": "number"
128
- }
129
- ]
130
- },
131
- {
132
- "event": "PostLoaded",
133
- "description": "Fired when Post finishes loading",
134
- "scope": "internal",
135
- "payloadSchema": [
136
- {
137
- "name": "data",
138
- "type": "[Post]"
139
- }
140
- ]
141
- },
142
- {
143
- "event": "PostLoadFailed",
144
- "description": "Fired when Post fails to load",
145
- "scope": "internal",
146
- "payloadSchema": [
147
- {
148
- "name": "error",
149
- "type": "string"
150
- },
151
- {
152
- "name": "code",
153
- "type": "string"
154
- }
155
- ]
156
- },
157
- {
158
- "event": "PostSaved",
159
- "scope": "internal",
160
- "payloadSchema": [
161
- {
162
- "name": "id",
163
- "type": "string"
164
- }
165
- ]
166
- },
167
- {
168
- "event": "PostSaveFailed",
169
- "scope": "internal",
170
- "payloadSchema": [
171
- {
172
- "name": "error",
173
- "type": "string"
174
- },
175
- {
176
- "name": "code",
177
- "type": "string"
178
- }
179
- ]
180
- },
181
- {
182
- "event": "CommentSaved",
183
- "scope": "internal",
184
- "payloadSchema": [
185
- {
186
- "name": "id",
187
- "type": "string"
188
- }
189
- ]
190
- },
191
- {
192
- "event": "CommentSaveFailed",
193
- "scope": "internal",
194
- "payloadSchema": [
195
- {
196
- "name": "error",
197
- "type": "string"
198
- },
199
- {
200
- "name": "code",
122
+ "name": "source",
201
123
  "type": "string"
202
124
  }
203
125
  ]
@@ -224,7 +146,7 @@
224
146
  "stateMachine": {
225
147
  "states": [
226
148
  {
227
- "name": "browsing",
149
+ "name": "composing",
228
150
  "isInitial": true
229
151
  }
230
152
  ],
@@ -253,704 +175,439 @@
253
175
  }
254
176
  ]
255
177
  },
256
- {
257
- "key": "PostLoaded",
258
- "name": "Post loaded",
259
- "payloadSchema": [
260
- {
261
- "name": "data",
262
- "type": "[Post]"
263
- }
264
- ]
265
- },
266
- {
267
- "key": "PostLoadFailed",
268
- "name": "Post load failed",
269
- "payloadSchema": [
270
- {
271
- "name": "error",
272
- "type": "string"
273
- },
274
- {
275
- "name": "code",
276
- "type": "string"
277
- }
278
- ]
279
- },
280
- {
281
- "key": "COMMENT",
282
- "name": "Comment"
283
- },
284
178
  {
285
179
  "key": "CREATE",
286
180
  "name": "Create"
287
- },
288
- {
289
- "key": "VIEW",
290
- "name": "View",
291
- "payloadSchema": [
292
- {
293
- "name": "id",
294
- "type": "string",
295
- "required": true
296
- },
297
- {
298
- "name": "row",
299
- "type": "Post"
300
- }
301
- ]
302
- },
303
- {
304
- "key": "PostSaved",
305
- "name": "Post saved",
306
- "payloadSchema": [
307
- {
308
- "name": "id",
309
- "type": "string"
310
- }
311
- ]
312
- },
313
- {
314
- "key": "PostSaveFailed",
315
- "name": "Post save failed",
316
- "payloadSchema": [
317
- {
318
- "name": "error",
319
- "type": "string"
320
- },
321
- {
322
- "name": "code",
323
- "type": "string"
324
- }
325
- ]
326
- },
327
- {
328
- "key": "CommentSaved",
329
- "name": "Comment saved",
330
- "payloadSchema": [
331
- {
332
- "name": "id",
333
- "type": "string"
334
- }
335
- ]
336
- },
337
- {
338
- "key": "CommentSaveFailed",
339
- "name": "Comment save failed",
340
- "payloadSchema": [
341
- {
342
- "name": "error",
343
- "type": "string"
344
- },
345
- {
346
- "name": "code",
347
- "type": "string"
348
- }
349
- ]
350
181
  }
351
182
  ],
352
183
  "transitions": [
353
184
  {
354
- "from": "browsing",
355
- "to": "browsing",
185
+ "from": "composing",
186
+ "to": "composing",
356
187
  "event": "INIT",
357
188
  "effects": [
358
- [
359
- "fetch",
360
- "Post",
361
- {
362
- "emit": {
363
- "failure": "PostLoadFailed",
364
- "success": "PostLoaded"
365
- }
366
- }
367
- ],
368
189
  [
369
190
  "render-ui",
370
191
  "main",
371
192
  {
372
- "gap": "md",
373
- "direction": "vertical",
374
- "align": "center",
375
- "className": "py-12",
376
- "type": "stack",
193
+ "gap": "lg",
377
194
  "children": [
378
195
  {
379
- "type": "spinner"
196
+ "direction": "horizontal",
197
+ "gap": "md",
198
+ "justify": "between",
199
+ "align": "center",
200
+ "type": "stack",
201
+ "children": [
202
+ {
203
+ "children": [
204
+ {
205
+ "name": "rss",
206
+ "type": "icon"
207
+ },
208
+ {
209
+ "type": "typography",
210
+ "content": "Feed",
211
+ "variant": "h2"
212
+ }
213
+ ],
214
+ "direction": "horizontal",
215
+ "align": "center",
216
+ "type": "stack",
217
+ "gap": "sm"
218
+ },
219
+ {
220
+ "direction": "horizontal",
221
+ "gap": "sm",
222
+ "children": [
223
+ {
224
+ "icon": "plus",
225
+ "type": "button",
226
+ "label": "New Post",
227
+ "variant": "primary",
228
+ "action": "CREATE"
229
+ }
230
+ ],
231
+ "type": "stack"
232
+ }
233
+ ]
234
+ },
235
+ {
236
+ "type": "divider"
237
+ },
238
+ {
239
+ "gap": "md",
240
+ "children": [
241
+ "@trait.PostSearch"
242
+ ],
243
+ "type": "stack",
244
+ "align": "center",
245
+ "direction": "horizontal"
380
246
  },
247
+ "@trait.PostStats",
381
248
  {
382
- "type": "typography",
383
- "variant": "caption",
384
- "color": "muted",
385
- "content": "Loading…"
386
- }
387
- ]
249
+ "type": "divider"
250
+ },
251
+ "@trait.PostBrowseList"
252
+ ],
253
+ "direction": "vertical",
254
+ "type": "stack"
388
255
  }
389
256
  ]
390
257
  ]
391
258
  },
392
259
  {
393
- "from": "browsing",
394
- "to": "browsing",
395
- "event": "POST_SEARCH",
260
+ "from": "composing",
261
+ "to": "composing",
262
+ "event": "POST_SEARCH"
263
+ },
264
+ {
265
+ "from": "composing",
266
+ "to": "composing",
267
+ "event": "POST_NOTIFICATIONS_OPEN",
396
268
  "effects": [
397
- [
398
- "fetch",
399
- "Post",
400
- {
401
- "emit": {
402
- "success": "PostLoaded",
403
- "failure": "PostLoadFailed"
404
- }
405
- }
406
- ],
407
269
  [
408
270
  "render-ui",
409
271
  "main",
410
272
  {
411
273
  "direction": "vertical",
412
- "className": "py-12",
413
274
  "align": "center",
275
+ "className": "py-8",
276
+ "type": "stack",
414
277
  "children": [
415
278
  {
416
- "type": "spinner"
417
- },
418
- {
419
- "color": "muted",
420
- "variant": "caption",
421
- "type": "typography",
422
- "content": "Searching…"
423
- }
424
- ],
425
- "gap": "md",
426
- "type": "stack"
427
- }
428
- ]
429
- ]
430
- },
431
- {
432
- "from": "browsing",
433
- "to": "browsing",
434
- "event": "POST_NOTIFICATIONS_OPEN",
435
- "effects": [
436
- [
437
- "render-ui",
438
- "main",
439
- {
440
- "children": [
441
- {
442
- "type": "icon",
443
- "name": "bell"
279
+ "name": "bell",
280
+ "type": "icon"
444
281
  },
445
282
  {
283
+ "variant": "h3",
446
284
  "content": "No notifications",
447
- "type": "typography",
448
- "variant": "h3"
285
+ "type": "typography"
449
286
  },
450
287
  {
451
288
  "variant": "caption",
452
- "color": "muted",
453
289
  "type": "typography",
454
- "content": "You're all caught up."
290
+ "content": "You're all caught up.",
291
+ "color": "muted"
455
292
  },
456
293
  {
457
294
  "type": "button",
458
- "variant": "ghost",
295
+ "action": "INIT",
459
296
  "label": "Back to feed",
460
- "action": "INIT"
297
+ "variant": "ghost"
461
298
  }
462
299
  ],
463
- "gap": "md",
464
- "direction": "vertical",
465
- "align": "center",
466
- "type": "stack",
467
- "className": "py-8"
300
+ "gap": "md"
468
301
  }
469
302
  ]
470
303
  ]
304
+ }
305
+ ]
306
+ },
307
+ "scope": "instance"
308
+ },
309
+ {
310
+ "ref": "Search.traits.SearchResultSearch",
311
+ "name": "PostSearch",
312
+ "config": {
313
+ "event": "POST_SEARCH",
314
+ "placeholder": "Search posts…"
315
+ }
316
+ },
317
+ {
318
+ "ref": "Stats.traits.StatsItemStats",
319
+ "name": "PostStats",
320
+ "config": {
321
+ "metrics": [
322
+ {
323
+ "aggregation": "count",
324
+ "format": "number",
325
+ "icon": "rss",
326
+ "label": "Total Posts",
327
+ "variant": "primary"
471
328
  },
472
329
  {
473
- "from": "browsing",
474
- "to": "browsing",
475
- "event": "PostLoaded",
476
- "effects": [
330
+ "filter": [
331
+ "fn",
332
+ "row",
477
333
  [
478
- "render-ui",
479
- "main",
480
- {
481
- "type": "stack",
482
- "gap": "lg",
483
- "direction": "vertical",
484
- "children": [
485
- {
486
- "align": "center",
487
- "direction": "horizontal",
488
- "gap": "md",
489
- "justify": "between",
490
- "type": "stack",
491
- "children": [
492
- {
493
- "type": "stack",
494
- "direction": "horizontal",
495
- "children": [
496
- {
497
- "type": "icon",
498
- "name": "rss"
499
- },
500
- {
501
- "type": "typography",
502
- "content": "Feed",
503
- "variant": "h2"
504
- }
505
- ],
506
- "gap": "sm",
507
- "align": "center"
508
- },
509
- {
510
- "gap": "sm",
511
- "type": "stack",
512
- "children": [
513
- {
514
- "icon": "plus",
515
- "type": "button",
516
- "action": "CREATE",
517
- "label": "New Post",
518
- "variant": "primary"
519
- }
520
- ],
521
- "direction": "horizontal"
522
- }
523
- ]
524
- },
525
- {
526
- "type": "divider"
527
- },
528
- {
529
- "gap": "sm",
530
- "fields": [
531
- {
532
- "name": "title",
533
- "variant": "h3",
534
- "icon": "rss"
535
- },
536
- {
537
- "format": "number",
538
- "variant": "badge",
539
- "name": "likes"
540
- },
541
- {
542
- "variant": "body",
543
- "name": "author"
544
- },
545
- {
546
- "name": "content",
547
- "variant": "body"
548
- },
549
- {
550
- "label": "Posted",
551
- "variant": "caption",
552
- "format": "date",
553
- "name": "createdAt"
554
- }
555
- ],
556
- "variant": "card",
557
- "entity": "@payload.data",
558
- "type": "data-list",
559
- "itemActions": [
560
- {
561
- "label": "View",
562
- "variant": "ghost",
563
- "event": "VIEW"
564
- }
565
- ]
566
- }
567
- ]
568
- }
334
+ "=",
335
+ "@row.timestamp",
336
+ "today"
569
337
  ]
570
- ]
338
+ ],
339
+ "aggregation": "count",
340
+ "variant": "info",
341
+ "format": "number",
342
+ "label": "Today",
343
+ "icon": "calendar"
571
344
  },
572
345
  {
573
- "from": "browsing",
574
- "to": "browsing",
575
- "event": "PostLoadFailed",
576
- "effects": [
577
- [
578
- "render-ui",
579
- "main",
580
- {
581
- "children": [
582
- {
583
- "type": "icon",
584
- "name": "alert-triangle",
585
- "color": "destructive"
586
- },
587
- {
588
- "content": "Failed to load post",
589
- "type": "typography",
590
- "variant": "h3"
591
- },
592
- {
593
- "color": "muted",
594
- "variant": "body",
595
- "content": "@payload.error",
596
- "type": "typography"
597
- },
598
- {
599
- "icon": "rotate-ccw",
600
- "type": "button",
601
- "variant": "primary",
602
- "label": "Retry",
603
- "action": "INIT"
604
- }
605
- ],
606
- "align": "center",
607
- "direction": "vertical",
608
- "className": "py-12",
609
- "gap": "md",
610
- "type": "stack"
611
- }
612
- ]
613
- ]
346
+ "aggregation": "mode",
347
+ "label": "Top Author",
348
+ "variant": "default",
349
+ "format": "text",
350
+ "field": "author",
351
+ "icon": "user"
352
+ },
353
+ {
354
+ "field": "tag",
355
+ "icon": "hash",
356
+ "variant": "warning",
357
+ "aggregation": "mode",
358
+ "label": "Top Tag",
359
+ "format": "text"
614
360
  }
615
- ]
361
+ ],
362
+ "title": "Feed"
616
363
  },
617
- "scope": "collection"
618
- },
619
- {
620
- "name": "PostCreate",
621
- "category": "interaction",
622
- "linkedEntity": "Post",
623
- "emits": [
624
- {
625
- "event": "PostLoadFailed",
626
- "description": "Fired when Post fails to load",
627
- "scope": "internal",
628
- "payloadSchema": [
629
- {
630
- "name": "error",
631
- "type": "string"
632
- },
633
- {
634
- "name": "code",
635
- "type": "string"
636
- }
637
- ]
638
- },
639
- {
640
- "event": "PostLoaded",
641
- "description": "Fired when Post finishes loading",
642
- "scope": "internal",
643
- "payloadSchema": [
644
- {
645
- "name": "data",
646
- "type": "[Post]"
647
- }
648
- ]
649
- },
650
- {
651
- "event": "PostSaveFailed",
652
- "scope": "internal",
653
- "payloadSchema": [
654
- {
655
- "name": "error",
656
- "type": "string"
657
- },
658
- {
659
- "name": "code",
660
- "type": "string"
661
- }
662
- ]
663
- },
664
- {
665
- "event": "PostSaved",
666
- "scope": "internal",
667
- "payloadSchema": [
668
- {
669
- "name": "id",
670
- "type": "string"
671
- }
672
- ]
673
- }
674
- ],
675
364
  "listens": [
676
365
  {
677
- "event": "CREATE",
678
- "triggers": "CREATE",
366
+ "event": "BrowseItemLoaded",
367
+ "triggers": "ITEMS_LOADED",
679
368
  "source": {
680
369
  "kind": "trait",
681
- "trait": "PostBrowse"
370
+ "trait": "PostBrowseList"
682
371
  }
683
372
  }
684
- ],
685
- "stateMachine": {
686
- "states": [
687
- {
688
- "name": "closed",
689
- "isInitial": true
690
- },
691
- {
692
- "name": "open"
693
- }
694
- ],
695
- "events": [
696
- {
697
- "key": "INIT",
698
- "name": "Initialize"
699
- },
373
+ ]
374
+ },
375
+ {
376
+ "ref": "Browse.traits.BrowseItemBrowse",
377
+ "name": "PostBrowseList",
378
+ "linkedEntity": "Post",
379
+ "config": {
380
+ "fields": [
700
381
  {
701
- "key": "CREATE",
702
- "name": "Create"
382
+ "name": "author",
383
+ "variant": "h4",
384
+ "icon": "user"
703
385
  },
704
386
  {
705
- "key": "CLOSE",
706
- "name": "Close"
387
+ "variant": "body",
388
+ "name": "content"
707
389
  },
708
390
  {
709
- "key": "SAVE",
710
- "name": "Save",
711
- "payloadSchema": [
712
- {
713
- "name": "data",
714
- "type": "object",
715
- "required": true
716
- }
717
- ]
391
+ "variant": "caption",
392
+ "name": "timestamp",
393
+ "format": "date"
718
394
  },
719
395
  {
720
- "key": "PostLoadFailed",
721
- "name": "Post load failed",
722
- "payloadSchema": [
723
- {
724
- "name": "error",
725
- "type": "string"
726
- },
727
- {
728
- "name": "code",
729
- "type": "string"
730
- }
731
- ]
732
- },
396
+ "variant": "badge",
397
+ "name": "likes",
398
+ "format": "number"
399
+ }
400
+ ],
401
+ "imageField": "image",
402
+ "itemActions": [
733
403
  {
734
- "key": "PostLoaded",
735
- "name": "Post loaded",
736
- "payloadSchema": [
737
- {
738
- "name": "data",
739
- "type": "[Post]"
740
- }
741
- ]
404
+ "variant": "ghost",
405
+ "label": "View",
406
+ "event": "VIEW"
742
407
  },
743
408
  {
744
- "key": "PostSaveFailed",
745
- "name": "Post save failed",
746
- "payloadSchema": [
747
- {
748
- "name": "error",
749
- "type": "string"
750
- },
751
- {
752
- "name": "code",
753
- "type": "string"
754
- }
755
- ]
409
+ "event": "EDIT",
410
+ "variant": "ghost",
411
+ "label": "Edit"
756
412
  },
757
413
  {
758
- "key": "PostSaved",
759
- "name": "Post saved",
760
- "payloadSchema": [
761
- {
762
- "name": "id",
763
- "type": "string"
764
- }
765
- ]
414
+ "variant": "danger",
415
+ "label": "Delete",
416
+ "event": "DELETE"
766
417
  }
767
418
  ],
768
- "transitions": [
769
- {
770
- "from": "closed",
771
- "to": "closed",
772
- "event": "INIT",
773
- "effects": [
774
- [
775
- "fetch",
776
- "Post",
777
- {
778
- "emit": {
779
- "success": "PostLoaded",
780
- "failure": "PostLoadFailed"
781
- }
782
- }
783
- ]
784
- ]
785
- },
786
- {
787
- "from": "closed",
788
- "to": "open",
789
- "event": "CREATE",
790
- "effects": [
791
- [
792
- "fetch",
793
- "Post",
794
- {
795
- "emit": {
796
- "success": "PostLoaded",
797
- "failure": "PostLoadFailed"
798
- }
799
- }
800
- ],
801
- [
802
- "render-ui",
803
- "modal",
804
- {
805
- "gap": "md",
806
- "type": "stack",
807
- "children": [
808
- {
809
- "children": [
810
- {
811
- "name": "plus-circle",
812
- "type": "icon"
813
- },
814
- {
815
- "variant": "h3",
816
- "content": "Create Post",
817
- "type": "typography"
818
- }
819
- ],
820
- "gap": "sm",
821
- "type": "stack",
822
- "direction": "horizontal"
823
- },
824
- {
825
- "type": "divider"
826
- },
827
- {
828
- "type": "form-section",
829
- "cancelEvent": "CLOSE",
830
- "submitEvent": "SAVE",
831
- "fields": [
832
- "title",
833
- "content",
834
- "author",
835
- "likes"
836
- ],
837
- "mode": "create"
838
- }
839
- ],
840
- "direction": "vertical"
841
- }
842
- ]
843
- ]
844
- },
845
- {
846
- "from": "open",
847
- "to": "closed",
848
- "event": "CLOSE",
849
- "effects": [
850
- [
851
- "render-ui",
852
- "modal",
853
- null
854
- ],
855
- [
856
- "render-ui",
857
- "main",
858
- {
859
- "type": "box"
860
- }
861
- ],
862
- [
863
- "notify",
864
- "Cancelled",
865
- "info"
866
- ]
867
- ]
868
- },
869
- {
870
- "from": "open",
871
- "to": "closed",
872
- "event": "SAVE",
873
- "effects": [
874
- [
875
- "persist",
876
- "create",
877
- "Post",
878
- "@payload.data",
879
- {
880
- "emit": {
881
- "success": "PostSaved",
882
- "failure": "PostSaveFailed"
883
- }
884
- }
885
- ],
886
- [
887
- "render-ui",
888
- "modal",
889
- null
890
- ],
891
- [
892
- "render-ui",
893
- "main",
894
- {
895
- "type": "box"
896
- }
897
- ]
898
- ]
419
+ "cols": 1.0,
420
+ "gap": "md",
421
+ "variant": "card"
422
+ },
423
+ "listens": [
424
+ {
425
+ "event": "SEARCH",
426
+ "triggers": "REFETCH_QUERY",
427
+ "source": {
428
+ "kind": "trait",
429
+ "trait": "PostSearch"
430
+ }
431
+ },
432
+ {
433
+ "event": "POST_CREATED",
434
+ "triggers": "INIT",
435
+ "source": {
436
+ "kind": "trait",
437
+ "trait": "PostPersistor"
438
+ }
439
+ },
440
+ {
441
+ "event": "POST_UPDATED",
442
+ "triggers": "INIT",
443
+ "source": {
444
+ "kind": "trait",
445
+ "trait": "PostPersistor"
446
+ }
447
+ },
448
+ {
449
+ "event": "POST_DELETED",
450
+ "triggers": "INIT",
451
+ "source": {
452
+ "kind": "trait",
453
+ "trait": "PostPersistor"
899
454
  }
455
+ }
456
+ ]
457
+ },
458
+ {
459
+ "ref": "Modal.traits.ModalRecordModal",
460
+ "name": "PostCreate",
461
+ "linkedEntity": "Post",
462
+ "config": {
463
+ "icon": "plus-circle",
464
+ "mode": "create",
465
+ "fields": [
466
+ "author",
467
+ "content",
468
+ "image",
469
+ "tag"
470
+ ],
471
+ "title": "New Post"
472
+ },
473
+ "events": {
474
+ "OPEN": "CREATE"
475
+ },
476
+ "listens": [
477
+ {
478
+ "event": "CREATE",
479
+ "triggers": "CREATE",
480
+ "source": {
481
+ "kind": "trait",
482
+ "trait": "FeedCatalog"
483
+ }
484
+ }
485
+ ]
486
+ },
487
+ {
488
+ "ref": "Modal.traits.ModalRecordModal",
489
+ "name": "PostEdit",
490
+ "linkedEntity": "Post",
491
+ "config": {
492
+ "icon": "edit",
493
+ "title": "Edit Post",
494
+ "mode": "edit",
495
+ "fields": [
496
+ "author",
497
+ "content",
498
+ "image",
499
+ "tag"
900
500
  ]
901
501
  },
902
- "scope": "collection"
502
+ "events": {
503
+ "OPEN": "EDIT"
504
+ },
505
+ "listens": [
506
+ {
507
+ "event": "EDIT",
508
+ "triggers": "EDIT",
509
+ "source": {
510
+ "kind": "trait",
511
+ "trait": "PostBrowseList"
512
+ }
513
+ }
514
+ ]
903
515
  },
904
516
  {
517
+ "ref": "Modal.traits.ModalRecordModal",
905
518
  "name": "PostView",
906
- "category": "interaction",
907
519
  "linkedEntity": "Post",
908
- "emits": [
520
+ "config": {
521
+ "icon": "eye",
522
+ "title": "View Post",
523
+ "mode": "edit",
524
+ "fields": [
525
+ "author",
526
+ "content",
527
+ "image",
528
+ "tag",
529
+ "likes"
530
+ ]
531
+ },
532
+ "events": {
533
+ "OPEN": "VIEW"
534
+ },
535
+ "listens": [
909
536
  {
910
- "event": "PostLoaded",
911
- "description": "Fired when Post finishes loading",
912
- "scope": "internal",
913
- "payloadSchema": [
914
- {
915
- "name": "data",
916
- "type": "[Post]"
917
- }
918
- ]
919
- },
537
+ "event": "VIEW",
538
+ "triggers": "VIEW",
539
+ "source": {
540
+ "kind": "trait",
541
+ "trait": "PostBrowseList"
542
+ }
543
+ }
544
+ ]
545
+ },
546
+ {
547
+ "ref": "Confirmation.traits.ConfirmActionConfirmation",
548
+ "name": "PostDeleteConfirm",
549
+ "linkedEntity": "Post",
550
+ "config": {
551
+ "icon": "alert-triangle",
552
+ "alertMessage": "This action cannot be undone.",
553
+ "confirmLabel": "Delete",
554
+ "title": "Delete Post"
555
+ },
556
+ "events": {
557
+ "CONFIRM": "CONFIRM_DELETE",
558
+ "REQUEST": "DELETE"
559
+ },
560
+ "listens": [
920
561
  {
921
- "event": "PostLoadFailed",
922
- "description": "Fired when Post fails to load",
923
- "scope": "internal",
562
+ "event": "DELETE",
563
+ "triggers": "DELETE",
564
+ "source": {
565
+ "kind": "trait",
566
+ "trait": "PostBrowseList"
567
+ }
568
+ }
569
+ ]
570
+ },
571
+ {
572
+ "ref": "Storage.traits.ServiceStorageStorage",
573
+ "name": "PostImageUpload",
574
+ "config": {
575
+ "acl": "public",
576
+ "uiTrait": "@trait.PostImageUploadForm",
577
+ "bucket": "social-feed-images",
578
+ "maxSize": 10485760.0,
579
+ "allowedMimeTypes": [
580
+ "image/png",
581
+ "image/jpeg",
582
+ "image/gif",
583
+ "image/webp"
584
+ ]
585
+ }
586
+ },
587
+ {
588
+ "name": "PostImageUploadForm",
589
+ "category": "interaction",
590
+ "emits": [
591
+ {
592
+ "event": "UPLOAD",
593
+ "scope": "external",
924
594
  "payloadSchema": [
925
595
  {
926
- "name": "error",
596
+ "name": "source",
927
597
  "type": "string"
928
598
  },
929
599
  {
930
- "name": "code",
600
+ "name": "file",
931
601
  "type": "string"
932
602
  }
933
603
  ]
934
604
  }
935
605
  ],
936
- "listens": [
937
- {
938
- "event": "VIEW",
939
- "triggers": "VIEW",
940
- "source": {
941
- "kind": "trait",
942
- "trait": "PostBrowse"
943
- }
944
- }
945
- ],
946
606
  "stateMachine": {
947
607
  "states": [
948
608
  {
949
- "name": "closed",
609
+ "name": "ready",
950
610
  "isInitial": true
951
- },
952
- {
953
- "name": "open"
954
611
  }
955
612
  ],
956
613
  "events": [
@@ -959,412 +616,81 @@
959
616
  "name": "Initialize"
960
617
  },
961
618
  {
962
- "key": "VIEW",
963
- "name": "View",
964
- "payloadSchema": [
965
- {
966
- "name": "id",
967
- "type": "string",
968
- "required": true
969
- }
970
- ]
971
- },
972
- {
973
- "key": "CLOSE",
974
- "name": "Close"
975
- },
976
- {
977
- "key": "SAVE",
978
- "name": "Save",
979
- "payloadSchema": [
980
- {
981
- "name": "data",
982
- "type": "object",
983
- "required": true
984
- }
985
- ]
986
- },
987
- {
988
- "key": "PostLoaded",
989
- "name": "Post loaded",
990
- "payloadSchema": [
991
- {
992
- "name": "data",
993
- "type": "[Post]"
994
- }
995
- ]
996
- },
997
- {
998
- "key": "PostLoadFailed",
999
- "name": "Post load failed",
1000
- "payloadSchema": [
1001
- {
1002
- "name": "error",
1003
- "type": "string"
1004
- },
1005
- {
1006
- "name": "code",
1007
- "type": "string"
1008
- }
1009
- ]
619
+ "key": "UPLOAD",
620
+ "name": "Upload"
1010
621
  }
1011
622
  ],
1012
623
  "transitions": [
1013
624
  {
1014
- "from": "closed",
1015
- "to": "closed",
625
+ "from": "ready",
626
+ "to": "ready",
1016
627
  "event": "INIT",
1017
628
  "effects": [
1018
- [
1019
- "set",
1020
- "@entity.author",
1021
- ""
1022
- ],
1023
- [
1024
- "set",
1025
- "@entity.content",
1026
- ""
1027
- ],
1028
- [
1029
- "set",
1030
- "@entity.createdAt",
1031
- ""
1032
- ],
1033
- [
1034
- "set",
1035
- "@entity.likes",
1036
- 0.0
1037
- ],
1038
- [
1039
- "set",
1040
- "@entity.title",
1041
- ""
1042
- ],
1043
- [
1044
- "fetch",
1045
- "Post",
1046
- {
1047
- "emit": {
1048
- "success": "PostLoaded",
1049
- "failure": "PostLoadFailed"
1050
- }
1051
- }
1052
- ]
1053
- ]
1054
- },
1055
- {
1056
- "from": "closed",
1057
- "to": "open",
1058
- "event": "VIEW",
1059
- "effects": [
1060
- [
1061
- "fetch",
1062
- "Post",
1063
- {
1064
- "id": "@payload.id",
1065
- "emit": {
1066
- "failure": "PostLoadFailed",
1067
- "success": "PostLoaded"
1068
- }
1069
- }
1070
- ],
1071
629
  [
1072
630
  "render-ui",
1073
- "modal",
631
+ "main",
1074
632
  {
1075
- "direction": "vertical",
633
+ "type": "stack",
1076
634
  "children": [
1077
635
  {
1078
- "children": [
1079
- {
1080
- "name": "eye",
1081
- "type": "icon"
1082
- },
1083
- {
1084
- "variant": "h3",
1085
- "type": "typography",
1086
- "content": "@entity.title"
1087
- }
1088
- ],
1089
- "align": "center",
1090
- "direction": "horizontal",
1091
- "type": "stack",
1092
- "gap": "sm"
1093
- },
1094
- {
1095
- "type": "divider"
1096
- },
1097
- {
1098
- "gap": "md",
1099
- "children": [
1100
- {
1101
- "variant": "caption",
1102
- "content": "Title",
1103
- "type": "typography"
1104
- },
1105
- {
1106
- "content": "@entity.title",
1107
- "type": "typography",
1108
- "variant": "body"
1109
- }
1110
- ],
1111
- "type": "stack",
1112
- "direction": "horizontal"
1113
- },
1114
- {
1115
- "type": "stack",
1116
- "direction": "horizontal",
1117
- "gap": "md",
1118
- "children": [
1119
- {
1120
- "content": "Content",
1121
- "type": "typography",
1122
- "variant": "caption"
1123
- },
1124
- {
1125
- "variant": "body",
1126
- "content": "@entity.content",
1127
- "type": "typography"
1128
- }
1129
- ]
1130
- },
1131
- {
1132
- "children": [
1133
- {
1134
- "type": "typography",
1135
- "variant": "caption",
1136
- "content": "Author"
1137
- },
1138
- {
1139
- "content": "@entity.author",
1140
- "variant": "body",
1141
- "type": "typography"
1142
- }
1143
- ],
1144
- "type": "stack",
1145
- "direction": "horizontal",
1146
- "gap": "md"
1147
- },
1148
- {
1149
- "direction": "horizontal",
1150
- "children": [
1151
- {
1152
- "content": "Created At",
1153
- "type": "typography",
1154
- "variant": "caption"
1155
- },
1156
- {
1157
- "type": "typography",
1158
- "content": "@entity.createdAt",
1159
- "variant": "body"
1160
- }
1161
- ],
1162
- "gap": "md",
1163
- "type": "stack"
1164
- },
1165
- {
1166
- "children": [
1167
- {
1168
- "type": "typography",
1169
- "variant": "caption",
1170
- "content": "Likes"
1171
- },
1172
- {
1173
- "variant": "body",
1174
- "content": "@entity.likes",
1175
- "type": "typography"
1176
- }
1177
- ],
1178
- "direction": "horizontal",
1179
- "type": "stack",
1180
- "gap": "md"
1181
- },
1182
- {
1183
- "type": "divider"
1184
- },
1185
- {
1186
- "type": "stack",
1187
- "children": [
1188
- {
1189
- "type": "button",
1190
- "action": "CLOSE",
1191
- "variant": "ghost",
1192
- "label": "Close"
1193
- }
1194
- ],
1195
- "direction": "horizontal",
1196
- "justify": "end",
1197
- "gap": "sm"
1198
- }
1199
- ],
1200
- "type": "stack",
1201
- "gap": "md"
1202
- }
1203
- ]
1204
- ]
1205
- },
1206
- {
1207
- "from": "open",
1208
- "to": "closed",
1209
- "event": "CLOSE",
1210
- "effects": [
1211
- [
1212
- "render-ui",
1213
- "modal",
1214
- null
1215
- ],
1216
- [
1217
- "render-ui",
1218
- "main",
1219
- {
1220
- "type": "box"
1221
- }
1222
- ],
1223
- [
1224
- "notify",
1225
- "Cancelled",
1226
- "info"
1227
- ]
1228
- ]
1229
- },
1230
- {
1231
- "from": "open",
1232
- "to": "closed",
1233
- "event": "SAVE",
1234
- "effects": [
1235
- [
1236
- "render-ui",
1237
- "modal",
1238
- null
1239
- ],
1240
- [
1241
- "render-ui",
1242
- "main",
1243
- {
1244
- "type": "box"
1245
- }
1246
- ]
1247
- ]
1248
- }
1249
- ]
1250
- },
1251
- "scope": "collection"
1252
- }
1253
- ],
1254
- "pages": [
1255
- {
1256
- "name": "FeedPage",
1257
- "path": "/feed",
1258
- "traits": [
1259
- {
1260
- "ref": "PostAppLayout"
1261
- },
1262
- {
1263
- "ref": "PostBrowse"
1264
- },
1265
- {
1266
- "ref": "PostCreate"
1267
- },
1268
- {
1269
- "ref": "PostView"
1270
- }
1271
- ]
1272
- }
1273
- ]
1274
- },
1275
- {
1276
- "name": "CommentOrbital",
1277
- "entity": {
1278
- "name": "Comment",
1279
- "persistence": "runtime",
1280
- "fields": [
1281
- {
1282
- "name": "id",
1283
- "type": "string",
1284
- "required": true
1285
- },
1286
- {
1287
- "name": "body",
1288
- "type": "string"
1289
- },
1290
- {
1291
- "name": "author",
1292
- "type": "string",
1293
- "default": ""
1294
- },
1295
- {
1296
- "name": "postId",
1297
- "type": "string"
636
+ "type": "typography",
637
+ "content": "Attach an image",
638
+ "variant": "caption"
639
+ },
640
+ {
641
+ "inputType": "text",
642
+ "placeholder": "Choose image…",
643
+ "type": "input"
644
+ },
645
+ {
646
+ "type": "button",
647
+ "action": "UPLOAD",
648
+ "variant": "ghost",
649
+ "icon": "upload",
650
+ "label": "Upload"
651
+ }
652
+ ],
653
+ "gap": "md",
654
+ "direction": "vertical"
655
+ }
656
+ ]
657
+ ]
658
+ }
659
+ ]
1298
660
  },
1299
- {
1300
- "name": "createdAt",
1301
- "type": "datetime",
1302
- "default": ""
1303
- }
1304
- ]
1305
- },
1306
- "traits": [
661
+ "scope": "instance"
662
+ },
1307
663
  {
1308
- "name": "CommentBrowse",
1309
- "category": "interaction",
1310
- "linkedEntity": "Comment",
664
+ "name": "PostPersistor",
665
+ "category": "lifecycle",
666
+ "linkedEntity": "Post",
1311
667
  "emits": [
1312
668
  {
1313
- "event": "COMPOSE"
1314
- },
1315
- {
1316
- "event": "VIEW",
669
+ "event": "POST_CREATED",
670
+ "scope": "external",
1317
671
  "payloadSchema": [
1318
672
  {
1319
673
  "name": "id",
1320
- "type": "string",
1321
- "required": true
1322
- },
1323
- {
1324
- "name": "row.id",
1325
- "type": "string",
1326
- "required": true
1327
- },
1328
- {
1329
- "name": "row.body",
1330
- "type": "string"
1331
- },
1332
- {
1333
- "name": "row.author",
1334
674
  "type": "string"
1335
- },
1336
- {
1337
- "name": "row.postId",
1338
- "type": "string"
1339
- },
1340
- {
1341
- "name": "row.createdAt",
1342
- "type": "datetime"
1343
675
  }
1344
676
  ]
1345
677
  },
1346
678
  {
1347
- "event": "CommentLoaded",
1348
- "description": "Fired when Comment finishes loading",
1349
- "scope": "internal",
679
+ "event": "POST_UPDATED",
680
+ "scope": "external",
1350
681
  "payloadSchema": [
1351
682
  {
1352
- "name": "data",
1353
- "type": "[Comment]"
683
+ "name": "id",
684
+ "type": "string"
1354
685
  }
1355
686
  ]
1356
687
  },
1357
688
  {
1358
- "event": "CommentLoadFailed",
1359
- "description": "Fired when Comment fails to load",
1360
- "scope": "internal",
689
+ "event": "POST_DELETED",
690
+ "scope": "external",
1361
691
  "payloadSchema": [
1362
692
  {
1363
- "name": "error",
1364
- "type": "string"
1365
- },
1366
- {
1367
- "name": "code",
693
+ "name": "id",
1368
694
  "type": "string"
1369
695
  }
1370
696
  ]
@@ -1372,27 +698,42 @@
1372
698
  ],
1373
699
  "listens": [
1374
700
  {
1375
- "event": "SEND",
1376
- "triggers": "INIT",
701
+ "event": "SAVE",
702
+ "triggers": "DO_CREATE",
1377
703
  "source": {
1378
704
  "kind": "trait",
1379
- "trait": "CommentCompose"
705
+ "trait": "PostCreate"
1380
706
  }
1381
707
  },
1382
708
  {
1383
- "event": "COMMENT",
1384
- "triggers": "INIT",
709
+ "event": "SAVE",
710
+ "triggers": "DO_UPDATE",
711
+ "source": {
712
+ "kind": "trait",
713
+ "trait": "PostEdit"
714
+ }
715
+ },
716
+ {
717
+ "event": "DO_UPDATE",
718
+ "triggers": "DO_UPDATE",
719
+ "source": {
720
+ "kind": "trait",
721
+ "trait": "PostLikeTracker"
722
+ }
723
+ },
724
+ {
725
+ "event": "CONFIRM_DELETE",
726
+ "triggers": "DO_DELETE",
1385
727
  "source": {
1386
- "kind": "orbital",
1387
- "orbital": "PostOrbital",
1388
- "trait": "PostBrowse"
728
+ "kind": "trait",
729
+ "trait": "PostDeleteConfirm"
1389
730
  }
1390
731
  }
1391
732
  ],
1392
733
  "stateMachine": {
1393
734
  "states": [
1394
735
  {
1395
- "name": "browsing",
736
+ "name": "idle",
1396
737
  "isInitial": true
1397
738
  }
1398
739
  ],
@@ -1402,311 +743,350 @@
1402
743
  "name": "Initialize"
1403
744
  },
1404
745
  {
1405
- "key": "CommentLoaded",
1406
- "name": "Comment loaded",
746
+ "key": "DO_CREATE",
747
+ "name": "Do Create",
1407
748
  "payloadSchema": [
1408
749
  {
1409
750
  "name": "data",
1410
- "type": "[Comment]"
751
+ "type": "object",
752
+ "required": true
1411
753
  }
1412
754
  ]
1413
755
  },
1414
756
  {
1415
- "key": "CommentLoadFailed",
1416
- "name": "Comment load failed",
757
+ "key": "DO_UPDATE",
758
+ "name": "Do Update",
1417
759
  "payloadSchema": [
1418
760
  {
1419
- "name": "error",
1420
- "type": "string"
1421
- },
761
+ "name": "data",
762
+ "type": "object",
763
+ "required": true
764
+ }
765
+ ]
766
+ },
767
+ {
768
+ "key": "DO_DELETE",
769
+ "name": "Do Delete",
770
+ "payloadSchema": [
1422
771
  {
1423
- "name": "code",
772
+ "name": "id",
1424
773
  "type": "string"
1425
774
  }
1426
775
  ]
1427
776
  },
1428
777
  {
1429
- "key": "COMPOSE",
1430
- "name": "Compose"
778
+ "key": "POST_CREATED",
779
+ "name": "Post Created"
1431
780
  },
1432
781
  {
1433
- "key": "VIEW",
1434
- "name": "View"
782
+ "key": "POST_UPDATED",
783
+ "name": "Post Updated"
784
+ },
785
+ {
786
+ "key": "POST_DELETED",
787
+ "name": "Post Deleted"
1435
788
  }
1436
789
  ],
1437
790
  "transitions": [
1438
791
  {
1439
- "from": "browsing",
1440
- "to": "browsing",
1441
- "event": "INIT",
792
+ "from": "idle",
793
+ "to": "idle",
794
+ "event": "INIT"
795
+ },
796
+ {
797
+ "from": "idle",
798
+ "to": "idle",
799
+ "event": "DO_CREATE",
1442
800
  "effects": [
1443
801
  [
1444
- "fetch",
1445
- "Comment",
802
+ "persist",
803
+ "create",
804
+ "Post",
805
+ "@payload.data",
1446
806
  {
1447
807
  "emit": {
1448
- "success": "CommentLoaded",
1449
- "failure": "CommentLoadFailed"
808
+ "success": "POST_CREATED"
1450
809
  }
1451
810
  }
1452
- ],
811
+ ]
812
+ ]
813
+ },
814
+ {
815
+ "from": "idle",
816
+ "to": "idle",
817
+ "event": "DO_UPDATE",
818
+ "effects": [
1453
819
  [
1454
- "render-ui",
1455
- "main",
820
+ "persist",
821
+ "update",
822
+ "Post",
823
+ "@payload.data",
1456
824
  {
1457
- "align": "center",
1458
- "children": [
1459
- {
1460
- "type": "spinner"
1461
- },
1462
- {
1463
- "color": "muted",
1464
- "variant": "caption",
1465
- "content": "Loading…",
1466
- "type": "typography"
1467
- }
1468
- ],
1469
- "gap": "md",
1470
- "type": "stack",
1471
- "className": "py-12",
1472
- "direction": "vertical"
825
+ "emit": {
826
+ "success": "POST_UPDATED"
827
+ }
1473
828
  }
1474
829
  ]
1475
830
  ]
1476
831
  },
1477
832
  {
1478
- "from": "browsing",
1479
- "to": "browsing",
1480
- "event": "CommentLoaded",
833
+ "from": "idle",
834
+ "to": "idle",
835
+ "event": "DO_DELETE",
1481
836
  "effects": [
1482
837
  [
1483
- "render-ui",
1484
- "main",
838
+ "persist",
839
+ "delete",
840
+ "Post",
841
+ "@payload.id",
1485
842
  {
1486
- "type": "dashboard-layout",
1487
- "appName": "SocialFeed",
1488
- "children": [
1489
- {
1490
- "className": "max-w-5xl mx-auto w-full",
1491
- "direction": "vertical",
1492
- "children": [
1493
- {
1494
- "justify": "between",
1495
- "children": [
1496
- {
1497
- "children": [
1498
- {
1499
- "type": "icon",
1500
- "name": "message-circle"
1501
- },
1502
- {
1503
- "type": "typography",
1504
- "variant": "h2",
1505
- "content": "Messages"
1506
- }
1507
- ],
1508
- "type": "stack",
1509
- "direction": "horizontal",
1510
- "gap": "sm",
1511
- "align": "center"
1512
- },
1513
- {
1514
- "gap": "sm",
1515
- "type": "stack",
1516
- "direction": "horizontal",
1517
- "children": [
1518
- {
1519
- "variant": "primary",
1520
- "label": "Compose",
1521
- "icon": "edit",
1522
- "type": "button",
1523
- "action": "COMPOSE"
1524
- }
1525
- ]
1526
- }
1527
- ],
1528
- "align": "center",
1529
- "direction": "horizontal",
1530
- "gap": "md",
1531
- "type": "stack"
1532
- },
1533
- {
1534
- "type": "divider"
1535
- },
1536
- {
1537
- "gap": "sm",
1538
- "entity": "@payload.data",
1539
- "type": "data-list",
1540
- "itemActions": [
1541
- {
1542
- "variant": "ghost",
1543
- "label": "View",
1544
- "event": "VIEW"
1545
- }
1546
- ],
1547
- "fields": [
1548
- {
1549
- "name": "author",
1550
- "variant": "h4",
1551
- "icon": "message-circle"
1552
- },
1553
- {
1554
- "name": "body",
1555
- "variant": "body"
1556
- },
1557
- {
1558
- "format": "date",
1559
- "variant": "caption",
1560
- "name": "createdAt"
1561
- }
1562
- ],
1563
- "variant": "card"
1564
- }
1565
- ],
1566
- "gap": "lg",
1567
- "type": "stack"
1568
- }
1569
- ],
1570
- "navItems": [
1571
- {
1572
- "href": "/feed",
1573
- "icon": "layout-list",
1574
- "label": "Feed"
1575
- },
1576
- {
1577
- "label": "Messages",
1578
- "href": "/messages",
1579
- "icon": "message-circle"
1580
- }
1581
- ]
843
+ "emit": {
844
+ "success": "POST_DELETED"
845
+ }
1582
846
  }
1583
847
  ]
1584
848
  ]
849
+ }
850
+ ]
851
+ },
852
+ "scope": "instance"
853
+ },
854
+ {
855
+ "name": "PostLikeTracker",
856
+ "category": "interaction",
857
+ "linkedEntity": "Post",
858
+ "emits": [
859
+ {
860
+ "event": "DO_UPDATE",
861
+ "scope": "external",
862
+ "payloadSchema": [
863
+ {
864
+ "name": "data",
865
+ "type": "object",
866
+ "required": true
867
+ }
868
+ ]
869
+ }
870
+ ],
871
+ "stateMachine": {
872
+ "states": [
873
+ {
874
+ "name": "ready",
875
+ "isInitial": true
876
+ }
877
+ ],
878
+ "events": [
879
+ {
880
+ "key": "INIT",
881
+ "name": "Initialize"
882
+ },
883
+ {
884
+ "key": "LIKE",
885
+ "name": "Like",
886
+ "payloadSchema": [
887
+ {
888
+ "name": "id",
889
+ "type": "string"
890
+ },
891
+ {
892
+ "name": "data",
893
+ "type": "object",
894
+ "required": true
895
+ }
896
+ ]
1585
897
  },
1586
898
  {
1587
- "from": "browsing",
1588
- "to": "browsing",
1589
- "event": "CommentLoadFailed",
899
+ "key": "DO_UPDATE",
900
+ "name": "Do Update"
901
+ }
902
+ ],
903
+ "transitions": [
904
+ {
905
+ "from": "ready",
906
+ "to": "ready",
907
+ "event": "INIT",
1590
908
  "effects": [
909
+ [
910
+ "set",
911
+ "@entity.likes",
912
+ 0.0
913
+ ],
914
+ [
915
+ "fetch",
916
+ "Post"
917
+ ],
1591
918
  [
1592
919
  "render-ui",
1593
920
  "main",
1594
921
  {
1595
- "gap": "md",
1596
922
  "type": "stack",
1597
- "className": "py-12",
923
+ "gap": "sm",
924
+ "direction": "horizontal",
925
+ "align": "center",
1598
926
  "children": [
1599
927
  {
1600
- "color": "destructive",
1601
- "name": "alert-triangle",
1602
- "type": "icon"
928
+ "icon": "heart",
929
+ "action": "LIKE",
930
+ "type": "button",
931
+ "label": "Like",
932
+ "variant": "ghost"
1603
933
  },
1604
934
  {
1605
- "variant": "h3",
1606
- "content": "Failed to load comment",
935
+ "variant": "caption",
936
+ "content": "@entity.likes",
1607
937
  "type": "typography"
1608
- },
1609
- {
1610
- "content": "@payload.error",
1611
- "variant": "body",
1612
- "type": "typography",
1613
- "color": "muted"
1614
- },
1615
- {
1616
- "variant": "primary",
1617
- "icon": "rotate-ccw",
1618
- "label": "Retry",
1619
- "type": "button",
1620
- "action": "INIT"
1621
938
  }
1622
- ],
1623
- "direction": "vertical",
1624
- "align": "center"
939
+ ]
940
+ }
941
+ ]
942
+ ]
943
+ },
944
+ {
945
+ "from": "ready",
946
+ "to": "ready",
947
+ "event": "LIKE",
948
+ "effects": [
949
+ [
950
+ "set",
951
+ "@entity.likes",
952
+ "@payload.data.likes"
953
+ ],
954
+ [
955
+ "emit",
956
+ "DO_UPDATE",
957
+ {
958
+ "data": "@payload.data"
1625
959
  }
1626
960
  ]
1627
961
  ]
1628
962
  }
1629
963
  ]
1630
964
  },
1631
- "scope": "collection"
1632
- },
965
+ "scope": "instance"
966
+ }
967
+ ],
968
+ "pages": [
1633
969
  {
1634
- "name": "CommentCompose",
1635
- "category": "interaction",
1636
- "linkedEntity": "Comment",
1637
- "emits": [
970
+ "name": "FeedPage",
971
+ "path": "/feed",
972
+ "traits": [
973
+ {
974
+ "ref": "PostAppLayout"
975
+ },
976
+ {
977
+ "ref": "FeedCatalog"
978
+ },
1638
979
  {
1639
- "event": "SEND"
980
+ "ref": "PostSearch"
1640
981
  },
1641
982
  {
1642
- "event": "CommentLoadFailed",
1643
- "description": "Fired when Comment fails to load",
1644
- "scope": "internal",
1645
- "payloadSchema": [
1646
- {
1647
- "name": "error",
1648
- "type": "string"
1649
- },
1650
- {
1651
- "name": "code",
1652
- "type": "string"
1653
- }
1654
- ]
983
+ "ref": "PostStats"
1655
984
  },
1656
985
  {
1657
- "event": "CommentLoaded",
1658
- "description": "Fired when Comment finishes loading",
1659
- "scope": "internal",
1660
- "payloadSchema": [
1661
- {
1662
- "name": "data",
1663
- "type": "[Comment]"
1664
- }
1665
- ]
986
+ "ref": "PostBrowseList"
1666
987
  },
1667
988
  {
1668
- "event": "CommentSaveFailed",
1669
- "scope": "internal",
1670
- "payloadSchema": [
1671
- {
1672
- "name": "error",
1673
- "type": "string"
1674
- },
1675
- {
1676
- "name": "code",
1677
- "type": "string"
1678
- }
1679
- ]
989
+ "ref": "PostCreate"
990
+ },
991
+ {
992
+ "ref": "PostEdit"
993
+ },
994
+ {
995
+ "ref": "PostView"
996
+ },
997
+ {
998
+ "ref": "PostDeleteConfirm"
999
+ },
1000
+ {
1001
+ "ref": "PostImageUpload"
1002
+ },
1003
+ {
1004
+ "ref": "PostImageUploadForm"
1005
+ },
1006
+ {
1007
+ "ref": "PostPersistor"
1680
1008
  },
1681
1009
  {
1682
- "event": "CommentSaved",
1683
- "scope": "internal",
1010
+ "ref": "PostLikeTracker"
1011
+ }
1012
+ ]
1013
+ }
1014
+ ]
1015
+ },
1016
+ {
1017
+ "name": "CommentOrbital",
1018
+ "uses": [
1019
+ {
1020
+ "from": "std/behaviors/std-modal",
1021
+ "as": "Modal"
1022
+ },
1023
+ {
1024
+ "from": "std/behaviors/std-confirmation",
1025
+ "as": "Confirmation"
1026
+ },
1027
+ {
1028
+ "from": "std/behaviors/std-browse",
1029
+ "as": "Browse"
1030
+ }
1031
+ ],
1032
+ "entity": {
1033
+ "name": "Comment",
1034
+ "collection": "comments",
1035
+ "persistence": "persistent",
1036
+ "fields": [
1037
+ {
1038
+ "name": "id",
1039
+ "type": "string",
1040
+ "required": true
1041
+ },
1042
+ {
1043
+ "name": "postId",
1044
+ "type": "string",
1045
+ "required": true
1046
+ },
1047
+ {
1048
+ "name": "author",
1049
+ "type": "string",
1050
+ "default": ""
1051
+ },
1052
+ {
1053
+ "name": "body",
1054
+ "type": "string",
1055
+ "default": ""
1056
+ },
1057
+ {
1058
+ "name": "createdAt",
1059
+ "type": "datetime",
1060
+ "default": ""
1061
+ },
1062
+ {
1063
+ "name": "pendingId",
1064
+ "type": "string",
1065
+ "default": ""
1066
+ }
1067
+ ]
1068
+ },
1069
+ "traits": [
1070
+ {
1071
+ "name": "CommentDisplay",
1072
+ "category": "interaction",
1073
+ "emits": [
1074
+ {
1075
+ "event": "CREATE",
1076
+ "scope": "external",
1684
1077
  "payloadSchema": [
1685
1078
  {
1686
- "name": "id",
1079
+ "name": "source",
1687
1080
  "type": "string"
1688
1081
  }
1689
1082
  ]
1690
1083
  }
1691
1084
  ],
1692
- "listens": [
1693
- {
1694
- "event": "COMPOSE",
1695
- "triggers": "COMPOSE",
1696
- "source": {
1697
- "kind": "trait",
1698
- "trait": "CommentBrowse"
1699
- }
1700
- }
1701
- ],
1702
1085
  "stateMachine": {
1703
1086
  "states": [
1704
1087
  {
1705
- "name": "closed",
1088
+ "name": "composing",
1706
1089
  "isInitial": true
1707
- },
1708
- {
1709
- "name": "open"
1710
1090
  }
1711
1091
  ],
1712
1092
  "events": [
@@ -1715,224 +1095,288 @@
1715
1095
  "name": "Initialize"
1716
1096
  },
1717
1097
  {
1718
- "key": "COMPOSE",
1719
- "name": "Compose"
1720
- },
1721
- {
1722
- "key": "CLOSE",
1723
- "name": "Close"
1724
- },
1725
- {
1726
- "key": "SEND",
1727
- "name": "Send",
1728
- "payloadSchema": [
1729
- {
1730
- "name": "data",
1731
- "type": "string"
1732
- }
1733
- ]
1734
- },
1735
- {
1736
- "key": "CommentLoadFailed",
1737
- "name": "Comment load failed",
1738
- "payloadSchema": [
1739
- {
1740
- "name": "error",
1741
- "type": "string"
1742
- },
1743
- {
1744
- "name": "code",
1745
- "type": "string"
1746
- }
1747
- ]
1748
- },
1749
- {
1750
- "key": "CommentLoaded",
1751
- "name": "Comment loaded",
1752
- "payloadSchema": [
1753
- {
1754
- "name": "data",
1755
- "type": "[Comment]"
1756
- }
1757
- ]
1758
- },
1759
- {
1760
- "key": "CommentSaveFailed",
1761
- "name": "Comment save failed",
1762
- "payloadSchema": [
1763
- {
1764
- "name": "error",
1765
- "type": "string"
1766
- },
1767
- {
1768
- "name": "code",
1769
- "type": "string"
1770
- }
1771
- ]
1772
- },
1773
- {
1774
- "key": "CommentSaved",
1775
- "name": "Comment saved",
1776
- "payloadSchema": [
1777
- {
1778
- "name": "id",
1779
- "type": "string"
1780
- }
1781
- ]
1098
+ "key": "CREATE",
1099
+ "name": "Create"
1782
1100
  }
1783
1101
  ],
1784
1102
  "transitions": [
1785
1103
  {
1786
- "from": "closed",
1787
- "to": "closed",
1104
+ "from": "composing",
1105
+ "to": "composing",
1788
1106
  "event": "INIT",
1789
- "effects": [
1790
- [
1791
- "fetch",
1792
- "Comment",
1793
- {
1794
- "emit": {
1795
- "failure": "CommentLoadFailed",
1796
- "success": "CommentLoaded"
1797
- }
1798
- }
1799
- ]
1800
- ]
1801
- },
1802
- {
1803
- "from": "closed",
1804
- "to": "open",
1805
- "event": "COMPOSE",
1806
1107
  "effects": [
1807
1108
  [
1808
1109
  "render-ui",
1809
- "modal",
1110
+ "main",
1810
1111
  {
1811
1112
  "direction": "vertical",
1812
- "type": "stack",
1813
- "gap": "md",
1113
+ "className": "max-w-5xl mx-auto w-full",
1814
1114
  "children": [
1815
1115
  {
1816
- "direction": "horizontal",
1817
1116
  "type": "stack",
1818
1117
  "children": [
1819
1118
  {
1820
- "type": "icon",
1821
- "name": "edit"
1119
+ "gap": "sm",
1120
+ "direction": "horizontal",
1121
+ "align": "center",
1122
+ "children": [
1123
+ {
1124
+ "type": "icon",
1125
+ "name": "message-circle"
1126
+ },
1127
+ {
1128
+ "content": "Comments",
1129
+ "type": "typography",
1130
+ "variant": "h2"
1131
+ }
1132
+ ],
1133
+ "type": "stack"
1822
1134
  },
1823
1135
  {
1824
- "type": "typography",
1825
- "content": "New Comment",
1826
- "variant": "h3"
1136
+ "gap": "sm",
1137
+ "children": [
1138
+ {
1139
+ "icon": "edit",
1140
+ "type": "button",
1141
+ "label": "New Comment",
1142
+ "action": "CREATE",
1143
+ "variant": "primary"
1144
+ }
1145
+ ],
1146
+ "direction": "horizontal",
1147
+ "type": "stack"
1827
1148
  }
1828
1149
  ],
1829
- "gap": "sm"
1150
+ "direction": "horizontal",
1151
+ "gap": "md",
1152
+ "justify": "between",
1153
+ "align": "center"
1830
1154
  },
1831
1155
  {
1832
1156
  "type": "divider"
1833
1157
  },
1834
- {
1835
- "mode": "create",
1836
- "fields": [
1837
- "body",
1838
- "author",
1839
- "postId"
1840
- ],
1841
- "type": "form-section",
1842
- "submitEvent": "SEND",
1843
- "cancelEvent": "CLOSE"
1844
- }
1845
- ]
1158
+ "@trait.CommentBrowseList"
1159
+ ],
1160
+ "gap": "lg",
1161
+ "type": "stack"
1846
1162
  }
1847
1163
  ]
1848
1164
  ]
1165
+ }
1166
+ ]
1167
+ },
1168
+ "scope": "instance"
1169
+ },
1170
+ {
1171
+ "ref": "Browse.traits.BrowseItemBrowse",
1172
+ "name": "CommentBrowseList",
1173
+ "linkedEntity": "Comment",
1174
+ "config": {
1175
+ "fields": [
1176
+ {
1177
+ "variant": "h4",
1178
+ "icon": "user",
1179
+ "name": "author"
1849
1180
  },
1850
1181
  {
1851
- "from": "open",
1852
- "to": "closed",
1853
- "event": "CLOSE",
1854
- "effects": [
1855
- [
1856
- "render-ui",
1857
- "modal",
1858
- null
1859
- ],
1860
- [
1861
- "render-ui",
1862
- "main",
1863
- {
1864
- "type": "box"
1865
- }
1866
- ],
1867
- [
1868
- "notify",
1869
- "Cancelled",
1870
- "info"
1871
- ]
1872
- ]
1182
+ "name": "body",
1183
+ "variant": "body"
1873
1184
  },
1874
1185
  {
1875
- "from": "open",
1876
- "to": "closed",
1877
- "event": "SEND",
1878
- "effects": [
1879
- [
1880
- "persist",
1881
- "create",
1882
- "Comment",
1883
- "@payload.data",
1884
- {
1885
- "emit": {
1886
- "success": "CommentSaved",
1887
- "failure": "CommentSaveFailed"
1888
- }
1889
- }
1890
- ],
1891
- [
1892
- "render-ui",
1893
- "modal",
1894
- null
1895
- ],
1896
- [
1897
- "render-ui",
1898
- "main",
1899
- {
1900
- "type": "box"
1901
- }
1902
- ]
1903
- ]
1186
+ "variant": "caption",
1187
+ "format": "date",
1188
+ "name": "createdAt"
1189
+ }
1190
+ ],
1191
+ "cols": 1.0,
1192
+ "gap": "sm",
1193
+ "itemActions": [
1194
+ {
1195
+ "variant": "ghost",
1196
+ "event": "VIEW",
1197
+ "label": "View"
1198
+ },
1199
+ {
1200
+ "label": "Edit",
1201
+ "variant": "ghost",
1202
+ "event": "EDIT"
1203
+ },
1204
+ {
1205
+ "event": "DELETE",
1206
+ "variant": "danger",
1207
+ "label": "Delete"
1208
+ }
1209
+ ],
1210
+ "variant": "card"
1211
+ },
1212
+ "listens": [
1213
+ {
1214
+ "event": "COMMENT_CREATED",
1215
+ "triggers": "INIT",
1216
+ "source": {
1217
+ "kind": "trait",
1218
+ "trait": "CommentPersistor"
1219
+ }
1220
+ },
1221
+ {
1222
+ "event": "COMMENT_UPDATED",
1223
+ "triggers": "INIT",
1224
+ "source": {
1225
+ "kind": "trait",
1226
+ "trait": "CommentPersistor"
1227
+ }
1228
+ },
1229
+ {
1230
+ "event": "COMMENT_DELETED",
1231
+ "triggers": "INIT",
1232
+ "source": {
1233
+ "kind": "trait",
1234
+ "trait": "CommentPersistor"
1235
+ }
1236
+ }
1237
+ ]
1238
+ },
1239
+ {
1240
+ "ref": "Modal.traits.ModalRecordModal",
1241
+ "name": "CommentCreate",
1242
+ "linkedEntity": "Comment",
1243
+ "config": {
1244
+ "icon": "plus-circle",
1245
+ "title": "New Comment",
1246
+ "fields": [
1247
+ "postId",
1248
+ "author",
1249
+ "body"
1250
+ ],
1251
+ "mode": "create"
1252
+ },
1253
+ "events": {
1254
+ "OPEN": "CREATE"
1255
+ },
1256
+ "listens": [
1257
+ {
1258
+ "event": "CREATE",
1259
+ "triggers": "CREATE",
1260
+ "source": {
1261
+ "kind": "trait",
1262
+ "trait": "CommentDisplay"
1904
1263
  }
1264
+ }
1265
+ ]
1266
+ },
1267
+ {
1268
+ "ref": "Modal.traits.ModalRecordModal",
1269
+ "name": "CommentEdit",
1270
+ "linkedEntity": "Comment",
1271
+ "config": {
1272
+ "icon": "edit",
1273
+ "mode": "edit",
1274
+ "title": "Edit Comment",
1275
+ "fields": [
1276
+ "postId",
1277
+ "author",
1278
+ "body"
1905
1279
  ]
1906
1280
  },
1907
- "scope": "collection"
1281
+ "events": {
1282
+ "OPEN": "EDIT"
1283
+ },
1284
+ "listens": [
1285
+ {
1286
+ "event": "EDIT",
1287
+ "triggers": "EDIT",
1288
+ "source": {
1289
+ "kind": "trait",
1290
+ "trait": "CommentBrowseList"
1291
+ }
1292
+ }
1293
+ ]
1908
1294
  },
1909
1295
  {
1296
+ "ref": "Modal.traits.ModalRecordModal",
1910
1297
  "name": "CommentView",
1911
- "category": "interaction",
1298
+ "linkedEntity": "Comment",
1299
+ "config": {
1300
+ "mode": "edit",
1301
+ "title": "View Comment",
1302
+ "icon": "eye",
1303
+ "fields": [
1304
+ "postId",
1305
+ "author",
1306
+ "body",
1307
+ "createdAt"
1308
+ ]
1309
+ },
1310
+ "events": {
1311
+ "OPEN": "VIEW"
1312
+ },
1313
+ "listens": [
1314
+ {
1315
+ "event": "VIEW",
1316
+ "triggers": "VIEW",
1317
+ "source": {
1318
+ "kind": "trait",
1319
+ "trait": "CommentBrowseList"
1320
+ }
1321
+ }
1322
+ ]
1323
+ },
1324
+ {
1325
+ "ref": "Confirmation.traits.ConfirmActionConfirmation",
1326
+ "name": "CommentDeleteConfirm",
1327
+ "linkedEntity": "Comment",
1328
+ "config": {
1329
+ "title": "Delete Comment",
1330
+ "icon": "alert-triangle",
1331
+ "alertMessage": "This action cannot be undone.",
1332
+ "confirmLabel": "Delete"
1333
+ },
1334
+ "events": {
1335
+ "CONFIRM": "CONFIRM_DELETE",
1336
+ "REQUEST": "DELETE"
1337
+ },
1338
+ "listens": [
1339
+ {
1340
+ "event": "DELETE",
1341
+ "triggers": "DELETE",
1342
+ "source": {
1343
+ "kind": "trait",
1344
+ "trait": "CommentBrowseList"
1345
+ }
1346
+ }
1347
+ ]
1348
+ },
1349
+ {
1350
+ "name": "CommentPersistor",
1351
+ "category": "lifecycle",
1912
1352
  "linkedEntity": "Comment",
1913
1353
  "emits": [
1914
1354
  {
1915
- "event": "CommentLoaded",
1916
- "description": "Fired when Comment finishes loading",
1917
- "scope": "internal",
1355
+ "event": "COMMENT_CREATED",
1356
+ "scope": "external",
1918
1357
  "payloadSchema": [
1919
1358
  {
1920
- "name": "data",
1921
- "type": "[Comment]"
1359
+ "name": "id",
1360
+ "type": "string"
1922
1361
  }
1923
1362
  ]
1924
1363
  },
1925
1364
  {
1926
- "event": "CommentLoadFailed",
1927
- "description": "Fired when Comment fails to load",
1928
- "scope": "internal",
1365
+ "event": "COMMENT_UPDATED",
1366
+ "scope": "external",
1929
1367
  "payloadSchema": [
1930
1368
  {
1931
- "name": "error",
1369
+ "name": "id",
1932
1370
  "type": "string"
1933
- },
1371
+ }
1372
+ ]
1373
+ },
1374
+ {
1375
+ "event": "COMMENT_DELETED",
1376
+ "scope": "external",
1377
+ "payloadSchema": [
1934
1378
  {
1935
- "name": "code",
1379
+ "name": "id",
1936
1380
  "type": "string"
1937
1381
  }
1938
1382
  ]
@@ -1940,22 +1384,35 @@
1940
1384
  ],
1941
1385
  "listens": [
1942
1386
  {
1943
- "event": "VIEW",
1944
- "triggers": "VIEW",
1387
+ "event": "SAVE",
1388
+ "triggers": "DO_CREATE",
1389
+ "source": {
1390
+ "kind": "trait",
1391
+ "trait": "CommentCreate"
1392
+ }
1393
+ },
1394
+ {
1395
+ "event": "SAVE",
1396
+ "triggers": "DO_UPDATE",
1945
1397
  "source": {
1946
1398
  "kind": "trait",
1947
- "trait": "CommentBrowse"
1399
+ "trait": "CommentEdit"
1400
+ }
1401
+ },
1402
+ {
1403
+ "event": "CONFIRM_DELETE",
1404
+ "triggers": "DO_DELETE",
1405
+ "source": {
1406
+ "kind": "trait",
1407
+ "trait": "CommentDeleteConfirm"
1948
1408
  }
1949
1409
  }
1950
1410
  ],
1951
1411
  "stateMachine": {
1952
1412
  "states": [
1953
1413
  {
1954
- "name": "closed",
1414
+ "name": "idle",
1955
1415
  "isInitial": true
1956
- },
1957
- {
1958
- "name": "open"
1959
1416
  }
1960
1417
  ],
1961
1418
  "events": [
@@ -1964,281 +1421,140 @@
1964
1421
  "name": "Initialize"
1965
1422
  },
1966
1423
  {
1967
- "key": "VIEW",
1968
- "name": "View",
1424
+ "key": "DO_CREATE",
1425
+ "name": "Do Create",
1969
1426
  "payloadSchema": [
1970
1427
  {
1971
- "name": "id",
1972
- "type": "string"
1428
+ "name": "data",
1429
+ "type": "object",
1430
+ "required": true
1973
1431
  }
1974
1432
  ]
1975
1433
  },
1976
1434
  {
1977
- "key": "CLOSE",
1978
- "name": "Close"
1979
- },
1980
- {
1981
- "key": "SAVE",
1982
- "name": "Save"
1983
- },
1984
- {
1985
- "key": "CommentLoaded",
1986
- "name": "Comment loaded",
1435
+ "key": "DO_UPDATE",
1436
+ "name": "Do Update",
1987
1437
  "payloadSchema": [
1988
1438
  {
1989
1439
  "name": "data",
1990
- "type": "[Comment]"
1440
+ "type": "object",
1441
+ "required": true
1991
1442
  }
1992
1443
  ]
1993
1444
  },
1994
1445
  {
1995
- "key": "CommentLoadFailed",
1996
- "name": "Comment load failed",
1446
+ "key": "DO_DELETE",
1447
+ "name": "Do Delete",
1997
1448
  "payloadSchema": [
1998
1449
  {
1999
- "name": "error",
2000
- "type": "string"
2001
- },
2002
- {
2003
- "name": "code",
1450
+ "name": "id",
2004
1451
  "type": "string"
2005
1452
  }
2006
1453
  ]
1454
+ },
1455
+ {
1456
+ "key": "COMMENT_CREATED",
1457
+ "name": "Comment Created"
1458
+ },
1459
+ {
1460
+ "key": "COMMENT_UPDATED",
1461
+ "name": "Comment Updated"
1462
+ },
1463
+ {
1464
+ "key": "COMMENT_DELETED",
1465
+ "name": "Comment Deleted"
2007
1466
  }
2008
1467
  ],
2009
1468
  "transitions": [
2010
1469
  {
2011
- "from": "closed",
2012
- "to": "closed",
2013
- "event": "INIT",
1470
+ "from": "idle",
1471
+ "to": "idle",
1472
+ "event": "INIT"
1473
+ },
1474
+ {
1475
+ "from": "idle",
1476
+ "to": "idle",
1477
+ "event": "DO_CREATE",
2014
1478
  "effects": [
2015
1479
  [
2016
- "set",
2017
- "@entity.author",
2018
- ""
2019
- ],
2020
- [
2021
- "set",
2022
- "@entity.body",
2023
- ""
2024
- ],
2025
- [
2026
- "set",
2027
- "@entity.createdAt",
2028
- ""
2029
- ],
2030
- [
2031
- "set",
2032
- "@entity.postId",
2033
- ""
2034
- ],
2035
- [
2036
- "fetch",
1480
+ "persist",
1481
+ "create",
2037
1482
  "Comment",
1483
+ "@payload.data",
2038
1484
  {
2039
1485
  "emit": {
2040
- "success": "CommentLoaded",
2041
- "failure": "CommentLoadFailed"
1486
+ "success": "COMMENT_CREATED"
2042
1487
  }
2043
1488
  }
2044
1489
  ]
2045
1490
  ]
2046
1491
  },
2047
1492
  {
2048
- "from": "closed",
2049
- "to": "open",
2050
- "event": "VIEW",
1493
+ "from": "idle",
1494
+ "to": "idle",
1495
+ "event": "DO_UPDATE",
2051
1496
  "effects": [
2052
1497
  [
2053
- "fetch",
1498
+ "persist",
1499
+ "update",
2054
1500
  "Comment",
1501
+ "@payload.data",
2055
1502
  {
2056
- "id": "@payload.id",
2057
1503
  "emit": {
2058
- "success": "CommentLoaded",
2059
- "failure": "CommentLoadFailed"
1504
+ "success": "COMMENT_UPDATED"
2060
1505
  }
2061
1506
  }
2062
- ],
2063
- [
2064
- "render-ui",
2065
- "modal",
2066
- {
2067
- "type": "stack",
2068
- "gap": "md",
2069
- "children": [
2070
- {
2071
- "direction": "horizontal",
2072
- "gap": "sm",
2073
- "type": "stack",
2074
- "align": "center",
2075
- "children": [
2076
- {
2077
- "name": "eye",
2078
- "type": "icon"
2079
- },
2080
- {
2081
- "type": "typography",
2082
- "variant": "h3",
2083
- "content": "@entity.body"
2084
- }
2085
- ]
2086
- },
2087
- {
2088
- "type": "divider"
2089
- },
2090
- {
2091
- "type": "stack",
2092
- "direction": "horizontal",
2093
- "gap": "md",
2094
- "children": [
2095
- {
2096
- "variant": "caption",
2097
- "content": "Body",
2098
- "type": "typography"
2099
- },
2100
- {
2101
- "type": "typography",
2102
- "content": "@entity.body",
2103
- "variant": "body"
2104
- }
2105
- ]
2106
- },
2107
- {
2108
- "type": "stack",
2109
- "gap": "md",
2110
- "direction": "horizontal",
2111
- "children": [
2112
- {
2113
- "content": "Author",
2114
- "type": "typography",
2115
- "variant": "caption"
2116
- },
2117
- {
2118
- "variant": "body",
2119
- "content": "@entity.author",
2120
- "type": "typography"
2121
- }
2122
- ]
2123
- },
2124
- {
2125
- "gap": "md",
2126
- "children": [
2127
- {
2128
- "variant": "caption",
2129
- "type": "typography",
2130
- "content": "Post ID"
2131
- },
2132
- {
2133
- "content": "@entity.postId",
2134
- "type": "typography",
2135
- "variant": "body"
2136
- }
2137
- ],
2138
- "direction": "horizontal",
2139
- "type": "stack"
2140
- },
2141
- {
2142
- "children": [
2143
- {
2144
- "content": "Created At",
2145
- "type": "typography",
2146
- "variant": "caption"
2147
- },
2148
- {
2149
- "variant": "body",
2150
- "content": "@entity.createdAt",
2151
- "type": "typography"
2152
- }
2153
- ],
2154
- "direction": "horizontal",
2155
- "type": "stack",
2156
- "gap": "md"
2157
- },
2158
- {
2159
- "type": "divider"
2160
- },
2161
- {
2162
- "direction": "horizontal",
2163
- "type": "stack",
2164
- "justify": "end",
2165
- "gap": "sm",
2166
- "children": [
2167
- {
2168
- "variant": "ghost",
2169
- "type": "button",
2170
- "label": "Close",
2171
- "action": "CLOSE"
2172
- }
2173
- ]
2174
- }
2175
- ],
2176
- "direction": "vertical"
2177
- }
2178
1507
  ]
2179
1508
  ]
2180
1509
  },
2181
1510
  {
2182
- "from": "open",
2183
- "to": "closed",
2184
- "event": "CLOSE",
1511
+ "from": "idle",
1512
+ "to": "idle",
1513
+ "event": "DO_DELETE",
2185
1514
  "effects": [
2186
1515
  [
2187
- "render-ui",
2188
- "modal",
2189
- null
2190
- ],
2191
- [
2192
- "render-ui",
2193
- "main",
2194
- {
2195
- "type": "box"
2196
- }
2197
- ],
2198
- [
2199
- "notify",
2200
- "Cancelled",
2201
- "info"
2202
- ]
2203
- ]
2204
- },
2205
- {
2206
- "from": "open",
2207
- "to": "closed",
2208
- "event": "SAVE",
2209
- "effects": [
2210
- [
2211
- "render-ui",
2212
- "modal",
2213
- null
2214
- ],
2215
- [
2216
- "render-ui",
2217
- "main",
1516
+ "persist",
1517
+ "delete",
1518
+ "Comment",
1519
+ "@payload.id",
2218
1520
  {
2219
- "type": "box"
1521
+ "emit": {
1522
+ "success": "COMMENT_DELETED"
1523
+ }
2220
1524
  }
2221
1525
  ]
2222
1526
  ]
2223
1527
  }
2224
1528
  ]
2225
1529
  },
2226
- "scope": "collection"
1530
+ "scope": "instance"
2227
1531
  }
2228
1532
  ],
2229
1533
  "pages": [
2230
1534
  {
2231
- "name": "Messages",
2232
- "path": "/messages",
1535
+ "name": "Comments",
1536
+ "path": "/comments",
2233
1537
  "traits": [
2234
1538
  {
2235
- "ref": "CommentBrowse"
1539
+ "ref": "CommentDisplay"
2236
1540
  },
2237
1541
  {
2238
- "ref": "CommentCompose"
1542
+ "ref": "CommentBrowseList"
1543
+ },
1544
+ {
1545
+ "ref": "CommentCreate"
1546
+ },
1547
+ {
1548
+ "ref": "CommentEdit"
2239
1549
  },
2240
1550
  {
2241
1551
  "ref": "CommentView"
1552
+ },
1553
+ {
1554
+ "ref": "CommentDeleteConfirm"
1555
+ },
1556
+ {
1557
+ "ref": "CommentPersistor"
2242
1558
  }
2243
1559
  ]
2244
1560
  }