@realiizlabs/admin 0.15.6 → 0.15.7

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.
@@ -250,7 +250,7 @@ var OutIcon = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...ico, children: [
250
250
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 17l5-5-5-5" }),
251
251
  /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12H9" })
252
252
  ] });
253
- function AccountMenu({ user, role, theme, onTheme, signOutPath, accountHref, helpHref, siteUrl }) {
253
+ function AccountMenu({ user, role, theme, onTheme, signOutPath, accountHref, helpHref, siteUrl, version }) {
254
254
  const [open, setOpen] = react.useState(false);
255
255
  const wrap = react.useRef(null);
256
256
  react.useEffect(() => {
@@ -303,11 +303,15 @@ function AccountMenu({ user, role, theme, onTheme, signOutPath, accountHref, hel
303
303
  /* @__PURE__ */ jsxRuntime.jsx("form", { method: "post", action: signOutPath, className: "rz-menu__signout", children: /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "submit", role: "menuitem", className: "rz-menu__item", children: [
304
304
  /* @__PURE__ */ jsxRuntime.jsx(OutIcon, {}),
305
305
  "Sign out"
306
- ] }) })
306
+ ] }) }),
307
+ version && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rz-menu__version", children: [
308
+ "Studio ",
309
+ version
310
+ ] })
307
311
  ] })
308
312
  ] });
309
313
  }
310
- function TopBar({ siteName, productName, logoUrl, homeHref, siteUrl, user, role, theme, onTheme, signOutPath, accountHref, helpHref }) {
314
+ function TopBar({ siteName, productName, logoUrl, homeHref, siteUrl, user, role, theme, onTheme, signOutPath, accountHref, helpHref, version }) {
311
315
  return /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "rz-topbar", children: [
312
316
  /* @__PURE__ */ jsxRuntime.jsxs(
313
317
  "a",
@@ -328,7 +332,7 @@ function TopBar({ siteName, productName, logoUrl, homeHref, siteUrl, user, role,
328
332
  "Welcome back, ",
329
333
  firstNameOf(user)
330
334
  ] }),
331
- /* @__PURE__ */ jsxRuntime.jsx(AccountMenu, { user, role, theme, onTheme, signOutPath, accountHref, helpHref, siteUrl })
335
+ /* @__PURE__ */ jsxRuntime.jsx(AccountMenu, { user, role, theme, onTheme, signOutPath, accountHref, helpHref, siteUrl, version })
332
336
  ] })
333
337
  ] });
334
338
  }
@@ -409,6 +413,7 @@ var SHELL_CSS = `
409
413
  .rz-sidebar__collapse:hover { color: var(--text-primary); }
410
414
  .rz-sidebar__collapse svg { flex-shrink: 0; }
411
415
  .rz-sidebar--collapsed .rz-sidebar__collapse { justify-content: center; padding: .6rem 0; }
416
+ .rz-menu__version { padding: .45rem 1rem .55rem; border-top: 1px solid var(--separator); font-family: var(--rz-font-mono); font-size: .6875rem; letter-spacing: .04em; color: var(--text-muted); }
412
417
  .rz-sidebar__version { display: block; padding: 0 1rem .75rem; font-family: var(--rz-font-mono); font-size: .6875rem; letter-spacing: .04em; color: var(--text-muted); opacity: .8; white-space: nowrap; }
413
418
  .rz-sidebar--collapsed .rz-sidebar__version { padding: 0 0 .75rem; text-align: center; }
414
419
  .rz-main { flex: 1; min-width: 0; }
@@ -640,7 +645,8 @@ function AdminShell({
640
645
  onTheme: setTheme,
641
646
  signOutPath: signOutPath ?? `${basePath}/auth/signout`,
642
647
  accountHref: accountHref === null ? void 0 : accountHref ?? `${basePath}/account`,
643
- helpHref: helpHref === null ? void 0 : helpHref ?? `${basePath}/help`
648
+ helpHref: helpHref === null ? void 0 : helpHref ?? `${basePath}/help`,
649
+ version
644
650
  }
645
651
  ),
646
652
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rz-body", children: [
@@ -733,7 +739,7 @@ function Tabs({ options, value, onChange, label = "Sections" }) {
733
739
  }
734
740
 
735
741
  // src/version.ts
736
- var ADMIN_VERSION = "0.15.6" ;
742
+ var ADMIN_VERSION = "0.15.7" ;
737
743
 
738
744
  // src/studio-ui/css.ts
739
745
  var STUDIO_CSS = `
