@wix/himalaya-cli 0.1208.0 → 0.1210.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 (124) hide show
  1. package/dist/cli.mjs +168 -25
  2. package/dist/preview-assets.generated.bin +0 -0
  3. package/package.json +2 -2
  4. package/templates/beauty-salon-owner/dev/index.ts +18 -13
  5. package/templates/beauty-salon-owner/tier5-src/_shared/himi-text.ts +24 -0
  6. package/templates/beauty-salon-owner/tier5-src/_shared/owner-account.ts +4 -0
  7. package/templates/beauty-salon-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  8. package/templates/beauty-salon-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  9. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  10. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  11. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  12. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  13. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  14. package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  15. package/templates/community-club-owner/dev/index.ts +18 -13
  16. package/templates/community-club-owner/tier5-src/_shared/himi-text.ts +24 -0
  17. package/templates/community-club-owner/tier5-src/_shared/owner-account.ts +4 -0
  18. package/templates/community-club-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  19. package/templates/community-club-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  20. package/templates/community-club-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  21. package/templates/community-club-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  22. package/templates/community-club-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  23. package/templates/community-club-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  24. package/templates/community-club-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  25. package/templates/community-club-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  26. package/templates/events-meetups-owner/dev/index.ts +18 -13
  27. package/templates/events-meetups-owner/tier5-src/_shared/himi-text.ts +24 -0
  28. package/templates/events-meetups-owner/tier5-src/_shared/owner-account.ts +4 -0
  29. package/templates/events-meetups-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  30. package/templates/events-meetups-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  31. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  32. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  33. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  34. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  35. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  36. package/templates/events-meetups-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  37. package/templates/gym-fitness-owner/dev/index.ts +18 -13
  38. package/templates/gym-fitness-owner/tier5-src/_shared/himi-text.ts +24 -0
  39. package/templates/gym-fitness-owner/tier5-src/_shared/owner-account.ts +4 -0
  40. package/templates/gym-fitness-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  41. package/templates/gym-fitness-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  42. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  43. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  44. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  45. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  46. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  47. package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  48. package/templates/nonprofit-cause-owner/dev/index.ts +18 -13
  49. package/templates/nonprofit-cause-owner/tier5-src/_shared/himi-text.ts +24 -0
  50. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-account.ts +4 -0
  51. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  52. package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  53. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  54. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  55. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  56. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  57. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  58. package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  59. package/templates/owner-lite/dev/index.ts +19 -14
  60. package/templates/owner-lite/tier5-src/_shared/himi-text.ts +24 -0
  61. package/templates/owner-lite/tier5-src/_shared/owner-account.ts +4 -0
  62. package/templates/owner-lite/tier5-src/_shared/owner-selected-site.ts +103 -0
  63. package/templates/owner-lite/tier5-src/_shared/owner-site-pick.ts +74 -0
  64. package/templates/owner-lite/tier5-src/himi-owner-lite-account/index.ts +12 -2
  65. package/templates/owner-lite/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  66. package/templates/owner-lite/tier5-src/himi-owner-lite-home/index.ts +24 -1
  67. package/templates/owner-lite/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  68. package/templates/owner-lite/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  69. package/templates/owner-lite/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  70. package/templates/podcast-creator-owner/dev/index.ts +18 -13
  71. package/templates/podcast-creator-owner/tier5-src/_shared/himi-text.ts +24 -0
  72. package/templates/podcast-creator-owner/tier5-src/_shared/owner-account.ts +4 -0
  73. package/templates/podcast-creator-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  74. package/templates/podcast-creator-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  75. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  76. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  77. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  78. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  79. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  80. package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  81. package/templates/portfolio-creative-owner/dev/index.ts +18 -13
  82. package/templates/portfolio-creative-owner/tier5-src/_shared/himi-text.ts +24 -0
  83. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-account.ts +4 -0
  84. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  85. package/templates/portfolio-creative-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  86. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  87. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  88. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  89. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  90. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  91. package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  92. package/templates/restaurant-owner/dev/index.ts +18 -13
  93. package/templates/restaurant-owner/tier5-src/_shared/himi-text.ts +24 -0
  94. package/templates/restaurant-owner/tier5-src/_shared/owner-account.ts +4 -0
  95. package/templates/restaurant-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  96. package/templates/restaurant-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  97. package/templates/restaurant-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  98. package/templates/restaurant-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  99. package/templates/restaurant-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  100. package/templates/restaurant-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  101. package/templates/restaurant-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  102. package/templates/restaurant-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  103. package/templates/retail-store-owner/dev/index.ts +18 -13
  104. package/templates/retail-store-owner/tier5-src/_shared/himi-text.ts +24 -0
  105. package/templates/retail-store-owner/tier5-src/_shared/owner-account.ts +4 -0
  106. package/templates/retail-store-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  107. package/templates/retail-store-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  108. package/templates/retail-store-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  109. package/templates/retail-store-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  110. package/templates/retail-store-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  111. package/templates/retail-store-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  112. package/templates/retail-store-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  113. package/templates/retail-store-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
  114. package/templates/yoga-studio-owner/dev/index.ts +18 -13
  115. package/templates/yoga-studio-owner/tier5-src/_shared/himi-text.ts +24 -0
  116. package/templates/yoga-studio-owner/tier5-src/_shared/owner-account.ts +4 -0
  117. package/templates/yoga-studio-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
  118. package/templates/yoga-studio-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
  119. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
  120. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
  121. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
  122. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
  123. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
  124. package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
