@wix/himalaya-cli 0.1033.0 → 0.1034.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 (126) hide show
  1. package/dist/cli.mjs +0 -2
  2. package/package.json +2 -2
  3. package/templates/beauty-salon/dev/index.ts +398 -1
  4. package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +4 -1
  5. package/templates/beauty-salon/tier5-src/_shared/collection-service.ts +36 -5
  6. package/templates/beauty-salon/tier5-src/_shared/empty-flags.ts +33 -0
  7. package/templates/beauty-salon/tier5-src/himi-store-saved/index.ts +3 -2
  8. package/templates/beauty-salon/tier5-src/wix-spaces-collections/index.ts +3 -2
  9. package/templates/beauty-salon/tier5-src/wix-spaces-my-subscriptions/index.ts +11 -2
  10. package/templates/beauty-salon/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  11. package/templates/beauty-salon-owner/dev/index.ts +1216 -0
  12. package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +4 -1
  13. package/templates/beauty-salon-owner/tier5-src/_shared/collection-service.ts +36 -5
  14. package/templates/branded-lite/dev/index.ts +2239 -343
  15. package/templates/branded-lite/tier5-src/_shared/branded-load-state.ts +106 -0
  16. package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +4 -1
  17. package/templates/branded-lite/tier5-src/_shared/collection-service.ts +36 -5
  18. package/templates/branded-lite/tier5-src/_shared/empty-flags.ts +33 -0
  19. package/templates/branded-lite/tier5-src/himi-branded-lite-badges/index.ts +20 -16
  20. package/templates/branded-lite/tier5-src/himi-branded-lite-coupons/index.ts +20 -20
  21. package/templates/branded-lite/tier5-src/himi-branded-lite-donations/index.ts +20 -16
  22. package/templates/branded-lite/tier5-src/himi-branded-lite-forms/index.ts +23 -31
  23. package/templates/branded-lite/tier5-src/himi-branded-lite-galleries/index.ts +19 -14
  24. package/templates/branded-lite/tier5-src/himi-branded-lite-giftcards/index.ts +20 -16
  25. package/templates/branded-lite/tier5-src/himi-branded-lite-inbox/index.ts +20 -15
  26. package/templates/branded-lite/tier5-src/himi-branded-lite-invoices/index.ts +20 -16
  27. package/templates/branded-lite/tier5-src/himi-branded-lite-loyalty/index.ts +20 -17
  28. package/templates/branded-lite/tier5-src/himi-branded-lite-notifications/index.ts +20 -18
  29. package/templates/branded-lite/tier5-src/himi-branded-lite-notifsettings/index.ts +23 -19
  30. package/templates/branded-lite/tier5-src/himi-branded-lite-podcasts/index.ts +1 -1
  31. package/templates/branded-lite/tier5-src/himi-branded-lite-reservations/index.ts +24 -20
  32. package/templates/branded-lite/tier5-src/himi-branded-lite-reviews/index.ts +20 -17
  33. package/templates/branded-lite/tier5-src/himi-branded-lite-videos/index.ts +19 -15
  34. package/templates/branded-lite/tier5-src/himi-store-saved/index.ts +3 -2
  35. package/templates/branded-lite/tier5-src/wix-spaces-collections/index.ts +3 -2
  36. package/templates/branded-lite/tier5-src/wix-spaces-forum/index.ts +3 -2
  37. package/templates/branded-lite/tier5-src/wix-spaces-members/index.ts +19 -6
  38. package/templates/branded-lite/tier5-src/wix-spaces-my-subscriptions/index.ts +11 -2
  39. package/templates/branded-lite/tier5-src/wix-spaces-new-message/index.ts +3 -2
  40. package/templates/branded-lite/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  41. package/templates/community-club/dev/index.ts +283 -2
  42. package/templates/community-club/tier5-src/_shared/collection-contract.ts +4 -1
  43. package/templates/community-club/tier5-src/_shared/collection-service.ts +36 -5
  44. package/templates/community-club/tier5-src/_shared/empty-flags.ts +33 -0
  45. package/templates/community-club/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  46. package/templates/community-club-owner/dev/index.ts +1216 -0
  47. package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +4 -1
  48. package/templates/community-club-owner/tier5-src/_shared/collection-service.ts +36 -5
  49. package/templates/events-meetups/dev/index.ts +197 -1
  50. package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +4 -1
  51. package/templates/events-meetups/tier5-src/_shared/collection-service.ts +36 -5
  52. package/templates/events-meetups/tier5-src/_shared/empty-flags.ts +33 -0
  53. package/templates/events-meetups/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  54. package/templates/events-meetups-owner/dev/index.ts +1088 -0
  55. package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +4 -1
  56. package/templates/events-meetups-owner/tier5-src/_shared/collection-service.ts +36 -5
  57. package/templates/gym-fitness/dev/index.ts +462 -1
  58. package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +4 -1
  59. package/templates/gym-fitness/tier5-src/_shared/collection-service.ts +36 -5
  60. package/templates/gym-fitness/tier5-src/_shared/empty-flags.ts +33 -0
  61. package/templates/gym-fitness/tier5-src/himi-store-saved/index.ts +3 -2
  62. package/templates/gym-fitness/tier5-src/wix-spaces-collections/index.ts +3 -2
  63. package/templates/gym-fitness/tier5-src/wix-spaces-my-subscriptions/index.ts +11 -2
  64. package/templates/gym-fitness/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  65. package/templates/gym-fitness-owner/dev/index.ts +1280 -0
  66. package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +4 -1
  67. package/templates/gym-fitness-owner/tier5-src/_shared/collection-service.ts +36 -5
  68. package/templates/nonprofit-cause/dev/index.ts +264 -1
  69. package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +4 -1
  70. package/templates/nonprofit-cause/tier5-src/_shared/collection-service.ts +36 -5
  71. package/templates/nonprofit-cause/tier5-src/_shared/empty-flags.ts +33 -0
  72. package/templates/nonprofit-cause/tier5-src/wix-spaces-my-subscriptions/index.ts +11 -2
  73. package/templates/nonprofit-cause/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  74. package/templates/nonprofit-cause-owner/dev/index.ts +1152 -0
  75. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +4 -1
  76. package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-service.ts +36 -5
  77. package/templates/owner-lite/dev/index.ts +1280 -0
  78. package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +4 -1
  79. package/templates/owner-lite/tier5-src/_shared/collection-service.ts +36 -5
  80. package/templates/podcast-creator/dev/index.ts +286 -23
  81. package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +4 -1
  82. package/templates/podcast-creator/tier5-src/_shared/collection-service.ts +36 -5
  83. package/templates/podcast-creator/tier5-src/_shared/empty-flags.ts +33 -0
  84. package/templates/podcast-creator/tier5-src/himi-branded-lite-podcasts/index.ts +1 -1
  85. package/templates/podcast-creator/tier5-src/wix-spaces-my-subscriptions/index.ts +11 -2
  86. package/templates/podcast-creator/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  87. package/templates/podcast-creator-owner/dev/index.ts +1216 -0
  88. package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +4 -1
  89. package/templates/podcast-creator-owner/tier5-src/_shared/collection-service.ts +36 -5
  90. package/templates/portfolio-creative/dev/index.ts +353 -23
  91. package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +4 -1
  92. package/templates/portfolio-creative/tier5-src/_shared/collection-service.ts +36 -5
  93. package/templates/portfolio-creative/tier5-src/_shared/empty-flags.ts +33 -0
  94. package/templates/portfolio-creative/tier5-src/himi-store-saved/index.ts +3 -2
  95. package/templates/portfolio-creative/tier5-src/wix-spaces-collections/index.ts +3 -2
  96. package/templates/portfolio-creative/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  97. package/templates/portfolio-creative-owner/dev/index.ts +1216 -0
  98. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +4 -1
  99. package/templates/portfolio-creative-owner/tier5-src/_shared/collection-service.ts +36 -5
  100. package/templates/restaurant/dev/index.ts +197 -1
  101. package/templates/restaurant/tier5-src/_shared/collection-contract.ts +4 -1
  102. package/templates/restaurant/tier5-src/_shared/collection-service.ts +36 -5
  103. package/templates/restaurant/tier5-src/_shared/empty-flags.ts +33 -0
  104. package/templates/restaurant/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  105. package/templates/restaurant-owner/dev/index.ts +1280 -0
  106. package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +4 -1
  107. package/templates/restaurant-owner/tier5-src/_shared/collection-service.ts +36 -5
  108. package/templates/retail-store/dev/index.ts +203 -1
  109. package/templates/retail-store/tier5-src/_shared/collection-contract.ts +4 -1
  110. package/templates/retail-store/tier5-src/_shared/collection-service.ts +36 -5
  111. package/templates/retail-store/tier5-src/_shared/empty-flags.ts +33 -0
  112. package/templates/retail-store/tier5-src/himi-store-saved/index.ts +3 -2
  113. package/templates/retail-store/tier5-src/wix-spaces-collections/index.ts +3 -2
  114. package/templates/retail-store/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  115. package/templates/retail-store-owner/dev/index.ts +1152 -0
  116. package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +4 -1
  117. package/templates/retail-store-owner/tier5-src/_shared/collection-service.ts +36 -5
  118. package/templates/yoga-studio/dev/index.ts +392 -1
  119. package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +4 -1
  120. package/templates/yoga-studio/tier5-src/_shared/collection-service.ts +36 -5
  121. package/templates/yoga-studio/tier5-src/_shared/empty-flags.ts +33 -0
  122. package/templates/yoga-studio/tier5-src/wix-spaces-my-subscriptions/index.ts +11 -2
  123. package/templates/yoga-studio/tier5-src/wix-spaces-whats-new/index.ts +3 -2
  124. package/templates/yoga-studio-owner/dev/index.ts +1152 -0
  125. package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +4 -1
  126. package/templates/yoga-studio-owner/tier5-src/_shared/collection-service.ts +36 -5