@@ -943,6 +949,10 @@ var STUDIO_CSS = `
943
949
  .rz-admin .rz-update--strip { margin: 0 0 1.5rem; }
944
950
  .rz-admin .rz-update__row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.1rem; }
945
951
  .rz-admin .rz-update__title { display: inline-flex; align-items: center; gap: .55rem; font-weight: 600; color: var(--text-primary); }
952
+ .rz-admin .rz-update--line { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem 1rem; padding: .55rem 1.1rem; font-size: .875rem; }
953
+ .rz-admin .rz-update--line .rz-update__later { margin-left: auto; }
954
+ .rz-admin .rz-update__row .rz-update__done { flex: 1; margin-top: .5rem; }
955
+ .rz-admin .rz-update__row .rz-update__later { align-self: flex-end; margin-top: .5rem; }
946
956
  .rz-admin .rz-update__title::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--signal); box-shadow: 0 0 0 3px color-mix(in srgb, var(--signal) 18%, transparent); }
947
957
  .rz-admin .rz-update__link { display: inline-flex; align-items: center; gap: .3rem; background: none; border: 0; padding: 0; font: inherit; font-size: .875rem; color: var(--signal); cursor: pointer; text-decoration: none; }
948
958
  .rz-admin .rz-update__link:hover { color: var(--text-primary); }
@@ -954,14 +964,16 @@ var STUDIO_CSS = `
954
964
  `;
955
965
  var POLL_MS = 8e3;
956
966
  var LOCAL_FALLBACK_MS = 15e4;
967
+ var SLOW_MS = 4 * 6e4;
957
968
  var GIVE_UP_MS = 15 * 6e4;
958
- function useDeployed(active, mergedSha) {
969
+ function useDeployed(active, mergedSha, attempt = 0) {
959
970
  const [state, setState] = react.useState("waiting");
960
971
  react.useEffect(() => {
961
972
  if (!active) return;
962
973
  let stop = false;
963
974
  let baseline;
964
975
  const started = Date.now();
976
+ setState("waiting");
965
977
  const read2 = async () => {
966
978
  try {
967
979
  const r = await fetch("/api/version", { cache: "no-store" });
@@ -985,22 +997,24 @@ function useDeployed(active, mergedSha) {
985
997
  return;
986
998
  }
987
999
  if (elapsed >= GIVE_UP_MS) {
988
- setState("slow");
1000
+ setState("stalled");
989
1001
  return;
990
1002
  }
1003
+ if (elapsed >= SLOW_MS) setState("slow");
991
1004
  setTimeout(tick, POLL_MS);
992
1005
  };
993
1006
  void tick();
994
1007
  return () => {
995
1008
  stop = true;
996
1009
  };
997
- }, [active, mergedSha]);
1010
+ }, [active, mergedSha, attempt]);
998
1011
  return state;
999
1012
  }
1000
1013
  var KEY = "rz-update-installing";
1014
+ var MIN_KEY = "rz-update-minimized";
1001
1015
  function readInstalling() {
1002
1016
  try {
1003
- const raw = sessionStorage.getItem(KEY);
1017
+ const raw = localStorage.getItem(KEY);
1004
1018
  if (!raw) return null;
1005
1019
  const v = JSON.parse(raw);
1006
1020
  return typeof v.version === "string" ? v : null;
@@ -1010,8 +1024,11 @@ function readInstalling() {
1010
1024
  }
1011
1025
  function writeInstalling(i) {
1012
1026
  try {
1013
- if (i) sessionStorage.setItem(KEY, JSON.stringify(i));
1014
- else sessionStorage.removeItem(KEY);
1027
+ if (i) localStorage.setItem(KEY, JSON.stringify(i));
1028
+ else {
1029
+ localStorage.removeItem(KEY);
1030
+ localStorage.removeItem(MIN_KEY);
1031
+ }
1015
1032
  } catch {
1016
1033
  }
1017
1034
  }
@@ -1032,21 +1049,55 @@ function useInstalling() {
1032
1049
  return [installing, update];
1033
1050
  }
1034
1051
  function InstallTracker({ installing, compact = false }) {
1035
- const deploy = useDeployed(true, installing.sha);
1052
+ const { actions, supportName } = useStudio();
1053
+ const [attempt, setAttempt] = react.useState(0);
1054
+ const [nudge, setNudge] = react.useState(null);
1055
+ const deploy = useDeployed(true, installing.sha, attempt);
1036
1056
  const live = deploy === "live";
1057
+ const late = deploy === "slow" || deploy === "stalled";
1058
+ const doNudge = async () => {
1059
+ if (!actions.nudgeBuild) return;
1060
+ setNudge("busy");
1061
+ const out = await actions.nudgeBuild();
1062
+ setNudge(out);
1063
+ if (out.state === "sent") setAttempt((n) => n + 1);
1064
+ };
1065
+ const [minimized, setMinimized] = react.useState(false);
1066
+ react.useEffect(() => {
1067
+ try {
1068
+ setMinimized(localStorage.getItem(MIN_KEY) === "1");
1069
+ } catch {
1070
+ }
1071
+ }, []);
1072
+ const minimize = (on) => {
1073
+ try {
1074
+ on ? localStorage.setItem(MIN_KEY, "1") : localStorage.removeItem(MIN_KEY);
1075
+ } catch {
1076
+ }
1077
+ setMinimized(on);
1078
+ };
1079
+ const reload = /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "rz-update__link", onClick: () => window.location.reload(), children: "Reload Studio" });
1080
+ if (live || minimized && compact) {
1081
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `rz-update rz-update--line${compact ? " rz-update--strip" : ""}`, role: "status", children: [
1082
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rz-update__title", children: live ? `Studio ${installing.version} is live` : `Installing Studio ${installing.version}` }),
1083
+ live ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1084
+ reload,
1085
+ " to start using it."
1086
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rz-muted", children: "The website is rebuilding \u2014 keep working." }),
1087
+ !live && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "rz-update__later", onClick: () => minimize(false), children: "Show progress" })
1088
+ ] });
1089
+ }
1037
1090
  const steps = [
1038
1091
  { label: "Updated", state: "done", note: `Studio ${installing.version}` },
1039
- { label: "Live", state: live ? "done" : "active", note: live ? "On the site now" : deploy === "slow" ? "Taking longer than usual" : "Rebuilding, about two minutes" }
1092
+ { label: "Live", state: "active", note: late ? "Taking longer than usual" : "Rebuilding the website" }
1040
1093
  ];
1041
1094
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `rz-update${compact ? " rz-update--strip" : ""}`, role: "status", children: [
1042
1095
  /* @__PURE__ */ jsxRuntime.jsx(Steps, { steps }),
1043
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rz-update__done", children: live ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1044
- "Studio ",
1045
- installing.version,
1046
- " is live. ",
1047
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "rz-update__link", onClick: () => window.location.reload(), children: "Reload Studio" }),
1048
- " to start using it \u2014 the version at the foot of the sidebar will change."
1049
- ] }) : "Update accepted. Nothing to do meanwhile \u2014 keep working. The website is rebuilding with the new Studio; this turns green when it's done, in about two minutes." })
1096
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rz-update__row", children: [
1097
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rz-update__done", children: !late ? "Update accepted. Nothing to do meanwhile \u2014 keep working. The website is rebuilding with the new Studio; usually a few minutes, sometimes longer. This turns green when it's done." : nudge === "busy" ? "Asking the hosting service to build again\u2026" : nudge?.state === "sent" ? "Asked. The rebuild should start within a minute; this turns green when it's done." : nudge?.state === "error" ? `That didn't work (${nudge.message}). Tell ${supportName} \u2014 it's a one-click fix on their side.` : nudge?.state === "unavailable" || !actions.nudgeBuild ? `This is taking longer than usual. Occasionally the hosting service misses a rebuild \u2014 tell ${supportName}; it's a one-click fix on their side, and nothing on your website has changed.` : "This is taking longer than usual. Occasionally the hosting service misses a rebuild. You can ask it again \u2014 it's safe to press, nothing on your website changes." }),
1098
+ late && actions.nudgeBuild && nudge !== "busy" && nudge?.state !== "sent" && nudge?.state !== "unavailable" && /* @__PURE__ */ jsxRuntime.jsx(Button, { size: "sm", onClick: doNudge, children: "Nudge the build" }),
1099
+ compact && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "rz-update__later", onClick: () => minimize(true), children: "Minimize" })
1100
+ ] })
1050
1101
  ] });
