efficient-web-builder 32.1.0 → 33.0.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/CHANGELOG.md +51 -0
- package/dist/editor/components/SectionIcon.js +1 -1
- package/dist/editor/components/SiteRestoreNotice.d.ts +1 -0
- package/dist/editor/components/SiteRestoreNotice.js +1 -0
- package/dist/editor/components/VersionHistoryDrawer.d.ts +21 -0
- package/dist/editor/components/VersionHistoryDrawer.js +1 -0
- package/dist/editor/components/WebsiteScreenParts.js +1 -1
- package/dist/editor/components/storefront-editor.css +17 -1
- package/dist/editor/components/usePinnedChromeSeed.js +1 -1
- package/dist/editor/components/useWebsiteMainAction.js +1 -1
- package/dist/editor/lib/editor-blocks.d.ts +16 -0
- package/dist/editor/lib/editor-document-adapter.d.ts +2 -0
- package/dist/editor/lib/editor-document-adapter.js +1 -1
- package/dist/editor/lib/puck/blocks/general/Text/fields.js +1 -1
- package/dist/editor/lib/puck/heading-outline.js +1 -1
- package/dist/editor/lib/puck/overrides.js +1 -1
- package/dist/editor/lib/puck/pinned-in-place-seed.d.ts +1 -0
- package/dist/editor/lib/puck/pinned-in-place-seed.js +1 -1
- package/dist/editor/lib/site-versions.d.ts +43 -0
- package/dist/editor/lib/site-versions.js +1 -0
- package/dist/format/lib/content/text-tag.d.ts +4 -0
- package/dist/format/lib/content/text-tag.js +1 -0
- package/dist/format/lib/editor-words-catalogue.d.ts +58 -0
- package/dist/format/lib/editor-words-catalogue.js +5 -5
- package/dist/format/lib/puck/container-blocks.js +1 -1
- package/dist/format/lib/puck/new-site-header-seed.d.ts +17 -0
- package/dist/format/lib/puck/new-site-header-seed.js +1 -0
- package/dist/format/lib/puck/passes/settings-groups.js +1 -1
- package/dist/format/lib/sections/section-head-style.d.ts +1 -0
- package/dist/format/lib/source-rules/flat-theme-palette.d.ts +1 -0
- package/dist/format/lib/source-rules/flat-theme-palette.js +5 -5
- package/dist/format/lib/source-rules/panel-rows-use-the-shared-row.d.ts +1 -0
- package/dist/format/lib/source-rules/panel-rows-use-the-shared-row.js +18 -18
- package/dist/format/lib/web-backend.d.ts +29 -0
- package/dist/render/components/SectionHeader.d.ts +30 -3
- package/dist/render/components/SectionHeader.js +1 -1
- package/dist/render/components/Text.d.ts +2 -1
- package/dist/render/components/Text.js +1 -1
- package/dist/render/lib/puck/blocks/general/Text/render.js +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 33.0.0 - 2026-10-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Version history of the whole website** (card [DESIGN] Website Version History, Lewis 2026-10-22: design final, all 7 recommendations). Every Publish of the website keeps a version; the editor shows them and puts one back AS A DRAFT, never live.
|
|
10
|
+
- The Publish ▾ menu ends with **Version history** (clock glyph), under Save now and one divider (efficient-easel 16.1.0 `ScreenMainAction.menuItems`). It opens `components/VersionHistoryDrawer`: the shell's `Drawer` on the right (full width on a phone), one `ListRow` a version, newest first. A row shows its number or name, the badges Live / Version N / Not published, who published (the business's name for that person), when, and how many changes. Open, it lists what that Publish changed and has Preview and Restore. Its ··· menu: Preview, Restore whole website, Restore one page only, Name this version. The live version has no restore; the kept drafts ("Draft before restore") have only "Put these drafts back".
|
|
11
|
+
- Restore asks first (the shell's `Dialog`): what goes back ("The whole website goes back to version 13 as a draft: 2 pages and Main menu."), that the live website does not change until Publish, how many pictures of that version were deleted from the media library since, and, when something is waiting, that it is kept as "Draft before restore". One page only: the open page if the version holds it, with a Page choice when it holds more than one.
|
|
12
|
+
- A restore saves what the editor holds, restores, writes the website's live state, and reloads the open page (`lib/site-versions`). The canvas then says "Version 13 is now your draft" (`components/SiteRestoreNotice`, the shell's `Banner` where the header-and-footer notice floats), with **Undo**, which restores the version the backend named for it. A Publish ends the notice: the restored draft is live then. A held edit that does not save stops the restore, and the dialog says so.
|
|
13
|
+
- Preview opens a new tab in the click and sends it to the version's link; it restores nothing.
|
|
14
|
+
- One sentence in the drawer says what is not versioned: "Products, prices and forms always show as they are now."
|
|
15
|
+
- `WebsiteSite.versions?`, `nameVersion?`, `restoreVersion?`, `previewVersion?` (`lib/web-backend`, with `SiteVersion`, `SiteRestoreAnswer`, `SiteVersionPreview`). Optional, and offered together with the site-wide `publish` / `liveState` or not at all: a backend without all of them shows no Version history (`WebsiteDocumentAdapter.siteVersions`). The EFFICIENT backend's routes come with efficient-backend (build plan B1 to B3) and its adapter in efficient-storefront-blocks (K1).
|
|
16
|
+
- **`SectionHeader` draws the Product Grid's head: `look="shelf"`** (audit 2026-10-20 item 11, card [MERGE] One Text Block And Click Through Parts). The Product Grid (efficient-storefront-blocks `ProductGridSection`) drew its own copy of a section head — a sticky bar with the number and title on the left, the supporting line, link and product count on the right — "matching SectionHeader". The bar moves here whole, as one more look of the one head, byte for byte. New props, `shelf` only: `titleSize` (`SHELF_TITLE_SIZES`, `DEFAULT_SHELF_TITLE_SIZE` = `lg`, `ShelfTitleSize`: the Product Grid's five title sizes, moved here), `count`, `capped`. `SectionHeaderLook` (`lib/sections/section-head-style`) = the merchant looks + `shelf`; `shelf` is not offered in the head style row. The Product Grid moves onto it in efficient-storefront-blocks after this release.
|
|
17
|
+
- **The Text block's HTML tag row** (one Text block, decision 9b; card [MERGE] One Text Block And Click Through Parts). A new `tag` prop and row "HTML tag": Paragraph, H1 … H6. The tag changes the meaning, never the look: a heading tag draws ONE element of that tag with the paragraph's classes (a blank line inside it is a line break, not a second heading). No stored tag is `<p>` (GG, 2026-10-22), so no saved page changes; a new Text block is born with `p`. The row sits in its own band "Text", which draws no heading while it holds one row.
|
|
18
|
+
- `lib/content/text-tag`: `TEXT_TAGS`, `textTagOf`, `headingLevelOfTag` — the one reader of the stored value.
|
|
19
|
+
- The heading outline (`lib/puck/heading-outline`) counts a Text with a heading tag at its level, and not a paragraph or a hidden one.
|
|
20
|
+
- **A repository may hold no block registry** (efficient-storefront wave 3: its blocks become a package). `flat-theme-palette` and `panel-rows-use-the-shared-row` take `holdsRegistry?: boolean`. Unset or `true` is today's rule: the registry's share must be read. `false` holds the repository to its claim instead: no registry file is handed in, and (panel rows) no builder import sits outside a registry. No caller changes.
|
|
21
|
+
- **The Account and Theme Switch blocks are in a Box's block menu** (`lib/puck/container-blocks`), after Cart and Country Switch, each with its `Cell width` as the Cart has. "Switch to Box header" already puts them in the bar's tools Box; now a merchant can add them to a Box too. Each has a glyph of its own (`components/SectionIcon`): head and shoulders, and a circle half dark.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- **The Account and Legal Line blocks take their Design groups** (card [SWITCH] Every Site To The Box Header). `GROUPED_BLOCKS` (`lib/puck/passes/settings-groups`) names `AccountBlock` (`Show as`, and `Cell width` from the Box menu, as Cart) and `LegalLineBlock` (storefront-blocks: its new `Copyright` text row and `Cell width`). The list stays named, never derived; storefront-blocks' `test-block-tabs` measures it both ways. A host without these blocks sees no change.
|
|
26
|
+
- **BREAKING: the efficient-easel peer range is `^16.1.0`** (was `^15.0.0`), the release with `ScreenMainAction.menuItems`. Easel 16.0.0 draws every menu row with the shell's renderer.
|
|
27
|
+
- **BREAKING: the efficient-shell peer range is `^8.18.0`** (was `^8.13.0`, peer and dev), which easel 16 needs. A host on an older easel or shell moves first.
|
|
28
|
+
|
|
29
|
+
### Guards
|
|
30
|
+
|
|
31
|
+
- New `scripts/test-version-history.tsx` (red first): the adapter offers versions only with all four calls and the site Publish, each call with the site's scope; the menu row only where offered, and it opens the drawer; a restore saves first, then restores, then writes the live state and reloads, and restores nothing when the save fails; Undo restores the kept drafts, and a Publish ends the notice; the drawer's rows, badges, menus and retention line, full width on a phone; the confirm's change count, deleted pictures, kept drafts and one-page words; the notice and its Undo; no word ends in "…".
|
|
32
|
+
- `scripts/test-shell-peer-range.ts`, `scripts/test-two-ways-to-add.ts`, `scripts/test-publish-main-action.tsx`: the new floors.
|
|
33
|
+
- `scripts/test-section-header-shelf.tsx` (red first): the shelf draws what the Product Grid's head drew on blocks main 8dcc72b, byte for byte, in 15 cases (`scripts/fixtures/shelf-head-bytes.json`); its five sizes and default; not a merchant choice.
|
|
34
|
+
- `scripts/test-text-html-tag.tsx` (red first): the row and its options, the same bytes for no tag and `p`, one heading element with the paragraph's look, the outline.
|
|
35
|
+
- `panel-group-order.baseline.json`: `Text` leaves `labelGroupRowsForBlocks`, because a panel here now builds a "Text" band.
|
|
36
|
+
- `scripts/test-registry-share-optional.ts` (red first: 7 of 12 fail without the option): the default still fails a read with no registry; `false` passes one, fails one that holds a registry file, and fails a stray `toggle` import.
|
|
37
|
+
- `scripts/test-grouped-account-legal-line.ts` (red first: 2 of 3 failed; the Box menu case added with the change). `scripts/test-block-icons.tsx` passes with the two glyphs.
|
|
38
|
+
|
|
39
|
+
## 32.2.0 - 2026-10-22
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- **A new site starts on the Box header** (plan 2026-10-10 step B3; card [SWITCH] Every Site To The Box Header). A new site already started on the Box footer: its site-footer document is laid down empty, and the seed fills it. That same new site now also gets the header group, pinned first, built by the HOST from the site's own header row. A site on the old footer, or on the Box footer only, keeps its header: it switches by its own choice ("Switch to Box header"). No live site changes.
|
|
44
|
+
- `EditorBlocks.seeds` (`lib/editor-blocks`, with `EditorSeeds` and `EditorSeedContext`): `siteHeader({ make, id, siteId, token })` resolves the `SiteHeader` group, or null. Optional: a host without it keeps a new site on the old header, as before.
|
|
45
|
+
- A TEMPLATE's site-footer page gets no old Footer or Header seeded (`components/usePinnedChromeSeed`). A site made from the template takes that page as its site-footer document, so it stays empty and the new site's seed lays down both Box groups.
|
|
46
|
+
- `lib/puck/new-site-header-seed` (`seedNewSiteHeader`): asks the host, then writes the group only when the same document is still open, no header group arrived meanwhile, and the answer is a header group. `inPlaceSeedPlan` gains `seedSiteHeader`.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- The comments that said nothing creates a group (`components/usePinnedChromeSeed`, `lib/puck/section-groups`) say the two ways a group is created now. The stale notes on the footer focus's seams and `panels.chromePage` are gone (`components/SectionEditor`, `components/WebsiteScreenParts`).
|
|
51
|
+
|
|
52
|
+
### Guards
|
|
53
|
+
|
|
54
|
+
- `scripts/test-new-site-box-header.ts` (red first): which sites get the header group, the write and each case that writes nothing, the seed's call, and the template's empty site-footer page.
|
|
55
|
+
|
|
5
56
|
## 32.1.0 - 2026-10-21
|
|
6
57
|
|
|
7
58
|
### Added
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{jsx as h,Fragment as t,jsxs as e}from"react/jsx-runtime";import{BlockBannerIcon as
|
|
1
|
+
import{jsx as h,Fragment as t,jsxs as e}from"react/jsx-runtime";import{BlockBannerIcon as a,BlockBoxIcon as n,BlockButtonIcon as g,BlockDividerIcon as x,BlockFooterIcon as M,BlockHeadingIcon as y,BlockProductIcon as p,BlockSocialIcon as w,BlockTextIcon as s,ChatIcon as B,GridIcon as k,ImageIcon as c,MediaIcon as u,PageIcon as S}from"efficient-easel/icons";import{CART_GLYPH as I}from"../../render/components/cartGlyph.js";const m={header:e(t,{children:[h("rect",{x:"3",y:"5",width:"18",height:"14",rx:"2"}),h("path",{d:"M3 9.5h18"})]}),website:e(t,{children:[h("circle",{cx:"12",cy:"12",r:"9"}),h("path",{d:"M3 12h18M12 3c2.6 2.7 2.6 15.3 0 18M12 3c-2.6 2.7-2.6 15.3 0 18"})]}),social:e(t,{children:[h("circle",{cx:"6",cy:"12",r:"2.5"}),h("circle",{cx:"18",cy:"6",r:"2.5"}),h("circle",{cx:"18",cy:"18",r:"2.5"}),h("path",{d:"M8.2 10.8l7.6-3.6M8.2 13.2l7.6 3.6"})]}),ticker:e(t,{children:[h("rect",{x:"3",y:"8.5",width:"18",height:"7",rx:"2"}),h("path",{d:"M6 12h3.5M11.5 12h2M15.5 12h2.5"})]}),FooterLogo:e(t,{children:[h("path",{d:"M4 15.5h6M4 18h4"}),h("path",{d:"M14 8.5l3 7 3-7"})]}),FooterMenu:h("path",{d:"M6 7h12M6 11h12M6 15h8M6 19h8"}),FooterGroup:e(t,{children:[h("rect",{x:"4",y:"4",width:"16",height:"16",rx:"2",strokeDasharray:"3 2.5"}),h("path",{d:"M8 9h8M8 13h8M8 16h5"})]}),FooterText:h("path",{d:"M5 7h14M5 12h14M5 17h9"}),FooterEmailSignup:e(t,{children:[h("rect",{x:"3",y:"6",width:"18",height:"12",rx:"2"}),h("path",{d:"M3.5 7l8.5 6 8.5-6"})]}),SearchBlock:e(t,{children:[h("circle",{cx:"11",cy:"11",r:"6"}),h("path",{d:"M20 20l-4.2-4.2"})]}),CartBlock:I,CountrySwitchBlock:e(t,{children:[h("circle",{cx:"12",cy:"12",r:"8.5"}),h("path",{d:"M3.5 12h17M12 3.5c2.6 2.4 3.6 5.2 3.6 8.5s-1 6.1-3.6 8.5M12 3.5c-2.6 2.4-3.6 5.2-3.6 8.5s1 6.1 3.6 8.5"})]}),AccountBlock:e(t,{children:[h("circle",{cx:"12",cy:"8",r:"4"}),h("path",{d:"M4.5 20c.8-3.8 3.8-6 7.5-6s6.7 2.2 7.5 6"})]}),ThemeSwitchBlock:e(t,{children:[h("circle",{cx:"12",cy:"12",r:"8.5"}),h("path",{d:"M12 3.5v17M12 5.5l6 6M12 10.5l5.2 5.2M12 15.5l2.8 2.8"})]}),LegalLineBlock:e(t,{children:[h("path",{d:"M3 9h18"}),h("path",{d:"M3 14h8M14 14h2M18 14h3"})]}),Hero:e(t,{children:[h("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),h("path",{d:"M7 13.5h7M7 16.5h10"})]}),HeroSlide:e(t,{children:[h("rect",{x:"3",y:"5",width:"18",height:"14",rx:"2"}),h("path",{d:"M7 15h6M16 9.5h.01M9.5 12l-2.5 3"})]}),HeroSingle:e(t,{children:[h("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),h("path",{d:"M10.5 8.5l4 2.5-4 2.5z"}),h("path",{d:"M7 17h7"})]}),Collections:e(t,{children:[h("rect",{x:"3",y:"5",width:"4.6",height:"14",rx:"1.3"}),h("rect",{x:"9.7",y:"5",width:"4.6",height:"14",rx:"1.3"}),h("rect",{x:"16.4",y:"5",width:"4.6",height:"14",rx:"1.3"})]}),CollectionCard:e(t,{children:[h("rect",{x:"6",y:"4",width:"12",height:"16",rx:"2"}),h("path",{d:"M9 15h6M9 17.5h4"})]}),AlloyWheelsListing:e(t,{children:[h("path",{d:"M3 5h5M3 9h5M3 13h5M3 17h5"}),h("rect",{x:"11.5",y:"5",width:"4.2",height:"5",rx:"1"}),h("rect",{x:"17.3",y:"5",width:"4.2",height:"5",rx:"1"}),h("rect",{x:"11.5",y:"12",width:"4.2",height:"5",rx:"1"}),h("rect",{x:"17.3",y:"12",width:"4.2",height:"5",rx:"1"})]}),CatalogFilterBar:e(t,{children:[h("path",{d:"M3 7h9M15.5 7H21"}),h("circle",{cx:"13.5",cy:"7",r:"1.7"}),h("path",{d:"M3 12h4M10.5 12H21"}),h("circle",{cx:"8.5",cy:"12",r:"1.7"}),h("path",{d:"M3 17h9M15.5 17H21"}),h("circle",{cx:"13.5",cy:"17",r:"1.7"})]}),ProductGrid:e(t,{children:[h("rect",{x:"3",y:"5",width:"4.8",height:"6",rx:"1"}),h("rect",{x:"9.6",y:"5",width:"4.8",height:"6",rx:"1"}),h("rect",{x:"16.2",y:"5",width:"4.8",height:"6",rx:"1"}),h("rect",{x:"3",y:"13",width:"4.8",height:"6",rx:"1"}),h("rect",{x:"9.6",y:"13",width:"4.8",height:"6",rx:"1"}),h("rect",{x:"16.2",y:"13",width:"4.8",height:"6",rx:"1"})]}),RelatedProducts:e(t,{children:[h("path",{d:"M3 5h10"}),h("rect",{x:"3",y:"9.5",width:"5",height:"9",rx:"1"}),h("rect",{x:"9.5",y:"9.5",width:"5",height:"9",rx:"1"}),h("rect",{x:"16",y:"9.5",width:"5",height:"9",rx:"1"})]}),Gallery:e(t,{children:[h("rect",{x:"3",y:"4",width:"11",height:"16",rx:"2"}),h("rect",{x:"15.5",y:"4",width:"5.5",height:"7.5",rx:"1.5"}),h("rect",{x:"15.5",y:"12.5",width:"5.5",height:"7.5",rx:"1.5"})]}),GalleryB:e(t,{children:[h("rect",{x:"3.5",y:"4",width:"7.5",height:"7.5",rx:"1.5"}),h("rect",{x:"13",y:"4",width:"7.5",height:"7.5",rx:"1.5"}),h("rect",{x:"3.5",y:"12.5",width:"7.5",height:"7.5",rx:"1.5"}),h("rect",{x:"13",y:"12.5",width:"7.5",height:"7.5",rx:"1.5"})]}),GalleryItem:e(t,{children:[h("rect",{x:"4",y:"5",width:"16",height:"14",rx:"2"}),h("circle",{cx:"9",cy:"10",r:"1.6"}),h("path",{d:"M20 15.5l-4.5-4L7 19"})]}),Events:e(t,{children:[h("rect",{x:"4",y:"5",width:"16",height:"15",rx:"2"}),h("path",{d:"M4 9.5h16M8.5 3v4M15.5 3v4M8 14h2M14 14h2"})]}),PostCard:e(t,{children:[h("rect",{x:"4",y:"3.5",width:"16",height:"17",rx:"2"}),h("rect",{x:"6.5",y:"6",width:"11",height:"6",rx:"1"}),h("path",{d:"M6.5 14.5h11M6.5 17.5h7"})]}),Manifesto:e(t,{children:[h("path",{d:"M7 8h3.2v4c0 1.6-1 2.6-3 3.2"}),h("path",{d:"M14 8h3.2v4c0 1.6-1 2.6-3 3.2"})]}),Stats:e(t,{children:[h("path",{d:"M3.5 20h17"}),h("path",{d:"M6 20v-7M11 20V7M16 20v-5M20.5 20v-9"})]}),Logos:e(t,{children:[h("circle",{cx:"6",cy:"12",r:"2.6"}),h("rect",{x:"10",y:"9.4",width:"5.2",height:"5.2",rx:"1.2"}),h("path",{d:"M19 9.2l2.4 5h-4.8z"})]}),Ticker:e(t,{children:[h("rect",{x:"3",y:"8.5",width:"18",height:"7",rx:"2"}),h("path",{d:"M6 12h3.5M11.5 12h2M15.5 12h2.5"})]}),SectionHeader:e(t,{children:[h("rect",{x:"3.5",y:"6",width:"5",height:"5",rx:"1.2"}),h("path",{d:"M11 8.5h9M3.5 15.5h17"})]}),IntroBleed:e(t,{children:[h("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),h("path",{d:"M3 13.5h18M7 16.8h6"})]}),Split:e(t,{children:[h("rect",{x:"3",y:"5",width:"8",height:"14",rx:"1.5"}),h("path",{d:"M14 8.5h6M14 12h6M14 15.5h4"})]}),Eyebrow:e(t,{children:[h("path",{d:"M4 8.5h4.5M11 8.5h9"}),h("path",{d:"M4 14.5h16"})]}),HeroGroup:e(t,{children:[h("rect",{x:"3.5",y:"4.5",width:"17",height:"15",rx:"2"}),h("path",{d:"M7 9h8M7 12.5h10M7 16h6"})]}),Form:e(t,{children:[h("rect",{x:"3",y:"4",width:"18",height:"16",rx:"2"}),h("path",{d:"M6.5 9h11M6.5 12.5h11"}),h("rect",{x:"6.5",y:"15",width:"6.5",height:"2.6",rx:"1.3"})]}),LogoBlock:h(t,{children:h("path",{d:"M12 3.5l7.5 3.2v5.1c0 4.2-3.2 7.1-7.5 8.7-4.3-1.6-7.5-4.5-7.5-8.7V6.7z"})}),Spacer:e(t,{children:[h("path",{d:"M12 4v6M9.5 6.5L12 4l2.5 2.5M12 20v-6M9.5 17.5L12 20l2.5-2.5"}),h("path",{d:"M5 13h14",strokeDasharray:"2 2.5"})]}),ContactRouting:e(t,{children:[h("rect",{x:"3",y:"4",width:"5",height:"5",rx:"1"}),h("rect",{x:"9.5",y:"4",width:"5",height:"5",rx:"1"}),h("rect",{x:"16",y:"4",width:"5",height:"5",rx:"1"}),h("path",{d:"M4 13.5h11M4 17.5h7"}),h("path",{d:"M17 15l3 2-3 2"})]}),CustomHTML:h("path",{d:"M9 8l-4 4 4 4M15 8l4 4-4 4"})},L=h("rect",{x:"4",y:"4",width:"16",height:"16",rx:"2.5"}),F={footer:M,Footer:M,Divider:x,FooterDivider:x,Banner:a,Flex:n,FooterSocial:w,page:S,chat:B,Heading:y,Text:s,ImageBlock:c,ButtonBlock:g,Grid:k,ProductRef:p,heroMedia:u,heroImage:c,heroImage2:c},v={MenuBlock:"FooterMenu",EmailFormBlock:"FooterEmailSignup",SocialLogosBlock:"FooterSocial",SiteHeader:"header",SiteFooter:"footer"};function H({type:i,size:r=16,className:d}){const o=v[i]??i,l=F[o];return l?h(l,{size:r,className:d}):h("svg",{width:r,height:r,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.7,strokeLinecap:"round",strokeLinejoin:"round",className:d,"aria-hidden":"true",children:m[o]??L})}export{H as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function SiteRestoreNotice(): import("react").JSX.Element | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import{useState as c}from"react";import{Banner as m,Button as h}from"efficient-shell/ui";import{UndoIcon as p}from"efficient-shell/icons/efficient";import{useScreenDocument as y}from"efficient-easel/screen/components/ScreenDocumentContext";import{say as r}from"../../format/lib/editor-words.js";import{clearRestoreNote as v,undoSiteRestore as S,useRestoreNote as g}from"../lib/site-versions.js";function P(){const t=g(),{adapter:l,flushSave:d,reloadFromServer:u}=y(),o=l.siteVersions,[n,s]=c(!1),[i,a]=c(!1);if(!t)return null;const f=async()=>{if(!(!o||n)){s(!0),a(!1);try{await S({access:o,flushSave:d,reload:u})}catch{a(!0)}finally{s(!1)}}};return e("aside",{className:"sf-canvas-notice",children:e(m,{tone:i?"danger":"info",title:t.title,onDismiss:v,action:o&&t.undo?e(h,{variant:"secondary",size:"sm",leftIcon:e(p,{}),loading:n,disabled:n,onClick:()=>{f()},children:r("Undo")}):void 0,children:i?r("Undo did not work. Nothing changed. Try again."):r("Check it with Preview. Press Publish to put it live.")})})}export{P as SiteRestoreNotice};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type SiteVersion, type SiteVersionsAccess } from "../lib/site-versions.js";
|
|
2
|
+
export declare function RestoreVersionDialog({ version, page, waiting, busy, error, onCancel, onConfirm, onPage, }: {
|
|
3
|
+
version: SiteVersion | null;
|
|
4
|
+
page: {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
} | null;
|
|
8
|
+
waiting: boolean;
|
|
9
|
+
busy: boolean;
|
|
10
|
+
error: string | null;
|
|
11
|
+
onCancel: () => void;
|
|
12
|
+
onConfirm: () => void;
|
|
13
|
+
onPage: (id: string) => void;
|
|
14
|
+
}): import("react").JSX.Element | null;
|
|
15
|
+
export declare function VersionHistoryDrawer({ open, onClose, access, waiting, }: {
|
|
16
|
+
open: boolean;
|
|
17
|
+
onClose: () => void;
|
|
18
|
+
access: SiteVersionsAccess;
|
|
19
|
+
waiting: boolean;
|
|
20
|
+
}): import("react").JSX.Element;
|
|
21
|
+
export declare function VersionHistory(): import("react").JSX.Element | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as u,Fragment as N}from"react/jsx-runtime";import{useCallback as W,useEffect as q,useId as D,useRef as J,useState as g}from"react";import{Avatar as Q,Banner as S,Button as k,ColoredBadge as z,Dialog as L,Drawer as X,DropdownMenu as Z,FormField as _,iconButtonClasses as ee,Inline as E,Input as ne,ListRow as te,Select as re,SortableList as oe,Stack as P}from"efficient-shell/ui";import{EditIcon as ae,EyeIcon as H,MenuIcon as se,MoreIcon as ie,PageIcon as Y,RevertIcon as j,StylesIcon as le}from"efficient-shell/icons/efficient";import{useScreenDocument as M}from"efficient-easel/screen/components/ScreenDocumentContext";import{say as n,sayCount as A}from"../../format/lib/editor-words.js";import{useSiteLiveState as ce}from"../lib/site-live-state.js";import{changeLine as de,closeVersionHistory as ue,HeldEditsNotSaved as he,changesSummary as ge,restoreSiteVersion as pe,useVersionHistoryOpen as fe,versionTitle as me,versionWhen as ye}from"../lib/site-versions.js";const we={page:Y,menu:se};function be(t,o){return t.pages.find(r=>r.id===o)??t.pages[0]??null}function ve(t,o){const r=window.open("","_blank");if(r)try{r.opener=null}catch{}return t.preview(o).then(({url:s})=>{r&&!r.closed?r.location.href=s:window.open(s,"_blank","noopener,noreferrer")},s=>{throw r?.close(),s})}function ke({version:t,page:o,waiting:r,busy:s,error:p,onCancel:b,onConfirm:y,onPage:i}){const l=D();if(!t)return null;const f=t.kind==="draft_before_restore",c=t.number,d=ge(t),v=f?n("Put your drafts back?"):o?n("Restore {page} from version {n}?",{page:o.name,n:c}):n("Restore version {n}?",{n:c}),m=f?n("Your drafts go back to how they were before the restore."):o?n("{page} goes back to version {n} as a draft. Nothing else on your website changes.",{page:o.name,n:c}):d?n("The whole website goes back to version {n} as a draft: {what}.",{n:c,what:d}):n("The whole website goes back to version {n} as a draft.",{n:c}),h=t.deletedPictures??0;return e(L,{open:!0,onClose:()=>{s||b()},size:"sm",title:v,footer:u(N,{children:[e(k,{variant:"secondary",onClick:b,disabled:s,children:n("Cancel")}),e(k,{onClick:y,loading:s,disabled:s,children:n("Restore as draft")})]}),children:u(P,{gap:4,children:[o&&t.pages.length>1?e(_,{label:n("Page"),htmlFor:l,children:e(re,{id:l,value:o.id,options:t.pages.map(C=>({value:C.id,label:C.name})),onChange:i,disabled:s})}):null,e("p",{children:m}),e("p",{children:n("Your live website does not change until you press Publish.")}),h>0?e(S,{tone:"warning",children:A("{n} picture in this version was deleted from the media library. It stays empty.","{n} pictures in this version were deleted from the media library. They stay empty.",h)}):null,r?e(S,{tone:"info",title:n("Your unpublished changes are kept"),children:n("They are saved in Version history as “Draft before restore”, so you can get them back.")}):null,p?e(S,{tone:"danger",children:p}):null]})})}function Ce({version:t,onCancel:o,onSave:r}){const s=D(),[p,b]=g(null),[y,i]=g(""),[l,f]=g(!1),[c,d]=g(null);if(t!==p&&(b(t),i(t?.name??""),d(null)),!t)return null;const v=y.trim()===t.name,m=async()=>{if(!(l||v)){f(!0),d(null);try{await r(y.trim())}catch{d(n("The name was not saved. Try again."))}finally{f(!1)}}};return e(L,{open:!0,onClose:()=>{l||o()},size:"sm",title:n("Name this version"),footer:u(N,{children:[e(k,{variant:"secondary",onClick:o,disabled:l,children:n("Cancel")}),e(k,{onClick:()=>{m()},loading:l,disabled:l||v,children:n("Save")})]}),children:e(_,{label:n("Name"),htmlFor:s,hint:n("Named versions are always kept. Leave it empty to take the name away."),error:c??void 0,children:e(ne,{id:s,value:y,invalid:!!c,onChange:h=>i(h.target.value),onKeyDown:h=>{h.key==="Enter"&&m()}})})})}function Ne({version:t,expanded:o,onToggle:r,onPreview:s,onRestore:p,onRestorePage:b,onName:y}){const i=t.kind==="draft_before_restore",l=!t.live,f=t.changes.length,c=[...i?[]:[{key:"preview",label:n("Preview"),icon:e(H,{}),onSelect:s}],...l?[{key:"restore",label:i?n("Put these drafts back"):n("Restore whole website"),icon:e(j,{}),onSelect:p}]:[],...l&&!i&&t.pages.length?[{key:"restore-page",label:n("Restore one page only"),icon:e(Y,{}),onSelect:b}]:[],...i?[]:[{type:"divider",key:"divider"},{key:"name",label:n("Name this version"),icon:e(ae,{}),onSelect:y}]];return e(te,{title:u("span",{className:"sf-version-title",children:[e("span",{children:me(t)}),t.live?e(z,{tone:"success",size:"xs",children:n("Live")}):null,t.name?e(z,{tone:"neutral",size:"xs",children:n("Version {n}",{n:t.number})}):null,i?e(z,{tone:"warning",size:"xs",children:n("Not published")}):null]}),expanded:o,onToggle:r,actions:e(Z,{align:"end","aria-label":n("More"),items:c,triggerClassName:ee({variant:"ghost",size:"sm"}),trigger:e(ie,{})}),below:u(P,{gap:3,children:[u(E,{gap:2,align:"center",wrap:!0,className:"sf-version-meta",children:[e(Q,{name:t.createdBy,size:"xs"}),e("span",{children:t.createdBy}),e("span",{"aria-hidden":"true",children:"·"}),e("span",{children:ye(t.createdAt)}),f?u(N,{children:[e("span",{"aria-hidden":"true",children:"·"}),e("span",{children:A("{n} change","{n} changes",f)})]}):null]}),o?u(P,{gap:3,children:[f?e(P,{gap:2,children:t.changes.map(d=>{const v=we[d.kind]??le;return u(E,{gap:2,align:"center",children:[e(v,{size:16}),e("span",{children:de(d)})]},`${d.kind}:${d.id}`)})}):null,u(E,{gap:2,children:[i?null:e(k,{variant:"secondary",size:"sm",leftIcon:e(H,{}),onClick:s,children:n("Preview")}),l?e(k,{variant:"secondary",size:"sm",leftIcon:e(j,{}),onClick:p,children:n("Restore")}):null]})]}):null]})})}function Se({open:t,onClose:o,access:r,waiting:s}){const{flushSave:p,reloadFromServer:b,docId:y}=M(),[i,l]=g(null),[f,c]=g(!1),[d,v]=g(null),[m,h]=g(null),[C,F]=g(!1),[G,I]=g(null),[B,T]=g(null),[O,V]=g(!1),x=J(0),R=W(()=>{const a=++x.current;c(!1),r.list().then(w=>{a===x.current&&l(w)},()=>{a===x.current&&c(!0)})},[r]);q(()=>{t&&R()},[t,R]);const $=a=>{V(!1),ve(r,a.id).catch(()=>V(!0))},K=async()=>{if(!(!m||C)){F(!0),I(null);try{await pe({access:r,version:m.version,page:m.page,flushSave:p,reload:b}),h(null),o()}catch(a){I(a instanceof he?n("Your last changes did not save, so nothing was restored. Try again."):n("The version was not restored. Nothing changed. Try again."))}finally{F(!1)}}};return u(N,{children:[e(X,{open:t,onClose:o,side:"right",size:"md",title:n("Version history"),description:u(N,{children:[n("Every Publish keeps a copy of the whole website: pages, menus and site styles.")," ",n("Products, prices and forms always show as they are now.")]}),footer:e("span",{className:"sf-version-foot",children:n("The newest 30 are kept. Named versions are always kept.")}),children:u(P,{gap:3,children:[O?e(S,{tone:"danger",onDismiss:()=>V(!1),children:n("The preview did not open. Try again.")}):null,f?e(S,{tone:"danger",action:e(k,{variant:"secondary",size:"sm",onClick:R,children:n("Try again")}),children:n("Version history did not load.")}):i===null?e("p",{className:"sf-version-foot",children:n("Loading versions")}):i.length===0?e("p",{className:"sf-version-foot",children:n("No versions yet. Every Publish from now on keeps one.")}):e(oe,{"aria-label":n("Versions"),spacing:"comfortable",children:i.map(a=>e(Ne,{version:a,expanded:d===a.id,onToggle:()=>v(w=>w===a.id?null:a.id),onPreview:()=>$(a),onRestore:()=>{I(null),h({version:a,page:null})},onRestorePage:()=>{I(null),h({version:a,page:be(a,y)})},onName:()=>T(a)},a.id))})]})}),e(ke,{version:m?.version??null,page:m?.page??null,waiting:s,busy:C,error:G,onCancel:()=>h(null),onConfirm:()=>{K()},onPage:a=>h(w=>w&&{...w,page:w.version.pages.find(U=>U.id===a)??w.page})}),e(Ce,{version:B,onCancel:()=>T(null),onSave:async a=>{await r.name(B.id,a),T(null),R()}})]})}function Fe(){const{adapter:t,hasUnsavedEdits:o}=M(),r=t.siteVersions,s=fe(),p=ce();return r?e(Se,{open:s,onClose:ue,access:r,waiting:o||p?.state==="changed"}):null}export{ke as RestoreVersionDialog,Fe as VersionHistory,Se as VersionHistoryDrawer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{jsx as n,Fragment as A,jsxs as C}from"react/jsx-runtime";import{useCallback as k,useEffect as h,useRef as X,useState as J}from"react";import{Button as Q,Tooltip as $}from"efficient-shell/ui";import{SettingsSwitch as ee}from"efficient-easel/panel";import{PagesIcon as te,StylesIcon as oe}from"efficient-easel/rail";import{PaletteIcon as re}from"efficient-shell/icons/efficient";import{TemplateIcon as ne}from"efficient-easel/icons";import{Subtree as ie,TreeRow as B}from"efficient-easel/tree";import{useEasel as se}from"efficient-easel/easel";import{useEaselStrings as y}from"efficient-easel/strings";import{LocationsTreeContext as ae}from"./LocationsTreeContext.js";import ce from"./PagesPanel.js";import{usePreviewChat as de}from"./PreviewChatContext.js";import{PREVIEW_DEVICES as le}from"./preview-devices.js";import{PreviewDeviceContext as pe}from"efficient-easel/draw/client";import{usePreviewHeader as me}from"../../render/components/PreviewHeaderContext.js";import{usePreviewSocial as fe}from"../../render/components/PreviewSocialContext.js";import{usePreviewSurface as ue}from"./PreviewSurfaceContext.js";import{TICKER_PART_LABEL as Se,usePreviewTicker as Ee}from"../../render/components/PreviewTickerContext.js";import{usePreviewHeroPart as we}from"../../render/components/PreviewHeroPartContext.js";import{HERO_MEDIA_PARTS as Pe,HERO_PART_MODE as N,heroMediaRows as Te,heroPartId as H,readHeroPartId as be}from"../../render/lib/puck/hero-media-parts.js";import he,{CHAT_MODE as ge,HEADER_MODE as D,SOCIAL_MODE as Ie,WEBSITE_MODE as W}from"./SectionEditor.js";import L from"./SectionIcon.js";import ve from"./SectionThumbnail.js";import{useScreenDocument as R}from"efficient-easel/screen/components/ScreenDocumentContext";import ke from"./StylesPanel.js";import{LOCATIONS_TYPE as _e,useLocationsTree as Ce}from"./useLocationsTree.js";import{usePinnedChromeSeed as Le}from"./usePinnedChromeSeed.js";import{usePreviewHref as Re}from"./usePreviewHref.js";import{WebsitePreviewButton as Oe}from"./WebsitePreviewButton.js";import{SITE_STYLES_TABS as Ae,SITE_STYLES_TEXT_TAB as Be,useWebsiteName as ye}from"./WebsiteSettingsPanel.js";import{useWebsiteMainAction as Ne}from"./useWebsiteMainAction.js";import{useEaselSession as He}from"efficient-easel/screen/lib/session-context";import{useOpenPageName as De}from"../lib/page-rows.js";import{HERO_GROUP_TYPE as We,heroGroupNestDepth as Me}from"../../format/lib/hero-group-placement.js";import{stripMarkup as Ve}from"../../format/lib/markup.js";import{categoryShortLabel as xe,PINNED_SECTION_TYPE as Ye}from"../lib/puck/add-palette.js";import{canAddTo as Ge}from"../lib/puck/add-target.js";import{blockIsOffered as Fe}from"../lib/puck/block-offer.js";import{sectionIdOfBoxZone as ze,setBookingPreview as Ke}from"../../render/lib/puck/booking-preview.js";import{footerBlockRowName as je}from"../../format/lib/puck/footer-block-row-name.js";import{FOOTER_TYPE as Ue,HEADER_TYPE as M}from"../lib/puck/footer-blocks.js";import{leftViewForSelection as Ze,readLeftView as qe,resolveLeftView as Xe,writeLeftView as Je}from"../../format/lib/puck/left-view.js";import{websiteIsLockedBlock as Qe}from"../lib/puck/locked-blocks.js";import{everyPageBadge as $e,everyPageNotice as et,pinnedGroupTab as tt,websiteDuplicateBlocked as ot}from"../lib/puck/every-page.js";import{pinnedChromeInPlace as _}from"../../format/lib/pinned-chrome-lock.js";import{scrollPreviewToSection as rt,scrollPreviewToTop as V}from"efficient-easel/screen/lib/puck/preview-dom";import{SiteCanvas as nt}from"../lib/puck/overrides.js";import{labelAtLevel as it}from"../../format/lib/puck/section-catalog.js";import{editorWords as st,say as c}from"../../format/lib/editor-words.js";import{SECTION_DESCRIPTIONS as at}from"../../format/lib/puck/section-descriptions.js";import{groupAccepts as ct,isSectionGroupType as dt,sectionGroupZone as lt,SITE_FOOTER_TYPE as pt,SITE_HEADER_TYPE as mt}from"../../format/lib/puck/section-groups.js";import{resolveSaveAsTemplateAction as ft,SAVE_AS_TEMPLATE_EVENT as ut}from"../../format/lib/save-as-template-action.js";import{newSectionNode as St}from"../lib/sections/new-section-node.js";import{useHostProducts as Et}from"../lib/use-host-products.js";import{backendOf as wt}from"../lib/website-session.js";function x({mode:e,open:t}){const{setSelectedHeroId:o,setSelectHandler:r}=Ee(),d=y().tree,l=e,p=l.kind==="ticker"?l.heroId:null,a=k(i=>{if(!i)return;t({kind:"ticker",heroId:i}),rt(i)},[t]);return h(()=>{o(p)},[p,o]),h(()=>{r(a)},[r,a]),{partRows:(i,{rowClick:u})=>{const m=String(i.props.id);return i.type==="Hero"&&n(B,{icon:n(L,{type:"ticker",size:13}),name:c(Se),onSelect:()=>a(m),selected:p===m,rowProps:{onClick:u(()=>a(m))},words:d})}}}function Y({mode:e,select:t}){const{setSelectedHeroPart:o,setSelectHandler:r}=we(),d=y().tree,{appState:l}=se(f=>f),p=l.data.content??[],a=X(p);a.current=p;const i=e,u=Pe.find(f=>N[f]===i.kind),m=u&&"nodeId"in i?H(String(i.nodeId),u):null,w=k(f=>{const s=be(f);if(!s)return;const P=a.current.findIndex(S=>String(S.props.id)===s.nodeId);if(P<0)return;const b={kind:N[s.part],nodeId:s.nodeId};t({index:P},b)},[t]);return h(()=>{o(m)},[m,o]),h(()=>{r(w)},[r,w]),{partRows:(f,{rowClick:s})=>{const P=String(f.props.id),b=Te(f);if(b.length===0)return null;const S=I=>{const g=H(P,I.part);return n(B,{icon:n(L,{type:I.part==="media"?"heroMedia":"heroImage",size:13}),name:c(I.label),onSelect:()=>w(g),selected:m===g,rowProps:{onClick:s(()=>w(g))},words:d},g)},[E,...T]=b;return C(A,{children:[S(E),T.length>0&&n(ie,{children:T.map(S)})]})}}}function G(e,t){return{partRows:(o,r)=>C(A,{children:[e.partRows?.(o,r),t.partRows?.(o,r)]})}}function Pt(e){const{adapter:t,capabilities:o,currentSlug:r,siteId:d,docId:l,hasUnsavedEdits:p,bridgeCapabilities:a,notifyParent:i,token:u}=R(),{hasPreviewLink:m}=o,w=wt(He()).preview?.draftLink,f=Ne(e.data),s=ft({hasTrustedConsole:!!u,canCreatePlatformTemplate:a.canCreatePlatformTemplate,capabilities:o,siteId:d,hasUnsavedEdits:p}),P=k(()=>{!d||!r||i(ut,{siteId:d,slug:r})},[i,d,r]),b=Re({pageSlug:r,siteId:d,token:u}),S=t.previewHref?.(r)??b;return{barLead:()=>s.visible&&n($,{side:"bottom",content:s.enabled?c("Save this website as a platform template"):c(s.disabledReason),children:n("span",{className:"sf-tip-disabled",tabIndex:s.enabled?void 0:0,children:n(Q,{variant:"secondary",disabled:!s.enabled,onClick:P,rightIcon:n(ne,{size:15}),children:c("Save as Template")})})}),barTrail:()=>m&&r&&n(Oe,{liveHref:S,pageId:l??null,draftLink:w}),mainAction:f}}function Tt(e,t){const{capabilities:o,templateId:r,siteId:d,tokenRef:l,navigate:p}=R(),{hasSiteTheme:a,explainsSiteSettings:i}=o,u=E=>t.setView(E),[m,w]=J(Ae[0].id),{surface:f,setSurface:s}=ue(),P=()=>{if(a){u("styles"),t.reveal(),V();return}e.show(W),e.reveal(),V()},b={id:"pages",label:c("Pages"),icon:n(te,{}),panel:({onHide:E})=>n(ce,{activeSurface:f,onPreviewSurface:s,onNavigate:T=>{s(null),p(r?{kind:"template",id:r,pageSlug:T}:{kind:"page",slug:T,siteId:d??void 0})},onClose:E})},S=[];return!a&&i&&S.push({id:"appearance",label:c("Appearance"),icon:n(re,{}),active:e.kind==="website",onSelect:P}),a&&S.push({id:"styles",label:c("Site styles"),icon:n(oe,{}),panel:({onHide:E,notify:T})=>n(ke,{tokenRef:l,siteId:d??void 0,onClose:E,onNotify:T,tab:m,onTabChange:w})}),{railLead:[b],railTrail:S,resolveLeftView:(E,T)=>Xe(E,a,T),openSettings:P,openStyles:()=>{w(Be),u("styles")}}}function bt(e,t,o,r){const{kind:d,open:l}=e,{selected:p,zoneOf:a}=t;h(()=>{Ke(p?.type==="BookingBox"&&p.props.region==="confirm"?ze(a(String(p.props.id))):null)},[p?.props.id]);const i=Ce(e,t),{capabilities:{hasSiteSettings:u}}=R(),{setSelected:m,setSelectHandler:w}=me(),{chat:f,setChat:s,setSelected:P,setSelectHandler:b}=de(),S=d==="header";h(()=>{m(S)},[S,m]),h(()=>{w(()=>l(D))},[w,l]);const E=k(()=>l(ge),[l]),T=d==="chat";h(()=>{P(T)},[T,P]),h(()=>{b(E)},[b,E]);const{setOpenHandler:I}=fe(),g=k(()=>l(Ie),[l]);h(()=>{I(g)},[I,g]);const K=G(x(e),Y(e)),j=Pt(t),U=Tt(e,r),Z=o.device;return{...K,...j,...U,hasOwnRows:v=>v.type===_e,ownRows:i.renderLocationTree,sectionPressed:i.sectionPressed,wrap:v=>n(ae.Provider,{value:!0,children:n(pe.Provider,{value:Z,children:v})}),addPanelRow:v=>u?C("div",{className:"sf-addside-sitewide",children:[n("span",{className:"sf-addside-sitewide-glyph","aria-hidden":"true",children:n(L,{type:"chat",size:16})}),C("button",{type:"button",className:"sf-addside-sitewide-name",onClick:()=>{v(),E()},children:[c("Live chat"),n("span",{className:"sf-addside-sitewide-desc",children:c("A chat bubble on every page")})]}),n(ee,{checked:f.enabled,onChange:q=>s({enabled:q}),ariaLabel:c("Show the chat bubble on the whole site")})]}):void 0}}let F=null,O=new WeakMap;function ht(e){const t=st();if(!e||!t)return e;F!==t&&(F=t,O=new WeakMap);let o=O.get(e);return o||(o={...e,choices:e.choices?e.choices.map(r=>({...r,label:c(r.label)})):null,spec:e.spec?{...e.spec,addLabel:c(e.spec.addLabel)}:null},O.set(e,o)),o}const gt={isLockedBlock:Qe,duplicateBlocked:ot,nestDepth:(e,t,o)=>t===We?Me(e,o):0,newSectionNode:St,canAddTo:(e,t)=>ht(Ge(e,t)),blockIsOffered:Fe},It=new Proxy(at,{get:(e,t)=>{const o=Reflect.get(e,t);return typeof o=="string"?c(o):o}}),vt={labelAtLevel:(e,t,o)=>c(it(e,t,o)),descriptions:It,categoryLabel:e=>{const t=xe(e);return t===void 0?void 0:c(t)},firstSection:Ye,blockRowName:je,plainText:Ve,Icon:L,Thumbnail:ve,useProducts:Et},kt={desktop:2e3,tablet:800,mobile:390},z="desktop",_t={options:le,initial:z,fluid:z,widths:kt},Ct={read:qe,write:e=>Je(e),forSelection:(e,t)=>Ze(e,t)},Lt={first:M,last:Ue,firstGroup:mt,lastGroup:pt,isSectionGroup:dt,sectionGroupZone:lt,panelOf:e=>e===M?D:null,get groupTab(){return _()?tt:void 0},get groupBadge(){return _()?$e():void 0},get changeNotice(){return _()?et():void 0},get band(){return _()?Rt:void 0},get groupAccepts(){return _()?ct:void 0}},Rt={foldable:!0};function Ot(e){return{...G(x(e),Y(e)),openSettings:()=>e.show(W)}}const No={useOwnerName:ye,useDocumentLabel:De,useBridges:bt,useStandaloneBridges:Ot,useDocumentPass:Le,blockRules:gt,blockLook:vt,devices:_t,leftView:Ct,pinned:Lt,Canvas:nt,Inspector:he};export{No as WEBSITE_SCREEN};
|
|
1
|
+
"use client";import{jsx as n,Fragment as A,jsxs as k}from"react/jsx-runtime";import{useCallback as _,useEffect as h,useRef as X,useState as J}from"react";import{Button as Q,Tooltip as $}from"efficient-shell/ui";import{SettingsSwitch as ee}from"efficient-easel/panel";import{PagesIcon as te,StylesIcon as oe}from"efficient-easel/rail";import{PaletteIcon as re}from"efficient-shell/icons/efficient";import{TemplateIcon as ne}from"efficient-easel/icons";import{Subtree as ie,TreeRow as B}from"efficient-easel/tree";import{useEasel as se}from"efficient-easel/easel";import{useEaselStrings as y}from"efficient-easel/strings";import{LocationsTreeContext as ae}from"./LocationsTreeContext.js";import ce from"./PagesPanel.js";import{usePreviewChat as de}from"./PreviewChatContext.js";import{PREVIEW_DEVICES as le}from"./preview-devices.js";import{PreviewDeviceContext as pe}from"efficient-easel/draw/client";import{usePreviewHeader as me}from"../../render/components/PreviewHeaderContext.js";import{usePreviewSocial as fe}from"../../render/components/PreviewSocialContext.js";import{usePreviewSurface as ue}from"./PreviewSurfaceContext.js";import{TICKER_PART_LABEL as Se,usePreviewTicker as Ee}from"../../render/components/PreviewTickerContext.js";import{usePreviewHeroPart as we}from"../../render/components/PreviewHeroPartContext.js";import{HERO_MEDIA_PARTS as Pe,HERO_PART_MODE as H,heroMediaRows as Te,heroPartId as N,readHeroPartId as be}from"../../render/lib/puck/hero-media-parts.js";import he,{CHAT_MODE as ge,HEADER_MODE as D,SOCIAL_MODE as Ie,WEBSITE_MODE as W}from"./SectionEditor.js";import L from"./SectionIcon.js";import ve from"./SectionThumbnail.js";import{useScreenDocument as R}from"efficient-easel/screen/components/ScreenDocumentContext";import ke from"./StylesPanel.js";import{LOCATIONS_TYPE as _e,useLocationsTree as Ce}from"./useLocationsTree.js";import{usePinnedChromeSeed as Le}from"./usePinnedChromeSeed.js";import{usePreviewHref as Re}from"./usePreviewHref.js";import{WebsitePreviewButton as Oe}from"./WebsitePreviewButton.js";import{SITE_STYLES_TABS as Ae,SITE_STYLES_TEXT_TAB as Be,useWebsiteName as ye}from"./WebsiteSettingsPanel.js";import{useWebsiteMainAction as He}from"./useWebsiteMainAction.js";import{VersionHistory as Ne}from"./VersionHistoryDrawer.js";import{useEaselSession as De}from"efficient-easel/screen/lib/session-context";import{useOpenPageName as We}from"../lib/page-rows.js";import{HERO_GROUP_TYPE as Ve,heroGroupNestDepth as Me}from"../../format/lib/hero-group-placement.js";import{stripMarkup as xe}from"../../format/lib/markup.js";import{categoryShortLabel as Ye,PINNED_SECTION_TYPE as Ge}from"../lib/puck/add-palette.js";import{canAddTo as Fe}from"../lib/puck/add-target.js";import{blockIsOffered as ze}from"../lib/puck/block-offer.js";import{sectionIdOfBoxZone as Ke,setBookingPreview as je}from"../../render/lib/puck/booking-preview.js";import{footerBlockRowName as Ue}from"../../format/lib/puck/footer-block-row-name.js";import{FOOTER_TYPE as Ze,HEADER_TYPE as V}from"../lib/puck/footer-blocks.js";import{leftViewForSelection as qe,readLeftView as Xe,resolveLeftView as Je,writeLeftView as Qe}from"../../format/lib/puck/left-view.js";import{websiteIsLockedBlock as $e}from"../lib/puck/locked-blocks.js";import{everyPageBadge as et,everyPageNotice as tt,pinnedGroupTab as ot,websiteDuplicateBlocked as rt}from"../lib/puck/every-page.js";import{pinnedChromeInPlace as C}from"../../format/lib/pinned-chrome-lock.js";import{scrollPreviewToSection as nt,scrollPreviewToTop as M}from"efficient-easel/screen/lib/puck/preview-dom";import{SiteCanvas as it}from"../lib/puck/overrides.js";import{labelAtLevel as st}from"../../format/lib/puck/section-catalog.js";import{editorWords as at,say as c}from"../../format/lib/editor-words.js";import{SECTION_DESCRIPTIONS as ct}from"../../format/lib/puck/section-descriptions.js";import{groupAccepts as dt,isSectionGroupType as lt,sectionGroupZone as pt,SITE_FOOTER_TYPE as mt,SITE_HEADER_TYPE as ft}from"../../format/lib/puck/section-groups.js";import{resolveSaveAsTemplateAction as ut,SAVE_AS_TEMPLATE_EVENT as St}from"../../format/lib/save-as-template-action.js";import{newSectionNode as Et}from"../lib/sections/new-section-node.js";import{useHostProducts as wt}from"../lib/use-host-products.js";import{backendOf as Pt}from"../lib/website-session.js";function x({mode:e,open:t}){const{setSelectedHeroId:o,setSelectHandler:r}=Ee(),d=y().tree,l=e,p=l.kind==="ticker"?l.heroId:null,a=_(i=>{if(!i)return;t({kind:"ticker",heroId:i}),nt(i)},[t]);return h(()=>{o(p)},[p,o]),h(()=>{r(a)},[r,a]),{partRows:(i,{rowClick:u})=>{const m=String(i.props.id);return i.type==="Hero"&&n(B,{icon:n(L,{type:"ticker",size:13}),name:c(Se),onSelect:()=>a(m),selected:p===m,rowProps:{onClick:u(()=>a(m))},words:d})}}}function Y({mode:e,select:t}){const{setSelectedHeroPart:o,setSelectHandler:r}=we(),d=y().tree,{appState:l}=se(f=>f),p=l.data.content??[],a=X(p);a.current=p;const i=e,u=Pe.find(f=>H[f]===i.kind),m=u&&"nodeId"in i?N(String(i.nodeId),u):null,w=_(f=>{const s=be(f);if(!s)return;const P=a.current.findIndex(S=>String(S.props.id)===s.nodeId);if(P<0)return;const b={kind:H[s.part],nodeId:s.nodeId};t({index:P},b)},[t]);return h(()=>{o(m)},[m,o]),h(()=>{r(w)},[r,w]),{partRows:(f,{rowClick:s})=>{const P=String(f.props.id),b=Te(f);if(b.length===0)return null;const S=I=>{const g=N(P,I.part);return n(B,{icon:n(L,{type:I.part==="media"?"heroMedia":"heroImage",size:13}),name:c(I.label),onSelect:()=>w(g),selected:m===g,rowProps:{onClick:s(()=>w(g))},words:d},g)},[E,...T]=b;return k(A,{children:[S(E),T.length>0&&n(ie,{children:T.map(S)})]})}}}function G(e,t){return{partRows:(o,r)=>k(A,{children:[e.partRows?.(o,r),t.partRows?.(o,r)]})}}function Tt(e){const{adapter:t,capabilities:o,currentSlug:r,siteId:d,docId:l,hasUnsavedEdits:p,bridgeCapabilities:a,notifyParent:i,token:u}=R(),{hasPreviewLink:m}=o,w=Pt(De()).preview?.draftLink,f=He(e.data),s=ut({hasTrustedConsole:!!u,canCreatePlatformTemplate:a.canCreatePlatformTemplate,capabilities:o,siteId:d,hasUnsavedEdits:p}),P=_(()=>{!d||!r||i(St,{siteId:d,slug:r})},[i,d,r]),b=Re({pageSlug:r,siteId:d,token:u}),S=t.previewHref?.(r)??b;return{barLead:()=>s.visible&&n($,{side:"bottom",content:s.enabled?c("Save this website as a platform template"):c(s.disabledReason),children:n("span",{className:"sf-tip-disabled",tabIndex:s.enabled?void 0:0,children:n(Q,{variant:"secondary",disabled:!s.enabled,onClick:P,rightIcon:n(ne,{size:15}),children:c("Save as Template")})})}),barTrail:()=>m&&r&&n(Oe,{liveHref:S,pageId:l??null,draftLink:w}),mainAction:f}}function bt(e,t){const{capabilities:o,templateId:r,siteId:d,tokenRef:l,navigate:p}=R(),{hasSiteTheme:a,explainsSiteSettings:i}=o,u=E=>t.setView(E),[m,w]=J(Ae[0].id),{surface:f,setSurface:s}=ue(),P=()=>{if(a){u("styles"),t.reveal(),M();return}e.show(W),e.reveal(),M()},b={id:"pages",label:c("Pages"),icon:n(te,{}),panel:({onHide:E})=>n(ce,{activeSurface:f,onPreviewSurface:s,onNavigate:T=>{s(null),p(r?{kind:"template",id:r,pageSlug:T}:{kind:"page",slug:T,siteId:d??void 0})},onClose:E})},S=[];return!a&&i&&S.push({id:"appearance",label:c("Appearance"),icon:n(re,{}),active:e.kind==="website",onSelect:P}),a&&S.push({id:"styles",label:c("Site styles"),icon:n(oe,{}),panel:({onHide:E,notify:T})=>n(ke,{tokenRef:l,siteId:d??void 0,onClose:E,onNotify:T,tab:m,onTabChange:w})}),{railLead:[b],railTrail:S,resolveLeftView:(E,T)=>Je(E,a,T),openSettings:P,openStyles:()=>{w(Be),u("styles")}}}function ht(e,t,o,r){const{kind:d,open:l}=e,{selected:p,zoneOf:a}=t;h(()=>{je(p?.type==="BookingBox"&&p.props.region==="confirm"?Ke(a(String(p.props.id))):null)},[p?.props.id]);const i=Ce(e,t),{capabilities:{hasSiteSettings:u}}=R(),{setSelected:m,setSelectHandler:w}=me(),{chat:f,setChat:s,setSelected:P,setSelectHandler:b}=de(),S=d==="header";h(()=>{m(S)},[S,m]),h(()=>{w(()=>l(D))},[w,l]);const E=_(()=>l(ge),[l]),T=d==="chat";h(()=>{P(T)},[T,P]),h(()=>{b(E)},[b,E]);const{setOpenHandler:I}=fe(),g=_(()=>l(Ie),[l]);h(()=>{I(g)},[I,g]);const K=G(x(e),Y(e)),j=Tt(t),U=bt(e,r),Z=o.device;return{...K,...j,...U,hasOwnRows:v=>v.type===_e,ownRows:i.renderLocationTree,sectionPressed:i.sectionPressed,wrap:v=>n(ae.Provider,{value:!0,children:k(pe.Provider,{value:Z,children:[v,n(Ne,{})]})}),addPanelRow:v=>u?k("div",{className:"sf-addside-sitewide",children:[n("span",{className:"sf-addside-sitewide-glyph","aria-hidden":"true",children:n(L,{type:"chat",size:16})}),k("button",{type:"button",className:"sf-addside-sitewide-name",onClick:()=>{v(),E()},children:[c("Live chat"),n("span",{className:"sf-addside-sitewide-desc",children:c("A chat bubble on every page")})]}),n(ee,{checked:f.enabled,onChange:q=>s({enabled:q}),ariaLabel:c("Show the chat bubble on the whole site")})]}):void 0}}let F=null,O=new WeakMap;function gt(e){const t=at();if(!e||!t)return e;F!==t&&(F=t,O=new WeakMap);let o=O.get(e);return o||(o={...e,choices:e.choices?e.choices.map(r=>({...r,label:c(r.label)})):null,spec:e.spec?{...e.spec,addLabel:c(e.spec.addLabel)}:null},O.set(e,o)),o}const It={isLockedBlock:$e,duplicateBlocked:rt,nestDepth:(e,t,o)=>t===Ve?Me(e,o):0,newSectionNode:Et,canAddTo:(e,t)=>gt(Fe(e,t)),blockIsOffered:ze},vt=new Proxy(ct,{get:(e,t)=>{const o=Reflect.get(e,t);return typeof o=="string"?c(o):o}}),kt={labelAtLevel:(e,t,o)=>c(st(e,t,o)),descriptions:vt,categoryLabel:e=>{const t=Ye(e);return t===void 0?void 0:c(t)},firstSection:Ge,blockRowName:Ue,plainText:xe,Icon:L,Thumbnail:ve,useProducts:wt},_t={desktop:2e3,tablet:800,mobile:390},z="desktop",Ct={options:le,initial:z,fluid:z,widths:_t},Lt={read:Xe,write:e=>Qe(e),forSelection:(e,t)=>qe(e,t)},Rt={first:V,last:Ze,firstGroup:ft,lastGroup:mt,isSectionGroup:lt,sectionGroupZone:pt,panelOf:e=>e===V?D:null,get groupTab(){return C()?ot:void 0},get groupBadge(){return C()?et():void 0},get changeNotice(){return C()?tt():void 0},get band(){return C()?Ot:void 0},get groupAccepts(){return C()?dt:void 0}},Ot={foldable:!0};function At(e){return{...G(x(e),Y(e)),openSettings:()=>e.show(W)}}const Do={useOwnerName:ye,useDocumentLabel:We,useBridges:ht,useStandaloneBridges:At,useDocumentPass:Le,blockRules:It,blockLook:kt,devices:Ct,leftView:Lt,pinned:Rt,Canvas:it,Inspector:he};export{Do as WEBSITE_SCREEN};
|
|
@@ -1500,7 +1500,7 @@
|
|
|
1500
1500
|
|
|
1501
1501
|
Everything left below is colour the row variant does not touch. */
|
|
1502
1502
|
|
|
1503
|
-
/* ── Left panel: Pages view (
|
|
1503
|
+
/* ── Left panel: Pages view (the page list) ─────────────────────────────── */
|
|
1504
1504
|
.sf-pages {
|
|
1505
1505
|
display: flex;
|
|
1506
1506
|
flex-direction: column;
|
|
@@ -4110,3 +4110,19 @@ input.sf-list-marking {
|
|
|
4110
4110
|
.es-ts + .es-ts-section {
|
|
4111
4111
|
margin-top: var(--es-rhythm-group);
|
|
4112
4112
|
}
|
|
4113
|
+
|
|
4114
|
+
/* Version history (components/VersionHistoryDrawer, 33.0.0): a row's name
|
|
4115
|
+
beside its badges, and the drawer's quiet lines (who, when, how much; the
|
|
4116
|
+
retention line; loading and empty). Layout and ink only; every part is the
|
|
4117
|
+
shell's (Drawer, ListRow, ColoredBadge, Avatar). */
|
|
4118
|
+
.sf-version-title {
|
|
4119
|
+
display: inline-flex;
|
|
4120
|
+
flex-wrap: wrap;
|
|
4121
|
+
align-items: center;
|
|
4122
|
+
gap: var(--space-8);
|
|
4123
|
+
}
|
|
4124
|
+
.sf-version-meta,
|
|
4125
|
+
.sf-version-foot {
|
|
4126
|
+
font-size: var(--text-xs);
|
|
4127
|
+
color: var(--sf-muted);
|
|
4128
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useEffect as
|
|
1
|
+
"use client";import{useEffect as j,useRef as q}from"react";import{createNode as T,newId as I}from"efficient-easel/data";import{useEaselApi as J}from"efficient-easel/easel";import{useScreenDocument as K}from"efficient-easel/screen/components/ScreenDocumentContext";import{useEaselSession as M}from"efficient-easel/screen/lib/session-context";import{SITE_FOOTER_SLUG as L}from"../../format/lib/content/footer.js";import{boxFooterFromFooter as U}from"../../format/lib/puck/box-footer.js";import{ROOT_ZONE as l,missingPinnedTypes as Q,pinnedDuplicateIds as O}from"efficient-easel/draw";import{FOOTER_TYPE as a,HEADER_TYPE as E,buildDefaultFooterBlocks as b,buildDefaultHeaderNode as N}from"../lib/puck/footer-blocks.js";import{canSeedPinnedChrome as V}from"../../format/lib/puck/pinned-seed-gate.js";import{siteFooterDocChrome as W,SITE_FOOTER_TYPE as f}from"../../format/lib/puck/section-groups.js";import{inPlaceSeedPlan as X}from"../lib/puck/pinned-in-place-seed.js";import{seedNewSiteHeader as $}from"../../format/lib/puck/new-site-header-seed.js";import{SITE_HEADER_TYPE as R}from"../../format/lib/puck/section-groups.js";import{blocksOf as ee}from"../lib/website-session.js";function he(t,D){const{adapter:_,capabilities:y,currentSlug:w,docId:S,data:C,saveStatus:H,siteId:v,tokenRef:x}=K(),z=M(),{hasSiteSettings:Y,hasPinnedChrome:A}=y,B=!!y.editsPinnedInPlace&&w!==L,g=w===L,h=J().getState,k=q(null);j(()=>{if(!V({docId:S,saveStatus:H,seededDocId:k.current})||(k.current=S,!A))return;const p=h().appState.data,n=p.content,d=C?.content??[],r=(e,s)=>e.some(i=>i?.type===s);if(!Y){const e=new Set(O(n)),s=e.size?n.filter(c=>!e.has(c.props.id)):n;if(e.size&&t.setDocument({...p,content:s}),g)return;const i=Q(s,d);if(i.includes(a)){const c=s.length,o=t.insertSection(a,c);t.replaceComponent(l,c,{type:a,props:{id:o,blocks:b()}})}i.includes(E)&&t.insertNode(l,0,N());return}if(g){const e=W(n);if(e!==n&&t.setDocument({...p,content:[...e]}),!e.find(i=>i.type===a)&&!r(d,a)&&!r(e,f)&&!r(d,f)){const i=(o,m)=>T(D,o,m),c={type:a,props:{blocks:b()}};t.insertNode(l,e.length,U(c,i,I(f)))}return}if(B){const e=!!_?.pinnedChrome?.state().docId,s=X(n,{hasChromeDoc:e}),i=new Set([...s.remove,...O(n.filter(o=>!s.remove.includes(String(o.props.id))))]),c=i.size?n.filter(o=>!i.has(String(o.props.id))):n;if(c.length!==n.length&&t.setDocument({...p,content:c}),s.seedFooter&&!r(d,a)&&!r(d,f)){const o=(u,Z)=>T(D,u,Z),m={type:a,props:{blocks:b()}};t.insertNode(l,c.length,U(m,o,I(f)))}if(s.seedHeader&&!r(d,E)){const o=c[0]?.type===R?1:0;t.insertNode(l,o,N())}if(s.seedSiteHeader&&!r(d,R)&&!r(d,a)&&!r(d,f)){const o=S;$({blocks:ee(z),make:(m,u)=>T(D,m,u),id:I(R),siteId:v??null,token:x.current,latest:()=>h().appState.data.content,stillOpen:()=>k.current===o,write:m=>{const u=h().appState.data;t.setDocument({...u,content:[...m]})}})}return}const P=n.filter(e=>e.type!==a),G=new Set(O(P)),F=G.size?P.filter(e=>!G.has(e.props.id)):P;F.length!==n.length&&t.setDocument({...p,content:F}),!r(F,E)&&!r(d,E)&&t.insertNode(l,0,N())},[S,H,C,h,t,Y,A,g,B,_,z,v,x])}export{he as usePinnedChromeSeed};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useCallback as
|
|
1
|
+
"use client";import{createElement as L,useCallback as P,useEffect as d,useRef as m,useState as R}from"react";import{ClockIcon as C}from"efficient-shell/icons/efficient";import{useScreenDocument as k}from"efficient-easel/screen/components/ScreenDocumentContext";import{useOpenPinnedChromeReport as E,usePinnedChromeState as I}from"./usePinnedChromeState.js";import{say as V}from"../../format/lib/editor-words.js";import{clearRestoreNote as A,openVersionHistory as D}from"../lib/site-versions.js";import{effectiveLive as H,goingLiveLines as U,mainActionFor as p,usePageLiveState as W}from"../lib/page-live-state.js";import{readSiteLiveStateWith as v,refreshSiteLiveState as w,useSiteLiveState as x}from"../lib/site-live-state.js";function J(i){const{docId:h,capabilities:S,hasUnsavedEdits:r,onPublish:s,adapter:o}=k(),b=H(W(h??null),r),g=I(E()),e=o.siteLiveState;d(()=>{if(e)return v(e),w(0),()=>v(null)},[e]);const t=x(),[u,c]=R(!1),a=m(i);a.current=i;const n=m(!0);d(()=>(n.current=!0,()=>{n.current=!1}),[]);const f=P(()=>{c(!0),s(a.current).then(()=>{A()}).finally(()=>{n.current&&c(!1)})},[s]);if(S.canPublish){if(e){const y=t===void 0?void 0:r||t.state==="changed"?"changed":"live",l=p({live:y,onPress:f,busy:u,goingLive:U(t?.changes??[])});return o.siteVersions?{...l,menuItems:B()}:l}return p({live:b,onPress:f,busy:u,pinnedUnpublished:g?.unpublished??!1})}}function B(){return[{key:"version-history",label:V("Version history"),icon:L(C),onSelect:D}]}export{J as useWebsiteMainAction};
|
|
@@ -7,6 +7,21 @@ export interface EditorBlockCategory {
|
|
|
7
7
|
components: string[];
|
|
8
8
|
before?: string;
|
|
9
9
|
}
|
|
10
|
+
export interface EditorSeedContext {
|
|
11
|
+
make: (type: string, props?: Record<string, unknown>) => {
|
|
12
|
+
type: string;
|
|
13
|
+
props: Record<string, unknown>;
|
|
14
|
+
};
|
|
15
|
+
id: string;
|
|
16
|
+
siteId: string | null;
|
|
17
|
+
token: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface EditorSeeds {
|
|
20
|
+
siteHeader?: (ctx: EditorSeedContext) => Promise<{
|
|
21
|
+
type: string;
|
|
22
|
+
props: Record<string, unknown>;
|
|
23
|
+
} | null>;
|
|
24
|
+
}
|
|
10
25
|
export interface EditorBlocks {
|
|
11
26
|
sets?: readonly BlockSet[];
|
|
12
27
|
allow?: readonly string[];
|
|
@@ -14,6 +29,7 @@ export interface EditorBlocks {
|
|
|
14
29
|
host?: Record<string, ComponentConfig>;
|
|
15
30
|
categories?: EditorBlockCategory[];
|
|
16
31
|
metadata?: Record<string, unknown>;
|
|
32
|
+
seeds?: EditorSeeds;
|
|
17
33
|
}
|
|
18
34
|
export type OfferedSets = Readonly<Record<BlockSet, boolean>>;
|
|
19
35
|
export declare function offeredSets(blocks: EditorBlocks | SessionBlocks | null | undefined): OfferedSets;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { LockHolder, SaveConflict } from "efficient-easel/edit-lock";
|
|
2
2
|
import { type OfferedSets } from "./editor-blocks.js";
|
|
3
3
|
import type { EaselCapabilities as EditorCapabilities, EaselDocument as EditorDocument, EaselDocumentAdapter as EditorDocumentAdapter } from "efficient-easel/screen/lib/document-contract";
|
|
4
|
+
import type { SiteVersionsAccess } from "./site-versions.js";
|
|
4
5
|
import type { EditorPageRow, SiteLiveState, WebsiteBackend } from "../../format/lib/web-backend.js";
|
|
5
6
|
export type { EditorPageRow };
|
|
6
7
|
export type { EditorCapabilities, EditorDocument, EditorDocumentAdapter };
|
|
@@ -23,6 +24,7 @@ export type WebsiteDocumentAdapter = EditorDocumentAdapter & {
|
|
|
23
24
|
capabilities: WebsiteCapabilities;
|
|
24
25
|
pinnedChrome?: PinnedChromeReport;
|
|
25
26
|
siteLiveState?: () => Promise<SiteLiveState>;
|
|
27
|
+
siteVersions?: SiteVersionsAccess;
|
|
26
28
|
};
|
|
27
29
|
export type SitePageAdapterOptions = {
|
|
28
30
|
editsPinnedInPlace?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{SITE_FOOTER_SLUG as g}from"../../format/lib/content/footer.js";import{offeredSetsOf as
|
|
1
|
+
"use client";import{SITE_FOOTER_SLUG as g}from"../../format/lib/content/footer.js";import{offeredSetsOf as O}from"./editor-blocks.js";import{isBackendError as B}from"efficient-easel/screen/lib/backend-error";import{isEfficientBackend as T}from"efficient-easel/screen/lib/session";import{noteLoaded as J,notePublished as V,noteSaved as j,pageLiveState as I}from"./page-live-state.js";import{noteSiteLiveState as _,refreshSiteLiveState as E}from"./site-live-state.js";import{say as D}from"../../format/lib/editor-words.js";import{sendSiteWrites as G}from"../../format/lib/site-writes.js";import{spliceChrome as M,splitChrome as k}from"./pinned-chrome-doc.js";import{setActivePinnedChrome as N}from"../../format/lib/pinned-chrome-lock.js";import{backendOf as R}from"./website-session.js";function F(n){return!!(n?.publish&&n.liveState)}function U(n,o){if(!F(n))return;const{versions:s,nameVersion:r,restoreVersion:t,previewVersion:e}=n;if(!(!s||!r||!t||!e))return{list:()=>s.call(n,o),name:(a,f)=>r.call(n,a,f,o),restore:(a,f)=>t.call(n,a,f??{},o),preview:a=>e.call(n,a,o)}}function W(n,o){return async(s,r)=>{try{await G()}catch(e){throw new Error(D("A change waiting to go live could not be saved."),{cause:e})}return(await n.publish(o)).state==="live"?_({state:"live",changes:[]}):E(0),{version:r??null}}}function L(n,o,s){const r=o?{siteId:o}:void 0;return{resolve:t=>n.load({slug:t,...r}).then(e=>(e&&J(e.id,e.live),e)),saveLayout:(t,e,a,f)=>n.save(t,{layout:e},{version:a,clientId:f??""}).then(m=>(j(t,m.live),E(),m)),rereadVersion:n.version?t=>n.version(t):void 0,publish:F(s)?W(s,r):n.publish?(t,e)=>n.publish(t,e?{version:e}:void 0).then(a=>(V(t,a.live),a)):void 0,listPages:()=>n.list(r),createPage:n.create?t=>n.create({...t,...r}):void 0,deletePage:n.remove?(t,e)=>n.remove(t,e):void 0}}function Y(n,o,s,r,t=!1){let e=null;const a=new Set;let f=!1,m={docId:null,lockHolder:null,conflict:null,saveFailed:!1,unpublished:!1,loadFailed:!1};const P=new Set,p=()=>{if(!e)return!1;const i=I(e.id);return i==="changed"||i==="never"||i===void 0&&f},h=i=>{m={...m,...i,docId:e?.id??null,unpublished:p()};for(const d of P)d()},y=i=>i&&typeof i=="object"&&!Array.isArray(i)?i:{},S=i=>!!e&&a.has(i),H={state:()=>m,subscribe:i=>(P.add(i),()=>{P.delete(i)})};return{resolve:async i=>{if(N(i===g?null:H),i===g)return s.resolve(i);let d=!1;const[u,l]=await Promise.all([s.resolve(i),n.load({slug:g,...o}).catch(()=>(d=!0,null))]);if(l){J(l.id,l.live);const v=y(l.layout);e={id:l.id,layout:v,version:l.version,savedJson:""}}else e=null;if(f=!1,!u||!e)return h({conflict:null,saveFailed:!1,loadFailed:d}),u;const c=M(y(u.layout),e.layout);return e.savedJson=JSON.stringify(k(c,e.layout).chrome),a.add(u.id),h({conflict:null,saveFailed:!1,loadFailed:!1}),{...u,layout:c}},saveLayout:async(i,d,u,l)=>{if(!e||!S(i))return s.saveLayout(i,d,u,l);const c=e,v=k(d,c.layout),A=await s.saveLayout(i,v.page,u,l),b=JSON.stringify(v.chrome);if(!v.chrome||b===c.savedJson||m.lockHolder)return A;try{const w=await n.save(c.id,{layout:v.chrome},{version:c.version,clientId:l??""});j(c.id,w.live),E(),c.layout=v.chrome,c.version=w.version,c.savedJson=b,f=!0,h({conflict:null,saveFailed:!1})}catch(w){B(w,"changed-elsewhere")?h({conflict:w.conflict??{savedBy:"",savedByYou:!1,secondsAgo:0}}):B(w,"lock-taken")?h({lockHolder:w.holder??{name:"",secondsSinceSeen:0,secondsSinceHeld:0}}):h({saveFailed:!0})}return A},publish:s.publish?async(i,d)=>{const u=await s.publish(i,d),l=e;if(l&&S(i)&&!t&&n.publish&&p()&&!m.lockHolder){const c=await n.publish(l.id,l.version?{version:l.version}:void 0);V(l.id,c.live),c.version!==null&&(l.version=c.version),f=!1,h({})}return u}:void 0,lock:r?{claim:async(i,d,u)=>{const l=await r.claim(i,d,u),c=e;if(c&&S(i))try{await r.claim(c.id,d,!1),m.lockHolder&&h({lockHolder:null})}catch(v){B(v,"lock-taken")&&h({lockHolder:v.holder??{name:"",secondsSinceSeen:0,secondsSinceHeld:0}})}return l},release:async(i,d)=>{await r.release(i,d);const u=e;u&&S(i)&&!m.lockHolder&&await r.release(u.id,d).catch(()=>{})}}:void 0,pinnedChrome:H}}function te(n,o=R(),s=O(),r={}){const t=T(o),e=n?{siteId:n}:void 0,a=t?!!n:!0,f=o.site.update,m=t&&s.commerce&&s.service,P=!!r.editsPinnedInPlace&&m,p=F(o.site)?o.site:void 0,h=L(o.pages,n,p),y=P?Y(o.pages,e,h,o.lock,!!p):null;return{capabilities:{canPublish:!!p||!!o.pages.publish,hasSiteSettings:t,hasSiteTheme:!!o.theme,placeholderFrames:!1,mediaEditing:!0,pageCreationInAdminForm:!o.pages.create,canDeletePagesInline:!!o.pages.remove,hasEditLock:!!o.lock,hasEditGuard:!0,hasPinnedChrome:m,editsPinnedInPlace:P,explainsSiteSettings:!1,hasSiteRecord:a,canEditSiteRecord:a&&!!f,hasPreviewLink:t||!!o.preview,hasCatalog:t&&s.commerce,hasForms:t&&s.service,hasBlog:!!o.blog&&s.service,offersCommerce:s.commerce,offersService:s.service},...h,...x(h.resolve),lock:o.lock,...y,site:a?()=>o.site.get(e):void 0,siteLiveState:p?()=>p.liveState(e):void 0,siteVersions:U(p,e),updateSite:a&&f?S=>f(S,e):void 0,previewHref:o.preview?S=>o.preview.href(S):void 0}}function se(n,o=R(),s=O()){const r=T(o),t=o.templates,e=t?t.pages(n):{list:()=>Promise.reject(new Error(C)),load:()=>Promise.reject(new Error(C)),save:()=>Promise.reject(new Error(C))};return{capabilities:{canPublish:!1,hasSiteSettings:!1,hasSiteTheme:!1,placeholderFrames:!0,mediaEditing:!1,pageCreationInAdminForm:!e.create,canDeletePagesInline:!!e.remove,hasEditLock:!1,hasEditGuard:!1,hasPinnedChrome:r&&s.commerce&&s.service,editsPinnedInPlace:!1,explainsSiteSettings:r,hasSiteRecord:!1,canEditSiteRecord:!1,hasPreviewLink:!1,hasCatalog:r&&s.commerce,hasForms:r&&s.service,hasBlog:!!o.blog&&s.service,offersCommerce:s.commerce,offersService:s.service},...L(e,void 0),...x(L(e,void 0).resolve),publish:void 0,templateName:t?()=>t.get(n).then(a=>a.name):void 0}}function x(n){return{resolve:o=>(N(null),n(o))}}const C="This editor's backend has no website templates.";export{te as makeSitePageAdapter,se as makeTemplatePageAdapter};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{textarea as o}from"../../../controls.js";import{PH as
|
|
1
|
+
import{jsx as e}from"react/jsx-runtime";import{FieldGlyph as l}from"../../../../../components/FieldGlyph.js";import{group as a,select as t,textarea as o}from"../../../controls.js";import{PH as r}from"../../../../../../format/lib/puck/blocks/placeholders.js";import{alignField as i,toneField as p}from"../../shared-fields.js";const g={fields:{text:o("Body",r.body),align:i(),tone:p(),_gText:a("Text"),tag:t("HTML tag",e(l,{noun:"heading"}),[{label:"Paragraph",value:"p"},{label:"H1",value:"h1"},{label:"H2",value:"h2"},{label:"H3",value:"h3"},{label:"H4",value:"h4"},{label:"H5",value:"h5"},{label:"H6",value:"h6"}],"p")}};export{g as TextFields};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{slotFieldsOf as u}from"efficient-easel/draw";import{readHidable as
|
|
1
|
+
import{slotFieldsOf as u}from"efficient-easel/draw";import{readHidable as c}from"efficient-easel/draw";import{headingLevelOfTag as d}from"../../../format/lib/content/text-tag.js";function p(n){return n.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim()}function m(n){const s=[],e=/<h([1-6])\b[^>]*>([\s\S]*?)<\/h\1>/gi;let a;for(;a=e.exec(n);)s.push({level:Number(a[1]),text:p(a[2])||"(empty)"});return s}const h=new Set(["SubmitBuild"]),b={AlloyWheelsListing:1,DocMasthead:1,AppointmentBooking:2,BookingBox:2,SubmitBox:2,Banner:2,BundleOffer:2,Cards:2,Chart:2,CheckoutCTA:2,CollectionCard:3,Collections:2,CompatibleTyres:2,ContactLocations:2,ContactRouting:2,DeliveryOptions:2,DetailRows:2,DocBody:2,EuTyreLabel:2,Events:2,FAQ:2,FeaturedCover:2,FitmentFinder:2,FitmentTable:2,FooterEmailSignup:4,FooterMenu:4,Footprint:2,Form:2,Gallery:2,GalleryB:2,GalleryItem:2,Integrations:2,IntroBleed:2,KeyFeatures:2,Logos:2,LongRead:2,Manifesto:2,Mockup:2,OrderSummary:2,PostCard:2,ProcessSteps:2,ProductGrid:2,Prose:2,RelatedProducts:2,ReviewForm:2,Reviews:2,SectionHeader:2,Series:2,SpecTable:2,Split:2,StatsParagraph:2,SubmitBuild:2,Subscribe:2,SubscribeBlogs:2,Testimonials:2,Timeline:2,TimelineTrack:2,TitleWithButtons:2,TyreFitment:2,TyreSizes:2};function T(n,s){const e=[];for(const a of n??[]){const i=a,r=i.props??{};switch(i.type){case"Heading":{const{text:t,hidden:o}=c(r.text);if(o)break;e.push({level:Number(r.level)||2,text:t||"(empty heading)"})}break;case"Text":{const t=d(r.tag),{text:o,hidden:l}=c(r.text);if(t===null||l)break;e.push({level:t,text:o||"(empty heading)"})}break;case"Hero":e.push({level:1,text:"Hero (brand headline)"});break;case"CustomHTML":e.push(...m(c(r.html).text));break;default:{const t=b[i.type??""],o=c(r.title??r.heading),l=o.text.trim();if(!t||o.hidden)break;l?e.push({level:t,text:l}):h.has(i.type??"")&&e.push({level:t,text:String(i.type)});break}}for(const t of u(s,i.type??"")){const o=r[t];Array.isArray(o)&&e.push(...T(o,s))}}return e}export{b as SECTION_TOP_LEVEL_FOR_TEST,T as headingOutline};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{Fragment as f,jsx as
|
|
1
|
+
"use client";import{Fragment as f,jsx as u,jsxs as C}from"react/jsx-runtime";import{useMemo as h,useRef as v}from"react";import{EaselCanvas as I,useEaselApi as P}from"efficient-easel/easel";import T from"../../components/PreviewThemeFrame.js";import{OpenDocumentChromeLoadNotice as w}from"../../components/PinnedChromeLoadNotice.js";import{SiteRestoreNotice as F}from"../../components/SiteRestoreNotice.js";import{usePreviewParts as y}from"efficient-easel/draw/client";import{partElement as A,partTypingTarget as D,setCanvasTypingPart as S}from"./canvas-typing.js";import{partThemeColors as x,readInks as O}from"../../../format/lib/puck/part-inks.js";import{partOpenOn as j,PART_ATTR as d}from"../../../render/lib/puck/text-parts.js";import{useSectionOps as B}from"efficient-easel/screen/lib/puck/use-section-ops";import{useBlockMetadata as E}from"../editor-block-metadata.js";import{usePreviewHeader as M}from"../../../render/components/PreviewHeaderContext.js";import{siteWidthsMetadata as R}from"../../../format/lib/content/section-width.js";import{useEditorCanvasStyles as W}from"../editor-canvas-styles.js";function _({children:n,componentId:o}){const{selectedPartId:s}=y();return j(s,o)?u(f,{}):u(f,{children:n})}function Z(n){const{mirrorHostStyles:o}=W(),s=E(),{sectionBackgroundWidth:m,sectionContentWidth:a,themeFromDocument:c}=M(),p=h(()=>({...n.metadata??s??{},...R(c?null:m,c?null:a)}),[n.metadata,s,m,a,c]),t=v(null),e=b(t),{onDocument:r}=n,i=l=>{t.current=l,r?.(l)};return C(f,{children:[u(F,{}),u(w,{}),u(I,{...n,onDocument:i,typing:e,metadata:p,height:"fill",mirrorStyles:o,frameWrapper:T,overlay:_})]})}function b(n){const o=P(),s=B(),m=y(),a=v({ops:s,parts:m});return a.current={ops:s,parts:m},h(()=>{const c={getItemById:t=>o.getState().getItemById(t),getSelectorForId:t=>o.getState().getSelectorForId(t),get components(){return o.getState().config.components},replace:(t,e,r)=>a.current.ops.replaceComponent(t,e,r)},p=(t,e)=>{const r=D(t,c);if(!r)return null;let i=e;const l=()=>(i=A(i,i?.ownerDocument??n.current,t),i),g=l();return g?{element:l,value:r.value,rules:r.rules,multiline:r.multiline,write:r.write,toolbar:{offered:r.offered,colors:r.offered.length>0?x(O(g)):void 0}}:null};return{at:t=>{const e=t.closest(`[${d}]`),r=e?.getAttribute(d);return e&&r?p(r,e):null},atSelection:()=>{const t=a.current.parts.selectedPartId;return t?p(t,null):null},onChange:t=>{if(!t.typing){S(null);return}const e=t.element.closest(`[${d}]`)?.getAttribute(d)??null;S(e),e&&a.current.parts.selectedPartId!==e&&a.current.parts.select(e)}}},[o,n])}export{Z as SiteCanvas};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{FOOTER_TYPE as
|
|
1
|
+
import{FOOTER_TYPE as p,HEADER_TYPE as a}from"./footer-blocks.js";import{SITE_FOOTER_TYPE as c,SITE_HEADER_TYPE as T}from"../../../format/lib/puck/section-groups.js";function _(o,E){const t=o.some(e=>e?.type===c),r=o[o.length-1],s=!t&&r?.type===p?r:null,m=o.filter(e=>e?.type===p&&e!==s).map(e=>String(e.props?.id??"")).filter(Boolean),n=E.hasChromeDoc&&!t&&!s;return{remove:m,seedHeader:!o.some(e=>e?.type===a),seedFooter:n,seedSiteHeader:n&&!o.some(e=>e?.type===T)}}export{_ as inPlaceSeedPlan};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { SiteRestoreAnswer, SiteVersion, SiteVersionPreview } from "../../format/lib/web-backend.js";
|
|
2
|
+
export type { SiteRestoreAnswer, SiteVersion, SiteVersionPreview };
|
|
3
|
+
export interface SiteVersionsAccess {
|
|
4
|
+
list(): Promise<SiteVersion[]>;
|
|
5
|
+
name(id: string, name: string): Promise<SiteVersion>;
|
|
6
|
+
restore(id: string, options?: {
|
|
7
|
+
page?: string;
|
|
8
|
+
}): Promise<SiteRestoreAnswer>;
|
|
9
|
+
preview(id: string): Promise<SiteVersionPreview>;
|
|
10
|
+
}
|
|
11
|
+
export interface RestoreNote {
|
|
12
|
+
title: string;
|
|
13
|
+
undo: string | null;
|
|
14
|
+
}
|
|
15
|
+
export declare function openVersionHistory(): void;
|
|
16
|
+
export declare function closeVersionHistory(): void;
|
|
17
|
+
export declare function versionHistoryOpen(): boolean;
|
|
18
|
+
export declare function useVersionHistoryOpen(): boolean;
|
|
19
|
+
export declare function restoreNote(): RestoreNote | null;
|
|
20
|
+
export declare function clearRestoreNote(): void;
|
|
21
|
+
export declare function useRestoreNote(): RestoreNote | null;
|
|
22
|
+
interface OpenDocument {
|
|
23
|
+
flushSave: () => Promise<boolean>;
|
|
24
|
+
reload: () => void;
|
|
25
|
+
}
|
|
26
|
+
export declare class HeldEditsNotSaved extends Error {
|
|
27
|
+
constructor();
|
|
28
|
+
}
|
|
29
|
+
export declare function restoreSiteVersion({ access, version, page, ...doc }: OpenDocument & {
|
|
30
|
+
access: SiteVersionsAccess;
|
|
31
|
+
version: SiteVersion;
|
|
32
|
+
page?: {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
} | null;
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
export declare function undoSiteRestore({ access, ...doc }: OpenDocument & {
|
|
38
|
+
access: SiteVersionsAccess;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
export declare function versionTitle(version: SiteVersion): string;
|
|
41
|
+
export declare function changesSummary(version: SiteVersion): string;
|
|
42
|
+
export declare function changeLine(change: SiteVersion["changes"][number]): string;
|
|
43
|
+
export declare function versionWhen(iso: string, now?: Date): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useSyncExternalStore as d}from"react";import{editorWordsLocale as m,say as o,sayCount as w}from"../../format/lib/editor-words.js";import{noteSiteLiveState as h}from"./site-live-state.js";let s=!1,a=null;const f=new Set;function u(){for(const e of f)e()}function l(e){return f.add(e),()=>{f.delete(e)}}function D(){s||(s=!0,u())}function T(){s&&(s=!1,u())}function p(){return s}function H(){return d(l,p,p)}function y(){return a}function V(){a&&(a=null,u())}function F(){return d(l,y,y)}class x extends Error{constructor(){super("The editor's last changes could not be saved, so nothing was restored."),this.name="HeldEditsNotSaved"}}async function g(e,n,t,{flushSave:r,reload:i}){if(!await r())throw new x;const c=await e.restore(n,t);return h(c.liveState),i(),c}async function _({access:e,version:n,page:t,...r}){const i=await g(e,n.id,t?{page:t.id}:{},r);a={title:S(n,t??null),undo:i.undo},u()}async function E({access:e,...n}){const t=a?.undo;t&&(await g(e,t,{},n),a=null,u())}function L(e){return e.name?e.name:e.kind==="draft_before_restore"?o("Draft before restore"):o("Version {n}",{n:e.number})}function S(e,n){return e.kind==="draft_before_restore"?o("Your drafts from before the restore are back"):n?o("{page} from version {n} is now your draft",{page:n.name,n:e.number}):o("Version {n} is now your draft",{n:e.number})}function I(e){const n=e.changes.filter(r=>r.kind==="page").length,t=[...n?[w("{n} page","{n} pages",n)]:[],...e.changes.filter(r=>r.kind!=="page").map(r=>r.name)];if(!t.length)return"";try{return new Intl.ListFormat(m(),{type:"conjunction"}).format(t)}catch{return t.join(", ")}}function R(e){return e.change==="take_down"?o("{name} (taken down)",{name:e.name}):e.name}function Y(e,n=new Date){const t=new Date(e);if(Number.isNaN(t.getTime()))return"";const r=m(),i=new Intl.DateTimeFormat(r,{hour:"numeric",minute:"2-digit"}).format(t);if(t.toDateString()===n.toDateString())return o("Today, {time}",{time:i});const c=new Intl.DateTimeFormat(r,{day:"numeric",month:"short",...t.getFullYear()===n.getFullYear()?{}:{year:"numeric"}}).format(t);return o("{day}, {time}",{day:c,time:i})}export{x as HeldEditsNotSaved,R as changeLine,I as changesSummary,V as clearRestoreNote,T as closeVersionHistory,D as openVersionHistory,y as restoreNote,_ as restoreSiteVersion,E as undoSiteRestore,F as useRestoreNote,H as useVersionHistoryOpen,p as versionHistoryOpen,L as versionTitle,Y as versionWhen};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const n=["p","h1","h2","h3","h4","h5","h6"];function r(t){return n.includes(t)?t:"p"}function h(t){const e=r(t);return e==="p"?null:Number(e.slice(1))}export{n as TEXT_TAGS,h as headingLevelOfTag,r as textTagOf};
|