@@ -30,6 +30,9 @@ export interface CollectionConfig {
30
30
  * `screenId` opens that screen with the row id; without it the verb reuses the
31
31
  * row's own tap action (the detail screen that owns the verb). */
32
32
  primaryVerb?: { label: string; screenId?: string };
33
+ /** A state field the DOMAIN narrows `rows` by (e.g. a category picker). While it is set,
34
+ * zero rows is a filtered result, not an empty source. */
35
+ narrowedBy?: string;
33
36
  }
34
37
  /** At or below this many records, with no query/filter narrowing them and no further
35
38
  * page, the list/grid toggle, Refine, chips, search and count are noise. */
@@ -41,7 +44,7 @@ export const COLLECTIONS: Record<string, CollectionConfig> = {
41
44
  defaultFilter: 'value:Upcoming', searchPlaceholder: 'Exact booking ID', filterValues: ['Upcoming', 'Past', 'Cancelled'],
42
45
  sortLabels: { default: 'Soonest', az: 'Oldest', za: 'Latest' } },
43
46
  himiEvents: { rows: 'results', title: 'title', subtitle: 'dateLine', image: 'image', view: 'grid', backendQuery: true, searchPlaceholder: 'Exact event title', filterValues: ['Upcoming', 'Past'], sortLabels: { default: 'Date', az: 'Title A–Z', za: 'Title Z–A' }, primaryVerb: { label: 'Register' } },