1051
1102
  }
1052
1103
  var HIDE_KEY = "rz-update-later";
@@ -3179,7 +3230,7 @@ function PublishPanel({ number, htmlUrl, merged, closed = false, branch, removal
3179
3230
  {
3180
3231
  label: removal ? "Removed" : "Live",
3181
3232
  state: onSite ? "done" : live ? "active" : "todo",
3182
- note: onSite ? removal ? "Off the site" : "On the site" : live ? deploy === "slow" ? "Taking longer than usual" : "Rebuilding, about two minutes" : "Automatic"
3233
+ note: onSite ? removal ? "Off the site" : "On the site" : live ? deploy === "waiting" ? "Rebuilding the website" : "Taking longer than usual" : "Automatic"
3183
3234
  }
3184
3235
  ];
3185
3236
  if (discarded) {
@@ -3201,7 +3252,7 @@ function PublishPanel({ number, htmlUrl, merged, closed = false, branch, removal
3201
3252
  }
3202
3253
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3203
3254
  /* @__PURE__ */ jsxRuntime.jsx(Steps, { steps }),
3204
- live ? onSite ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: removal ? `Done \u2014 the ${noun} is off the website.` : "Done \u2014 your change is on the website now." }) : deploy === "slow" ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: "The site is taking longer than usual to rebuild. It will get there; check back in a few minutes." }) : /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: "Published. The website is rebuilding with your change \u2014 this usually takes about two minutes. Stay here and this page will tell you the moment it's live; if you look at the site before then you'll still see the old version." }) : stale ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rz-alert admin__alert", children: [
3255
+ live ? onSite ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: removal ? `Done \u2014 the ${noun} is off the website.` : "Done \u2014 your change is on the website now." }) : deploy === "stalled" ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: "The website still hasn't rebuilt. Your change is saved and published; the rebuild just hasn't happened. Tell your web team \u2014 it's a one-click fix on their side." }) : deploy === "slow" ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: "The site is taking longer than usual to rebuild. It will get there; check back in a few minutes." }) : /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: "Published. The website is rebuilding with your change \u2014 usually a few minutes. Stay here and this page will tell you the moment it's live; if you look at the site before then you'll still see the old version." }) : stale ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rz-alert admin__alert", children: [
3205
3256
  "Someone else changed this file first. ",
