@flamingo-stack/openframe-frontend-core 0.0.757 → 0.0.759

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/build/export-map.json +1 -1
  2. package/dist/{chunk-7RADSQJF.cjs → chunk-4IXA5CJT.cjs} +142 -96
  3. package/dist/{chunk-S5ITKW6G.cjs → chunk-6VDOHVYE.cjs} +83 -82
  4. package/dist/{chunk-RPADJ2E6.cjs → chunk-7ITYKDJN.cjs} +3 -3
  5. package/dist/{chunk-ORC3ZKHT.cjs → chunk-CDA2MY7U.cjs} +48 -24
  6. package/dist/{chunk-L2RNZOCI.cjs → chunk-DHFQECP3.cjs} +11 -11
  7. package/dist/{chunk-33RJU565.cjs → chunk-EFCX5SYN.cjs} +2 -2
  8. package/dist/{chunk-WSRMYHIV.cjs → chunk-F7WIKBRI.cjs} +2 -2
  9. package/dist/{chunk-JEIAB7JQ.cjs → chunk-G7RDJACG.cjs} +2 -2
  10. package/dist/{chunk-AZFSHHWT.cjs → chunk-I4W4DQ6C.cjs} +4 -4
  11. package/dist/{chunk-BLYP7ZT4.cjs → chunk-O75A3FBT.cjs} +47 -36
  12. package/dist/{chunk-NTGIQP7O.cjs → chunk-QU5K52OP.cjs} +8 -2
  13. package/dist/{chunk-VD4HVLXG.cjs → chunk-S23DIVIP.cjs} +25 -25
  14. package/dist/{chunk-UWXUGP3V.cjs → chunk-SIOSQMIB.cjs} +3 -3
  15. package/dist/{chunk-33PJH2TF.cjs → chunk-SYACKQYF.cjs} +13 -13
  16. package/dist/{chunk-HB3QFOHD.cjs → chunk-WBSYC6EY.cjs} +5 -5
  17. package/dist/{chunk-CT3UDNAV.cjs → chunk-WGFTIEHY.cjs} +75 -68
  18. package/dist/{chunk-3C4U4UW6.cjs → chunk-XXM74P3N.cjs} +1 -1
  19. package/dist/{cloud-tenants-PA5UU2KQ.cjs → cloud-tenants-YUMG3O36.cjs} +4 -4
  20. package/dist/components/case-studies/index.cjs +12 -12
  21. package/dist/components/chat/index.cjs +2 -2
  22. package/dist/components/contact/index.cjs +5 -5
  23. package/dist/components/docs/doc-viewer.d.ts +4 -0
  24. package/dist/components/docs/doc-viewer.d.ts.map +1 -1
  25. package/dist/components/docs/doc-viewer.js +3 -0
  26. package/dist/components/docs/index.cjs +8 -8
  27. package/dist/components/docs/use-document-tree.d.ts.map +1 -1
  28. package/dist/components/docs/use-document-tree.js +9 -1
  29. package/dist/components/embeds/index.cjs +5 -5
  30. package/dist/components/faq/index.cjs +6 -6
  31. package/dist/components/features/index.cjs +4 -4
  32. package/dist/components/help-center-pages/index.cjs +58 -57
  33. package/dist/components/help-center-pages/trust-center-page.d.ts +7 -1
  34. package/dist/components/help-center-pages/trust-center-page.d.ts.map +1 -1
  35. package/dist/components/help-center-pages/trust-center-page.js +4 -3
  36. package/dist/components/index.cjs +35 -33
  37. package/dist/components/layout/page-data-sync.d.ts +18 -0
  38. package/dist/components/layout/page-data-sync.d.ts.map +1 -0
  39. package/dist/components/layout/page-data-sync.js +33 -0
  40. package/dist/components/meeting-scheduler/index.cjs +20 -20
  41. package/dist/components/navigation/index.cjs +7 -7
  42. package/dist/components/onboarding-guides/index.cjs +6 -6
  43. package/dist/components/product-demo/index.cjs +7 -7
  44. package/dist/components/shared/delivery/delivery-lists.d.ts.map +1 -1
  45. package/dist/components/shared/delivery/delivery-lists.js +6 -0
  46. package/dist/components/shared/dev-section/dev-section-view.d.ts +3 -16
  47. package/dist/components/shared/dev-section/dev-section-view.d.ts.map +1 -1
  48. package/dist/components/shared/dev-section/dev-section-view.js +6 -13
  49. package/dist/components/shared/legal-document/legal-document-page.d.ts +1 -3
  50. package/dist/components/shared/legal-document/legal-document-page.d.ts.map +1 -1
  51. package/dist/components/shared/legal-document/legal-document-page.js +3 -9
  52. package/dist/components/shared/roadmap/roadmap-view.d.ts.map +1 -1
  53. package/dist/components/shared/roadmap/roadmap-view.js +29 -17
  54. package/dist/components/tickets/hooks/use-tickets-list.d.ts +4 -0
  55. package/dist/components/tickets/hooks/use-tickets-list.d.ts.map +1 -1
  56. package/dist/components/tickets/hooks/use-tickets-list.js +1 -0
  57. package/dist/components/tickets/index.cjs +9 -9
  58. package/dist/components/tickets/ticket-center.d.ts.map +1 -1
  59. package/dist/components/tickets/ticket-center.js +5 -6
  60. package/dist/components/ui/data-attribution.d.ts +13 -0
  61. package/dist/components/ui/data-attribution.d.ts.map +1 -1
  62. package/dist/components/ui/data-attribution.js +30 -1
  63. package/dist/components/ui/drawer.d.ts.map +1 -1
  64. package/dist/components/ui/drawer.js +5 -2
  65. package/dist/components/ui/index.cjs +6 -4
  66. package/dist/{devices-72YSJM4Z.cjs → devices-EFDFNWIV.cjs} +5 -5
  67. package/dist/{embeddable-chat-CHHWPGAY.cjs → embeddable-chat-LTXUQWEK.cjs} +4 -4
  68. package/dist/index.cjs +14 -8
  69. package/dist/{knowledge-76RIDA7P.cjs → knowledge-UT2XI45N.cjs} +4 -4
  70. package/dist/{logs-ODMJ3KOP.cjs → logs-ZTYEI35Y.cjs} +12 -12
  71. package/dist/{policies-5BZ5X2S4.cjs → policies-S3IF2U3D.cjs} +8 -8
  72. package/dist/{scripts-TWQPG46M.cjs → scripts-IZWNCX5A.cjs} +9 -9
  73. package/dist/{software-update-TSGISQV5.cjs → software-update-6T4GFJPA.cjs} +7 -7
  74. package/dist/types/data-sync.d.ts +22 -0
  75. package/dist/types/data-sync.d.ts.map +1 -0
  76. package/dist/types/data-sync.js +12 -0
  77. package/dist/types/doc-source.d.ts +4 -0
  78. package/dist/types/doc-source.d.ts.map +1 -1
  79. package/dist/types/index.cjs +12 -0
  80. package/dist/types/index.d.ts +1 -0
  81. package/dist/types/index.d.ts.map +1 -1
  82. package/dist/types/index.js +1 -0
  83. package/package.json +1 -1
  84. package/src/components/docs/doc-viewer.tsx +9 -0
  85. package/src/components/docs/use-document-tree.ts +10 -0
  86. package/src/components/help-center-pages/trust-center-page.tsx +10 -3
  87. package/src/components/layout/page-data-sync.tsx +60 -0
  88. package/src/components/shared/delivery/delivery-lists.tsx +12 -2
  89. package/src/components/shared/dev-section/dev-section-view.tsx +37 -56
  90. package/src/components/shared/legal-document/legal-document-page.tsx +5 -13
  91. package/src/components/shared/roadmap/roadmap-view.tsx +37 -20
  92. package/src/components/tickets/hooks/use-tickets-list.ts +7 -0
  93. package/src/components/tickets/ticket-center.tsx +7 -3
  94. package/src/components/ui/data-attribution.tsx +44 -0
  95. package/src/components/ui/drawer.tsx +12 -1
  96. package/src/types/data-sync.ts +26 -0
  97. package/src/types/doc-source.ts +4 -0
  98. package/src/types/index.ts +1 -0