44
- himiBlogFeed: { rows: 'posts', title: 'title', subtitle: 'excerpt', image: 'image', filter: 'category', filterValuesFrom: 'categories', view: 'grid' },
47
+ himiBlogFeed: { rows: 'posts', title: 'title', subtitle: 'excerpt', image: 'image', filter: 'category', filterValuesFrom: 'categories', view: 'grid', narrowedBy: 'selectedCategoryId' },
45
48
  himiOwnerLiteProducts: { rows: 'products', title: 'name', subtitle: 'price', image: 'image', view: 'grid', backendQuery: true },
46
49
  himiOwnerModules: { instanceInput: 'module', rows: 'rows', title: 'title', subtitle: 'subtitle', image: 'image', filter: 'statusLabel', view: 'list', paged: true, reviewAction: 'prepareRecord', reviewSelectedAction: 'prepareSelected' },
47
50
  himiOwnerLiteServices: { rows: 'services', title: 'name', subtitle: 'subtitle', view: 'list', backendQuery: true, searchPlaceholder: 'Service name starts with…' },
@@ -122,14 +122,38 @@ export function decorateCollection(name: string, def: { state: State; actions?:
122
122
  const errored = s.status === 'error' || s.isErrored === true || s.errored === true || backendState?.status === 'error';
123
123
  const domainError = typeof s.error === 'string' ? s.error.trim() : '';
124
124
  const queryError = typeof backendState?.error === 'string' ? backendState.error.trim() : '';
125
- const errorMessage = queryError || domainError || copyParam('collection.loadError', 'This collection could not load. Try again.');
125
+ // Some domains carry their failure sentence in `emptyText` (portfolio, podcasts);
126
+ // the screen folds that node into this block, so keep the domain's own words.
127
+ const domainEmptyError = errored && typeof s.emptyText === 'string' ? s.emptyText.trim() : '';
128
+ const errorMessage = queryError || domainError || domainEmptyError || copyParam('collection.loadError', 'This collection could not load. Try again.');
126
129
  const canRetry = !!backend || typeof def.actions?.refresh === 'function' || typeof def.actions?.load === 'function' || typeof def.actions?.collectionRetry === 'function';
130
+ // Wix refused the visitor: retrying cannot help, signing in can.
131
+ const signInRequired = errored && s.signInRequired === true;
132
+ // "the source has nothing" and "your filter matched nothing" are
133
+ // different states. Only the second may offer "Clear filters", and the list chrome
134
+ // (view, refine, chips, counter, search) means nothing over a source with no rows.
135
+ // Loaded-row collections hold the whole source in `rows`, so zero rows IS an empty
136
+ // source. A backend query returns only matches, so zero rows is source-empty only
137
+ // when nothing narrowed it.
138
+ // Anything the customer (or the domain) narrowed the result by. While narrowed, zero rows
139
+ // is "your filter matched nothing" and the controls that got them here must stay.
140
+ // The DOMAIN's own filter (config.narrowedBy, e.g. blog category) narrowed the rows: the
141
+ // domain owns that empty state and its clear action. The shared "Clear filters" block
142
+ // cannot reset a domain filter, so it never shows for one.
143
+ const domainNarrowed = !!config.narrowedBy && !!s[config.narrowedBy];
127
144
  // A default view is what the screen opens on; anything else is the member's own
128
145
  // narrowing, which keeps the chrome (and the Clear that undoes it) on screen.
129
146
  // "All" and the collection's own default (e.g. Upcoming) are both un-narrowed: Clear
130
147
  // resets to "All", so showing it on either would offer a reset that changes nothing.
131
- const narrowed = !!prefs.query.trim() || (prefs.filter !== 'all' && prefs.filter !== initialCollection(config).filter);
132
- const hideChrome = !narrowed && !s.nextCursor && projected.loaded < COLLECTION_CHROME_MIN_ITEMS;
148
+ const narrowed = !!prefs.query.trim() || (prefs.filter !== 'all' && prefs.filter !== initialCollection(config).filter) || domainNarrowed;
149
+ const sourceEmpty = !loading && !errored && rows.length === 0 &&
150
+ (!(backend && config.backendQuery) || !narrowed) && !domainNarrowed;
151
+ const emptySourceText = (typeof s.emptyText === 'string' && s.emptyText.trim()) || copyParam('collection.emptySource', 'Nothing here yet');
152
+ // Chrome is noise over a small un-narrowed list (fewer than COLLECTION_CHROME_MIN_ITEMS
153
+ // records, no further page), over an empty source, and before the FIRST load or an
154
+ // un-narrowed failure. A re-query while typing keeps it (and the search field's focus).
155
+ const hideChrome = (!narrowed && !s.nextCursor && projected.loaded < COLLECTION_CHROME_MIN_ITEMS)
156
+ || sourceEmpty || ((loading || errored) && rows.length === 0 && !narrowed);
133
157
  return { ...s, collection: { ...prefs, ...projected,
134
158
  hideChrome, noActiveCriteria: !narrowed,
135
159
  viewName, viewMessage, saveMessage, noSavedViews: prefs.savedViews.length === 0,
@@ -138,8 +162,15 @@ export function decorateCollection(name: string, def: { state: State; actions?:
138
162
  noPageError: s.pageError !== true,
139
163
  noOffline: s.fromCache !== true,
140
164
  noError: !errored,
141
- noRetry: !canRetry,
165
+ noRetry: !canRetry || signInRequired,
166
+ noSignIn: !signInRequired,
167
+ errorTitle: signInRequired ? copyParam('collection.signInTitle', 'Sign in to see this') : copyParam('collection.loadErrorTitle', 'This collection could not load'),
142
168
  errorMessage,
169
+ noLoading: !loading,
170
+ // De-dup against a domain that paints its OWN empty block (screen-kit emptyBlock is
171
+ // gated on the domain's top-level `noEmpty`): only one empty state ever shows.
172
+ noEmptySource: !sourceEmpty || s.noEmpty === false,
173
+ emptySourceText,
143
174
  hideList: prefs.view !== 'list', hideGrid: prefs.view !== 'grid',
144
175
  hideComfortable: prefs.density !== 'comfortable', hideCompact: prefs.density !== 'compact',
145
176
  selectingLabel: prefs.selecting ? copyParam('collection.done', 'Done') : copyParam('collection.select', 'Select'),
@@ -147,7 +178,7 @@ export function decorateCollection(name: string, def: { state: State; actions?:
147
178
  cannotSaveSelected: !prefs.selectedIds.length || prefs.selectedIds.some(id => !rows.some(row => collectionId(row) === id)),
148
179
  filtersPresented, previewPresented: !!previewId, preview: projected.items.filter(row => row.collectionId === previewId),
149
180
  persistenceLabel: persisted.available ? copyParam('collection.onDevice', 'Saved on this device') : copyParam('collection.sessionOnly', 'Choices last for this session'),
150
- noEmpty: loading || errored || projected.items.length > 0,
181
+ noEmpty: loading || errored || sourceEmpty || domainNarrowed || projected.items.length > 0,
151
182
  summary: backend && config.backendQuery
152
183
  ? (s.fromCache ? copyParam('collection.cached', 'Saved offline · may be outdated')
153
184
  : typeof s.total === 'number' ? `${projected.items.length} / ${s.total} ${copyParam('collection.results', 'results')}`
@@ -4670,7 +4670,8 @@ const SCREENS = runtimeSetting({
4670
4670
  "props": {
4671
4671
  "text": "$service:spacesDeleteAccount.message",
4672
4672
  "style": "caption",
4673
- "color": "textTertiary"
4673
+ "color": "textTertiary",
4674
+ "collapseWhenEmpty": true
4674
4675
  }
4675
4676
  }
4676
4677
  },
@@ -4965,6 +4966,9 @@ const SCREENS = runtimeSetting({
4965
4966
  }
4966
4967
  ]
4967
4968
  }
4969
+ },
4970
+ "modifiers": {
4971
+ "hiddenPath": "$service:spacesWhatsNew.noItems"
4968
4972
  }
4969
4973
  },
4970
4974
  {
@@ -5346,6 +5350,24 @@ const SCREENS = runtimeSetting({
5346
5350
  "props": {
5347
5351
  "spacing": 0,
5348
5352
  "children": [
5353
+ {
5354
+ "id": "himi_shop.list.collection.loading",
5355
+ "body": {
5356
+ "package": "himalaya",
5357
+ "type": "Skeleton",
5358
+ "props": {
5359
+ "height": 72,
5360
+ "cornerRadius": 12,
5361
+ "count": 3
5362
+ }
5363
+ },
5364
+ "modifiers": {
5365
+ "hiddenPath": "$service:himiStoreShop.collection.noLoading",
5366
+ "padding": {
5367
+ "bottom": 12
5368
+ }
5369
+ }
5370
+ },
5349
5371
  {
5350
5372
  "id": "",
5351
5373
  "body": {
@@ -5607,6 +5629,52 @@ const SCREENS = runtimeSetting({
5607
5629
  }
5608
5630
  }
5609
5631
  },
5632
+ {
5633
+ "id": "himi_shop.list.collection.empty-source",
5634
+ "body": {
5635
+ "package": "himalaya",
5636
+ "type": "VStack",
5637
+ "props": {
5638
+ "spacing": 8,
5639
+ "alignment": "center",
5640
+ "children": [
5641
+ {
5642
+ "id": "",
5643
+ "body": {
5644
+ "package": "himalaya",
5645
+ "type": "Icon",
5646
+ "props": {
5647
+ "name": "inbox",
5648
+ "size": 28,
5649
+ "tint": "textTertiary"
5650
+ }
5651
+ },
5652
+ "modifiers": {
5653
+ "accessibilityRole": "decorative"
5654
+ }
5655
+ },
5656
+ {
5657
+ "id": "",
5658
+ "body": {
5659
+ "package": "himalaya",
5660
+ "type": "Text",
5661
+ "props": {
5662
+ "text": "$service:himiStoreShop.collection.emptySourceText",
5663
+ "style": "body",
5664
+ "color": "textSecondary"
5665
+ }
5666
+ }
5667
+ }
5668
+ ]
5669
+ }
5670
+ },
5671
+ "modifiers": {
5672
+ "hiddenPath": "$service:himiStoreShop.collection.noEmptySource",
5673
+ "padding": {
5674
+ "bottom": 12
5675
+ }
5676
+ }
5677
+ },
5610
5678
  {
5611
5679
  "id": "",
5612
5680
  "body": {
@@ -8021,6 +8089,9 @@ const SCREENS = runtimeSetting({
8021
8089
  "actionId": "tier5.himiStoreSaved.load"
8022
8090
  }
8023
8091
  }
8092
+ },
8093
+ "modifiers": {
8094
+ "hiddenPath": "$service:himiStoreSaved.noRows"
8024
8095
  }
8025
8096
  },
8026
8097
  {
@@ -8272,6 +8343,9 @@ const SCREENS = runtimeSetting({
8272
8343
  }
8273
8344
  ]
8274
8345
  }
8346
+ },
8347
+ "modifiers": {
8348
+ "hiddenPath": "$service:spacesCollections.noCollections"
8275
8349
  }
8276
8350
  },
8277
8351
  {
@@ -9318,6 +9392,24 @@ const SCREENS = runtimeSetting({
9318
9392
  "props": {
9319
9393
  "spacing": 0,
9320
9394
  "children": [
9395
+ {
9396
+ "id": "himi_orders.list.collection.loading",
9397
+ "body": {
9398
+ "package": "himalaya",
9399
+ "type": "Skeleton",
9400
+ "props": {
9401
+ "height": 72,
9402
+ "cornerRadius": 12,
9403
+ "count": 3
9404
+ }
9405
+ },
9406
+ "modifiers": {
9407
+ "hiddenPath": "$service:himiBrandedOrders.collection.noLoading",
9408
+ "padding": {
9409
+ "bottom": 12
9410
+ }
9411
+ }
9412
+ },
9321
9413
  {
9322
9414
  "id": "himi_orders.list.collection.search",
9323
9415
  "body": {
@@ -9600,6 +9692,52 @@ const SCREENS = runtimeSetting({
9600
9692
  }
9601
9693
  }
9602
9694
  },
9695
+ {
9696
+ "id": "himi_orders.list.collection.empty-source",
9697
+ "body": {
9698
+ "package": "himalaya",
9699
+ "type": "VStack",
9700
+ "props": {
9701
+ "spacing": 8,
9702
+ "alignment": "center",
9703
+ "children": [
9704
+ {
9705
+ "id": "",
9706
+ "body": {
9707
+ "package": "himalaya",
9708
+ "type": "Icon",
9709
+ "props": {
9710
+ "name": "inbox",
9711
+ "size": 28,
9712
+ "tint": "textTertiary"
9713
+ }
9714
+ },
9715
+ "modifiers": {
9716
+ "accessibilityRole": "decorative"
9717
+ }
9718
+ },
9719
+ {
9720
+ "id": "",
9721
+ "body": {
9722
+ "package": "himalaya",
9723
+ "type": "Text",
9724
+ "props": {
9725
+ "text": "$service:himiBrandedOrders.collection.emptySourceText",
9726
+ "style": "body",
9727
+ "color": "textSecondary"
9728
+ }
9729
+ }
9730
+ }
9731
+ ]
9732
+ }
9733
+ },
9734
+ "modifiers": {
9735
+ "hiddenPath": "$service:himiBrandedOrders.collection.noEmptySource",
9736
+ "padding": {
9737
+ "bottom": 12
9738
+ }
9739
+ }
9740
+ },
9603
9741
  {
9604
9742
  "id": "",
9605
9743
  "body": {
@@ -11619,6 +11757,24 @@ const SCREENS = runtimeSetting({
11619
11757
  "props": {
11620
11758
  "spacing": 0,
11621
11759
  "children": [
11760
+ {
11761
+ "id": "himi_portfolio.rows.collection.loading",
11762
+ "body": {
11763
+ "package": "himalaya",
11764
+ "type": "Skeleton",
11765
+ "props": {
11766
+ "height": 72,
11767
+ "cornerRadius": 12,
11768
+ "count": 3
11769
+ }
11770
+ },
11771
+ "modifiers": {
11772
+ "hiddenPath": "$service:himiBrandedPortfolio.collection.noLoading",
11773
+ "padding": {
11774
+ "bottom": 12
11775
+ }
11776
+ }
11777
+ },
11622
11778
  {
11623
11779
  "id": "himi_portfolio.rows.collection.search",
11624
11780
  "body": {
@@ -11872,7 +12028,7 @@ const SCREENS = runtimeSetting({
11872
12028
  "package": "himalaya",
11873
12029
  "type": "Text",
11874
12030
  "props": {
11875
- "text": "This collection could not load",
12031
+ "text": "$service:himiBrandedPortfolio.collection.errorTitle",
11876
12032
  "style": "bodyEmphasis"
11877
12033
  }
11878
12034
  }
@@ -11906,6 +12062,27 @@ const SCREENS = runtimeSetting({
11906
12062
  "modifiers": {
11907
12063
  "hiddenPath": "$service:himiBrandedPortfolio.collection.noRetry"
11908
12064
  }
12065
+ },
12066
+ {
12067
+ "id": "himi_portfolio.rows.collection.sign_in",
12068
+ "body": {
12069
+ "package": "himalaya",
12070
+ "type": "Button",
12071
+ "props": {
12072
+ "title": "Sign in",
12073
+ "style": "primary",
12074
+ "leadingIcon": "person",
12075
+ "action": {
12076
+ "actionId": "himi.open",
12077
+ "params": {
12078
+ "screenId": "himi_account"
12079
+ }
12080
+ }
12081
+ }
12082
+ },
12083
+ "modifiers": {
12084
+ "hiddenPath": "$service:himiBrandedPortfolio.collection.noSignIn"
12085
+ }
11909
12086
  }
11910
12087
  ]
11911
12088
  }
@@ -11917,6 +12094,52 @@ const SCREENS = runtimeSetting({
11917
12094
  }
11918
12095
  }
11919
12096
  },
12097
+ {
12098
+ "id": "himi_portfolio.rows.collection.empty-source",
12099
+ "body": {
12100
+ "package": "himalaya",
12101
+ "type": "VStack",
12102
+ "props": {
12103
+ "spacing": 8,
12104
+ "alignment": "center",
12105
+ "children": [
12106
+ {
12107
+ "id": "",
12108
+ "body": {
12109
+ "package": "himalaya",
12110
+ "type": "Icon",
12111
+ "props": {
12112
+ "name": "inbox",
12113
+ "size": 28,
12114
+ "tint": "textTertiary"
12115
+ }
12116
+ },
12117
+ "modifiers": {
12118
+ "accessibilityRole": "decorative"
12119
+ }
12120
+ },
12121
+ {
12122
+ "id": "",
12123
+ "body": {
12124
+ "package": "himalaya",
12125
+ "type": "Text",
12126
+ "props": {
12127
+ "text": "$service:himiBrandedPortfolio.collection.emptySourceText",
12128
+ "style": "body",
12129
+ "color": "textSecondary"
12130
+ }
12131
+ }
12132
+ }
12133
+ ]
12134
+ }
12135
+ },
12136
+ "modifiers": {
12137
+ "hiddenPath": "$service:himiBrandedPortfolio.collection.noEmptySource",
12138
+ "padding": {
12139
+ "bottom": 12
12140
+ }
12141
+ }
12142
+ },
11920
12143
  {
11921
12144
  "id": "",
11922
12145
  "body": {
@@ -13797,27 +14020,6 @@ const SCREENS = runtimeSetting({
13797
14020
  ]
13798
14021
  }
13799
14022
  }
13800
- },
13801
- {
13802
- "id": "",
13803
- "body": {
13804
- "package": "himalaya",
13805
- "type": "Text",
13806
- "props": {
13807
- "text": "$service:himiBrandedPortfolio.emptyText",
13808
- "style": "body",
13809
- "color": "textSecondary",
13810
- "collapseWhenEmpty": true
13811
- }
13812
- },
13813
- "modifiers": {
13814
- "padding": {
13815
- "leading": 8,
13816
- "trailing": 8,
13817
- "top": 8,
13818
- "bottom": 0
13819
- }
13820
- }
13821
14023
  }
13822
14024
  ]
13823
14025
  }
@@ -14848,6 +15050,24 @@ const SCREENS = runtimeSetting({
14848
15050
  "props": {
14849
15051
  "spacing": 0,
14850
15052
  "children": [
15053
+ {
15054
+ "id": "himi_events.list.collection.loading",
15055
+ "body": {
15056
+ "package": "himalaya",
15057
+ "type": "Skeleton",
15058
+ "props": {
15059
+ "height": 72,
15060
+ "cornerRadius": 12,
15061
+ "count": 3
15062
+ }
15063
+ },
15064
+ "modifiers": {
15065
+ "hiddenPath": "$service:himiEvents.collection.noLoading",
15066
+ "padding": {
15067
+ "bottom": 12
15068
+ }
15069
+ }
15070
+ },
14851
15071
  {
14852
15072
  "id": "",
14853
15073
  "body": {
@@ -15109,6 +15329,52 @@ const SCREENS = runtimeSetting({
15109
15329
  }
15110
15330
  }
15111
15331
  },
15332
+ {
15333
+ "id": "himi_events.list.collection.empty-source",
15334
+ "body": {
15335
+ "package": "himalaya",
15336
+ "type": "VStack",
15337
+ "props": {
15338
+ "spacing": 8,
15339
+ "alignment": "center",
15340
+ "children": [
15341
+ {
15342
+ "id": "",
15343
+ "body": {
15344
+ "package": "himalaya",
15345
+ "type": "Icon",
15346
+ "props": {
15347
+ "name": "inbox",
15348
+ "size": 28,
15349
+ "tint": "textTertiary"
15350
+ }
15351
+ },
15352
+ "modifiers": {
15353
+ "accessibilityRole": "decorative"
15354
+ }
15355
+ },
15356
+ {
15357
+ "id": "",
15358
+ "body": {
15359
+ "package": "himalaya",
15360
+ "type": "Text",
15361
+ "props": {
15362
+ "text": "$service:himiEvents.collection.emptySourceText",
15363
+ "style": "body",
15364
+ "color": "textSecondary"
15365
+ }
15366
+ }
15367
+ }
15368
+ ]
15369
+ }
15370
+ },
15371
+ "modifiers": {
15372
+ "hiddenPath": "$service:himiEvents.collection.noEmptySource",
15373
+ "padding": {
15374
+ "bottom": 12
15375
+ }
15376
+ }
15377
+ },
15112
15378
  {
15113
15379
  "id": "",
15114
15380
  "body": {
@@ -18152,6 +18418,24 @@ const SCREENS = runtimeSetting({
18152
18418
  "props": {
18153
18419
  "spacing": 0,
18154
18420
  "children": [
18421
+ {
18422
+ "id": "himi_blog.list.collection.loading",
18423
+ "body": {
18424
+ "package": "himalaya",
18425
+ "type": "Skeleton",
18426
+ "props": {
18427
+ "height": 72,
18428
+ "cornerRadius": 12,
18429
+ "count": 3
18430
+ }
18431
+ },
18432
+ "modifiers": {
18433
+ "hiddenPath": "$service:himiBlogFeed.collection.noLoading",
18434
+ "padding": {
18435
+ "bottom": 12
18436
+ }
18437
+ }
18438
+ },
18155
18439
  {
18156
18440
  "id": "",
18157
18441
  "body": {
@@ -18370,6 +18654,52 @@ const SCREENS = runtimeSetting({
18370
18654
  }
18371
18655
  }
18372
18656
  },
18657
+ {
18658
+ "id": "himi_blog.list.collection.empty-source",
18659
+ "body": {
18660
+ "package": "himalaya",
18661
+ "type": "VStack",
18662
+ "props": {
18663
+ "spacing": 8,
18664
+ "alignment": "center",
18665
+ "children": [
18666
+ {
18667
+ "id": "",
18668
+ "body": {
18669
+ "package": "himalaya",
18670
+ "type": "Icon",
18671
+ "props": {
18672
+ "name": "inbox",
18673
+ "size": 28,
18674
+ "tint": "textTertiary"
18675
+ }
18676
+ },
18677
+ "modifiers": {
18678
+ "accessibilityRole": "decorative"
18679
+ }
18680
+ },
18681
+ {
18682
+ "id": "",
18683
+ "body": {
18684
+ "package": "himalaya",
18685
+ "type": "Text",
18686
+ "props": {
18687
+ "text": "$service:himiBlogFeed.collection.emptySourceText",
18688
+ "style": "body",
18689
+ "color": "textSecondary"
18690
+ }
18691
+ }
18692
+ }
18693
+ ]
18694
+ }
18695
+ },
18696
+ "modifiers": {
18697
+ "hiddenPath": "$service:himiBlogFeed.collection.noEmptySource",
18698
+ "padding": {
18699
+ "bottom": 12
18700
+ }
18701
+ }
18702
+ },
18373
18703
  {
18374
18704
  "id": "",
18375
18705
  "body": {
@@ -30,6 +30,9 @@ export interface CollectionConfig {
30
30
  * `screenId` opens that screen with the row id; without it the verb reuses the
31
31
  * row's own tap action (the detail screen that owns the verb). */
32
32
  primaryVerb?: { label: string; screenId?: string };
33
+ /** A state field the DOMAIN narrows `rows` by (e.g. a category picker). While it is set,
34
+ * zero rows is a filtered result, not an empty source. */
35
+ narrowedBy?: string;
33
36
  }
34
37
  /** At or below this many records, with no query/filter narrowing them and no further
35
38
  * page, the list/grid toggle, Refine, chips, search and count are noise. */
@@ -41,7 +44,7 @@ export const COLLECTIONS: Record<string, CollectionConfig> = {
41
44
  defaultFilter: 'value:Upcoming', searchPlaceholder: 'Exact booking ID', filterValues: ['Upcoming', 'Past', 'Cancelled'],
42
45
  sortLabels: { default: 'Soonest', az: 'Oldest', za: 'Latest' } },
43
46
  himiEvents: { rows: 'results', title: 'title', subtitle: 'dateLine', image: 'image', view: 'grid', backendQuery: true, searchPlaceholder: 'Exact event title', filterValues: ['Upcoming', 'Past'], sortLabels: { default: 'Date', az: 'Title A–Z', za: 'Title Z–A' }, primaryVerb: { label: 'Register' } },
44
- himiBlogFeed: { rows: 'posts', title: 'title', subtitle: 'excerpt', image: 'image', filter: 'category', filterValuesFrom: 'categories', view: 'grid' },
47
+ himiBlogFeed: { rows: 'posts', title: 'title', subtitle: 'excerpt', image: 'image', filter: 'category', filterValuesFrom: 'categories', view: 'grid', narrowedBy: 'selectedCategoryId' },
45
48
  himiOwnerLiteProducts: { rows: 'products', title: 'name', subtitle: 'price', image: 'image', view: 'grid', backendQuery: true },
46
49
  himiOwnerModules: { instanceInput: 'module', rows: 'rows', title: 'title', subtitle: 'subtitle', image: 'image', filter: 'statusLabel', view: 'list', paged: true, reviewAction: 'prepareRecord', reviewSelectedAction: 'prepareSelected' },
47
50
  himiOwnerLiteServices: { rows: 'services', title: 'name', subtitle: 'subtitle', view: 'list', backendQuery: true, searchPlaceholder: 'Service name starts with…' },