3206
3257
  /* @__PURE__ */ jsxRuntime.jsx(Link3__default.default, { href: "/admin", children: "Open it again" }),
3207
3258
  ", make your change on the latest version, and publish."
@@ -3221,7 +3272,7 @@ function PublishPanel({ number, htmlUrl, merged, closed = false, branch, removal
3221
3272
  noun
3222
3273
  ] })),
3223
3274
  /* @__PURE__ */ jsxRuntime.jsx(LinkButton, { variant: removal || !liveUrl ? "primary" : "secondary", href: listUrl, children: backLabel }),
3224
- live && !onSite && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rz-actions__hint", children: deploy === "slow" ? "Still rebuilding." : "Waiting for the site to rebuild\u2026" })
3275
+ live && !onSite && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rz-actions__hint", children: deploy === "waiting" ? "Waiting for the site to rebuild\u2026" : "Still rebuilding." })
3225
3276
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3226
3277
  /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "primary", disabled: pending || !ready, onClick: publish, children: pending ? "Publishing\u2026" : "Publish" }),
3227
3278
  previewUrl && ready && /* @__PURE__ */ jsxRuntime.jsx(LinkButton, { external: true, href: previewUrl, children: "Preview the change" }),
@@ -5225,7 +5276,7 @@ The new version didn't build cleanly against your website. Nothing was installed
5225
5276
 
5226
5277
  ## The tracker is stuck on "Live"
5227
5278
 
5228
- The rebuild usually takes about two minutes; occasionally the hosting service is slow and it takes ten. If the tracker says *taking longer than usual*, that's all it means. Leave the page and come back \u2014 the update is already accepted and will finish on its own.
5279
+ The rebuild usually takes a few minutes. After a while the tracker says *taking longer than usual* and, on most sites, offers **Nudge the build**. Press it \u2014 it asks the hosting service to build the website again. It's safe: the update is already accepted, nothing on your website changes, and pressing it twice does no harm. If the button isn't there, or it doesn't help within ten minutes, tell {supportName}; it's a one-click fix on their side. Either way you can leave the page and come back \u2014 the tracker remembers.
5229
5280
 
5230
5281
  ## I'm not seeing updates at all
5231
5282
 
@@ -5671,6 +5722,7 @@ function BackArrow() {
5671
5722
  // src/studio-ui/types.ts
5672
5723
  var ACTION_NAMES = [
5673
5724
  "updateStudio",
5725
+ "nudgeBuild",
5674
5726
  "publishContent",
5675
5727
  "removeContent",
5676
5728
  "mergeContentPr",