@qoretechnologies/reqraft 0.10.57-pr.127.ge03fd3a → 0.10.57

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 (53) hide show
  1. package/.claude/CLAUDE.md +1 -1
  2. package/README.md +1 -1
  3. package/design/TRACKING.md +82 -2
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +3 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/tracking/ui/ExperimentCard.d.ts +55 -0
  9. package/dist/tracking/ui/ExperimentCard.d.ts.map +1 -0
  10. package/dist/tracking/ui/ExperimentCard.js +396 -0
  11. package/dist/tracking/ui/ExperimentCard.js.map +1 -0
  12. package/dist/tracking/ui/ExperimentsOverlay.d.ts +59 -0
  13. package/dist/tracking/ui/ExperimentsOverlay.d.ts.map +1 -0
  14. package/dist/tracking/ui/ExperimentsOverlay.js +359 -0
  15. package/dist/tracking/ui/ExperimentsOverlay.js.map +1 -0
  16. package/dist/tracking/ui/anchor.d.ts +107 -0
  17. package/dist/tracking/ui/anchor.d.ts.map +1 -0
  18. package/dist/tracking/ui/anchor.js +108 -0
  19. package/dist/tracking/ui/anchor.js.map +1 -0
  20. package/dist/tracking/ui/card.d.ts +121 -0
  21. package/dist/tracking/ui/card.d.ts.map +1 -0
  22. package/dist/tracking/ui/card.js +417 -0
  23. package/dist/tracking/ui/card.js.map +1 -0
  24. package/dist/tracking/ui/client.d.ts +42 -0
  25. package/dist/tracking/ui/client.d.ts.map +1 -0
  26. package/dist/tracking/ui/client.js +123 -0
  27. package/dist/tracking/ui/client.js.map +1 -0
  28. package/dist/tracking/ui/index.d.ts +20 -0
  29. package/dist/tracking/ui/index.d.ts.map +1 -0
  30. package/dist/tracking/ui/index.js +60 -0
  31. package/dist/tracking/ui/index.js.map +1 -0
  32. package/dist/tracking/ui/types.d.ts +120 -0
  33. package/dist/tracking/ui/types.d.ts.map +1 -0
  34. package/dist/tracking/ui/types.js +8 -0
  35. package/dist/tracking/ui/types.js.map +1 -0
  36. package/dist/tracking/ui/useExperimentsAdmin.d.ts +31 -0
  37. package/dist/tracking/ui/useExperimentsAdmin.d.ts.map +1 -0
  38. package/dist/tracking/ui/useExperimentsAdmin.js +136 -0
  39. package/dist/tracking/ui/useExperimentsAdmin.js.map +1 -0
  40. package/package.json +3 -3
  41. package/src/index.tsx +3 -1
  42. package/src/stories/tracking.tsx +206 -0
  43. package/src/tracking/ui/ExperimentCard.stories.tsx +296 -0
  44. package/src/tracking/ui/ExperimentCard.tsx +667 -0
  45. package/src/tracking/ui/ExperimentsOverlay.stories.tsx +155 -0
  46. package/src/tracking/ui/ExperimentsOverlay.tsx +437 -0
  47. package/src/tracking/ui/anchor.ts +180 -0
  48. package/src/tracking/ui/card.ts +464 -0
  49. package/src/tracking/ui/client.ts +117 -0
  50. package/src/tracking/ui/index.ts +77 -0
  51. package/src/tracking/ui/types.ts +110 -0
  52. package/src/tracking/ui/useExperimentsAdmin.ts +103 -0
  53. package/src/tracking/react/Experiment.stories.tsx +0 -174
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ /**
3
+ * The plain logic behind the A/B test overlay: where the handle and the card go (anchored to the
4
+ * tested element, flipped above or below to stay in view), and which card is open (hover,
5
+ * keyboard focus, a click; closed by ✕, Esc or a click outside). No React, no DOM
6
+ * (unit-tested in `__tests__/tracking/anchor.test.ts`).
7
+ */
8
+ var __assign = (this && this.__assign) || function () {
9
+ __assign = Object.assign || function(t) {
10
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
11
+ s = arguments[i];
12
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
13
+ t[p] = s[p];
14
+ }
15
+ return t;
16
+ };
17
+ return __assign.apply(this, arguments);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.OUTSIDE_IGNORE = exports.activatesRow = exports.cardReducer = exports.openCard = exports.CLOSED = exports.placeCard = exports.CARD_MIN_HEIGHT = exports.CARD_MAX_WIDTH = void 0;
21
+ exports.CARD_MAX_WIDTH = 440;
22
+ /** The card never gets shorter than this; a smaller window scrolls inside it. */
23
+ exports.CARD_MIN_HEIGHT = 180;
24
+ var clamp = function (n, lo, hi) { return Math.min(Math.max(n, lo), Math.max(lo, hi)); };
25
+ /**
26
+ * Where the outline, the handle and the card go. The handle sits at the element's top-left
27
+ * corner and, while the element is partly scrolled away, slides down to stay on its visible
28
+ * part. The card hangs under the handle, or above it when there is more room there than
29
+ * below and it does not fit below; its height is capped to that room (it scrolls inside).
30
+ */
31
+ var placeCard = function (_a) {
32
+ var box = _a.box, viewport = _a.viewport, scroll = _a.scroll, handle = _a.handle, card = _a.card, topInset = _a.topInset, _b = _a.edge, edge = _b === void 0 ? 12 : _b, _c = _a.gap, gap = _c === void 0 ? 8 : _c, _d = _a.maxWidth, maxWidth = _d === void 0 ? exports.CARD_MAX_WIDTH : _d, current = _a.side;
33
+ var bottom = box.top + box.height;
34
+ var right = box.left + box.width;
35
+ var outline = {
36
+ top: box.top + scroll.y,
37
+ left: box.left + scroll.x,
38
+ width: box.width,
39
+ height: box.height,
40
+ };
41
+ var visible = bottom > topInset && box.top < viewport.height && right > 0 && box.left < viewport.width;
42
+ // The handle: inside the element, below the header, above the element's bottom edge.
43
+ var hTop = Math.min(Math.max(box.top + edge, topInset + edge), bottom - handle.height - edge);
44
+ var hLeft = clamp(box.left + edge, edge, viewport.width - handle.width - edge);
45
+ var handlePos = { top: Math.max(hTop, box.top) + scroll.y, left: hLeft + scroll.x };
46
+ if (!card)
47
+ return { visible: visible, outline: outline, handle: handlePos, card: null };
48
+ var width = Math.min(maxWidth, viewport.width - 2 * edge);
49
+ var left = clamp(hLeft, edge, viewport.width - width - edge);
50
+ var handleTop = handlePos.top - scroll.y;
51
+ var handleBottom = handleTop + handle.height;
52
+ var below = viewport.height - edge - (handleBottom + gap);
53
+ var above = handleTop - gap - (topInset + edge);
54
+ var fits = { below: card.height <= below, above: card.height <= above };
55
+ var side = current && fits[current] ? current
56
+ : fits.below || below >= above ? 'below'
57
+ : 'above';
58
+ var room = Math.max(side === 'below' ? below : above, exports.CARD_MIN_HEIGHT);
59
+ var height = Math.min(card.height, room);
60
+ var top = side === 'below' ? handleBottom + gap : handleTop - gap - height;
61
+ return {
62
+ visible: visible,
63
+ outline: outline,
64
+ handle: handlePos,
65
+ card: { top: top + scroll.y, left: left + scroll.x, width: width, maxHeight: room, side: side },
66
+ };
67
+ };
68
+ exports.placeCard = placeCard;
69
+ exports.CLOSED = { hovered: null, focused: null, pinned: null, dismissed: null };
70
+ /** The one open card: a click wins, then the keyboard, then the pointer. */
71
+ var openCard = function (s) { var _a, _b; return (_b = (_a = s.pinned) !== null && _a !== void 0 ? _a : s.focused) !== null && _b !== void 0 ? _b : (s.hovered !== s.dismissed ? s.hovered : null); };
72
+ exports.openCard = openCard;
73
+ var cardReducer = function (s, e) {
74
+ var _a;
75
+ switch (e.type) {
76
+ case 'hover':
77
+ if (e.key === s.hovered)
78
+ return s;
79
+ // Leaving the element a card was closed on lets hovering open it again.
80
+ return __assign(__assign({}, s), { hovered: e.key, dismissed: s.dismissed && s.dismissed !== e.key ? null : s.dismissed });
81
+ case 'focus':
82
+ return s.focused === e.key && s.dismissed !== e.key ?
83
+ s
84
+ : __assign(__assign({}, s), { focused: e.key, dismissed: s.dismissed === e.key ? null : s.dismissed });
85
+ case 'blur':
86
+ return s.focused === e.key ? __assign(__assign({}, s), { focused: null }) : s;
87
+ case 'toggle':
88
+ // A click on the handle of an open card pins it (hover or focus opened it); a second click closes it.
89
+ return s.pinned === e.key ?
90
+ (0, exports.cardReducer)(s, { type: 'close' })
91
+ : __assign(__assign({}, s), { pinned: e.key, dismissed: null });
92
+ case 'close': {
93
+ var open_1 = (0, exports.openCard)(s);
94
+ if (!open_1)
95
+ return s;
96
+ return { hovered: s.hovered, focused: null, pinned: null, dismissed: (_a = s.hovered) !== null && _a !== void 0 ? _a : open_1 };
97
+ }
98
+ }
99
+ };
100
+ exports.cardReducer = cardReducer;
101
+ /** Enter or Space on a version's row itself (not on its Accept / Remove buttons) shows that version. */
102
+ var activatesRow = function (key, onRowItself) {
103
+ return onRowItself && (key === 'Enter' || key === ' ');
104
+ };
105
+ exports.activatesRow = activatesRow;
106
+ /** Whether a click lands outside the overlay's cards (and outside Reqore's dialogs and menus they open). */
107
+ exports.OUTSIDE_IGNORE = '[data-experiment-float], .reqore-modal, .reqore-popover-content, .reqore-drawer, .reqore-notification, [role="dialog"]';
108
+ //# sourceMappingURL=anchor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor.js","sourceRoot":"","sources":["../../../src/tracking/ui/anchor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * What the A/B test card shows, as plain functions of the qorus-api objects: the version rows,
3
+ * the verdict, the numbers line, the bars, the status tag, which actions a status allows, and
4
+ * the words of the confirm step and of the outcome. No React, no DOM (unit-tested in
5
+ * `__tests__/tracking/card.test.ts`).
6
+ */
7
+ import type { IExperimentEntry, IExperimentResults, TExperimentActionResult, TExperimentStatus, TLifecycleAction, TVersionAction } from './types';
8
+ export declare const canAccept: (status: TExperimentStatus) => boolean;
9
+ /** Start a draft, or resume a paused test. */
10
+ export declare const canStart: (status: TExperimentStatus) => boolean;
11
+ export declare const canPause: (status: TExperimentStatus) => boolean;
12
+ export declare const canStop: (status: TExperimentStatus) => boolean;
13
+ export declare const canRemove: (status: TExperimentStatus, versions: number) => boolean;
14
+ export interface IVersionRow {
15
+ key: string;
16
+ name: string;
17
+ control: boolean;
18
+ /** Visitors exposed in the current phase (null: no numbers yet). */
19
+ visitors: number | null;
20
+ /** Conversion on the primary metric, 0..1. */
21
+ conversion: number | null;
22
+ /** Chance to beat the original on the primary metric, 0..1 (null for the original). */
23
+ chance: number | null;
24
+ /** The page's code renders it (false: the server has a version the code does not, so it cannot be shown). */
25
+ inCode: boolean;
26
+ }
27
+ export declare const primaryMetric: (results: IExperimentResults | null | undefined) => import("./types").IResultsMetric;
28
+ export declare const versionName: (key: string) => string;
29
+ /**
30
+ * One row per version. Keys come from the server's experiment when there is one, otherwise from
31
+ * the page's code (`codeVariants`, the `data-variants` of `<Experiment>`): a test that exists
32
+ * only in code can still be switched.
33
+ */
34
+ export declare const versionRows: (entry: IExperimentEntry | undefined, codeVariants?: string[]) => IVersionRow[];
35
+ /** The verdict in plain words: the server's sentence when it sends one. */
36
+ /** The test is in the page's code, but the analytics service does not know it (or cannot be reached). */
37
+ export declare const NOT_SET_UP_TEXT = "This test is in the page's code but isn't set up yet: ask the Designer to set it up. Until then you can switch versions here, but nothing is counted.";
38
+ export declare const UNREACHABLE_TEXT = "Can't reach the analytics service right now, so there are no numbers and no test controls. You can still switch versions here; try again in a minute.";
39
+ /**
40
+ * The verdict in plain words: the server's sentence when it sends one. Without a server entry:
41
+ * `unreachable` (the list could not be loaded) or not set up yet (`notSetUpText`).
42
+ */
43
+ export declare const verdictLine: (entry: IExperimentEntry | undefined, { unreachable, notSetUpText, }?: {
44
+ unreachable?: boolean;
45
+ notSetUpText?: string;
46
+ }) => string;
47
+ export declare const percent: (n: number | null | undefined, digits?: number) => string;
48
+ export declare const count: (n: number | null | undefined) => string;
49
+ /**
50
+ * One line of numbers under a version: visitors, conversion, chance to beat the original. In
51
+ * words when there is nothing to count yet, never a row of dashes.
52
+ */
53
+ export declare const numbersLine: (row: IVersionRow, metricName?: string, status?: TExperimentStatus) => string;
54
+ /** Each version's bar: its conversion as a share of the best one (0..100; 0 with no numbers). */
55
+ export declare const barValues: (rows: IVersionRow[]) => number[];
56
+ /** The verdict's colour: green for a likely winner, amber for likely losers, neutral otherwise. */
57
+ export declare const verdictIntent: (entry: IExperimentEntry | undefined) => 'success' | 'warning' | 'info' | 'muted';
58
+ export declare const STATUS_LABEL: Record<TExperimentStatus, string>;
59
+ export type TStatusIntent = 'success' | 'warning' | 'danger' | 'muted';
60
+ /** The status tag: its words (with the phase after a removal), its icon and its colour. */
61
+ export declare const statusTag: (entry: IExperimentEntry | undefined, unreachable?: boolean) => {
62
+ label: string;
63
+ icon: string;
64
+ intent: TStatusIntent;
65
+ };
66
+ export interface IConfirmCopy {
67
+ title: string;
68
+ description: string;
69
+ confirmLabel: string;
70
+ }
71
+ /** What the confirm step says before Accept / Remove. */
72
+ export declare const confirmCopy: (action: TVersionAction, entry: IExperimentEntry, variant: string) => IConfirmCopy;
73
+ /** What the confirm step says before Start / Pause / Stop. */
74
+ export declare const lifecycleCopy: (action: TLifecycleAction, entry: IExperimentEntry) => IConfirmCopy;
75
+ /** The notification after Accept / Remove. */
76
+ export declare const actionOutcome: (action: TVersionAction, result: TExperimentActionResult | null | undefined, variant: string) => string;
77
+ /**
78
+ * Why the numbers restarted: the current phase began when a version was removed. Null in the
79
+ * first phase. `actorLabels` names who removed it (`{ 'landing-editor': 'in the editor' }`).
80
+ */
81
+ export declare const phaseNote: (entry: IExperimentEntry | undefined, actorLabels?: Record<string, string>) => string | null;
82
+ /** The note on an element whose test has ended. */
83
+ export declare const winnerNote: (entry: IExperimentEntry | undefined, shown: string) => string;
84
+ /** Versions visible before the list scrolls: three and a half, so the half row says "there is more". */
85
+ export declare const VISIBLE_VERSIONS = 3.5;
86
+ /**
87
+ * The versions list's height cap (px): 3.5 rows, or less when the card has less room
88
+ * (`available`, what is left after the header, verdict and footer), never under one row.
89
+ * Null when every row fits (no cap, no scrolling).
90
+ */
91
+ export declare const versionsMaxHeight: ({ rows, rowHeight, gap, available, }: {
92
+ rows: number;
93
+ rowHeight: number;
94
+ gap: number;
95
+ available?: number;
96
+ }) => number | null;
97
+ /**
98
+ * Best first: conversion on the primary metric, then visitors; versions without numbers keep
99
+ * their order at the end. Stable: equal versions keep the server's order.
100
+ */
101
+ export declare const sortVersionRows: (rows: IVersionRow[]) => IVersionRow[];
102
+ /**
103
+ * The version to highlight: the winner when the test ended with one or the verdict is a likely
104
+ * winner, otherwise the one converting best so far ("Leading"). Null while nothing is counted,
105
+ * or when the best conversion is shared.
106
+ */
107
+ export declare const leadingVersion: (entry: IExperimentEntry | undefined, rows: IVersionRow[]) => {
108
+ key: string;
109
+ kind: 'winner' | 'leading';
110
+ } | null;
111
+ export declare const DEFAULT_MIN_SAMPLE: {
112
+ per_variant: number;
113
+ days: number;
114
+ };
115
+ export interface IHelpSection {
116
+ title: string;
117
+ paragraphs: string[];
118
+ }
119
+ /** What the card's "?" explains, in plain words for a marketer. */
120
+ export declare const helpSections: (entry: IExperimentEntry | undefined, analyticsLabel?: string) => IHelpSection[];
121
+ //# sourceMappingURL=card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../src/tracking/ui/card.ts"],"names":[],"mappings":"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"}