@@ -0,0 +1,18 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { DataSync } from '../../types/data-sync';
3
+ export declare function PageDataSyncProvider({ children }: {
4
+ children: ReactNode;
5
+ }): import("react").JSX.Element;
6
+ /**
7
+ * The page's sync row: what a list below reported, its skeleton while it loads, nothing when it states none. `inline`
8
+ * when it sits in a heading's action slot (`SectionHeading`), which places it itself.
9
+ */
10
+ export declare function PageDataSyncRow({ inline }: {
11
+ inline?: boolean;
12
+ }): import("react").JSX.Element | null;
13
+ /**
14
+ * Report a list's sync to the page's row. Returns false when the list is rendered outside a page that has one (an
15
+ * embed of the list alone), so the list draws the line itself.
16
+ */
17
+ export declare function usePageDataSync(sync: DataSync | null | undefined, loading: boolean): boolean;
18
+ //# sourceMappingURL=page-data-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-data-sync.d.ts","sourceRoot":"","sources":["../../../src/components/layout/page-data-sync.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,SAAS,EAA4C,MAAM,OAAO,CAAC;AAChG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAyBtD,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAIzE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,MAAc,EAAE,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,sCAIvE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAW5F"}
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext, useEffect, useMemo, useState } from "react";
4
+ import { DataSyncLine } from "../ui/data-attribution.js";
5
+ const PageDataSyncContext = createContext(null);
6
+ const EMPTY = { sync: null, loading: false };
7
+ function PageDataSyncProvider({ children }) {
8
+ const [state, report] = useState(EMPTY);
9
+ const value = useMemo(() => ({ state, report }), [state]);
10
+ return /* @__PURE__ */ jsx(PageDataSyncContext.Provider, { value, children });
11
+ }
12
+ function PageDataSyncRow({ inline = false }) {
13
+ const context = useContext(PageDataSyncContext);
14
+ if (!context) return null;
15
+ return /* @__PURE__ */ jsx(DataSyncLine, { sync: context.state.sync, loading: context.state.loading, inline });
16
+ }
17
+ function usePageDataSync(sync, loading) {
18
+ const context = useContext(PageDataSyncContext);
19
+ const report = context?.report;
20
+ const source = sync?.source ?? null;
21
+ const syncedAt = sync?.syncedAt ?? null;
22
+ useEffect(() => {
23
+ if (!report) return;
24
+ report({ sync: source ? { source, syncedAt } : null, loading });
25
+ }, [report, source, syncedAt, loading]);
26
+ useEffect(() => report ? () => report(EMPTY) : void 0, [report]);
27
+ return Boolean(context);
28
+ }
29
+ export {
30
+ PageDataSyncProvider,
31
+ PageDataSyncRow,
32
+ usePageDataSync
33
+ };
@@ -16,9 +16,9 @@ var _chunk5E6JHOGXcjs = require('../../chunk-5E6JHOGX.cjs');
16
16
 
17
17
 
18
18
 
19
- var _chunk7RADSQJFcjs = require('../../chunk-7RADSQJF.cjs');
19
+ var _chunk4IXA5CJTcjs = require('../../chunk-4IXA5CJT.cjs');
20
20
  require('../../chunk-2ANICXS7.cjs');
21
- require('../../chunk-NTGIQP7O.cjs');
21
+ require('../../chunk-QU5K52OP.cjs');
22
22
 
23
23
 
24
24
 
@@ -46,7 +46,7 @@ var _chunkYUMFVQINcjs = require('../../chunk-YUMFVQIN.cjs');
46
46
 
47
47
 
48
48
 
49
- var _chunk3C4U4UW6cjs = require('../../chunk-3C4U4UW6.cjs');
49
+ var _chunkXXM74P3Ncjs = require('../../chunk-XXM74P3N.cjs');
50
50
 
51
51
 
52
52
  var _chunkQTYSYEHKcjs = require('../../chunk-QTYSYEHK.cjs');
@@ -2194,7 +2194,7 @@ function useMeetingBooking(options) {
2194
2194
  const seededOffset = _optionalChain([initialAvailability, 'optionalAccess', _12 => _12.meetingId]) === meetingId ? initialAvailability.monthOffset : void 0;
2195
2195
  const [monthOffset, setMonthOffsetState] = _react.useState.call(void 0, _nullishCoalesce(seededOffset, () => ( 0)));
2196
2196
  const setMonthOffset = _react.useCallback.call(void 0, (offset) => {
2197
- setMonthOffsetState(Math.max(0, Math.min(_chunk3C4U4UW6cjs.MAX_MONTH_OFFSET, offset)));
2197
+ setMonthOffsetState(Math.max(0, Math.min(_chunkXXM74P3Ncjs.MAX_MONTH_OFFSET, offset)));
2198
2198
  }, []);
2199
2199
  const prevMeetingIdRef = _react.useRef.call(void 0, meetingId);
2200
2200
  _react.useLayoutEffect.call(void 0, () => {
@@ -2324,7 +2324,7 @@ var FIELD_CONTROLS = {
2324
2324
  }
2325
2325
  ),
2326
2326
  textarea: ({ field, id, registerName, error, register }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2327
- _chunk7RADSQJFcjs.Textarea,
2327
+ _chunk4IXA5CJTcjs.Textarea,
2328
2328
  {
2329
2329
  id,
2330
2330
  required: field.required,
@@ -2401,14 +2401,14 @@ var FIELD_CONTROLS = {
2401
2401
  control,
2402
2402
  name: registerName,
2403
2403
  render: ({ field: rhf }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2404
- _chunk7RADSQJFcjs.RadioGroup,
2404
+ _chunk4IXA5CJTcjs.RadioGroup,
2405
2405
  {
2406
2406
  value: _nullishCoalesce(rhf.value, () => ( "")),
2407
2407
  onValueChange: rhf.onChange,
2408
2408
  "aria-required": field.required || void 0,
2409
2409
  "aria-invalid": Boolean(error),
2410
2410
  children: (_nullishCoalesce(field.options, () => ( []))).map((opt) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-[var(--spacing-system-xs)]", children: [
2411
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7RADSQJFcjs.RadioGroupItem, { id: `${id}-${opt}`, value: opt }),
2411
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk4IXA5CJTcjs.RadioGroupItem, { id: `${id}-${opt}`, value: opt }),
2412
2412
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkK6VWTUCHcjs.Label, { htmlFor: `${id}-${opt}`, children: optionLabel(field, opt) })
2413
2413
  ] }, opt))
2414
2414
  }
@@ -2656,8 +2656,8 @@ function BookingForm({
2656
2656
  children: _nullishCoalesce(submitLabel, () => ( DEFAULT_SUBMIT_LABEL))
2657
2657
  }
2658
2658
  );
2659
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { id: formId, onSubmit: submit, className: FORM_STACK, noValidate: true, ..._chunk3C4U4UW6cjs.HUBSPOT_DO_NOT_COLLECT_FORM_PROPS, children: [
2660
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7RADSQJFcjs.HoneypotField, { ...honeypotInputProps }),
2659
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { id: formId, onSubmit: submit, className: FORM_STACK, noValidate: true, ..._chunkXXM74P3Ncjs.HUBSPOT_DO_NOT_COLLECT_FORM_PROPS, children: [
2660
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk4IXA5CJTcjs.HoneypotField, { ...honeypotInputProps }),
2661
2661
  fieldRows ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2662
2662
  placedRows.map((row) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: ROW_GRID, children: row.map((slot, slotIndex) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: slotColumnClass(row, slot, slotIndex), children: slotNode(slot.name) }, slot.name)) }, row.map((s) => s.name).join("|"))),
