@liiift-studio/sanity-visitor-insights 0.75.0 → 0.76.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +46 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46 -17
- package/dist/index.mjs.map +1 -1
- package/dist/{ranges-DfjCK0XY.d.mts → ranges-B2W_3Z0t.d.mts} +2 -0
- package/dist/{ranges-DfjCK0XY.d.ts → ranges-B2W_3Z0t.d.ts} +2 -0
- package/dist/server.d.mts +4 -4
- package/dist/server.d.ts +4 -4
- package/dist/server.js +6 -4
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +6 -4
- package/dist/server.mjs.map +1 -1
- package/dist/testing.d.mts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/{vercel-CNoYeZgN.d.mts → vercel-D0tEOU9d.d.mts} +9 -0
- package/dist/{vercel-CNoYeZgN.d.ts → vercel-D0tEOU9d.d.ts} +9 -0
- package/package.json +1 -1
- package/src/reportData.ts +2 -0
- package/src/server/orders.ts +20 -5
- package/src/server/reports/reports.test.ts +53 -0
- package/src/studio/Figure.tsx +98 -0
- package/src/studio/panels.test.tsx +92 -1
- package/src/studio/panels.tsx +18 -19
- package/src/studio/useReport.ts +8 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-
|
|
4
|
-
export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DateRange, j as DiagnosticCheck, E as EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneySegment, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-
|
|
3
|
+
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-B2W_3Z0t.mjs';
|
|
4
|
+
export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DateRange, j as DiagnosticCheck, E as EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneySegment, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-B2W_3Z0t.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Data hook for the Studio panels.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as sanity from 'sanity';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-
|
|
4
|
-
export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DateRange, j as DiagnosticCheck, E as EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneySegment, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-
|
|
3
|
+
import { R as ReportEnvelope, a as ReportName, b as RangeKey, M as MetricValue, A as AcquisitionData, c as MeasurementHealthData, D as DiagnosticReport, J as JourneyData, T as TypefaceInterestData } from './ranges-B2W_3Z0t.js';
|
|
4
|
+
export { C as CaptureBasis, d as CaptureEstimate, e as CaptureModel, f as CheckStatus, g as Coverage, h as CrossSourceDay, i as DateRange, j as DiagnosticCheck, E as EmailCampaign, k as EventCutover, l as JourneyOutcome, m as JourneySegment, n as JourneyStep, L as LandingPage, o as LicenceTierRow, P as PREEXISTING, p as REPORT_NAMES, q as ReportError, S as SiteAnalyticsConfig, r as SourceName, s as SourceRow, t as SourceStatus, u as TimelineEvent, v as TypefaceInterestRow, U as UnavailableReason, w as coverageForRange, x as estimated, y as isReportName, z as ok, B as partial, F as previousRange, G as resolveRange, H as unavailable, I as validateSiteConfig, K as valueOrNull } from './ranges-B2W_3Z0t.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Data hook for the Studio panels.
|
package/dist/index.js
CHANGED
|
@@ -165,7 +165,7 @@ function useReport({ apiBaseUrl, report, range, custom, compare, enabled = true
|
|
|
165
165
|
}
|
|
166
166
|
void run();
|
|
167
167
|
return () => controller.abort();
|
|
168
|
-
}, [client, apiBaseUrl, report, range, custom?.start, custom?.end, nonce, enabled]);
|
|
168
|
+
}, [client, apiBaseUrl, report, range, custom?.start, custom?.end, compare, nonce, enabled]);
|
|
169
169
|
return { state, reload };
|
|
170
170
|
}
|
|
171
171
|
|
|
@@ -814,6 +814,21 @@ function gapLabel(delta, measurement, entry = 0) {
|
|
|
814
814
|
}
|
|
815
815
|
var partialSlot = { height: 10 };
|
|
816
816
|
var funnelSegmentKey = { display: "flex", gap: 14, flexWrap: "wrap", paddingTop: 4 };
|
|
817
|
+
var ladderRow = {
|
|
818
|
+
display: "grid",
|
|
819
|
+
gridTemplateColumns: "minmax(80px, 1.1fr) minmax(60px, 0.8fr) minmax(60px, 2fr) auto",
|
|
820
|
+
gap: 10,
|
|
821
|
+
alignItems: "center"
|
|
822
|
+
};
|
|
823
|
+
var ladderTrack = {
|
|
824
|
+
position: "relative",
|
|
825
|
+
height: 8,
|
|
826
|
+
borderRadius: 4,
|
|
827
|
+
overflow: "hidden",
|
|
828
|
+
background: mark("bar.track")
|
|
829
|
+
};
|
|
830
|
+
var ladderValue = { textAlign: "right", fontVariantNumeric: "tabular-nums", whiteSpace: "nowrap" };
|
|
831
|
+
var ladderMoney = { opacity: 0.7 };
|
|
817
832
|
var funnelList = { listStyle: "none", margin: 0, padding: 0 };
|
|
818
833
|
var funnelItem = { display: "grid", gap: 4 };
|
|
819
834
|
function funnelGapStyle(hasBar) {
|
|
@@ -1039,6 +1054,34 @@ function EstimateDotPlot({
|
|
|
1039
1054
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size: 0, muted: true, children: "The rule marks 100%." })
|
|
1040
1055
|
] });
|
|
1041
1056
|
}
|
|
1057
|
+
function LicenceLadder({ rows, currency }) {
|
|
1058
|
+
if (rows.length === 0) return null;
|
|
1059
|
+
const peak = Math.max(1, ...rows.map((row) => row.orders));
|
|
1060
|
+
const types = [];
|
|
1061
|
+
for (const row of rows) {
|
|
1062
|
+
const facet = types.find((t) => t.type === row.type);
|
|
1063
|
+
if (facet) facet.rungs.push(row);
|
|
1064
|
+
else types.push({ type: row.type, rungs: [row] });
|
|
1065
|
+
}
|
|
1066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Stack, { space: 4, children: types.map((facet) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_sanity_ui_compat.Stack, { space: 2, children: [
|
|
1067
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size: 1, weight: "semibold", children: facet.type }),
|
|
1068
|
+
facet.rungs.map((row, index) => {
|
|
1069
|
+
const sameTierAsAbove = index > 0 && facet.rungs[index - 1]?.tier === row.tier;
|
|
1070
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: ladderRow, children: [
|
|
1071
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size: 0, muted: true, children: sameTierAsAbove ? "" : row.tier }),
|
|
1072
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_sanity_ui_compat.Text, { size: 0, muted: true, children: row.term }),
|
|
1073
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { "aria-hidden": "true", style: ladderTrack, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...barFill, width: `${Math.max(2, row.orders / peak * 100)}%` } }) }),
|
|
1074
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_sanity_ui_compat.Text, { size: 0, style: ladderValue, children: [
|
|
1075
|
+
formatCount(row.orders),
|
|
1076
|
+
row.revenue !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: ladderMoney, children: [
|
|
1077
|
+
" \xB7 ",
|
|
1078
|
+
formatMoney(row.revenue, currency)
|
|
1079
|
+
] })
|
|
1080
|
+
] })
|
|
1081
|
+
] }, `${row.tier}\0${row.term}`);
|
|
1082
|
+
})
|
|
1083
|
+
] }, facet.type)) });
|
|
1084
|
+
}
|
|
1042
1085
|
function RatioFigure({
|
|
1043
1086
|
value,
|
|
1044
1087
|
format,
|
|
@@ -3291,22 +3334,8 @@ function TypefaceInterestPanel({ data }) {
|
|
|
3291
3334
|
] }),
|
|
3292
3335
|
(data.licences?.length ?? 0) > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_sanity_ui_compat3.Stack, { space: 3, children: [
|
|
3293
3336
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionTitle, { title: "How licences sell" }),
|
|
3294
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 1, muted: true, children: "From your orders, so exact.
|
|
3295
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3296
|
-
ProportionChart,
|
|
3297
|
-
{
|
|
3298
|
-
bars: (data.licences ?? []).map((row) => ({
|
|
3299
|
-
key: `${row.type}-${row.tier}-${row.term}`,
|
|
3300
|
-
label: `${row.type} \xB7 ${row.tier}`,
|
|
3301
|
-
sublabel: row.term,
|
|
3302
|
-
// Ranked by revenue where it is known, by orders where it is not — a
|
|
3303
|
-
// count would put a cheap tier above one worth ten times as much.
|
|
3304
|
-
value: row.revenue ?? row.orders
|
|
3305
|
-
})),
|
|
3306
|
-
format: (value) => (data.licences ?? []).some((r) => r.revenue !== null) ? formatMoney(value, data.currency ?? null) : `${formatCount(value)} orders`,
|
|
3307
|
-
totalLabel: (data.licences ?? []).some((r) => r.revenue !== null) ? "Total across licences" : "Total licence lines"
|
|
3308
|
-
}
|
|
3309
|
-
)
|
|
3337
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 1, muted: true, children: "From your orders, so exact. Bars are orders; the money beside them is that order total split evenly across the licences on it, so it is a share rather than a price." }),
|
|
3338
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LicenceLadder, { rows: data.licences ?? [], currency: data.currency ?? null })
|
|
3310
3339
|
] }),
|
|
3311
3340
|
data.revenueIsApportioned && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_sanity_ui_compat3.Text, { size: 0, muted: true, children: "An order covering several families is split evenly between them, because the order documents carry no per-line value." }),
|
|
3312
3341
|
finiteOrNull(data.unattributedRevenue) !== null && data.unattributedRevenue > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_sanity_ui_compat3.Text, { size: 0, muted: true, children: [
|