@@ -48568,7 +48568,7 @@ const SCREENS = runtimeSetting({
48568
48568
  "package": "himalaya",
48569
48569
  "type": "Text",
48570
48570
  "props": {
48571
- "text": "__HIMI_APP_NAME__",
48571
+ "text": "$service:himiOwnerLiteHome.businessName",
48572
48572
  "style": "footnote",
48573
48573
  "color": "textSecondary",
48574
48574
  "collapseWhenEmpty": true
@@ -50777,7 +50777,8 @@ const SCREENS = runtimeSetting({
50777
50777
  "params": {
50778
50778
  "copy": "{\"ownerHome.acrossBusiness\":\"Across the gym\",\"ownerHome.briefCta\":\"Show me the floor\",\"ownerHome.briefSubtitle\":\"Which classes are filling, which are empty, what the pro shop owes, and who’s signed up for the next challenge.\",\"ownerHome.briefTitle\":\"The floor today\",\"ownerHome.errorLabel\":\"Couldn’t load the floor\",\"ownerHome.headerSubtitle\":\"Gym owner · the floor today\",\"ownerHome.openManage\":\"Open the gym\",\"ownerHome.ordersDaily\":\"Pro shop sales · daily\",\"ownerHome.statAppointments\":\"Members booked in\",\"ownerHome.statEvents\":\"Challenges ahead\",\"ownerHome.statOrders\":\"Pro shop orders\",\"ownerHome.statPosts\":\"Coach notes\",\"ownerHome.statProducts\":\"Pro shop items\",\"ownerHome.statRevenue\":\"Revenue\",\"ownerHome.statSites\":\"Gyms\",\"ownerHome.switchBusiness\":\"Switch gym\"}",
50779
50779
  "homeModules": "[{\"id\":\"attention\",\"label\":\"Needs attention\",\"dataSource\":\"owner-today\",\"emptyWhen\":[\"hideContent\"]},{\"id\":\"schedule\",\"label\":\"Up next\",\"dataSource\":\"owner-schedule\",\"emptyWhen\":[\"hideContent\"]},{\"id\":\"shortcuts\",\"label\":\"Quick actions\",\"dataSource\":\"owner-actions\"},{\"id\":\"metrics\",\"label\":\"Business overview\",\"dataSource\":\"dashboard\",\"emptyWhen\":[\"hideContent\"]},{\"id\":\"brief\",\"label\":\"Daily brief\",\"dataSource\":\"brief\"}]",
50780
- "enabledSources": "[\"products\",\"posts\",\"sites\",\"orders\",\"bookings\",\"events\",\"members\",\"reviews\",\"reservations\"]"
50780
+ "enabledSources": "[\"products\",\"posts\",\"sites\",\"orders\",\"bookings\",\"events\",\"members\",\"reviews\",\"reservations\"]",
50781
+ "businessName": "__HIMI_APP_NAME__"
50781
50782
  }
50782
50783
  }
50783
50784
  }
@@ -50846,7 +50847,7 @@ const SCREENS = runtimeSetting({
50846
50847
  "package": "himalaya",
50847
50848
  "type": "Text",
50848
50849
  "props": {
50849
- "text": "__HIMI_APP_NAME__",
50850
+ "text": "$service:himiOwnerLiteManage.businessName",
50850
50851
  "style": "footnote",
50851
50852
  "color": "textSecondary",
50852
50853
  "collapseWhenEmpty": true
@@ -52017,7 +52018,8 @@ const SCREENS = runtimeSetting({
52017
52018
  "actionId": "tier5.himiOwnerLiteManage.load",
52018
52019
  "params": {
52019
52020
  "areas": "[{\"id\":\"store\",\"title\":\"Pro shop\",\"subtitle\":\"Products, inventory and sales\",\"groupId\":\"commerce\",\"group\":\"Commerce\",\"screenId\":\"himi_owner_lite_products\",\"icon\":\"bag\",\"metricKey\":\"products\",\"countLabel\":\"products\",\"createScreenId\":\"himi_owner_lite_product_new\",\"createLabel\":\"Create product\"},{\"id\":\"himi_owner_lite_orders\",\"title\":\"Pro shop orders\",\"subtitle\":\"Review and complete customer orders\",\"groupId\":\"commerce\",\"group\":\"Commerce\",\"screenId\":\"himi_owner_lite_orders\",\"icon\":\"cart\",\"metricKey\":\"orders\",\"countLabel\":\"orders\"},{\"id\":\"bookings\",\"title\":\"Classes\",\"subtitle\":\"Services and your schedule\",\"groupId\":\"scheduling\",\"group\":\"Scheduling\",\"screenId\":\"himi_owner_lite_services\",\"icon\":\"calendar\",\"metricKey\":\"services\",\"countLabel\":\"services\"},{\"id\":\"himi_owner_lite_appointments\",\"title\":\"Members booked in\",\"subtitle\":\"Your upcoming appointments\",\"groupId\":\"scheduling\",\"group\":\"Scheduling\",\"screenId\":\"himi_owner_lite_appointments\",\"icon\":\"clock\",\"metricKey\":\"appointments\",\"countLabel\":\"appointments\"},{\"id\":\"events\",\"title\":\"Challenges\",\"subtitle\":\"Events and attendance\",\"groupId\":\"scheduling\",\"group\":\"Scheduling\",\"screenId\":\"himi_owner_lite_events\",\"icon\":\"calendar\",\"metricKey\":\"events\",\"countLabel\":\"events\"},{\"id\":\"blog\",\"title\":\"Coach notes\",\"subtitle\":\"Stories and publishing\",\"groupId\":\"content\",\"group\":\"Content\",\"screenId\":\"himi_owner_lite_posts\",\"icon\":\"newspaper\",\"metricKey\":\"posts\",\"countLabel\":\"posts\",\"createScreenId\":\"himi_owner_lite_post_new\",\"createLabel\":\"Write post\"},{\"id\":\"coupons\",\"title\":\"Coupons\",\"subtitle\":\"Offers, codes and usage\",\"groupId\":\"commerce\",\"group\":\"Commerce\",\"screenId\":\"himi_owner_lite_module_coupons\",\"icon\":\"tag\",\"metricKey\":\"module:coupons\",\"countLabel\":\"coupons\"},{\"id\":\"invoices\",\"title\":\"Invoices\",\"subtitle\":\"Customers, balances and payment status\",\"groupId\":\"commerce\",\"group\":\"Commerce\",\"screenId\":\"himi_owner_lite_module_invoices\",\"icon\":\"document\",\"metricKey\":\"module:invoices\",\"countLabel\":\"invoices\"},{\"id\":\"giftCards\",\"title\":\"Gift cards\",\"subtitle\":\"Balances, recipients and expiration\",\"groupId\":\"commerce\",\"group\":\"Commerce\",\"screenId\":\"himi_owner_lite_module_giftCards\",\"icon\":\"ticket\",\"metricKey\":\"module:giftCards\",\"countLabel\":\"gift cards\"},{\"id\":\"contacts\",\"title\":\"Contacts\",\"subtitle\":\"Your customer relationships\",\"groupId\":\"people-and-community\",\"group\":\"People and community\",\"screenId\":\"himi_owner_lite_module_contacts\",\"icon\":\"person\",\"metricKey\":\"module:contacts\",\"countLabel\":\"contacts\"},{\"id\":\"members\",\"title\":\"Members\",\"subtitle\":\"Membership access and profiles\",\"groupId\":\"people-and-community\",\"group\":\"People and community\",\"screenId\":\"himi_owner_lite_module_members\",\"icon\":\"person\",\"metricKey\":\"module:members\",\"countLabel\":\"members\"},{\"id\":\"groups\",\"title\":\"Groups\",\"subtitle\":\"Communities and conversations\",\"groupId\":\"people-and-community\",\"group\":\"People and community\",\"screenId\":\"himi_owner_lite_module_groups\",\"icon\":\"person\",\"metricKey\":\"module:groups\",\"countLabel\":\"groups\"},{\"id\":\"reviews\",\"title\":\"Reviews\",\"subtitle\":\"Published and pending customer feedback\",\"groupId\":\"people-and-community\",\"group\":\"People and community\",\"screenId\":\"himi_owner_lite_module_reviews\",\"icon\":\"star\",\"metricKey\":\"module:reviews\",\"countLabel\":\"reviews\"},{\"id\":\"plans\",\"title\":\"Plans\",\"subtitle\":\"Pricing, benefits and visibility\",\"groupId\":\"membership-and-learning\",\"group\":\"Membership and learning\",\"screenId\":\"himi_owner_lite_module_plans\",\"icon\":\"bookmark\",\"metricKey\":\"module:plans\",\"countLabel\":\"plans\"},{\"id\":\"subscriptions\",\"title\":\"Subscriptions\",\"subtitle\":\"Member plans and subscription status\",\"groupId\":\"membership-and-learning\",\"group\":\"Membership and learning\",\"screenId\":\"himi_owner_lite_module_subscriptions\",\"icon\":\"bookmark\",\"metricKey\":\"module:subscriptions\",\"countLabel\":\"subscriptions\"},{\"id\":\"programs\",\"title\":\"Programs\",\"subtitle\":\"Learning experiences and participation\",\"groupId\":\"membership-and-learning\",\"group\":\"Membership and learning\",\"screenId\":\"himi_owner_lite_module_programs\",\"icon\":\"play\",\"metricKey\":\"module:programs\",\"countLabel\":\"programs\"},{\"id\":\"badges\",\"title\":\"Badges\",\"subtitle\":\"Recognition, access and member badges\",\"groupId\":\"membership-and-learning\",\"group\":\"Membership and learning\",\"screenId\":\"himi_owner_lite_module_badges\",\"icon\":\"star\",\"metricKey\":\"module:badges\",\"countLabel\":\"badges\"},{\"id\":\"reservations\",\"title\":\"Reservations\",\"subtitle\":\"Guests, tables and arrival times\",\"groupId\":\"scheduling\",\"group\":\"Scheduling\",\"screenId\":\"himi_owner_lite_module_reservations\",\"icon\":\"calendar\",\"metricKey\":\"module:reservations\",\"countLabel\":\"reservations\"},{\"id\":\"forms\",\"title\":\"Forms\",\"subtitle\":\"Forms and their configuration\",\"groupId\":\"content\",\"group\":\"Content\",\"screenId\":\"himi_owner_lite_module_forms\",\"icon\":\"document\",\"metricKey\":\"module:forms\",\"countLabel\":\"forms\"},{\"id\":\"portfolio\",\"title\":\"Portfolio\",\"subtitle\":\"Projects, stories and galleries\",\"groupId\":\"content\",\"group\":\"Content\",\"screenId\":\"himi_owner_lite_module_portfolio\",\"icon\":\"image\",\"metricKey\":\"module:portfolio\",\"countLabel\":\"portfolio\"},{\"id\":\"donationCampaigns\",\"title\":\"Donation campaigns\",\"subtitle\":\"Campaign goals, status and fundraising\",\"groupId\":\"content\",\"group\":\"Content\",\"screenId\":\"himi_owner_lite_module_donationCampaigns\",\"icon\":\"heart\",\"metricKey\":\"module:donationCampaigns\",\"countLabel\":\"donation campaigns\"}]",
52020
- "copy": "{\"ownerManage.blogLabel\":\"Coach notes\",\"ownerManage.bookingsLabel\":\"Classes\",\"ownerManage.eventsLabel\":\"Challenges\",\"ownerManage.storeLabel\":\"Pro shop\",\"ownerManage.title\":\"Gym\"}"
52021
+ "copy": "{\"ownerManage.blogLabel\":\"Coach notes\",\"ownerManage.bookingsLabel\":\"Classes\",\"ownerManage.eventsLabel\":\"Challenges\",\"ownerManage.storeLabel\":\"Pro shop\",\"ownerManage.title\":\"Gym\"}",
52022
+ "businessName": "__HIMI_APP_NAME__"
52021
52023
  }
52022
52024
  }
52023
52025
  }
@@ -52136,7 +52138,7 @@ const SCREENS = runtimeSetting({
52136
52138
  "package": "himalaya",
52137
52139
  "type": "Text",
52138
52140
  "props": {
52139
- "text": "__HIMI_APP_NAME__",
52141
+ "text": "$service:himiOwnerLiteAccount.businessName",
52140
52142
  "style": "bodyEmphasis",
52141
52143
  "maxLines": 1
52142
52144
  }
@@ -52399,6 +52401,7 @@ const SCREENS = runtimeSetting({
52399
52401
  "supportUrl": "https://www.wix.com/support",
52400
52402
  "privacyUrl": "https://www.wix.com/about/privacy",
52401
52403
  "termsUrl": "https://www.wix.com/about/terms-of-use",
52404
+ "businessName": "__HIMI_APP_NAME__",
52402
52405
  "copy": "{\"ownerAccount.roleValue\":\"Gym owner\",\"ownerAccount.subtitle\":\"Gym owner\"}"
52403
52406
  }
52404
52407
  }
@@ -52946,7 +52949,10 @@ const SCREENS = runtimeSetting({
52946
52949
  },
52947
52950
  "fillMaxWidth": true,
52948
52951
  "onAppear": {
52949
- "actionId": "tier5.drawer.syncActive"
52952
+ "actionId": "tier5.drawer.refresh",
52953
+ "params": {
52954
+ "businessName": "__HIMI_APP_NAME__"
52955
+ }
52950
52956
  }
52951
52957
  }
52952
52958
  },
@@ -61917,10 +61923,10 @@ const SCREENS = runtimeSetting({
61917
61923
  },
61918
61924
  "fillMaxWidth": true,
61919
61925
  "onTap": {
61920
- "actionId": "himi.open",
61926
+ "actionId": "tier5.himiOwnerLiteSites.pick",
61921
61927
  "params": {
61922
- "screenId": "himi_owner_lite_home",
61923
- "business": "$item.id"
61928
+ "id": "$item.id",
61929
+ "name": "$item.name"
61924
61930
  }
61925
61931
  },
61926
61932
  "pressFeedback": "scale",
@@ -62017,7 +62023,6 @@ const SCREENS = runtimeSetting({
62017
62023
  "contentType": "application/javascript+ts-bundle",
62018
62024
  "declaredCapabilities": [
62019
62025
  "wix_api",
62020
- "wix_platform",
62021
62026
  "local_database"
62022
62027
  ],
62023
62028
  "minBinaryVersion": "0.1.0",
@@ -62478,10 +62483,10 @@ const SCREENS = runtimeSetting({
62478
62483
  },
62479
62484
  "fillMaxWidth": true,
62480
62485
  "onTap": {
62481
- "actionId": "himi.open",
62486
+ "actionId": "tier5.himiOwnerLiteOverview.pick",
62482
62487
  "params": {
62483
- "screenId": "himi_owner_lite_home",
62484
- "business": "$item.id"
62488
+ "id": "$item.id",
62489
+ "name": "$item.name"
62485
62490
  }
62486
62491
  },
62487
62492
  "pressFeedback": "scale",
@@ -0,0 +1,24 @@
1
+ // Shared display-text helpers for himi cards: trim catalog artifacts from titles and
2
+ // derive up-to-two-letter placeholder initials so same-first-letter lists still vary.
3
+
4
+ /** Trim trailing artifact markers (stray asterisks / footnote daggers) and whitespace
5
+ * that leak from test/seed catalogs, without touching interior punctuation. Falls back
6
+ * to the original when trimming would empty the string. */
7
+ export function cleanTitle(value?: string): string {
8
+ const raw = (value ?? "").trim();
9
+ const cleaned = raw.replace(/[\s*†‡]+$/u, "").trim();
10
+ return cleaned || raw;
11
+ }
12
+
13
+ /** Up to two significant initials for a placeholder avatar. Two-plus words → first
14
+ * letter of the first two; a single word → its first two alphanumerics. Keeps a list
15
+ * of similar names (e.g. many "Booking…") from collapsing to one identical glyph. */
16
+ export function initials(value?: string): string {
17
+ const words = (value ?? "").trim().split(/\s+/).filter(Boolean);
18
+ if (words.length === 0) return "#";
19
+ if (words.length === 1) {
20
+ const alnum = words[0].replace(/[^\p{L}\p{N}]/gu, "");
21
+ return (alnum.slice(0, 2) || "#").toUpperCase();
22
+ }
23
+ return ((words[0][0] ?? "") + (words[1][0] ?? "")).toUpperCase();
24
+ }
@@ -3,6 +3,9 @@
3
3
 
4
4
  export interface AccountState {
5
5
  status: "loading" | "ready";
6
+ /** The business the "Business" row names: the one picked on Sites, else the
7
+ * build-time fallback (see `owner-selected-site.ts`). */
8
+ businessName: string;
6
9
  /** "Name · email", the email alone, or "" (the line collapses). */
7
10
  ownerLine: string;
8
11
  /** "Version 1.2.0 (34)", or "" when the host cannot say. */
@@ -36,6 +39,7 @@ export function shapeAccount(s: Partial<AccountState>): AccountState {
36
39
  const supportUrl = safeUrl(s.supportUrl), privacyUrl = safeUrl(s.privacyUrl), termsUrl = safeUrl(s.termsUrl);
37
40
  return {
38
41
  status: s.status ?? "loading",
42
+ businessName: s.businessName ?? "",
39
43
  ownerLine: s.ownerLine ?? "",
40
44
  versionLine: s.versionLine ?? "",
41
45
  error: s.error ?? "",
@@ -0,0 +1,103 @@
1
+ // The business the owner is managing RIGHT NOW, shared by every __HIMI_APP_NAME__ worker.
2
+ //
3
+ // Home, Manage, Account and the drawer used to name the business from the build-time
4
+ // `provisioning.json` (`identity.businessName`), so after picking another site on the
5
+ // Sites list the chrome still named the provisioning one — three different names for
6
+ // "the current business" in one session, none of them the site actually picked.
7
+ //
8
+ // The picker (`owner-site-pick.ts`) is the one place that knows both the id and the
9
+ // display name of the business being switched to, so it records them here; every
10
+ // other worker reads them back. The channel is `himalaya.storage` — the app-scoped KV
11
+ // every worker of the app shares on every host (UserDefaults / SharedPreferences / one
12
+ // localStorage namespace) and that needs no capability.
13
+ //
14
+ // ONE key, not one per owner: the host only tells a worker who the owner is once a
15
+ // business is scoped, so the picker (which runs before that) and the screens after it
16
+ // would otherwise land on different keys. The owner is recorded INSIDE the entry
17
+ // instead, and an entry written for a different owner is never shown.
18
+ //
19
+ // The build-time name is only ever the cold-start fallback, passed in by the
20
+ // descriptor: a worker never hardcodes it.
21
+
22
+ import { initials } from "./himi-text.js";
23
+
24
+ type StorageLike = { getItem(key: string): string | null; setItem(key: string, value: string): void };
25
+ type Host = typeof globalThis & { himalaya?: { storage?: StorageLike; input?: Record<string, unknown> } };
26
+
27
+ export interface SelectedSite {
28
+ id: string;
29
+ name: string;
30
+ }
31
+
32
+ const KEY = "himi.ownerLite.selectedSite.v1";
33
+
34
+ function host(): Host["himalaya"] {
35
+ return (globalThis as Host).himalaya;
36
+ }
37
+
38
+ function inputString(key: string): string {
39
+ const v = host()?.input?.[key];
40
+ return typeof v === "string" && v !== "default" ? v.trim() : "";
41
+ }
42
+
43
+ /** The business the owner last picked, or null when none has been picked, the host
44
+ * has no storage, or the entry does not apply to this worker. Never throws. */
45
+ export function readSelectedSite(): SelectedSite | null {
46
+ try {
47
+ const raw = host()?.storage?.getItem(KEY);
48
+ if (!raw) return null;
49
+ const parsed = JSON.parse(raw) as Partial<SelectedSite> & { account?: unknown };
50
+ const id = typeof parsed?.id === "string" ? parsed.id.trim() : "";
51
+ const name = typeof parsed?.name === "string" ? parsed.name.trim() : "";
52
+ if (!id || !name) return null;
53
+ // Another owner's pick on a shared device is never this owner's business. Fail
54
+ // CLOSED: an owner-tagged entry is shown only to a worker that knows it IS that
55
+ // owner. A worker that cannot tell who the owner is (the account-level flow before
56
+ // a business is scoped, or a host that cannot supply the identity) gets the
57
+ // fallback, never a name that may be another owner's.
58
+ const account = typeof parsed.account === "string" ? parsed.account : "";
59
+ const me = inputString("__himiPreferenceAccount");
60
+ if (account && account !== me) return null;
61
+ // An entry the picker wrote before the host knew the owner is CLAIMED by the first
62
+ // worker that does know it, so from then on no other owner on the device reads it.
63
+ if (!account && me) host()?.storage?.setItem(KEY, JSON.stringify({ id, name, account: me }));
64
+ // A screen opened FOR a specific business (a deep link or push carrying
65
+ // `business`) names that business's data; a name recorded for another one would
66
+ // sit over the wrong numbers, so it falls back instead.
67
+ const opened = inputString("business");
68
+ if (opened && opened !== id) return null;
69
+ return { id, name };
70
+ } catch {
71
+ return null; // a corrupt entry reads as "nothing picked", never as a crash
72
+ }
73
+ }
74
+
75
+ /** Record the business the owner just picked. Best-effort: a host without storage
76
+ * simply keeps showing the fallback. */
77
+ export function rememberSelectedSite(site: SelectedSite): void {
78
+ const id = site.id.trim();
79
+ const name = site.name.trim();
80
+ if (!id || !name) return;
81
+ const account = inputString("__himiPreferenceAccount");
82
+ try {
83
+ host()?.storage?.setItem(KEY, JSON.stringify(account ? { id, name, account } : { id, name }));
84
+ } catch {
85
+ // Quota / storage disabled: the chrome falls back to the build-time name.
86
+ }
87
+ }
88
+
89
+ /** Display name for "the current business": the picked one, else `fallback`. */
90
+ export function selectedSiteName(fallback: string): string {
91
+ return readSelectedSite()?.name || fallback;
92
+ }
93
+
94
+ /** Badge letters for a business name ("Riverbend Market" → "RM"); Unicode-aware. */
95
+ export function siteInitials(name: string): string {
96
+ return initials(name);
97
+ }
98
+
99
+ /** The fallback name a descriptor passes in its `onAppear` params (`businessName`). */
100
+ export function fallbackNameFrom(arg: unknown, current = ""): string {
101
+ const v = (arg as { businessName?: unknown } | undefined)?.businessName;
102
+ return typeof v === "string" && v.trim() ? v.trim() : current;
103
+ }
@@ -0,0 +1,74 @@
1
+ // Switching the business an __HIMI_APP_NAME__ session manages — the one implementation
2
+ // behind every "pick a business" row (the Sites list and the cross-business Overview).
3
+ //
4
+ // Previously those rows were declarative `himi.open{business}` taps: the shell scoped
5
+ // the bridge and PUSHED Home, and nothing recorded which business was picked, so the
6
+ // chrome kept naming the build-time one and a `‹ Back` led to the list just left. As a
7
+ // worker action the row can record the name first, then hand the shell the same
8
+ // `business`-carrying open — now as a `replace` onto the Home root.
9
+ //
10
+ // Scoping stays with the shell's router (SP-1: a `business` nav param scopes the Wix
11
+ // bridge BEFORE navigating, on iOS and Android). It is deliberately not done here with
12
+ // `site.setActiveSite`: owner-lite's native shells do not register the worker-facing
13
+ // `siteSetActive` capability, so the call throws and the tap would go nowhere.
14
+
15
+ import { navigate, type NavDirective } from "@himalaya/state";
16
+ import { forgetCatalogVersion } from "@himalaya/wix-stores";
17
+ import { rememberSelectedSite } from "./owner-selected-site.js";
18
+
19
+ export const OWNER_HOME = "himi_owner_lite_home";
20
+
21
+ /** Set by a pick, cleared by `settleBusinessSwitch` once the new business is scoped. */
22
+ const SWITCH_PENDING_KEY = "himi.ownerLite.businessSwitchPending.v1";
23
+
24
+ type StorageLike = { getItem(key: string): string | null; setItem(key: string, value: string): void };
25
+ const storage = (): StorageLike | undefined =>
26
+ (globalThis as { himalaya?: { storage?: StorageLike } }).himalaya?.storage;
27
+
28
+ /** `{ id | business, name }` from a row's action params (or a bare msid string). */
29
+ export function pickedSite(arg: unknown): { msid: string; name: string } {
30
+ if (typeof arg === "string") return { msid: arg.trim(), name: "" };
31
+ const a = (arg ?? {}) as { business?: unknown; id?: unknown; name?: unknown };
32
+ const msid = typeof a.business === "string" && a.business ? a.business : typeof a.id === "string" ? a.id : "";
33
+ return { msid: msid.trim(), name: typeof a.name === "string" ? a.name.trim() : "" };
34
+ }
35
+
36
+ /**
37
+ * Record `name` as the business being managed, then return `state` carrying a
38
+ * `replace` onto the Home root that asks the shell to scope to `msid`. Returns `state`
39
+ * untouched (no navigation) when there is no msid.
40
+ */
41
+ export function pickSite<S extends object>(state: S, msid: string, name: string): S | (S & { _nav: NavDirective }) {
42
+ if (!msid) return state;
43
+ // Another business may run the other Stores catalog. The resolved version is
44
+ // persisted app-wide and routes WRITES, which have no 428 retry, so it is dropped
45
+ // before the switch rather than left to be re-used against the new site.
46
+ forgetCatalogVersion();
47
+ // ...but the shell scopes the bridge to `msid` only AFTER this returns, so a warm
48
+ // Stores worker resolving in that gap still talks to the OLD site and can persist
49
+ // its version over the tombstone above. Leave a marker so the first worker that
50
+ // runs after scoping drops the catalog version once more (`settleBusinessSwitch`).
51
+ try { storage()?.setItem(SWITCH_PENDING_KEY, msid); } catch { /* no storage: the first forget stands */ }
52
+ if (name) rememberSelectedSite({ id: msid, name });
53
+ // `replace` onto Home, the tab root the pickers are reached from: the core router
54
+ // lands ON the root instead of stacking a second Home above the list.
55
+ return navigate(state, { screenId: OWNER_HOME, presentation: "replace", args: { business: msid } });
56
+ }
57
+
58
+ /**
59
+ * Finish a business switch: if a pick is pending, drop the Stores catalog version
60
+ * again and clear the marker. Call it first in a worker that runs only after the shell
61
+ * has scoped the bridge to the picked business (Home's `load`: the pick `replace`s
62
+ * onto Home, and the router scopes before it navigates), so a version persisted from
63
+ * the old site during the scoping gap is discarded. Never throws.
64
+ */
65
+ export function settleBusinessSwitch(): void {
66
+ try {
67
+ const s = storage();
68
+ if (!s?.getItem(SWITCH_PENDING_KEY)) return;
69
+ forgetCatalogVersion();
70
+ s.setItem(SWITCH_PENDING_KEY, "");
71
+ } catch {
72
+ // No storage, or it failed: nothing pending can be recorded either.
73
+ }
74
+ }
@@ -11,6 +11,11 @@
11
11
  // from provisioning.json `identity` — so a branded template ships ITS links,
12
12
  // and `openLink` can only ever open one of those three URLs.
13
13
  //
14
+ // • which business this is — the one the owner picked on Sites (see
15
+ // `_shared/owner-selected-site.ts`), not the build-time provisioning name,
16
+ // which arrives only as the cold-start `businessName` param. A local read,
17
+ // so it is set synchronously in the initial state and again on every load.
18
+ //
14
19
  // Every read is best-effort: an identity or version the host cannot answer
15
20
  // collapses its line rather than rendering an error on a settings screen.
16
21
 
@@ -20,19 +25,24 @@ import { displayVersion } from "@himalaya/app-info";
20
25
  import { open } from "@himalaya/open-url";
21
26
  import { stashCopy, copyTemplate } from "../_shared/himi-copy.js";
22
27
  import { ownerLineOf, shapeAccount, type AccountState } from "../_shared/owner-account.js";
28
+ import { fallbackNameFrom, selectedSiteName } from "../_shared/owner-selected-site.js";
23
29
 
24
30
  type LinkKind = "support" | "privacy" | "terms";
25
31
 
26
32
  const obj = (v: unknown): Record<string, unknown> => (v && typeof v === "object" ? v as Record<string, unknown> : {});
27
33
 
34
+ let fallbackBusinessName = "";
35
+
28
36
  const svc = defineService<AccountState, {
29
37
  load: (s: AccountState, arg?: unknown) => Promise<AccountState>;
30
38
  openLink: (s: AccountState, arg?: unknown) => Promise<AccountState>;
31
39
  }>("himiOwnerLiteAccount", {
32
- state: shapeAccount({}),
40
+ state: shapeAccount({ businessName: selectedSiteName(fallbackBusinessName) }),
33
41
  actions: {
34
42
  load: async (s, arg) => {
35
43
  stashCopy(arg);
44
+ fallbackBusinessName = fallbackNameFrom(arg, fallbackBusinessName);
45
+ const businessName = selectedSiteName(fallbackBusinessName);
36
46
  const p = obj(arg);
37
47
  const links = { supportUrl: String(p.supportUrl ?? s.supportUrl), privacyUrl: String(p.privacyUrl ?? s.privacyUrl), termsUrl: String(p.termsUrl ?? s.termsUrl) };
38
48
  let ownerLine = "";
@@ -54,7 +64,7 @@ const svc = defineService<AccountState, {
54
64
  const v = await displayVersion();
55
65
  versionLine = v ? copyTemplate("ownerAccount.version", "Version {version}", { version: v }) : "";
56
66
  } catch { /* host without app_info — the row collapses */ }
57
- return shapeAccount({ ...s, ...links, status: "ready", ownerLine, versionLine, error });
67
+ return shapeAccount({ ...s, ...links, status: "ready", businessName, ownerLine, versionLine, error });
58
68
  },
59
69
  openLink: async (s, arg) => {
60
70
  const kind = String(obj(arg).kind ?? arg ?? "") as LinkKind;
@@ -20,13 +20,23 @@
20
20
  import { defineService } from "@himalaya/state";
21
21
  import { serializeForAgent } from "@himalaya/agent";
22
22
  import { activeScreenFromInput, attentionRow, navRow, withDerived, type DrawerState } from "./logic.js";
23
+ import { fallbackNameFrom, selectedSiteName } from "../_shared/owner-selected-site.js";
23
24
 
24
25
  /** The shell passes the screen it is showing as worker input, so the drawer can mark
25
26
  * that destination selected the way the declarative drawer does. */
26
27
  const hostActiveScreen = () => activeScreenFromInput((globalThis as { himalaya?: { input?: unknown } }).himalaya?.input);
27
28
 
29
+ /** Cold-start name from the descriptor's onAppear params (provisioning identity). */
30
+ let fallbackBusinessName = "";
31
+
32
+ /** "Which site am I on": the business picked on Sites, else the fallback. */
33
+ const currentSiteName = () => selectedSiteName(fallbackBusinessName);
34
+
28
35
  const drawer = defineService<DrawerState, {
29
- /** Re-read the active screen from host input (root onAppear). An explicit
36
+ /** The panel opened (root onAppear): re-read the live site and the active screen.
37
+ * `arg.businessName` is the cold-start fallback for the site name. */
38
+ refresh: (s: DrawerState, arg?: unknown) => DrawerState;
39
+ /** Re-read the active screen from host input. An explicit
30
40
  * `{ screenId }` wins, for a host that pushes the change instead. */
31
41
  syncActive: (s: DrawerState, args?: { screenId?: string }) => DrawerState;
32
42
  /** First tap on "Mark all handled": ask before hiding anything. */
@@ -37,7 +47,7 @@ const drawer = defineService<DrawerState, {
37
47
  clearAttention: (s: DrawerState) => DrawerState;
38
48
  }>("drawer", {
39
49
  state: withDerived({
40
- siteName: "My Site",
50
+ siteName: currentSiteName(),
41
51
  nav: [
42
52
  navRow("drawer_home", "Home", "home", "himi_owner_lite_home"),
43
53
  // Between Home and Manage deliberately: analytics answers "how is the
@@ -55,6 +65,15 @@ const drawer = defineService<DrawerState, {
55
65
  activeScreenId: hostActiveScreen(),
56
66
  }),
57
67
  actions: {
68
+ refresh: (s, arg) => {
69
+ fallbackBusinessName = fallbackNameFrom(arg, fallbackBusinessName);
70
+ const screenId = (arg as { screenId?: unknown } | undefined)?.screenId;
71
+ return snap(withDerived({
72
+ ...s,
73
+ siteName: currentSiteName(),
74
+ activeScreenId: typeof screenId === "string" ? screenId : hostActiveScreen(),
75
+ }));
76
+ },
58
77
  syncActive: (s, args) => snap(withDerived({
59
78
  ...s,
60
79
  activeScreenId: typeof args?.screenId === "string" ? args.screenId : hostActiveScreen(),
@@ -21,6 +21,8 @@ import { getSiteAnalytics, getSiteTimeZone, localDateRange, localDateOf, localMi
21
21
  import { ownerDisplayError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
22
22
  import { DEMO_DASHBOARD, DEMO_NOTE, DEMO_TODAY } from "../_shared/owner-preview-demo.js";
23
23
  import { stashCopy, copyParam, copyTemplate } from "../_shared/himi-copy.js";
24
+ import { fallbackNameFrom, selectedSiteName } from "../_shared/owner-selected-site.js";
25
+ import { settleBusinessSwitch } from "../_shared/owner-site-pick.js";
24
26
  import { formatCurrency } from "../_shared/engine-intl.js";
25
27
  import {
26
28
  attentionRecords,
@@ -51,6 +53,9 @@ interface SourceState {
51
53
  }
52
54
 
53
55
  interface HomeState {
56
+ /** The business the header names: the one picked on Sites, else the descriptor's
57
+ * build-time fallback. */
58
+ businessName: string;
54
59
  attention: TodayRecord[];
55
60
  schedule: TodayRecord[];
56
61
  allSchedule: TodayRecord[];
@@ -101,11 +106,18 @@ const SOURCE_LABELS: Record<HomeSourceId, string> = {
101
106
  reviews: "Reviews", reservations: "Reservations",
102
107
  };
103
108
 
109
+ /** Cold-start name from the descriptor's onAppear params (provisioning identity). */
110
+ let fallbackBusinessName = "";
111
+ /** Resolved once per load, not per shape: a storage read is a host round-trip, and the
112
+ * picked business only changes between loads (the picker is another screen). */
113
+ let currentBusinessName = selectedSiteName("");
114
+
104
115
  function shape(s: Partial<HomeState>): HomeState {
105
116
  const status = s.status ?? "ready";
106
117
  const isLoading = status === "loading";
107
118
  return {
108
119
  status,
120
+ businessName: currentBusinessName,
109
121
  attention: s.attention ?? [],
110
122
  schedule: s.schedule ?? [],
111
123
  allSchedule: s.allSchedule ?? s.schedule ?? [],
@@ -834,8 +846,19 @@ const svc = defineService<HomeState, {
834
846
  })) }),
835
847
  actions: {
836
848
  load: async (s, arg) => {
849
+ // FIRST, before anything reads the catalog: a business pick `replace`s onto
850
+ // Home, and the shell scopes the bridge to the picked business before it
851
+ // navigates, so this load is the first code that runs on the new site. A Stores
852
+ // catalog version persisted from the OLD site during that gap is dropped here.
853
+ settleBusinessSwitch();
837
854
  stashCopy(arg);
838
- const sources = enabledSourcesFrom(arg) ?? [...HOME_SOURCE_IDS];
855
+ fallbackBusinessName = fallbackNameFrom(arg, fallbackBusinessName);
856
+ // Re-read here: Home's root is not remounted when the owner switches business,
857
+ // and the picker records the selection from a different worker.
858
+ currentBusinessName = selectedSiteName(fallbackBusinessName);
859
+ // An argless re-load (the host refreshing a warm root after the owner switches
860
+ // business) keeps the sources the descriptor enabled rather than widening to all.
861
+ const sources = enabledSourcesFrom(arg) ?? activeSources;
839
862
  return loadDashboard(shape({ ...s, status: "loading" }), sources);
840
863
  },
841
864
  retry: async (s) => loadDashboard(shape({ ...s, status: "loading" }), activeSources),
@@ -16,9 +16,13 @@ import { queryOwnerModule } from '../_shared/owner-module-data.js';
16
16
  import { OWNER_MODULES, ownerModuleId } from '../_shared/owner-modules.js';
17
17
  import { localPreferences } from '../_shared/local-preferences.js';
18
18
  import { stashCopy, copyParam, copyTemplate } from '../_shared/himi-copy.js';
19
+ import { fallbackNameFrom, selectedSiteName } from '../_shared/owner-selected-site.js';
19
20
  import { DASHBOARD_PATHS, deriveManage, parseAreas, recentAreas, rememberArea, withMetrics, type ManageArea, type Metric } from './logic.js';
20
21
 
21
22
  interface State {
23
+ /** The business the header names: the one picked on Sites, else the descriptor's
24
+ * build-time fallback. */
25
+ businessName: string;
22
26
  /** `loading` until the descriptor has delivered the areas, then
23
27
  * `ready`. The descriptor keys a FragmentSlot on it whose DEFAULT case is the
24
28
  * skeleton, so an unresolved path (worker not booted yet) is loading too —
@@ -178,6 +182,11 @@ async function metricFor(metricKey: string): Promise<Metric> {
178
182
  }
179
183
  }
180
184
 
185
+ /** Cold-start name from the descriptor's onAppear params (provisioning identity). */
186
+ let fallbackBusinessName = '';
187
+ /** Resolved per load/refresh, not per derive (a storage read is a host round-trip). */
188
+ let currentBusinessName = selectedSiteName('');
189
+
181
190
  function derive(state: State, areas = state.areas): State {
182
191
  const next = deriveManage(
183
192
  areas,
@@ -191,7 +200,7 @@ function derive(state: State, areas = state.areas): State {
191
200
  // areas arrive — or when this app provisions none at all — there is nothing a
192
201
  // filter could have excluded, so "Clear filters" would be a lie.
193
202
  const noEmpty = next.noEmpty || state.status !== 'ready' || areas.length === 0;
194
- return { ...state, ...next, noEmpty, recents, hasRecents: recents.length > 0, noRecents: recents.length === 0 };
203
+ return { ...state, ...next, noEmpty, recents, hasRecents: recents.length > 0, noRecents: recents.length === 0, businessName: currentBusinessName };
195
204
  }
196
205
 
197
206
  // Loads are not serialized: on a warm reappearance the host's bare refresh and
@@ -261,6 +270,7 @@ const svc = defineService<State, {
261
270
  handoff: (s: State, arg?: unknown) => Promise<State>;
262
271
  }>('himiOwnerLiteManage', {
263
272
  state: {
273
+ businessName: currentBusinessName,
264
274
  status: 'loading',
265
275
  areas: [], results: [], sections: [], recents: [], query: '', group: 'all',
266
276
  // 'All' is always a valid filter, so the chip row paints from the first frame
@@ -271,6 +281,10 @@ const svc = defineService<State, {
271
281
  actions: {
272
282
  load: async (state, arg) => {
273
283
  stashCopy(arg);
284
+ fallbackBusinessName = fallbackNameFrom(arg, fallbackBusinessName);
285
+ // Re-read on every load: this worker stays warm across tab switches, and the
286
+ // picker records the selection from another worker.
287
+ currentBusinessName = selectedSiteName(fallbackBusinessName);
274
288
  // A `load` with no areas comes from the host, not the descriptor: the
275
289
  // warm-worker refresh lifecycle calls it bare. Before the areas are known
276
290
  // it must not settle (that derived "0 business areas" and painted the
@@ -278,7 +292,7 @@ const svc = defineService<State, {
278
292
  if (!('areas' in read(arg))) {
279
293
  return state.status === 'ready'
280
294
  ? loadMetrics(derive({ ...state, isLoading: true, notLoading: false, summaryNote: '', handoffError: '' }))
281
- : state;
295
+ : { ...state, businessName: currentBusinessName };
282
296
  }
283
297
  const parsed = (() => { try { return JSON.parse(str(arg, 'areas') || '[]'); } catch { return []; } })();
284
298
  const areas = parseAreas(parsed);
@@ -286,8 +300,12 @@ const svc = defineService<State, {
286
300
  },
287
301
  // Refresh re-reads summaries for KNOWN areas. Before the descriptor has
288
302
  // delivered them there is nothing to refresh, and settling here would open
289
- // the skeleton gate over an empty hub.
290
- refresh: async state => state.status !== 'ready' ? state : loadMetrics(derive({ ...state, isLoading: true, notLoading: false, summaryNote: '', handoffError: '' })),
303
+ // the skeleton gate over an empty hub. The business name is a local read, so
304
+ // it is re-read either way.
305
+ refresh: async state => {
306
+ currentBusinessName = selectedSiteName(fallbackBusinessName);
307
+ return state.status !== 'ready' ? { ...state, businessName: currentBusinessName } : loadMetrics(derive({ ...state, isLoading: true, notLoading: false, summaryNote: '', handoffError: '' }));
308
+ },
291
309
  search: (state, arg) => derive({ ...state, query: str(arg, 'value').slice(0, 256) }),
292
310
  filter: (state, arg) => {
293
311
  const ids = read(arg).selectedIds;
@@ -30,6 +30,7 @@ import { searchOrders } from "@himalaya/wix-ecom";
30
30
  import { ownerLoadError, isBridgeUnavailable, isOwnerPreviewDemo } from "../_shared/owner-load-error.js";
31
31
  import { DEMO_SITES, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
32
32
  import { stashCopy, copyParam } from "../_shared/himi-copy.js";
33
+ import { pickSite, pickedSite } from "../_shared/owner-site-pick.js";
33
34
 
34
35
  /** Mirrors the Home dashboard's "needs attention" definition, so a number here means the
35
36
  * same thing it means after the owner drills into that business. */
@@ -205,6 +206,7 @@ async function loadRollup(): Promise<OverviewState> {
205
206
  const svc = defineService<OverviewState, {
206
207
  load: (s: OverviewState, arg?: unknown) => Promise<OverviewState>;
207
208
  retry: (s: OverviewState) => Promise<OverviewState>;
209
+ pick: (s: OverviewState, arg?: unknown) => OverviewState;
208
210
  }>("himiOwnerLiteOverview", {
209
211
  state: shape({ status: "loading" }),
210
212
  actions: {
@@ -213,6 +215,12 @@ const svc = defineService<OverviewState, {
213
215
  return loadRollup();
214
216
  },
215
217
  retry: async () => loadRollup(),
218
+ // Drilling into one business is the ONLY thing that moves the active business —
219
+ // the same switch the Sites list makes (scope, name it, reset to Home).
220
+ pick: (s, arg) => {
221
+ const { msid, name } = pickedSite(arg);
222
+ return pickSite(s, msid, name || s.rows.find((r) => r.id === msid)?.name || "");
223
+ },
216
224
  },
217
225
  });
218
226