@wix/himalaya-cli 0.1583.0 → 0.1584.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/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/blog-v3/src/extensions.d.ts +2 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/comments-v1/src/extensions.d.ts +2 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/events/src/index.d.ts +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/groups/src/extensions.d.ts +15 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/loyalty/src/extensions.d.ts +13 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/stdlib/wix-sdk/members-v1/src/index.d.ts +19 -4
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-comments.mjs +3 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-events.mjs +4 -2
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-groups.mjs +5 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-loyalty.mjs +4 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/wix-members.mjs +10 -3
- package/dist/cli.mjs +247 -186
- package/dist/preview-assets.generated.bin +0 -0
- package/fixtures/wix-canned.json +25 -0
- package/guides/one-app-to-himi-app.md +52 -1
- package/guides/sdk-reference.json +37 -9
- package/guides/wix-api-usage.md +9 -0
- package/package.json +2 -2
- package/templates/beauty-salon/config.ts +7 -0
- package/templates/beauty-salon/dev/index.ts +758 -352
- package/templates/beauty-salon/himalaya.content.json +3 -0
- package/templates/beauty-salon/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/beauty-salon/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/beauty-salon/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/beauty-salon/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/beauty-salon/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/beauty-salon/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/beauty-salon/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/beauty-salon/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/beauty-salon/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/beauty-salon/tier5-src/himi-store-product/index.ts +14 -3
- package/templates/beauty-salon/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/beauty-salon/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/beauty-salon-owner/dev/index.ts +129 -66
- package/templates/beauty-salon-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/beauty-salon-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/branded-lite/config.ts +9 -0
- package/templates/branded-lite/dev/index.ts +4988 -3304
- package/templates/branded-lite/himalaya.content.json +3 -0
- package/templates/branded-lite/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/branded-lite/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/branded-lite/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/branded-lite/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/branded-lite/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/branded-lite/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/branded-lite/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/branded-lite/tier5-src/himi-branded-lite-badges/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/branded-lite/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/branded-lite/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-loyalty/index.ts +115 -49
- package/templates/branded-lite/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-podcasts/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-portfolio/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-branded-lite-portfolio-project/index.ts +3 -2
- package/templates/branded-lite/tier5-src/himi-branded-lite-program/facts.ts +52 -0
- package/templates/branded-lite/tier5-src/himi-branded-lite-program/index.ts +21 -11
- package/templates/branded-lite/tier5-src/himi-branded-lite-video/index.ts +2 -1
- package/templates/branded-lite/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/branded-lite/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/branded-lite/tier5-src/himi-store-product/index.ts +13 -3
- package/templates/branded-lite/tier5-src/wix-spaces-forum-post/index.ts +3 -2
- package/templates/branded-lite/tier5-src/wix-spaces-member-detail/index.ts +53 -37
- package/templates/branded-lite/tier5-src/wix-spaces-members/index.ts +100 -34
- package/templates/branded-lite/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/branded-lite/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/community-club/config.ts +16 -0
- package/templates/community-club/dev/index.ts +1930 -401
- package/templates/community-club/himalaya.content.json +6 -0
- package/templates/community-club/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/community-club/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/community-club/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/community-club/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/community-club/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/community-club/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/community-club/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
- package/templates/community-club/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/community-club/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/community-club/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/community-club/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/community-club-owner/dev/index.ts +53 -1
- package/templates/community-club-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/community-club-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/community-club-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/community-club-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/community-club-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/community-club-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/community-club-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/community-club-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/events-meetups/config.ts +16 -0
- package/templates/events-meetups/dev/index.ts +1930 -401
- package/templates/events-meetups/himalaya.content.json +6 -0
- package/templates/events-meetups/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/events-meetups/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/events-meetups/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/events-meetups/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/events-meetups/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/events-meetups/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/events-meetups/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
- package/templates/events-meetups/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/events-meetups/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/events-meetups/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/events-meetups/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/events-meetups-owner/dev/index.ts +6 -0
- package/templates/events-meetups-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/events-meetups-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/gym-fitness/config.ts +7 -0
- package/templates/gym-fitness/dev/index.ts +1115 -278
- package/templates/gym-fitness/himalaya.content.json +3 -0
- package/templates/gym-fitness/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/gym-fitness/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/gym-fitness/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/gym-fitness/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/gym-fitness/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/gym-fitness/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/gym-fitness/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/gym-fitness/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/gym-fitness/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/gym-fitness/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/gym-fitness/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/gym-fitness/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/gym-fitness/tier5-src/himi-store-product/index.ts +14 -3
- package/templates/gym-fitness/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/gym-fitness/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/gym-fitness-owner/dev/index.ts +132 -66
- package/templates/gym-fitness-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/gym-fitness-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/nonprofit-cause/config.ts +16 -0
- package/templates/nonprofit-cause/dev/index.ts +1925 -396
- package/templates/nonprofit-cause/himalaya.content.json +6 -0
- package/templates/nonprofit-cause/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/nonprofit-cause/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/nonprofit-cause/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/nonprofit-cause/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/nonprofit-cause/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-group-about/index.ts +243 -0
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/nonprofit-cause/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/nonprofit-cause/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/nonprofit-cause/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/nonprofit-cause/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/nonprofit-cause/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/nonprofit-cause-owner/dev/index.ts +85 -65
- package/templates/nonprofit-cause-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/nonprofit-cause-owner/tier5-src/_shared/owner-rich-guard.ts +27 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/nonprofit-cause-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/owner-lite/dev/index.ts +132 -66
- package/templates/owner-lite/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/owner-lite/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/owner-lite/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/owner-lite/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/owner-lite/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/owner-lite/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/owner-lite/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/owner-lite/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/owner-lite/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/owner-lite/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/owner-lite/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/podcast-creator/config.ts +7 -0
- package/templates/podcast-creator/dev/index.ts +1051 -158
- package/templates/podcast-creator/himalaya.content.json +3 -0
- package/templates/podcast-creator/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/podcast-creator/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/podcast-creator/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/podcast-creator/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/podcast-creator/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/podcast-creator/tier5-src/himi-branded-lite-feed/index.ts +4 -3
- package/templates/podcast-creator/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/podcast-creator/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/podcast-creator/tier5-src/himi-branded-lite-podcasts/index.ts +2 -1
- package/templates/podcast-creator/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/podcast-creator/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/podcast-creator/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/podcast-creator/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/podcast-creator-owner/dev/index.ts +53 -1
- package/templates/podcast-creator-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/podcast-creator-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/portfolio-creative/config.ts +7 -0
- package/templates/portfolio-creative/dev/index.ts +1305 -468
- package/templates/portfolio-creative/himalaya.content.json +3 -0
- package/templates/portfolio-creative/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/portfolio-creative/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/portfolio-creative/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/portfolio-creative/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/portfolio-creative/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/portfolio-creative/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/portfolio-creative/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-portfolio/index.ts +2 -1
- package/templates/portfolio-creative/tier5-src/himi-branded-lite-portfolio-project/index.ts +3 -2
- package/templates/portfolio-creative/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/portfolio-creative/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/portfolio-creative/tier5-src/himi-store-product/index.ts +14 -3
- package/templates/portfolio-creative/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/portfolio-creative-owner/dev/index.ts +129 -66
- package/templates/portfolio-creative-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/portfolio-creative-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/restaurant/config.ts +7 -0
- package/templates/restaurant/dev/index.ts +1051 -158
- package/templates/restaurant/himalaya.content.json +3 -0
- package/templates/restaurant/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/restaurant/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/restaurant/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/restaurant/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/restaurant/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/restaurant/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/restaurant/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/restaurant/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/restaurant/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/restaurant-owner/dev/index.ts +132 -66
- package/templates/restaurant-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/restaurant-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
- package/templates/retail-store/config.ts +7 -0
- package/templates/retail-store/dev/index.ts +597 -191
- package/templates/retail-store/himalaya.content.json +3 -0
- package/templates/retail-store/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/retail-store/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/retail-store/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/retail-store/tier5-src/_shared/owner-editor-value.ts +164 -0
- package/templates/retail-store/tier5-src/_shared/store-product-info.ts +50 -0
- package/templates/retail-store/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/retail-store/tier5-src/himi-branded-lite-category/index.ts +3 -2
- package/templates/retail-store/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/retail-store/tier5-src/himi-store-product/index.ts +13 -3
- package/templates/retail-store/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/retail-store-owner/dev/index.ts +50 -1
- package/templates/retail-store-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-product/index.ts +39 -6
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-product-form/index.ts +14 -8
- package/templates/retail-store-owner/tier5-src/himi-owner-lite-products/index.ts +7 -4
- package/templates/yoga-studio/config.ts +7 -0
- package/templates/yoga-studio/dev/index.ts +1107 -110
- package/templates/yoga-studio/himalaya.content.json +3 -0
- package/templates/yoga-studio/tier5-src/_shared/branded-lite-hosted.ts +1 -1
- package/templates/yoga-studio/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/yoga-studio/tier5-src/_shared/event-registration.ts +86 -0
- package/templates/yoga-studio/tier5-src/_shared/himi-restaurants.ts +2 -1
- package/templates/yoga-studio/tier5-src/himi-blog-post/index.ts +21 -8
- package/templates/yoga-studio/tier5-src/himi-branded-lite-notifsettings/index.ts +173 -0
- package/templates/yoga-studio/tier5-src/himi-branded-lite-plans/index.ts +2 -1
- package/templates/yoga-studio/tier5-src/himi-branded-lite-program/facts.ts +52 -0
- package/templates/yoga-studio/tier5-src/himi-branded-lite-program/index.ts +21 -11
- package/templates/yoga-studio/tier5-src/himi-events-detail/index.ts +12 -86
- package/templates/yoga-studio/tier5-src/himi-events-list/index.ts +47 -6
- package/templates/yoga-studio/tier5-src/wix-spaces-plan-detail/index.ts +2 -1
- package/templates/yoga-studio/tier5-src/wix-spaces-whats-new/index.ts +2 -1
- package/templates/yoga-studio-owner/dev/index.ts +85 -65
- package/templates/yoga-studio-owner/tier5-src/_shared/collection-contract.ts +19 -3
- package/templates/yoga-studio-owner/tier5-src/_shared/owner-rich-guard.ts +27 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event/index.ts +16 -8
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-event-form/index.ts +16 -7
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-events/index.ts +4 -2
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-post/index.ts +7 -0
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service/index.ts +38 -7
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-service-form/index.ts +53 -7
- package/templates/yoga-studio-owner/tier5-src/himi-owner-lite-services/index.ts +4 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { descriptionBody } from "../_shared/rich-body.js";
|
|
1
2
|
// Tier-5 bundle: __HIMI_APP_NAME__ — create/edit Store product (the CRUD "C" + "U").
|
|
2
3
|
// Opened from the products list ("New product") or a product detail ("Edit").
|
|
3
4
|
// The Apptestersite catalog is Stores v1 (v3 428s), so this uses the v1 client:
|
|
@@ -243,19 +244,23 @@ const svc = defineService<ProductFormState, {
|
|
|
243
244
|
name: (p as any).name ?? "",
|
|
244
245
|
price: priceOf(p),
|
|
245
246
|
sku: (p as any).sku ?? "",
|
|
246
|
-
...((
|
|
247
|
+
...((raw: unknown, rich: unknown) => {
|
|
248
|
+
const html = typeof raw === "string" ? raw : "";
|
|
249
|
+
const preview = htmlPreviewText(html);
|
|
250
|
+
const description = descriptionBody(raw);
|
|
251
|
+
const legacyRich = !!parseRicosJson(raw) || (raw != null && typeof raw !== "string") || (!!preview.trim() && !description.bodyText);
|
|
247
252
|
// `richDescription` is present only on a Catalog V3 site. V3 is edited in the RichContentEditor;
|
|
248
253
|
// a V3 product whose Ricos document did not come back is edited only when its HTML is trivial
|
|
249
254
|
// (seeded as paragraphs), else locked — fail closed. V1 keeps the plain/locked split: the
|
|
250
255
|
// editor writes Ricos, and a V1 description is HTML.
|
|
251
256
|
const doc = rich === undefined || rich === null ? null : parseRicosJson(rich);
|
|
252
257
|
const hasDoc = !!doc && doc.nodes.length > 0;
|
|
253
|
-
const text =
|
|
254
|
-
const descriptionMode = rich === undefined ? (htmlIsTrivial(html) ? "plain" as const : "locked" as const)
|
|
258
|
+
const text = descriptionBody(rich, legacyRich ? description.bodyText : preview).bodyText;
|
|
259
|
+
const descriptionMode = rich === undefined ? (!legacyRich && htmlIsTrivial(html) ? "plain" as const : "locked" as const)
|
|
255
260
|
: hasDoc || htmlIsTrivial(html) ? "editor" as const : "locked" as const;
|
|
256
|
-
const descriptionJson = descriptionMode !== "editor" ? "" : hasDoc ? JSON.stringify(
|
|
261
|
+
const descriptionJson = descriptionMode !== "editor" ? "" : hasDoc ? JSON.stringify(doc) : text ? docJson(plainPostBody(text)) : "";
|
|
257
262
|
return { ...DESCRIPTION_LOADED, description: text, originalDescription: text, descriptionMode, descriptionJson };
|
|
258
|
-
})(
|
|
263
|
+
})((p as any).description, (p as { richDescription?: unknown }).richDescription),
|
|
259
264
|
visible: (p as any).visible !== false ? "true" : "false",
|
|
260
265
|
status: "idle",
|
|
261
266
|
error: "",
|
|
@@ -265,12 +270,13 @@ const svc = defineService<ProductFormState, {
|
|
|
265
270
|
// Offline: prefill from the last-synced local cache before the demo/error fallbacks.
|
|
266
271
|
const cached = await cacheGet(id);
|
|
267
272
|
if (cached) {
|
|
273
|
+
const description = descriptionBody(cached.descriptionJson || cached.bodyJson, descriptionBody(cached.description ?? cached.bodyText ?? cached.summary).bodyText).bodyText;
|
|
268
274
|
return shape({
|
|
269
275
|
...s, mode: "edit", id, heading: "Edit product",
|
|
270
276
|
name: String(cached.name ?? ""), price: editablePrice(String(cached.price ?? "")), sku: String(cached.sku ?? ""),
|
|
271
|
-
description
|
|
272
|
-
//
|
|
273
|
-
//
|
|
277
|
+
description, originalDescription: description, ...DESCRIPTION_LOADED,
|
|
278
|
+
// Only the form's document establishes its editor mode. Detail bodyJson can also come
|
|
279
|
+
// from a V1 catalog, so it supplies the preview without guessing a V3 write contract.
|
|
274
280
|
...(cached.descriptionJson ? { descriptionMode: "editor" as const, descriptionJson: String(cached.descriptionJson) }
|
|
275
281
|
: { descriptionMode: cached.descriptionProtected === "false" ? "plain" as const : "locked" as const, descriptionJson: "" }),
|
|
276
282
|
visible: cached.visible === "false" ? "false" : "true",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { descriptionBody } from "../_shared/rich-body.js";
|
|
1
2
|
// Tier-5 bundle: __HIMI_APP_NAME__ — Store products management list.
|
|
2
3
|
// Owner/management view of the active business's Wix Stores catalog. Site-scoped
|
|
3
4
|
// through the native wix-native (mode:owner) provider + WixApiCapability, which
|
|
@@ -6,11 +7,11 @@
|
|
|
6
7
|
|
|
7
8
|
import { compareText } from "../_shared/engine-intl.js";
|
|
8
9
|
import { defineBackendCollection } from "../_shared/collection-service.js";
|
|
9
|
-
import { searchStoreProducts, productImage, productPrice,
|
|
10
|
+
import { searchStoreProducts, productImage, productPrice, type StoreProduct } from "../_shared/himi-store.js";
|
|
10
11
|
import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
|
|
11
12
|
import { DEMO_PRODUCTS, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
|
|
12
13
|
import { copyParam } from "../_shared/himi-copy.js";
|
|
13
|
-
import { getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
|
|
14
|
+
import { get, getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
|
|
14
15
|
|
|
15
16
|
// Offline-first (data-offline): the owner's last-synced rows are the READ-THROUGH
|
|
16
17
|
// cache for the `owner_products` entity — paint them instantly (works offline),
|
|
@@ -24,7 +25,9 @@ async function readCachedRows(): Promise<ProductRow[]> {
|
|
|
24
25
|
try { return (await getAll(ENTITY)) as unknown as ProductRow[]; } catch { return []; }
|
|
25
26
|
}
|
|
26
27
|
async function writeCachedRows(rows: ProductRow[]): Promise<void> {
|
|
27
|
-
try {
|
|
28
|
+
try {
|
|
29
|
+
for (const r of rows) await upsert(ENTITY, { ...await get(ENTITY, r.id), ...r, title: r.name } as unknown as DbEntity);
|
|
30
|
+
} catch { /* capability not granted → online-only */ }
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
interface ProductRow {
|
|
@@ -76,7 +79,7 @@ function normalize(raw: StoreProduct): ProductRow {
|
|
|
76
79
|
const name = (raw.name || "Untitled product").trim();
|
|
77
80
|
const image = productImage(raw);
|
|
78
81
|
const price = productPrice(raw);
|
|
79
|
-
const desc =
|
|
82
|
+
const desc = descriptionBody(raw.description, descriptionBody(raw.plainDescription).bodyText).bodyText;
|
|
80
83
|
return {
|
|
81
84
|
id: raw.id || "",
|
|
82
85
|
name,
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { descriptionBody } from "../_shared/rich-body.js";
|
|
2
|
+
import { openRichLink } from "../_shared/rich-content-link.js";
|
|
1
3
|
// Tier-5 bundle: __HIMI_APP_NAME__ — Bookings service DETAIL (read view).
|
|
2
4
|
// Inner admin page opened from the services list (himi_owner_lite_service_<id>).
|
|
3
5
|
// Fetches the single Bookings v2 service and exposes a flat string state bound by
|
|
@@ -35,6 +37,10 @@ interface ServiceState {
|
|
|
35
37
|
title: string;
|
|
36
38
|
subtitle: string;
|
|
37
39
|
summary: string;
|
|
40
|
+
bodyJson: string;
|
|
41
|
+
bodyText: string;
|
|
42
|
+
hasBodyJson: boolean;
|
|
43
|
+
noBodyJson: boolean;
|
|
38
44
|
initial: string;
|
|
39
45
|
image: string;
|
|
40
46
|
typeLabel: string;
|
|
@@ -99,7 +105,7 @@ function imageOf(s: WixService): string {
|
|
|
99
105
|
|
|
100
106
|
/** The fact rows this detail shows (the descriptor"s DETAIL_T5 rows): each publishes
|
|
101
107
|
* `<key>Blank`, so a fact with no value hides instead of painting a dangling label. */
|
|
102
|
-
const FACT_KEYS = ["typeLabel", "category", "capacity"
|
|
108
|
+
const FACT_KEYS = ["typeLabel", "category", "capacity"] as const;
|
|
103
109
|
|
|
104
110
|
function shape(s: Partial<ServiceState>): ServiceState {
|
|
105
111
|
const out = shapeFields(s);
|
|
@@ -121,6 +127,10 @@ function shapeFields(s: Partial<ServiceState>): ServiceState {
|
|
|
121
127
|
title: s.title ?? "",
|
|
122
128
|
subtitle: s.subtitle ?? "",
|
|
123
129
|
summary: s.summary ?? "",
|
|
130
|
+
bodyJson: s.bodyJson ?? "",
|
|
131
|
+
bodyText: s.bodyText ?? "",
|
|
132
|
+
hasBodyJson: !!s.bodyJson,
|
|
133
|
+
noBodyJson: !s.bodyJson,
|
|
124
134
|
initial: s.initial ?? "?",
|
|
125
135
|
image,
|
|
126
136
|
typeLabel: s.typeLabel ?? "—",
|
|
@@ -152,7 +162,9 @@ function demoDetail(s: ServiceState, id: string): ServiceState | null {
|
|
|
152
162
|
status: "ready",
|
|
153
163
|
title: d.name,
|
|
154
164
|
subtitle: [d.type, d.category].filter(Boolean).join(" · "),
|
|
155
|
-
summary:
|
|
165
|
+
summary: "",
|
|
166
|
+
bodyText: d.description,
|
|
167
|
+
bodyJson: "",
|
|
156
168
|
initial: (d.name[0] || "S").toUpperCase(),
|
|
157
169
|
image: "",
|
|
158
170
|
typeLabel: d.type,
|
|
@@ -169,20 +181,24 @@ function cachedDetail(s: ServiceState, row: DbEntity): ServiceState {
|
|
|
169
181
|
const title = String(row.title ?? row.name ?? "");
|
|
170
182
|
const type = String(row.typeLabel ?? "");
|
|
171
183
|
const category = String(row.category ?? "");
|
|
184
|
+
const body = descriptionBody(row.bodyJson || row.description, descriptionBody(row.bodyText || row.summary).bodyText);
|
|
172
185
|
return shape({
|
|
173
186
|
...s,
|
|
174
187
|
id: String(row.id),
|
|
175
188
|
status: "ready",
|
|
176
189
|
title,
|
|
177
190
|
subtitle: String(row.subtitle ?? [type, category].filter(Boolean).join(" · ")),
|
|
178
|
-
summary:
|
|
191
|
+
summary: "",
|
|
192
|
+
bodyJson: body.bodyJson,
|
|
193
|
+
bodyText: body.bodyText,
|
|
179
194
|
initial: String(row.initial ?? (title[0] || "S")).slice(0, 1).toUpperCase(),
|
|
180
195
|
image: String(row.image ?? ""),
|
|
181
196
|
typeLabel: type || "—",
|
|
182
197
|
category: category || "—",
|
|
183
198
|
capacity: String(row.capacity ?? "—"),
|
|
184
|
-
description:
|
|
199
|
+
description: body.bodyText || "—",
|
|
185
200
|
error: "",
|
|
201
|
+
actionMessage: "",
|
|
186
202
|
demoNote: "",
|
|
187
203
|
});
|
|
188
204
|
}
|
|
@@ -197,21 +213,24 @@ async function refresh(prev: ServiceState, id: string): Promise<ServiceState> {
|
|
|
197
213
|
const type = serviceTypeLabel((svc as any).type);
|
|
198
214
|
const category = categoryName(svc) || "—";
|
|
199
215
|
const cap = (svc as any).defaultCapacity;
|
|
200
|
-
const
|
|
216
|
+
const body = descriptionBody((svc as any).description, descriptionBody((svc as any).tagLine).bodyText);
|
|
201
217
|
return shape({
|
|
202
218
|
...prev,
|
|
203
219
|
id,
|
|
204
220
|
status: "ready",
|
|
205
221
|
title: name,
|
|
206
222
|
subtitle: [type, category !== "—" ? category : ""].filter(Boolean).join(" · "),
|
|
207
|
-
summary:
|
|
223
|
+
summary: "",
|
|
224
|
+
bodyJson: body.bodyJson,
|
|
225
|
+
bodyText: body.bodyText,
|
|
208
226
|
initial: (name[0] || "S").toUpperCase(),
|
|
209
227
|
image: imageOf(svc),
|
|
210
228
|
typeLabel: type,
|
|
211
229
|
category,
|
|
212
230
|
capacity: cap != null ? `${cap} ${Number(cap) === 1 ? "guest" : "guests"}` : "—",
|
|
213
|
-
description:
|
|
231
|
+
description: body.bodyText || "—",
|
|
214
232
|
error: "",
|
|
233
|
+
actionMessage: "",
|
|
215
234
|
demoNote: "",
|
|
216
235
|
});
|
|
217
236
|
}
|
|
@@ -220,9 +239,16 @@ const svc = defineService<ServiceState, {
|
|
|
220
239
|
load: (s: ServiceState, arg?: unknown) => Promise<ServiceState>;
|
|
221
240
|
retry: (s: ServiceState) => Promise<ServiceState>;
|
|
222
241
|
delete: (s: ServiceState) => Promise<ServiceState>;
|
|
242
|
+
openLink: (s: ServiceState, arg?: unknown) => Promise<ServiceState>;
|
|
223
243
|
}>("himiOwnerLiteService", {
|
|
224
244
|
state: shape({ status: "loading" }),
|
|
225
245
|
actions: {
|
|
246
|
+
openLink: async (_state, arg): Promise<ServiceState> => {
|
|
247
|
+
const opened = await openRichLink(arg);
|
|
248
|
+
const failed = copyParam("ownerService.linkOpenFailed", "This link could not be opened.");
|
|
249
|
+
const current = svc.getState();
|
|
250
|
+
return shape({ ...current, actionMessage: opened ? (current.actionMessage === failed ? "" : current.actionMessage) : failed });
|
|
251
|
+
},
|
|
226
252
|
load: async (s, arg) => {
|
|
227
253
|
stashCopy(arg); // absorb the descriptor's onAppear copy-pack param
|
|
228
254
|
const id = idFrom(arg, s.id) || inputId();
|
|
@@ -284,4 +310,9 @@ const svc = defineService<ServiceState, {
|
|
|
284
310
|
},
|
|
285
311
|
});
|
|
286
312
|
|
|
313
|
+
// Hydration shallow-merges older snapshots over defaults; derive both body gates from
|
|
314
|
+
// the restored document before the first paint, without waiting for a load action.
|
|
315
|
+
const bootedBody = svc.getState();
|
|
316
|
+
Object.assign(bootedBody, { hasBodyJson: !!bootedBody.bodyJson, noBodyJson: !bootedBody.bodyJson });
|
|
317
|
+
|
|
287
318
|
export { svc };
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { descriptionBody } from "../_shared/rich-body.js";
|
|
2
|
+
import { htmlIsTrivial, htmlPreviewText } from "../_shared/owner-rich-guard.js";
|
|
3
|
+
import { parseRicosJson } from "@himalaya/wix-rich-content";
|
|
1
4
|
// Tier-5 bundle: __HIMI_APP_NAME__ — edit Bookings service (the CRUD "U").
|
|
2
5
|
// Opened from the service detail ("Edit"). EDIT-ONLY — the Bookings v2
|
|
3
6
|
// service-create needs a full nested structure the generated client doesn't
|
|
@@ -31,6 +34,10 @@ interface ServiceFormState {
|
|
|
31
34
|
heading: string;
|
|
32
35
|
name: string;
|
|
33
36
|
description: string;
|
|
37
|
+
originalDescription: unknown;
|
|
38
|
+
descriptionProtected: boolean;
|
|
39
|
+
descriptionEditable: boolean;
|
|
40
|
+
descriptionNote: string;
|
|
34
41
|
category: string;
|
|
35
42
|
status: "idle" | "loading" | "saving" | "saved" | "error";
|
|
36
43
|
writeBusy: boolean;
|
|
@@ -79,6 +86,16 @@ function categoryName(s: WixService): string {
|
|
|
79
86
|
return "";
|
|
80
87
|
}
|
|
81
88
|
|
|
89
|
+
function descriptionFields(value: unknown, known = true) {
|
|
90
|
+
const body = descriptionBody(value);
|
|
91
|
+
const protectedBody = !known || (value != null && (typeof value !== "string" || !!parseRicosJson(value)
|
|
92
|
+
|| !htmlIsTrivial(value) || (!!htmlPreviewText(value).trim() && !body.bodyText)));
|
|
93
|
+
return { description: body.bodyText, originalDescription: known ? value ?? "" : undefined, descriptionProtected: protectedBody,
|
|
94
|
+
descriptionEditable: !protectedBody, descriptionNote: protectedBody
|
|
95
|
+
? known ? copyParam("ownerServiceForm.richDescriptionNote", "This description has formatting or media. Edit it in your site dashboard to keep that content intact; the name can be changed here.")
|
|
96
|
+
: copyParam("ownerServiceForm.descriptionNotLoaded", "The description is not available yet. The name can be changed here.") : "" };
|
|
97
|
+
}
|
|
98
|
+
|
|
82
99
|
function shape(s: Partial<ServiceFormState>): ServiceFormState {
|
|
83
100
|
const id = typeof s.id === "string" ? s.id : "";
|
|
84
101
|
const savedId = typeof s.savedId === "string" ? s.savedId : id;
|
|
@@ -89,6 +106,10 @@ function shape(s: Partial<ServiceFormState>): ServiceFormState {
|
|
|
89
106
|
heading: s.heading ?? copyParam("ownerServiceForm.headingEdit", "Edit service"),
|
|
90
107
|
name: s.name ?? "",
|
|
91
108
|
description: s.description ?? "",
|
|
109
|
+
originalDescription: s.originalDescription,
|
|
110
|
+
descriptionProtected: s.descriptionProtected ?? true,
|
|
111
|
+
descriptionEditable: s.descriptionProtected === false,
|
|
112
|
+
descriptionNote: s.descriptionNote ?? copyParam("ownerServiceForm.descriptionNotLoaded", "The description is not available yet. The name can be changed here."),
|
|
92
113
|
category: s.category ?? "",
|
|
93
114
|
status: s.status ?? "idle",
|
|
94
115
|
writeBusy: s.writeBusy ?? false,
|
|
@@ -117,6 +138,8 @@ const svc = defineService<ServiceFormState, {
|
|
|
117
138
|
submit: (s: ServiceFormState, values?: Record<string, unknown>) => Promise<ServiceFormState>;
|
|
118
139
|
}>("himiOwnerLiteServiceForm", {
|
|
119
140
|
state: shape({ id: initialId }),
|
|
141
|
+
notHydrated: ["originalDescription", "descriptionProtected", "descriptionEditable", "descriptionNote"],
|
|
142
|
+
perVisit: ["originalDescription", "descriptionProtected", "descriptionEditable", "descriptionNote"],
|
|
120
143
|
actions: {
|
|
121
144
|
load: async (s, arg): Promise<ServiceFormState | undefined> => landsOnLive(svc, s, await (async () => {
|
|
122
145
|
stashCopy(arg); // absorb the descriptor's onAppear copy-pack param
|
|
@@ -130,7 +153,7 @@ const svc = defineService<ServiceFormState, {
|
|
|
130
153
|
if (d) {
|
|
131
154
|
return shape({
|
|
132
155
|
...s, id, heading: copyParam("ownerServiceForm.headingEdit", "Edit service"),
|
|
133
|
-
name: d.name,
|
|
156
|
+
name: d.name, ...descriptionFields(d.description), category: d.category,
|
|
134
157
|
status: "idle", error: "", savedMessage: "", demoNote: copyParam("ownerCommon.demoNote", DEMO_NOTE),
|
|
135
158
|
});
|
|
136
159
|
}
|
|
@@ -144,7 +167,7 @@ const svc = defineService<ServiceFormState, {
|
|
|
144
167
|
...s, id, heading: copyParam("ownerServiceForm.headingEdit", "Edit service"),
|
|
145
168
|
revision: String((svcObj as any).revision ?? ""),
|
|
146
169
|
name: (svcObj as any).name ?? "",
|
|
147
|
-
|
|
170
|
+
...descriptionFields((svcObj as any).description),
|
|
148
171
|
category: categoryName(svcObj),
|
|
149
172
|
status: "idle", error: "", savedMessage: "",
|
|
150
173
|
});
|
|
@@ -155,7 +178,7 @@ const svc = defineService<ServiceFormState, {
|
|
|
155
178
|
return shape({
|
|
156
179
|
...s, id, heading: "Edit service",
|
|
157
180
|
name: String(cached.name ?? cached.title ?? ""),
|
|
158
|
-
|
|
181
|
+
...descriptionFields(cached.description, Object.hasOwn(cached, "description")),
|
|
159
182
|
category: String(cached.category ?? ""),
|
|
160
183
|
status: "idle", error: "", savedMessage: "",
|
|
161
184
|
});
|
|
@@ -165,7 +188,7 @@ const svc = defineService<ServiceFormState, {
|
|
|
165
188
|
if (d) {
|
|
166
189
|
return shape({
|
|
167
190
|
...s, id, heading: copyParam("ownerServiceForm.headingEdit", "Edit service"),
|
|
168
|
-
name: d.name,
|
|
191
|
+
name: d.name, ...descriptionFields(d.description), category: d.category,
|
|
169
192
|
status: "idle", error: "", savedMessage: "", demoNote: copyParam("ownerCommon.demoNote", DEMO_NOTE),
|
|
170
193
|
});
|
|
171
194
|
}
|
|
@@ -177,25 +200,42 @@ const svc = defineService<ServiceFormState, {
|
|
|
177
200
|
if (isOwnerPreviewDemo() || s.demoNote) return demoRefusal(s);
|
|
178
201
|
const v = values ?? {};
|
|
179
202
|
const targetId = s.id || (typeof v.id === "string" ? v.id : "");
|
|
203
|
+
const cached = !s.id && targetId ? await cacheGet(targetId) : null;
|
|
204
|
+
// Legacy queued payloads arrive without a loaded form. Read the current body before
|
|
205
|
+
// accepting their text, so replay cannot replace a rich description blindly.
|
|
206
|
+
if (!s.id && targetId) {
|
|
207
|
+
try {
|
|
208
|
+
const service = (await getService(targetId)).service;
|
|
209
|
+
if (!service?.id) return shape({ ...s, status: "error", error: copyParam("ownerServiceForm.errorNotFound", "Service not found") });
|
|
210
|
+
s = shape({ ...s, id: targetId, revision: String(service.revision ?? ""),
|
|
211
|
+
...descriptionFields(service.description), category: categoryName(service) || String(cached?.category ?? "") });
|
|
212
|
+
} catch (error) {
|
|
213
|
+
return shape({ ...s, status: "error", error: ownerWriteError(error), savedMessage: "" });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
180
216
|
const name = String(v.name ?? s.name).trim();
|
|
181
217
|
const description = String(v.description ?? s.description).trim();
|
|
218
|
+
const descriptionEdited = description !== descriptionBody(s.originalDescription).bodyText.trim();
|
|
219
|
+
if (s.descriptionProtected && descriptionEdited) return shape({ ...s, status: "error", error: s.descriptionNote, savedMessage: "" });
|
|
182
220
|
if (!name) return shape({ ...s, status: "error", error: copyParam("ownerServiceForm.nameRequired", "Name is required"), savedMessage: "" });
|
|
183
221
|
if (!targetId) return shape({ ...s, status: "error", error: copyParam("ownerServiceForm.errorNoService", "No service to edit."), savedMessage: "" });
|
|
184
222
|
|
|
185
|
-
const
|
|
186
|
-
|
|
223
|
+
const localRow: DbEntity = { ...(cached ?? {}), id: targetId, name, title: name,
|
|
224
|
+
...(descriptionEdited || s.originalDescription !== undefined ? { description: descriptionEdited ? description : s.originalDescription } : {}),
|
|
225
|
+
category: s.category || String(cached?.category ?? "") };
|
|
187
226
|
try {
|
|
188
227
|
// v2 PATCH is a masked update requiring the current `revision` (optimistic
|
|
189
228
|
// concurrency), captured from the getService on load. The response wraps
|
|
190
229
|
// the UPDATED entity ({ service }) with its bumped revision — carry it
|
|
191
230
|
// into state, or the SECOND consecutive save would send the stale
|
|
192
231
|
// load-time revision and reject.
|
|
193
|
-
const res = await updateService(targetId, { name, ...(
|
|
232
|
+
const res = await updateService(targetId, { name, ...(!s.descriptionProtected && descriptionEdited ? { description } : {}), ...(s.revision ? { revision: s.revision } : {}) });
|
|
194
233
|
const bumped = String((res?.service as { revision?: unknown } | undefined)?.revision ?? "");
|
|
195
234
|
// The local row follows only what Wix confirmed.
|
|
196
235
|
await cachePut(localRow);
|
|
197
236
|
return shape({
|
|
198
237
|
...s, id: targetId, name, description,
|
|
238
|
+
originalDescription: descriptionEdited ? description : s.originalDescription,
|
|
199
239
|
revision: bumped || s.revision,
|
|
200
240
|
status: "saved", error: "", savedMessage: copyParam("ownerServiceForm.savedMessage", "Service saved."),
|
|
201
241
|
savedId: targetId,
|
|
@@ -211,4 +251,10 @@ const svc = defineService<ServiceFormState, {
|
|
|
211
251
|
},
|
|
212
252
|
});
|
|
213
253
|
|
|
254
|
+
// Older binaries ignore notHydrated. Their restored preview must also stay read-only until load.
|
|
255
|
+
if (!(globalThis as { himalaya?: { hydrationOptOut?: boolean } }).himalaya?.hydrationOptOut) {
|
|
256
|
+
Object.assign(svc.getState(), { originalDescription: undefined, descriptionProtected: true, descriptionEditable: false,
|
|
257
|
+
descriptionNote: copyParam("ownerServiceForm.descriptionNotLoaded", "The description is not available yet. The name can be changed here.") });
|
|
258
|
+
}
|
|
259
|
+
|
|
214
260
|
export { svc };
|
|
@@ -8,7 +8,7 @@ import { queryServices, type WixService } from "@himalaya/wix-bookings";
|
|
|
8
8
|
import { ownerLoadError, isOwnerPreviewDemo, ownerDemoFallback } from "../_shared/owner-load-error.js";
|
|
9
9
|
import { DEMO_SERVICES, DEMO_NOTE } from "../_shared/owner-preview-demo.js";
|
|
10
10
|
import { copyParam } from "../_shared/himi-copy.js";
|
|
11
|
-
import { getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
|
|
11
|
+
import { get, getAll, upsert, type DbEntity } from "../_shared/owner-local-db.js";
|
|
12
12
|
|
|
13
13
|
// Last-synced rows are an explicitly incomplete fallback for an unfiltered
|
|
14
14
|
// request during an outage. Filtered pages never claim this cache is complete.
|
|
@@ -17,8 +17,10 @@ const ENTITY = "owner_services";
|
|
|
17
17
|
async function readCachedRows(): Promise<ServiceRow[]> {
|
|
18
18
|
try { return (await getAll(ENTITY)) as unknown as ServiceRow[]; } catch { return []; }
|
|
19
19
|
}
|
|
20
|
+
// A list row carries no description. Merge it over the stored row so a normal refresh keeps the
|
|
21
|
+
// rich body the service form cached, as Products and Events do.
|
|
20
22
|
async function writeCachedRows(rows: ServiceRow[]): Promise<void> {
|
|
21
|
-
try { for (const r of rows) await upsert(ENTITY, r as unknown as DbEntity); } catch { /* capability not granted → online-only */ }
|
|
23
|
+
try { for (const r of rows) await upsert(ENTITY, { ...await get(ENTITY, r.id), ...r } as unknown as DbEntity); } catch { /* capability not granted → online-only */ }
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
interface ServiceRow {
|
|
@@ -183,6 +183,13 @@ export default defineApp({
|
|
|
183
183
|
"parentScreenId": "himi_blog",
|
|
184
184
|
"tabId": "home"
|
|
185
185
|
},
|
|
186
|
+
{
|
|
187
|
+
"screenId": "himi_notif_settings",
|
|
188
|
+
"isPublic": true,
|
|
189
|
+
"paramKeys": [],
|
|
190
|
+
"parentScreenId": "himi_account",
|
|
191
|
+
"tabId": "profile"
|
|
192
|
+
},
|
|
186
193
|
{
|
|
187
194
|
"screenId": "himi_events",
|
|
188
195
|
"isPublic": true,
|
|
@@ -254,6 +261,15 @@ export default defineApp({
|
|
|
254
261
|
"parentScreenId": "himi_groups",
|
|
255
262
|
"tabId": ""
|
|
256
263
|
},
|
|
264
|
+
{
|
|
265
|
+
"screenId": "himi_group_about",
|
|
266
|
+
"isPublic": true,
|
|
267
|
+
"paramKeys": [
|
|
268
|
+
"id"
|
|
269
|
+
],
|
|
270
|
+
"parentScreenId": "himi_group",
|
|
271
|
+
"tabId": ""
|
|
272
|
+
},
|
|
257
273
|
{
|
|
258
274
|
"screenId": "himi_account",
|
|
259
275
|
"isPublic": true,
|