2663
2663
  [...unplacedBuiltIns, ...unplacedFields].map((field) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react.Fragment, { children: slotNode(field.name) }, field.name))
@@ -2670,7 +2670,7 @@ function BookingForm({
2670
2670
  supportedFields.map((field) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react.Fragment, { children: renderDeclaredField(field) }, field.name))
2671
2671
  ] }),
2672
2672
  consent && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2673
- _chunk7RADSQJFcjs.CheckboxBlock,
2673
+ _chunk4IXA5CJTcjs.CheckboxBlock,
2674
2674
  {
2675
2675
  id: "ms-host-consent",
2676
2676
  checked: consented,
@@ -2705,7 +2705,7 @@ function BookingForm({
2705
2705
  // same block the waitlist form uses): box + label in one
2706
2706
  // bordered row.
2707
2707
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2708
- _chunk7RADSQJFcjs.CheckboxBlock,
2708
+ _chunk4IXA5CJTcjs.CheckboxBlock,
2709
2709
  {
2710
2710
  id: `ms-consent-${box.communicationTypeId}`,
2711
2711
  checked: _nullishCoalesce(_optionalChain([current, 'optionalAccess', _34 => _34.consented]), () => ( false)),
@@ -2906,7 +2906,7 @@ function SchedulerContextPanel({
2906
2906
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunk3ATAYP36cjs.cn.call(void 0, STRIP_ASIDE, locked && "content-max-lg:hidden"), children: [
2907
2907
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: FIELD_LABEL_CLASS, children: "Timezone" }),
2908
2908
  timezone ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2909
- _chunk7RADSQJFcjs.TimezoneSelect,
2909
+ _chunk4IXA5CJTcjs.TimezoneSelect,
2910
2910
  {
2911
2911
  value: timezone,
2912
2912
  disabled,
@@ -2986,7 +2986,7 @@ function SchedulerModalHeader({
2986
2986
  showTimezone && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: _chunk3ATAYP36cjs.cn.call(void 0, ROW_CLASS, "flex flex-col gap-[var(--spacing-system-xxs)]"), children: [
2987
2987
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: FIELD_LABEL_CLASS2, children: "Timezone" }),
2988
2988
  timezone ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2989
- _chunk7RADSQJFcjs.TimezoneSelect,
2989
+ _chunk4IXA5CJTcjs.TimezoneSelect,
2990
2990
  {
2991
2991
  value: timezone,
2992
2992
  disabled,
@@ -3095,18 +3095,18 @@ var NOOP = () => void 0;
3095
3095
  function DayCalendar({ monthOffset, onMonthOffsetChange, selectedDay, onSelectDay, slotsByDay }) {
3096
3096
  const now = /* @__PURE__ */ new Date();
3097
3097
  const startMonth = new Date(now.getFullYear(), now.getMonth(), 1);
3098
- const endMonth = new Date(now.getFullYear(), now.getMonth() + _chunk3C4U4UW6cjs.MAX_MONTH_OFFSET + 1, 0);
3098
+ const endMonth = new Date(now.getFullYear(), now.getMonth() + _chunkXXM74P3Ncjs.MAX_MONTH_OFFSET + 1, 0);
3099
3099
  const visibleMonth = new Date(now.getFullYear(), now.getMonth() + monthOffset, 1);
3100
3100
  const dayHasNoSlots = _react.useCallback.call(void 0, (day) => !_optionalChain([slotsByDay, 'optionalAccess', _37 => _37.has, 'call', _38 => _38(calendarDayKey(day))]), [slotsByDay]);
3101
3101
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex min-h-0 flex-1 flex-col", "aria-busy": slotsByDay === null, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3102
- _chunk7RADSQJFcjs.DatePickerCalendar,
3102
+ _chunk4IXA5CJTcjs.DatePickerCalendar,
3103
3103
  {
3104
3104
  mode: "single",
3105
3105
  bare: true,
3106
3106
  month: visibleMonth,
3107
3107
  onMonthChange: (month) => {
3108
3108
  const offset = (month.getFullYear() - now.getFullYear()) * 12 + (month.getMonth() - now.getMonth());
3109
- onMonthOffsetChange(Math.max(0, Math.min(_chunk3C4U4UW6cjs.MAX_MONTH_OFFSET, offset)));
3109
+ onMonthOffsetChange(Math.max(0, Math.min(_chunkXXM74P3Ncjs.MAX_MONTH_OFFSET, offset)));
3110
3110
  },
3111
3111
  fromDate: startMonth,
3112
3112
  toDate: endMonth,
@@ -3250,7 +3250,7 @@ function SlotPicker({
3250
3250
  monthLabelFor(monthOffset),
3251
3251
  "."
3252
3252
  ] }),
3253
- monthOffset < _chunk3C4U4UW6cjs.MAX_MONTH_OFFSET && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3253
+ monthOffset < _chunkXXM74P3Ncjs.MAX_MONTH_OFFSET && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3254
3254
  _chunk2QMBXGMQcjs.Button,
3255
3255
  {
3256
3256
  variant: "outline",
@@ -3765,7 +3765,7 @@ function HubSpotMeetingScheduler({
3765
3765
  }
3766
3766
  )
3767
3767
  ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3768
- bookingError === "SLOT_TAKEN" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7RADSQJFcjs.Alert, { variant: "warning", className: "mx-[var(--spacing-system-m)] mt-[var(--spacing-system-m)] w-auto", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7RADSQJFcjs.AlertDescription, { children: "That time was just taken \u2014 pick another slot below. (If you already submitted, check your email for a confirmation before rebooking.)" }) }),
3768
+ bookingError === "SLOT_TAKEN" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk4IXA5CJTcjs.Alert, { variant: "warning", className: "mx-[var(--spacing-system-m)] mt-[var(--spacing-system-m)] w-auto", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk4IXA5CJTcjs.AlertDescription, { children: "That time was just taken \u2014 pick another slot below. (If you already submitted, check your email for a confirmation before rebooking.)" }) }),
3769
3769
  timezone && durationMs != null ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3770
3770
  SlotPicker,
3771
3771
  {
@@ -3884,11 +3884,11 @@ function HubSpotMeetingScheduler({
3884
3884
  )
3885
3885
  ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-[var(--spacing-system-m)] content-md:min-h-0 content-md:flex-1", children: [
3886
3886
  bookingError === "SLOT_TAKEN" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3887
- _chunk7RADSQJFcjs.Alert,
3887
+ _chunk4IXA5CJTcjs.Alert,
3888
3888
  {
3889
3889
  variant: "warning",
3890
3890
  className: "mx-[var(--spacing-system-l)] mt-[var(--spacing-system-l)] w-auto content-lg:m-0 content-lg:w-full",
3891
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk7RADSQJFcjs.AlertDescription, { children: "That time was just taken \u2014 pick another slot below. (If you already submitted, check your email for a confirmation before rebooking.)" })
3891
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk4IXA5CJTcjs.AlertDescription, { children: "That time was just taken \u2014 pick another slot below. (If you already submitted, check your email for a confirmation before rebooking.)" })
3892
3892
  }
3893
3893
  ),
3894
3894
  timezone && durationMs != null ? (
@@ -24,15 +24,15 @@
24
24
 
25
25
 
26
26
 
27
- var _chunkVD4HVLXGcjs = require('../../chunk-VD4HVLXG.cjs');
27
+ var _chunkS23DIVIPcjs = require('../../chunk-S23DIVIP.cjs');
28
28
 
29
29
 
30
30
 
31
31
 
32
32
 
33
33
 
34
- var _chunkJEIAB7JQcjs = require('../../chunk-JEIAB7JQ.cjs');
35
- require('../../chunk-WSRMYHIV.cjs');
34
+ var _chunkG7RDJACGcjs = require('../../chunk-G7RDJACG.cjs');
35
+ require('../../chunk-F7WIKBRI.cjs');
36
36
 
37
37
 
38
38
 
@@ -47,9 +47,9 @@ require('../../chunk-WSRMYHIV.cjs');
47
47
 
48
48
 
49
49
 
50
- var _chunk7RADSQJFcjs = require('../../chunk-7RADSQJF.cjs');
50
+ var _chunk4IXA5CJTcjs = require('../../chunk-4IXA5CJT.cjs');
51
51
  require('../../chunk-2ANICXS7.cjs');
52
- require('../../chunk-NTGIQP7O.cjs');
52
+ require('../../chunk-QU5K52OP.cjs');
53
53
  require('../../chunk-AXBVN5SW.cjs');
54
54
  require('../../chunk-HQQE74RO.cjs');
55
55
  require('../../chunk-DEY6XXGO.cjs');
@@ -63,7 +63,7 @@ require('../../chunk-YUMFVQIN.cjs');
63
63
 
64
64
 
65
65
 
66
- var _chunk3C4U4UW6cjs = require('../../chunk-3C4U4UW6.cjs');
66
+ var _chunkXXM74P3Ncjs = require('../../chunk-XXM74P3N.cjs');
67
67
 
68
68
 
69
69
 
@@ -1951,4 +1951,4 @@ require('../../chunk-3ATAYP36.cjs');
1951
1951
 
1952
1952
 
1953
1953
 
1954
- exports.ASK_AI_OPEN_EVENT = _chunkQTYSYEHKcjs.ASK_AI_OPEN_EVENT; exports.ASK_AI_OPEN_WITH_REF_EVENT = _chunkQTYSYEHKcjs.ASK_AI_OPEN_WITH_REF_EVENT; exports.AppHeader = _chunkVD4HVLXGcjs.AppHeader; exports.AppLayout = _chunkVD4HVLXGcjs.AppLayout; exports.AppLayoutDrawer = _chunk7RADSQJFcjs.AppLayoutDrawerRoot; exports.AppLayoutDrawerBody = _chunk7RADSQJFcjs.AppLayoutDrawerBody; exports.AppLayoutDrawerClose = _chunk7RADSQJFcjs.AppLayoutDrawerClose; exports.AppLayoutDrawerContent = _chunk7RADSQJFcjs.AppLayoutDrawerContent; exports.AppLayoutDrawerDescription = _chunk7RADSQJFcjs.AppLayoutDrawerDescription; exports.AppLayoutDrawerFooter = _chunk7RADSQJFcjs.AppLayoutDrawerFooter; exports.AppLayoutDrawerHeader = _chunk7RADSQJFcjs.AppLayoutDrawerHeader; exports.AppLayoutDrawerTitle = _chunk7RADSQJFcjs.AppLayoutDrawerTitle; exports.AppLayoutDrawerTrigger = _chunk7RADSQJFcjs.AppLayoutDrawerTrigger; exports.HeaderButton = _chunk7RADSQJFcjs.HeaderButton; exports.HeaderGlobalSearch = _chunkVD4HVLXGcjs.HeaderGlobalSearch; exports.HeaderMingoButton = _chunkVD4HVLXGcjs.HeaderMingoButton; exports.HeaderOrganizationFilter = _chunkVD4HVLXGcjs.HeaderOrganizationFilter; exports.MOBILE_NAV_SHEET_ID = _chunkVD4HVLXGcjs.MOBILE_NAV_SHEET_ID; exports.MingoAiButton = _chunk3C4U4UW6cjs.MingoAiButton; exports.MobileBurgerMenu = _chunkVD4HVLXGcjs.MobileBurgerMenu; exports.MobileNavSheet = _chunkVD4HVLXGcjs.MobileNavSheet; exports.MobileNavigationDropdown = _chunkJEIAB7JQcjs.MobileNavigationDropdown; exports.MultiLevelNavigation = _chunkJEIAB7JQcjs.MultiLevelNavigation; exports.NAVIGATION_SIDEBAR_WIDTH_VAR = _chunkVD4HVLXGcjs.NAVIGATION_SIDEBAR_WIDTH_VAR; exports.NavItemRow = _chunkVD4HVLXGcjs.NavItemRow; exports.NavPanel = _chunkVD4HVLXGcjs.NavPanel; exports.NavigationItemBadge = _chunkVD4HVLXGcjs.NavigationItemBadge; exports.NavigationSidebar = _chunkVD4HVLXGcjs.NavigationSidebar; exports.SIDE_PANEL_FRAME_WIDTH = _chunkVD4HVLXGcjs.SIDE_PANEL_FRAME_WIDTH; exports.SiteFooter = _chunkVD4HVLXGcjs.SiteFooter; exports.SiteHeader = _chunkVD4HVLXGcjs.SiteHeader; exports.SlidingSidebar = _chunkVD4HVLXGcjs.SlidingSidebar; exports.StickySectionNav = _chunkJEIAB7JQcjs.StickySectionNav; exports.TicketAlertsButton = _chunkVD4HVLXGcjs.TicketAlertsButton; exports.TopNavigation = _chunkVD4HVLXGcjs.TopNavigation; exports.UnreadCountBadge = _chunk7RADSQJFcjs.UnreadCountBadge; exports.UnreadDot = _chunk7RADSQJFcjs.UnreadDot; exports.defaultRenderSiteNavLink = _chunkVD4HVLXGcjs.defaultRenderSiteNavLink; exports.isMegaMenu = _chunkVD4HVLXGcjs.isMegaMenu; exports.navLinkLabel = _chunkVD4HVLXGcjs.navLinkLabel; exports.openAskAi = _chunk3C4U4UW6cjs.openAskAi; exports.siteNavHasMobileMenus = _chunkVD4HVLXGcjs.siteNavHasMobileMenus; exports.useAppLayoutDrawerContainer = _chunk7RADSQJFcjs.useAppLayoutDrawerContainer; exports.useScrollSpy = _chunkJEIAB7JQcjs.useScrollSpy; exports.useSectionNavigation = _chunkJEIAB7JQcjs.useSectionNavigation;
1954
+ exports.ASK_AI_OPEN_EVENT = _chunkQTYSYEHKcjs.ASK_AI_OPEN_EVENT; exports.ASK_AI_OPEN_WITH_REF_EVENT = _chunkQTYSYEHKcjs.ASK_AI_OPEN_WITH_REF_EVENT; exports.AppHeader = _chunkS23DIVIPcjs.AppHeader; exports.AppLayout = _chunkS23DIVIPcjs.AppLayout; exports.AppLayoutDrawer = _chunk4IXA5CJTcjs.AppLayoutDrawerRoot; exports.AppLayoutDrawerBody = _chunk4IXA5CJTcjs.AppLayoutDrawerBody; exports.AppLayoutDrawerClose = _chunk4IXA5CJTcjs.AppLayoutDrawerClose; exports.AppLayoutDrawerContent = _chunk4IXA5CJTcjs.AppLayoutDrawerContent; exports.AppLayoutDrawerDescription = _chunk4IXA5CJTcjs.AppLayoutDrawerDescription; exports.AppLayoutDrawerFooter = _chunk4IXA5CJTcjs.AppLayoutDrawerFooter; exports.AppLayoutDrawerHeader = _chunk4IXA5CJTcjs.AppLayoutDrawerHeader; exports.AppLayoutDrawerTitle = _chunk4IXA5CJTcjs.AppLayoutDrawerTitle; exports.AppLayoutDrawerTrigger = _chunk4IXA5CJTcjs.AppLayoutDrawerTrigger; exports.HeaderButton = _chunk4IXA5CJTcjs.HeaderButton; exports.HeaderGlobalSearch = _chunkS23DIVIPcjs.HeaderGlobalSearch; exports.HeaderMingoButton = _chunkS23DIVIPcjs.HeaderMingoButton; exports.HeaderOrganizationFilter = _chunkS23DIVIPcjs.HeaderOrganizationFilter; exports.MOBILE_NAV_SHEET_ID = _chunkS23DIVIPcjs.MOBILE_NAV_SHEET_ID; exports.MingoAiButton = _chunkXXM74P3Ncjs.MingoAiButton; exports.MobileBurgerMenu = _chunkS23DIVIPcjs.MobileBurgerMenu; exports.MobileNavSheet = _chunkS23DIVIPcjs.MobileNavSheet; exports.MobileNavigationDropdown = _chunkG7RDJACGcjs.MobileNavigationDropdown; exports.MultiLevelNavigation = _chunkG7RDJACGcjs.MultiLevelNavigation; exports.NAVIGATION_SIDEBAR_WIDTH_VAR = _chunkS23DIVIPcjs.NAVIGATION_SIDEBAR_WIDTH_VAR; exports.NavItemRow = _chunkS23DIVIPcjs.NavItemRow; exports.NavPanel = _chunkS23DIVIPcjs.NavPanel; exports.NavigationItemBadge = _chunkS23DIVIPcjs.NavigationItemBadge; exports.NavigationSidebar = _chunkS23DIVIPcjs.NavigationSidebar; exports.SIDE_PANEL_FRAME_WIDTH = _chunkS23DIVIPcjs.SIDE_PANEL_FRAME_WIDTH; exports.SiteFooter = _chunkS23DIVIPcjs.SiteFooter; exports.SiteHeader = _chunkS23DIVIPcjs.SiteHeader; exports.SlidingSidebar = _chunkS23DIVIPcjs.SlidingSidebar; exports.StickySectionNav = _chunkG7RDJACGcjs.StickySectionNav; exports.TicketAlertsButton = _chunkS23DIVIPcjs.TicketAlertsButton; exports.TopNavigation = _chunkS23DIVIPcjs.TopNavigation; exports.UnreadCountBadge = _chunk4IXA5CJTcjs.UnreadCountBadge; exports.UnreadDot = _chunk4IXA5CJTcjs.UnreadDot; exports.defaultRenderSiteNavLink = _chunkS23DIVIPcjs.defaultRenderSiteNavLink; exports.isMegaMenu = _chunkS23DIVIPcjs.isMegaMenu; exports.navLinkLabel = _chunkS23DIVIPcjs.navLinkLabel; exports.openAskAi = _chunkXXM74P3Ncjs.openAskAi; exports.siteNavHasMobileMenus = _chunkS23DIVIPcjs.siteNavHasMobileMenus; exports.useAppLayoutDrawerContainer = _chunk4IXA5CJTcjs.useAppLayoutDrawerContainer; exports.useScrollSpy = _chunkG7RDJACGcjs.useScrollSpy; exports.useSectionNavigation = _chunkG7RDJACGcjs.useSectionNavigation;
@@ -7,12 +7,12 @@
7
7
 
8
8
 
9
9
 
10
- var _chunk33PJH2TFcjs = require('../../chunk-33PJH2TF.cjs');
10
+ var _chunkSYACKQYFcjs = require('../../chunk-SYACKQYF.cjs');
11
11
  require('../../chunk-VUSXDMCE.cjs');
12
- require('../../chunk-33RJU565.cjs');
13
- require('../../chunk-7RADSQJF.cjs');
12
+ require('../../chunk-EFCX5SYN.cjs');
13
+ require('../../chunk-4IXA5CJT.cjs');
14
14
  require('../../chunk-2ANICXS7.cjs');
15
- require('../../chunk-NTGIQP7O.cjs');
15
+ require('../../chunk-QU5K52OP.cjs');
16
16
  require('../../chunk-AXBVN5SW.cjs');
17
17
  require('../../chunk-HQQE74RO.cjs');
18
18
  require('../../chunk-DEY6XXGO.cjs');
@@ -23,7 +23,7 @@ require('../../chunk-A6P6DHEZ.cjs');
23
23
  require('../../chunk-MZ4KBSH7.cjs');
24
24
  require('../../chunk-T4BBZ5ST.cjs');
25
25
  require('../../chunk-YUMFVQIN.cjs');
26
- require('../../chunk-3C4U4UW6.cjs');
26
+ require('../../chunk-XXM74P3N.cjs');
27
27
  require('../../chunk-QTYSYEHK.cjs');
28
28
  require('../../chunk-F64VMOIB.cjs');
29
29
  require('../../chunk-3RFQPQ7Z.cjs');
@@ -1870,4 +1870,4 @@ require('../../chunk-3ATAYP36.cjs');
1870
1870
 
1871
1871
 
1872
1872
 
1873
- exports.OnboardingGuideDetailView = _chunk33PJH2TFcjs.OnboardingGuideDetailView; exports.OnboardingGuidesCatalogSkeleton = _chunk33PJH2TFcjs.OnboardingGuidesCatalogSkeleton; exports.OnboardingGuidesCatalogView = _chunk33PJH2TFcjs.OnboardingGuidesCatalogView; exports.onboardingGuideKeys = _chunk33PJH2TFcjs.onboardingGuideKeys; exports.useOnboardingGuide = _chunk33PJH2TFcjs.useOnboardingGuide; exports.useOnboardingGuideSections = _chunk33PJH2TFcjs.useOnboardingGuideSections; exports.useOnboardingGuides = _chunk33PJH2TFcjs.useOnboardingGuides;
1873
+ exports.OnboardingGuideDetailView = _chunkSYACKQYFcjs.OnboardingGuideDetailView; exports.OnboardingGuidesCatalogSkeleton = _chunkSYACKQYFcjs.OnboardingGuidesCatalogSkeleton; exports.OnboardingGuidesCatalogView = _chunkSYACKQYFcjs.OnboardingGuidesCatalogView; exports.onboardingGuideKeys = _chunkSYACKQYFcjs.onboardingGuideKeys; exports.useOnboardingGuide = _chunkSYACKQYFcjs.useOnboardingGuide; exports.useOnboardingGuideSections = _chunkSYACKQYFcjs.useOnboardingGuideSections; exports.useOnboardingGuides = _chunkSYACKQYFcjs.useOnboardingGuides;
@@ -23,14 +23,14 @@ var _react = require('react');
23
23
  // src/components/product-demo/registry.ts
24
24
  var PRODUCT_SCREEN_LOADERS = {
25
25
  "remote-session": () => Promise.resolve().then(() => _interopRequireWildcard(require("../../remote-session-SKNXYG6K.cjs"))),
26
- "software-update": () => Promise.resolve().then(() => _interopRequireWildcard(require("../../software-update-TSGISQV5.cjs"))),
27
- devices: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../devices-72YSJM4Z.cjs"))),
28
- policies: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../policies-5BZ5X2S4.cjs"))),
29
- "cloud-tenants": () => Promise.resolve().then(() => _interopRequireWildcard(require("../../cloud-tenants-PA5UU2KQ.cjs"))),
26
+ "software-update": () => Promise.resolve().then(() => _interopRequireWildcard(require("../../software-update-6T4GFJPA.cjs"))),
27
+ devices: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../devices-EFDFNWIV.cjs"))),
28
+ policies: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../policies-S3IF2U3D.cjs"))),
29
+ "cloud-tenants": () => Promise.resolve().then(() => _interopRequireWildcard(require("../../cloud-tenants-YUMG3O36.cjs"))),
30
30
  "tickets-board": () => Promise.resolve().then(() => _interopRequireWildcard(require("../../tickets-board-B2FH7Z4B.cjs"))),
31
- logs: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../logs-ODMJ3KOP.cjs"))),
32
- knowledge: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../knowledge-76RIDA7P.cjs"))),
33
- scripts: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../scripts-TWQPG46M.cjs")))
31
+ logs: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../logs-ZTYEI35Y.cjs"))),
32
+ knowledge: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../knowledge-UT2XI45N.cjs"))),
33
+ scripts: () => Promise.resolve().then(() => _interopRequireWildcard(require("../../scripts-IZWNCX5A.cjs")))
34
34
  };
35
35
 
36
36
  // src/components/product-demo/screen-keys.ts
@@ -1 +1 @@
1
- {"version":3,"file":"delivery-lists.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/delivery/delivery-lists.tsx"],"names":[],"mappings":"AA0DA,MAAM,WAAW,kBAAkB;IACjC;qCACiC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;uCACmC;IACnC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;kEAC8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;qEACiE;IACjE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAAC,EAC5B,oBAAiD,EACjD,qBAAoD,EACpD,cAAyC,EACzC,gBAA8C,GAC/C,GAAE,kBAAuB,+BAgJzB"}
1
+ {"version":3,"file":"delivery-lists.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/delivery/delivery-lists.tsx"],"names":[],"mappings":"AA+DA,MAAM,WAAW,kBAAkB;IACjC;qCACiC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;uCACmC;IACnC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;kEAC8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;qEACiE;IACjE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAAC,EAC5B,oBAAiD,EACjD,qBAAoD,EACpD,cAAyC,EACzC,gBAA8C,GAC/C,GAAE,kBAAuB,+BAqJzB"}
@@ -6,7 +6,9 @@ import { useScrollToHash } from "../../../hooks/use-scroll-to-hash.js";
6
6
  import { DEV_SECTION_PARAM_KEYS } from "../../../utils/dev-sections/dev-section-param-keys.js";
7
7
  import { contentFetch } from "../../../utils/embed-content-fetch.js";
8
8
  import { STICKY_HEADER_OFFSET_PX } from "../../../utils/same-page-hash-nav.js";
9
+ import { usePageDataSync } from "../../layout/page-data-sync.js";
9
10
  import { ListEmptyState } from "../../list-empty-state.js";
11
+ import { DataSyncLine } from "../../ui/data-attribution.js";
10
12
  import { LoadError } from "../../ui/error-state.js";
11
13
  import { DeliveryTable } from "./delivery-table.js";
12
14
  const DEFAULT_COMPLETED_ENDPOINT = "/api/delivery/completed";
@@ -25,6 +27,7 @@ function DeliveryLists({
25
27
  const [data, setData] = useState(null);
26
28
  const [isLoading, setIsLoading] = useState(true);
27
29
  const [error, setError] = useState(null);
30
+ const [sync, setSync] = useState(null);
28
31
  const searchQuery = searchParams.get(searchParamKey) || "";
29
32
  const taskTypeFilter = searchParams.get(taskTypeParamKey) || "all";
30
33
  useEffect(() => {
@@ -58,6 +61,7 @@ function DeliveryLists({
58
61
  completed: completedResult.items ?? [],
59
62
  inProgress: inProgressResult.items ?? []
60
63
  });
64
+ setSync(completedResult.sync ?? inProgressResult.sync ?? null);
61
65
  } catch (err) {
62
66
  if (cancelled) return;
63
67
  console.error("Error fetching delivery items:", err);
@@ -74,6 +78,7 @@ function DeliveryLists({
74
78
  const filteredCompleted = data?.completed || [];
75
79
  const filteredInProgress = data?.inProgress || [];
76
80
  useScrollToHash(data, { headerOffset: STICKY_HEADER_OFFSET_PX });
81
+ const syncInPage = usePageDataSync(sync, isLoading && !data);
77
82
  const showCompleted = true;
78
83
  const showInProgress = true;
79
84
  const hasActiveFilters = searchQuery !== "" || taskTypeFilter !== "all";
@@ -82,6 +87,7 @@ function DeliveryLists({
82
87
  return /* @__PURE__ */ jsx("div", { className: "w-full", children: /* @__PURE__ */ jsx(LoadError, { message: error, onRetry: () => window.location.reload() }) });
83
88
  }
84
89
  return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-[40px]", children: [
90
+ !syncInPage && /* @__PURE__ */ jsx(DataSyncLine, { sync, loading: isLoading && !data }),
85
91
  !isLoading && !hasResults && /* @__PURE__ */ jsx(
86
92
  ListEmptyState,
87
93
  {
@@ -17,20 +17,7 @@ export interface DevSectionViewProps {
17
17
  /** Which section to render — drives title, search, and filter
18
18
  * config via the `OPENFRAME_DEV_SECTIONS` registry. */
19
19
  sectionKey: OpenframeDevSectionKey;
20
- /** When set, renders the rich page-level hero (icon + h1 + description).
21
- * Omit for the compact tab-context heading. */
22
- hero?: {
23
- /** Pre-rendered icon JSX. Server components render the icon themselves
24
- * and pass the element here — function references can't cross the
25
- * server→client boundary, but React elements can. */
26
- icon: ReactNode;
27
- /** Hero title. Falls back to `OPENFRAME_DEV_SECTIONS[sectionKey].hero.title`
28
- * when omitted, so embedders can override the (OpenFrame-specific) default
29
- * copy without forking the registry. */
30
- title?: string;
31
- description: string;
32
- };
33
- /** Optional slot rendered BETWEEN the hero and the search/filter
20
+ /** Optional slot rendered BETWEEN the heading and the search/filter
34
21
  * controls. Use this for an entry-action surface that should sit
35
22
  * above the list (e.g. the Help Center's "Open a new ticket" form).
36
23
  * The slot is wrapped in the same `gap-10` flex column so spacing
@@ -40,12 +27,12 @@ export interface DevSectionViewProps {
40
27
  /** The page-specific list body. Reads URL params written by this
41
28
  * component (search input + filter pills). */
42
29
  children: ReactNode;
43
- /** Render this component's own title heading (hero or compact `h2`). Default
30
+ /** Render this component's own title heading (the section's `h2`). Default
44
31
  * `true` — the tab context renders the compact heading itself. Pass `false`
45
32
  * when the host already renders the title elsewhere (e.g. `DevSectionPage`
46
33
  * routes it through the unified `PageLayout` `TitleBlock`): then only the
47
34
  * search + filter controls + list render, with no duplicate heading. */
48
35
  showHeading?: boolean;
49
36
  }
50
- export declare function DevSectionView({ sectionKey, hero, preControls, children, showHeading }: DevSectionViewProps): import("react").JSX.Element;
37
+ export declare function DevSectionView({ sectionKey, preControls, children, showHeading }: DevSectionViewProps): import("react").JSX.Element;
51
38
  //# sourceMappingURL=dev-section-view.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dev-section-view.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/dev-section/dev-section-view.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,oDAAoD,CAAC;AAI5D,MAAM,WAAW,mBAAmB;IAClC;4DACwD;IACxD,UAAU,EAAE,sBAAsB,CAAC;IACnC;oDACgD;IAChD,IAAI,CAAC,EAAE;QACL;;8DAEsD;QACtD,IAAI,EAAE,SAAS,CAAC;QAChB;;iDAEyC;QACzC,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF;;;;;uEAKmE;IACnE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;mDAC+C;IAC/C,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;6EAIyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAkB,EAAE,EAAE,mBAAmB,+BA6GlH"}
1
+ {"version":3,"file":"dev-section-view.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/dev-section/dev-section-view.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,oDAAoD,CAAC;AAM5D,MAAM,WAAW,mBAAmB;IAClC;4DACwD;IACxD,UAAU,EAAE,sBAAsB,CAAC;IACnC;;;;;uEAKmE;IACnE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;mDAC+C;IAC/C,QAAQ,EAAE,SAAS,CAAC;IACpB;;;;6EAIyE;IACzE,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAkB,EAAE,EAAE,mBAAmB,+BAqG5G"}
@@ -6,8 +6,10 @@ import {
6
6
  OPENFRAME_DEV_SECTIONS
7
7
  } from "../../../utils/dev-sections/openframe-dev-sections.js";
8
8
  import { StatusFilterComponent } from "../../features/index.js";
9
+ import { PageDataSyncProvider, PageDataSyncRow } from "../../layout/page-data-sync.js";
10
+ import { SectionHeading } from "../../layout/page-heading.js";
9
11
  import { SearchInput } from "../../ui/index.js";
10
- function DevSectionView({ sectionKey, hero, preControls, children, showHeading = true }) {
12
+ function DevSectionView({ sectionKey, preControls, children, showHeading = true }) {
11
13
  const section = OPENFRAME_DEV_SECTIONS[sectionKey];
12
14
  const router = useRouter();
13
15
  const pathname = usePathname();
@@ -45,17 +47,8 @@ function DevSectionView({ sectionKey, hero, preControls, children, showHeading =
45
47
  else params.set(filter.paramKey, value);
46
48
  router.replace(`${pathname}?${params.toString()}`, { scroll: false });
47
49
  };
48
- return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-10", children: [
49
- showHeading && (hero ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
50
- /* @__PURE__ */ jsxs("h1", { className: "flex items-center gap-3 tracking-[-1.12px] text-ods-text-primary text-h1", children: [
51
- hero.icon,
52
- hero.title ?? section.hero.title
53
- ] }),
54
- /* @__PURE__ */ jsx("p", { className: "max-w-3xl text-ods-text-secondary text-h4", children: hero.description })
55
- ] }) : /* @__PURE__ */ jsx("div", { className: "flex w-full items-center justify-between", children: /* @__PURE__ */ jsxs("h2", { className: "font-['Azeret_Mono'] text-[32px] font-semibold leading-[40px] tracking-[-0.64px] text-ods-text-primary content-md:text-[40px] content-md:leading-[48px] content-md:tracking-[-0.8px] content-lg:text-[48px] content-lg:leading-[56px] content-lg:tracking-[-0.96px]", children: [
56
- section.hero.title,
57
- /* @__PURE__ */ jsx("span", { className: "text-ods-accent", children: ":" })
58
- ] }) })),
50
+ return /* @__PURE__ */ jsx(PageDataSyncProvider, { children: /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-10", children: [
51
+ showHeading ? /* @__PURE__ */ jsx(SectionHeading, { title: section.hero.title, punctuation: ":", action: /* @__PURE__ */ jsx(PageDataSyncRow, { inline: true }) }) : /* @__PURE__ */ jsx(PageDataSyncRow, {}),
59
52
  preControls,
60
53
  (search || filter) && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
61
54
  search && /* @__PURE__ */ jsx(
@@ -78,7 +71,7 @@ function DevSectionView({ sectionKey, hero, preControls, children, showHeading =
78
71
  )
79
72
  ] }),
80
73
  children
81
- ] });
74
+ ] }) });
82
75
  }
83
76
  export {
84
77
  DevSectionView
@@ -48,8 +48,6 @@ export interface LegalDocumentPageProps {
48
48
  emptyStateMessage?: string;
49
49
  /** SSR-prepared document, if available. */
50
50
  initialData?: LegalDocument | null;
51
- /** SSR-prepared formatted "Last Updated" label. Stable across hydration. */
52
- initialLastUpdatedLabel?: string | null;
53
51
  /** Override the default `/api/legal/<docType>` endpoint
54
52
  * (reverse-proxy embedders, alternate API paths). */
55
53
  apiEndpoint?: string;
@@ -85,5 +83,5 @@ export interface LegalDocumentPageProps {
85
83
  * null for one that states neither. One wording for every legal surface.
86
84
  */
87
85
  export declare function legalDocumentStampLabel(doc: Pick<LegalDocument, 'version' | 'effectiveDate'> | null | undefined): string | null;
88
- export declare function LegalDocumentPage({ docType, title: titleProp, fallbackDescription, contactEmail, errorContactPrompt, errorTitle: errorTitleProp, emptyStateMessage: emptyStateMessageProp, initialData, initialLastUpdatedLabel, apiEndpoint, MarkdownRenderer, documentsEndpoint, backButton, faq, shell, }: LegalDocumentPageProps): import("react").JSX.Element;
86
+ export declare function LegalDocumentPage({ docType, title: titleProp, fallbackDescription, contactEmail, errorContactPrompt, errorTitle: errorTitleProp, emptyStateMessage: emptyStateMessageProp, initialData, apiEndpoint, MarkdownRenderer, documentsEndpoint, backButton, faq, shell, }: LegalDocumentPageProps): import("react").JSX.Element;
89
87
  //# sourceMappingURL=legal-document-page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"legal-document-page.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/legal-document/legal-document-page.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAI3C,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAInF,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGpE,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC;;qDAEiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB;0EACsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;wEACoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;4DACwD;IACxD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,4EAA4E;IAC5E,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC;0DACsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,aAAa,CAAC,kCAAkC,CAAC,CAAC;IACrE;mEAC+D;IAC/D,UAAU,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IACvD;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C;;sCAEkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,eAAe,CAAC,GAAG,IAAI,GAAG,SAAS,GACvE,MAAM,GAAG,IAAI,CAMf;AAED,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,KAAK,EAAE,SAAS,EAChB,mBAAwB,EACxB,YAAY,EACZ,kBAAyE,EACzE,UAAU,EAAE,cAAc,EAC1B,iBAAiB,EAAE,qBAAqB,EACxC,WAAkB,EAClB,uBAA8B,EAC9B,WAAW,EACX,gBAAuC,EACvC,iBAAiB,EACjB,UAAU,EACV,GAAG,EACH,KAAY,GACb,EAAE,sBAAsB,+BAkGxB"}
1
+ {"version":3,"file":"legal-document-page.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/legal-document/legal-document-page.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,EAA4B,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKnF,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGpE,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC;;qDAEiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB;0EACsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;wEACoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;4DACwD;IACxD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC;0DACsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,aAAa,CAAC,kCAAkC,CAAC,CAAC;IACrE;mEAC+D;IAC/D,UAAU,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,KAAK,CAAC;IACvD;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C;;sCAEkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,eAAe,CAAC,GAAG,IAAI,GAAG,SAAS,GACvE,MAAM,GAAG,IAAI,CAMf;AAED,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,KAAK,EAAE,SAAS,EAChB,mBAAwB,EACxB,YAAY,EACZ,kBAAyE,EACzE,UAAU,EAAE,cAAc,EAC1B,iBAAiB,EAAE,qBAAqB,EACxC,WAAkB,EAClB,WAAW,EACX,gBAAuC,EACvC,iBAAiB,EACjB,UAAU,EACV,GAAG,EACH,KAAY,GACb,EAAE,sBAAsB,+BA6FxB"}
@@ -2,10 +2,10 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import Link from "../../../embed-shims/next-link.js";
4
4
  import { useRouter } from "../../../embed-shims/next-navigation.js";
5
- import { formatLegalDate } from "../../../utils/format.js";
6
5
  import { FaqSection, pageFaqProps } from "../../faq/faq-section.js";
7
6
  import { UnifiedSkeleton } from "../../loading/unified-skeleton.js";
8
7
  import { PageShell, PageLayout } from "../../ui/index.js";
8
+ import { DataSyncLine } from "../../ui/data-attribution.js";
9
9
  import { RichMarkdownRenderer } from "../../ui/markdown/index.js";
10
10
  import { useLegalDocs } from "./use-legal-docs.js";
11
11
  import { useLegalDocuments } from "./use-legal-documents.js";
@@ -25,7 +25,6 @@ function LegalDocumentPage({
25
25
  errorTitle: errorTitleProp,
26
26
  emptyStateMessage: emptyStateMessageProp,
27
27
  initialData = null,
28
- initialLastUpdatedLabel = null,
29
28
  apiEndpoint,
30
29
  MarkdownRenderer = RichMarkdownRenderer,
31
30
  documentsEndpoint,
@@ -46,14 +45,9 @@ function LegalDocumentPage({
46
45
  const faqSlot = faq && faqTopic ? { ...faq, topic: faqTopic } : null;
47
46
  const errorTitle = errorTitleProp ?? `Unable to load ${title}`;
48
47
  const emptyStateMessage = emptyStateMessageProp ?? `${title} is not available at this time.`;
49
- const fallbackLastUpdatedLabel = data?.lastSynced != null ? formatLegalDate(data.lastSynced) : null;
50
- const effectiveLastUpdatedLabel = initialLastUpdatedLabel ?? fallbackLastUpdatedLabel;
51
- const subtitle = legalDocumentStampLabel(data) ?? (effectiveLastUpdatedLabel ? `Last Updated: ${effectiveLastUpdatedLabel}` : fallbackDescription);
48
+ const subtitle = legalDocumentStampLabel(data) ?? fallbackDescription;
52
49
  const inner = /* @__PURE__ */ jsxs(PageLayout, { title, subtitle, backButton: backCfg, titleSize: "h1", titleWrap: true, children: [
53
- data?.sourceFile && /* @__PURE__ */ jsxs("p", { className: "text-ods-text-secondary opacity-75 text-h6", children: [
54
- "Source: ",
55
- data.sourceFile
56
- ] }),
50
+ /* @__PURE__ */ jsx(DataSyncLine, { sync: data ? { source: "github", syncedAt: data.lastSynced } : null, loading: isLoading && !data }),
57
51
  /* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col items-start gap-6 lg:flex-row lg:gap-10", children: /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx("div", { className: "w-full", children: /* @__PURE__ */ jsx("article", { className: "space-y-2", children: isLoading ? (
58
52
  // Loading skeleton matching Knowledge Hub pattern
59
53
  /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
@@ -1 +1 @@
1
- {"version":3,"file":"roadmap-view.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/roadmap/roadmap-view.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAI1E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAQpE,MAAM,WAAW,gBAAgB;IAC/B;0BACsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gFAAgF;IAChF,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,yDAAyD;IACzD,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC;iEAC6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;iEAC6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAA2B,EAC3B,YAAY,EACZ,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAyC,EACzC,cAAyC,GAC1C,GAAE,gBAAqB,+BA0DvB"}
1
+ {"version":3,"file":"roadmap-view.d.ts","sourceRoot":"","sources":["../../../../src/components/shared/roadmap/roadmap-view.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAM1E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAUpE,MAAM,WAAW,gBAAgB;IAC/B;0BACsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gFAAgF;IAChF,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,yDAAyD;IACzD,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC;iEAC6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;iEAC6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAA2B,EAC3B,YAAY,EACZ,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAyC,EACzC,cAAyC,GAC1C,GAAE,gBAAqB,+BAsEvB"}
@@ -1,15 +1,18 @@
1
1
  "use client";
2
- import { jsx } from "react/jsx-runtime";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useMemo } from "react";
4
4
  import { useSearchParams } from "../../../embed-shims/index.js";
5
5
  import { useScrollToHash } from "../../../hooks/use-scroll-to-hash.js";
6
6
  import { useSelfFetch } from "../../../hooks/use-self-fetch.js";
7
7
  import { DEV_SECTION_PARAM_KEYS } from "../../../utils/dev-sections/dev-section-param-keys.js";
8
8
  import { STICKY_HEADER_OFFSET_PX } from "../../../utils/same-page-hash-nav.js";
9
+ import { usePageDataSync } from "../../layout/page-data-sync.js";
10
+ import { DataSyncLine } from "../../ui/data-attribution.js";
9
11
  import { LoadError } from "../../ui/error-state.js";
10
12
  import { RoadmapGrid } from "./roadmap-grid.js";
11
13
  import { RoadmapGridSkeleton } from "./roadmap-grid-skeleton.js";
12
14
  const DEFAULT_ENDPOINT = "/api/roadmap";
15
+ const SYNCED_LIST_CLASS = "flex w-full flex-col gap-[var(--spacing-system-lf)]";
13
16
  const DEFAULT_SEARCH_PARAM_KEY = DEV_SECTION_PARAM_KEYS.search;
14
17
  const DEFAULT_STATUS_PARAM_KEY = DEV_SECTION_PARAM_KEYS.status;
15
18
  function RoadmapView({
@@ -30,29 +33,38 @@ function RoadmapView({
30
33
  const qs = listParams.toString();
31
34
  const url = qs ? `${endpoint}?${qs}` : endpoint;
32
35
  const initialData = useMemo(() => initialItems ? { items: initialItems } : void 0, [initialItems]);
33
- const { data, setData, isLoading, error, reload } = useSelfFetch(url, { initialData });
36
+ const { data, setData, isLoading, error, reload } = useSelfFetch(url, {
37
+ initialData
38
+ });
34
39
  const items = data?.items ?? [];
35
40
  useScrollToHash(data, { headerOffset: STICKY_HEADER_OFFSET_PX });
41
+ const syncInPage = usePageDataSync(data?.sync, isLoading && !data);
36
42
  if (error) {
37
43
  return /* @__PURE__ */ jsx(LoadError, { message: "Failed to load roadmap.", onRetry: reload });
38
44
  }
39
45
  if (isLoading && !data) {
40
- return /* @__PURE__ */ jsx(RoadmapGridSkeleton, { showLeftMargin });
46
+ return /* @__PURE__ */ jsxs("div", { className: SYNCED_LIST_CLASS, children: [
47
+ !syncInPage && /* @__PURE__ */ jsx(DataSyncLine, { loading: true }),
48
+ /* @__PURE__ */ jsx(RoadmapGridSkeleton, { showLeftMargin })
49
+ ] });
41
50
  }
42
- return /* @__PURE__ */ jsx(
43
- RoadmapGrid,
44
- {
45
- items,
46
- showLeftMargin,
47
- buildRefreshUrl,
48
- votingOptions,
49
- groupByQuarter: true,
50
- hasActiveFilters: search !== "" || status !== "all",
51
- onItemUpdate: (updated) => setData(
52
- (prev) => prev ? { ...prev, items: (prev.items ?? []).map((it) => it.id === updated.id ? updated : it) } : prev
53
- )
54
- }
55
- );
51
+ return /* @__PURE__ */ jsxs("div", { className: SYNCED_LIST_CLASS, children: [
52
+ !syncInPage && /* @__PURE__ */ jsx(DataSyncLine, { sync: data?.sync }),
53
+ /* @__PURE__ */ jsx(
54
+ RoadmapGrid,
55
+ {
56
+ items,
57
+ showLeftMargin,
58
+ buildRefreshUrl,
59
+ votingOptions,
60
+ groupByQuarter: true,
61
+ hasActiveFilters: search !== "" || status !== "all",
62
+ onItemUpdate: (updated) => setData(
63
+ (prev) => prev ? { ...prev, items: (prev.items ?? []).map((it) => it.id === updated.id ? updated : it) } : prev
64
+ )
65
+ }
66
+ )
67
+ ] });
56
68
  }
57
69
  export {
58
70
  RoadmapView