@wix/himalaya-cli 0.1209.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.
- package/dist/cli.mjs +22 -18
- package/dist/preview-assets.generated.bin +0 -0
- package/package.json +2 -2
- package/templates/beauty-salon-owner/dev/index.ts +18 -13
- package/templates/beauty-salon-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/beauty-salon-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/community-club-owner/dev/index.ts +18 -13
- package/templates/community-club-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/community-club-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/community-club-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/community-club-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/community-club-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/community-club-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/community-club-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/community-club-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/events-meetups-owner/dev/index.ts +18 -13
- package/templates/events-meetups-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/events-meetups-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/events-meetups-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/events-meetups-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/gym-fitness-owner/dev/index.ts +18 -13
- package/templates/gym-fitness-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/gym-fitness-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/nonprofit-cause-owner/dev/index.ts +18 -13
- package/templates/nonprofit-cause-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/owner-lite/dev/index.ts +19 -14
- package/templates/owner-lite/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/owner-lite/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/owner-lite/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/owner-lite/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/owner-lite/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/owner-lite/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/owner-lite/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/owner-lite/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/podcast-creator-owner/dev/index.ts +18 -13
- package/templates/podcast-creator-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/podcast-creator-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/portfolio-creative-owner/dev/index.ts +18 -13
- package/templates/portfolio-creative-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/portfolio-creative-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/restaurant-owner/dev/index.ts +18 -13
- package/templates/restaurant-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/restaurant-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/restaurant-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/restaurant-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/retail-store-owner/dev/index.ts +18 -13
- package/templates/retail-store-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/retail-store-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/retail-store-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/retail-store-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
- package/templates/yoga-studio-owner/dev/index.ts +18 -13
- package/templates/yoga-studio-owner/tier5-src/_shared/himi-text.ts +24 -0
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-account.ts +4 -0
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-selected-site.ts +103 -0
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-site-pick.ts +74 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-account/index.ts +12 -2
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-drawer/index.ts +21 -2
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-home/index.ts +24 -1
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-manage/index.ts +22 -4
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-overview/index.ts +8 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-sites/index.ts +14 -31
package/dist/cli.mjs
CHANGED
|
@@ -6869,7 +6869,6 @@ function resolveTranslation(value, catalog, sourceCatalog) {
|
|
|
6869
6869
|
var BINDING_SIGILS, BINDING_SIGIL_RE, TRANSLATION_PREFIX, TRANSLATION_KEY_RE;
|
|
6870
6870
|
var init_bindings = __esm({
|
|
6871
6871
|
"../../core/ts/src/bindings.ts"() {
|
|
6872
|
-
"use strict";
|
|
6873
6872
|
BINDING_SIGILS = ["service", "flag", "item", "t"];
|
|
6874
6873
|
BINDING_SIGIL_RE = new RegExp(
|
|
6875
6874
|
`^\\$(?:${BINDING_SIGILS.filter((s) => s !== "t").join("|")})\\b|^\\$t:`
|
|
@@ -9325,7 +9324,7 @@ async function bootBundleWorker(bundleJs, opts) {
|
|
|
9325
9324
|
input: opts.input ?? {},
|
|
9326
9325
|
wixApi,
|
|
9327
9326
|
// v1 best-effort stubs — a visitor-scoped load() reads Wix, not device-local state.
|
|
9328
|
-
storage: { get: () => "", set: () => {
|
|
9327
|
+
storage: opts.storage ? { get: (k) => opts.storage.getItem(k) ?? "", set: (k, v) => opts.storage.setItem(k, v), getItem: (k) => opts.storage.getItem(k), setItem: (k, v) => opts.storage.setItem(k, v) } : { get: () => "", set: () => {
|
|
9329
9328
|
}, getItem: () => null, setItem: () => {
|
|
9330
9329
|
} },
|
|
9331
9330
|
dispatch: dispatchHost,
|
|
@@ -9500,7 +9499,12 @@ async function bootBundleWorker(bundleJs, opts) {
|
|
|
9500
9499
|
if (typeof v === "string" && k !== "screenId") args[k] = v;
|
|
9501
9500
|
}
|
|
9502
9501
|
}
|
|
9503
|
-
|
|
9502
|
+
const verb = nav.presentation;
|
|
9503
|
+
navDirectives.push({
|
|
9504
|
+
screenId: nav.screenId,
|
|
9505
|
+
args,
|
|
9506
|
+
...verb === "push" || verb === "replace" ? { presentation: verb } : {}
|
|
9507
|
+
});
|
|
9504
9508
|
}
|
|
9505
9509
|
if ("_nav" in rec || "_stream" in rec || "_poll" in rec || "_error" in rec) {
|
|
9506
9510
|
const stripped = {};
|
|
@@ -62545,21 +62549,21 @@ var init_preview_assets_generated = __esm({
|
|
|
62545
62549
|
"../../packages/serve/src/preview-assets.generated.ts"() {
|
|
62546
62550
|
init_preview_assets_format();
|
|
62547
62551
|
PREVIEW_ASSET_MANIFEST = [
|
|
62548
|
-
{ key: "assets/index-
|
|
62549
|
-
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset:
|
|
62550
|
-
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset:
|
|
62551
|
-
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset:
|
|
62552
|
-
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
62553
|
-
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset:
|
|
62554
|
-
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset:
|
|
62555
|
-
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
62556
|
-
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset:
|
|
62557
|
-
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset:
|
|
62558
|
-
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset:
|
|
62559
|
-
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset:
|
|
62560
|
-
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset:
|
|
62561
|
-
{ key: "index.html", contentType: "text/html; charset=utf-8", offset:
|
|
62562
|
-
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset:
|
|
62552
|
+
{ key: "assets/index-CRDm5E9l.js", contentType: "application/javascript; charset=utf-8", offset: 8, length: 1184658, sha256: "e00b8e526ebcd4dd07db3a03ee7bb81e401575c162498b42bb9aca49d60a6918" },
|
|
62553
|
+
{ key: "fonts/Roboto-LICENSE.txt", contentType: "application/octet-stream", offset: 1184666, length: 4610, sha256: "994062dd7af4186a739de55dd9e151c63b6301f8e2cbafc608d35c2e87da0cd2" },
|
|
62554
|
+
{ key: "fonts/Roboto-Variable.ttf", contentType: "font/ttf", offset: 1189276, length: 488584, sha256: "d7598e12c5dbef095ff8272cfc55da0250bd07fbdecbac8a530b9b277872a134" },
|
|
62555
|
+
{ key: "fonts/WixMadeforDisplay-Bold.ttf", contentType: "font/ttf", offset: 1677860, length: 90924, sha256: "ec4c7d63772d980d6e147b2df6215fd2737e4b04cebe0cf7e11dc695fb63cdcf" },
|
|
62556
|
+
{ key: "fonts/WixMadeforDisplay-ExtraBold.ttf", contentType: "font/ttf", offset: 1768784, length: 90984, sha256: "bf4c16a2774edd38a921edf3099469866cd74c094fd596f3fa4e81f54a04dfaa" },
|
|
62557
|
+
{ key: "fonts/WixMadeforDisplay-Medium.ttf", contentType: "font/ttf", offset: 1859768, length: 90980, sha256: "368faca44fb9f7207e4af784e94750b1ee59c1098b8689e0f4a918926f244fb5" },
|
|
62558
|
+
{ key: "fonts/WixMadeforDisplay-Regular.ttf", contentType: "font/ttf", offset: 1950748, length: 90872, sha256: "97ed8f1a6772abe26e3d8af5cecfc4b02faa94497d585b0398b5053b739a70c1" },
|
|
62559
|
+
{ key: "fonts/WixMadeforDisplay-SemiBold.ttf", contentType: "font/ttf", offset: 2041620, length: 90980, sha256: "642feab8a48ddf6c7a89d7c2a7c0edfa0e6e773f671287e460e222703563191e" },
|
|
62560
|
+
{ key: "fonts/WixMadeforText-Bold.ttf", contentType: "font/ttf", offset: 2132600, length: 108636, sha256: "37c179b4fefb63ea9637322b84583a2df53aa226c150294eea1675c14b1b8e29" },
|
|
62561
|
+
{ key: "fonts/WixMadeforText-ExtraBold.ttf", contentType: "font/ttf", offset: 2241236, length: 109084, sha256: "62e2fe4718129f36ecdb0ae4de385bd6b81ecc876146447167c6c140fad699a9" },
|
|
62562
|
+
{ key: "fonts/WixMadeforText-Medium.ttf", contentType: "font/ttf", offset: 2350320, length: 109048, sha256: "4ecf270136af928612c76fe4ebade91d8156975e5ea4c0cf9225501dd1788e02" },
|
|
62563
|
+
{ key: "fonts/WixMadeforText-Regular.ttf", contentType: "font/ttf", offset: 2459368, length: 107700, sha256: "dee56f09fd3efc127c1ea95557edc74110c1460a46287da36e0af25efd341ef5" },
|
|
62564
|
+
{ key: "fonts/WixMadeforText-SemiBold.ttf", contentType: "font/ttf", offset: 2567068, length: 88108, sha256: "dced97a77624bc5f8b1ae65850360908297f4588e09feb6f22792d29dc7e765b" },
|
|
62565
|
+
{ key: "index.html", contentType: "text/html; charset=utf-8", offset: 2655176, length: 4947, sha256: "094afa56a8e94767674ee8fd7ca3290f67f64930f8e2c6cc874d6d101e35fd7d" },
|
|
62566
|
+
{ key: "t5-frame.html", contentType: "text/html; charset=utf-8", offset: 2660123, length: 17344, sha256: "d057298d75e7373e5e2c4d11b7d1bcbea88e03af555ba63d97641c78509c58e4" }
|
|
62563
62567
|
];
|
|
62564
62568
|
}
|
|
62565
62569
|
});
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1210.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"artifactId": "himalaya-cli"
|
|
68
68
|
}
|
|
69
69
|
},
|
|
70
|
-
"falconPackageHash": "
|
|
70
|
+
"falconPackageHash": "506ed6e4b472a5634a05b0f8e7709afbd371c022b52be11874929da7"
|
|
71
71
|
}
|
|
@@ -48568,7 +48568,7 @@ const SCREENS = runtimeSetting({
|
|
|
48568
48568
|
"package": "himalaya",
|
|
48569
48569
|
"type": "Text",
|
|
48570
48570
|
"props": {
|
|
48571
|
-
"text": "
|
|
48571
|
+
"text": "$service:himiOwnerLiteHome.businessName",
|
|
48572
48572
|
"style": "footnote",
|
|
48573
48573
|
"color": "textSecondary",
|
|
48574
48574
|
"collapseWhenEmpty": true
|
|
@@ -50706,7 +50706,8 @@ const SCREENS = runtimeSetting({
|
|
|
50706
50706
|
"params": {
|
|
50707
50707
|
"copy": "{\"ownerHome.acrossBusiness\":\"Across the salon\",\"ownerHome.briefCta\":\"Show me the chair\",\"ownerHome.briefSubtitle\":\"Who’s in the chair, where the gaps are, and which retail lines are down to the last tube.\",\"ownerHome.briefTitle\":\"Today at the salon\",\"ownerHome.errorLabel\":\"Couldn’t load today’s chair\",\"ownerHome.headerSubtitle\":\"Salon owner · today’s chair\",\"ownerHome.openManage\":\"Open the salon\",\"ownerHome.ordersDaily\":\"Retail sales · daily\",\"ownerHome.statAppointments\":\"Booked in\",\"ownerHome.statOrders\":\"Retail orders\",\"ownerHome.statPosts\":\"Salon notes\",\"ownerHome.statProducts\":\"Retail lines\",\"ownerHome.statRevenue\":\"Takings\",\"ownerHome.statSites\":\"Salons\",\"ownerHome.switchBusiness\":\"Switch salon\"}",
|
|
50708
50708
|
"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\"}]",
|
|
50709
|
-
"enabledSources": "[\"products\",\"posts\",\"sites\",\"orders\",\"bookings\",\"members\",\"reviews\",\"reservations\"]"
|
|
50709
|
+
"enabledSources": "[\"products\",\"posts\",\"sites\",\"orders\",\"bookings\",\"members\",\"reviews\",\"reservations\"]",
|
|
50710
|
+
"businessName": "__HIMI_APP_NAME__"
|
|
50710
50711
|
}
|
|
50711
50712
|
}
|
|
50712
50713
|
}
|
|
@@ -50775,7 +50776,7 @@ const SCREENS = runtimeSetting({
|
|
|
50775
50776
|
"package": "himalaya",
|
|
50776
50777
|
"type": "Text",
|
|
50777
50778
|
"props": {
|
|
50778
|
-
"text": "
|
|
50779
|
+
"text": "$service:himiOwnerLiteManage.businessName",
|
|
50779
50780
|
"style": "footnote",
|
|
50780
50781
|
"color": "textSecondary",
|
|
50781
50782
|
"collapseWhenEmpty": true
|
|
@@ -51946,7 +51947,8 @@ const SCREENS = runtimeSetting({
|
|
|
51946
51947
|
"actionId": "tier5.himiOwnerLiteManage.load",
|
|
51947
51948
|
"params": {
|
|
51948
51949
|
"areas": "[{\"id\":\"store\",\"title\":\"Retail\",\"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\":\"Retail 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\":\"Treatments\",\"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\":\"The chair\",\"subtitle\":\"Your upcoming appointments\",\"groupId\":\"scheduling\",\"group\":\"Scheduling\",\"screenId\":\"himi_owner_lite_appointments\",\"icon\":\"clock\",\"metricKey\":\"appointments\",\"countLabel\":\"appointments\"},{\"id\":\"blog\",\"title\":\"Salon 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\"}]",
|
|
51949
|
-
"copy": "{\"ownerManage.blogLabel\":\"Salon notes\",\"ownerManage.bookingsLabel\":\"Treatments\",\"ownerManage.storeLabel\":\"Retail\",\"ownerManage.title\":\"Salon\"}"
|
|
51950
|
+
"copy": "{\"ownerManage.blogLabel\":\"Salon notes\",\"ownerManage.bookingsLabel\":\"Treatments\",\"ownerManage.storeLabel\":\"Retail\",\"ownerManage.title\":\"Salon\"}",
|
|
51951
|
+
"businessName": "__HIMI_APP_NAME__"
|
|
51950
51952
|
}
|
|
51951
51953
|
}
|
|
51952
51954
|
}
|
|
@@ -52065,7 +52067,7 @@ const SCREENS = runtimeSetting({
|
|
|
52065
52067
|
"package": "himalaya",
|
|
52066
52068
|
"type": "Text",
|
|
52067
52069
|
"props": {
|
|
52068
|
-
"text": "
|
|
52070
|
+
"text": "$service:himiOwnerLiteAccount.businessName",
|
|
52069
52071
|
"style": "bodyEmphasis",
|
|
52070
52072
|
"maxLines": 1
|
|
52071
52073
|
}
|
|
@@ -52328,6 +52330,7 @@ const SCREENS = runtimeSetting({
|
|
|
52328
52330
|
"supportUrl": "https://www.wix.com/support",
|
|
52329
52331
|
"privacyUrl": "https://www.wix.com/about/privacy",
|
|
52330
52332
|
"termsUrl": "https://www.wix.com/about/terms-of-use",
|
|
52333
|
+
"businessName": "__HIMI_APP_NAME__",
|
|
52331
52334
|
"copy": "{\"ownerAccount.roleValue\":\"Salon owner\",\"ownerAccount.subtitle\":\"Salon owner\"}"
|
|
52332
52335
|
}
|
|
52333
52336
|
}
|
|
@@ -52875,7 +52878,10 @@ const SCREENS = runtimeSetting({
|
|
|
52875
52878
|
},
|
|
52876
52879
|
"fillMaxWidth": true,
|
|
52877
52880
|
"onAppear": {
|
|
52878
|
-
"actionId": "tier5.drawer.
|
|
52881
|
+
"actionId": "tier5.drawer.refresh",
|
|
52882
|
+
"params": {
|
|
52883
|
+
"businessName": "__HIMI_APP_NAME__"
|
|
52884
|
+
}
|
|
52879
52885
|
}
|
|
52880
52886
|
}
|
|
52881
52887
|
},
|
|
@@ -61846,10 +61852,10 @@ const SCREENS = runtimeSetting({
|
|
|
61846
61852
|
},
|
|
61847
61853
|
"fillMaxWidth": true,
|
|
61848
61854
|
"onTap": {
|
|
61849
|
-
"actionId": "
|
|
61855
|
+
"actionId": "tier5.himiOwnerLiteSites.pick",
|
|
61850
61856
|
"params": {
|
|
61851
|
-
"
|
|
61852
|
-
"
|
|
61857
|
+
"id": "$item.id",
|
|
61858
|
+
"name": "$item.name"
|
|
61853
61859
|
}
|
|
61854
61860
|
},
|
|
61855
61861
|
"pressFeedback": "scale",
|
|
@@ -61946,7 +61952,6 @@ const SCREENS = runtimeSetting({
|
|
|
61946
61952
|
"contentType": "application/javascript+ts-bundle",
|
|
61947
61953
|
"declaredCapabilities": [
|
|
61948
61954
|
"wix_api",
|
|
61949
|
-
"wix_platform",
|
|
61950
61955
|
"local_database"
|
|
61951
61956
|
],
|
|
61952
61957
|
"minBinaryVersion": "0.1.0",
|
|
@@ -62407,10 +62412,10 @@ const SCREENS = runtimeSetting({
|
|
|
62407
62412
|
},
|
|
62408
62413
|
"fillMaxWidth": true,
|
|
62409
62414
|
"onTap": {
|
|
62410
|
-
"actionId": "
|
|
62415
|
+
"actionId": "tier5.himiOwnerLiteOverview.pick",
|
|
62411
62416
|
"params": {
|
|
62412
|
-
"
|
|
62413
|
-
"
|
|
62417
|
+
"id": "$item.id",
|
|
62418
|
+
"name": "$item.name"
|
|
62414
62419
|
}
|
|
62415
62420
|
},
|
|
62416
62421
|
"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
|
-
/**
|
|
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:
|
|
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
|
-
|
|
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),
|