@mx-cartographer/experiences 9.4.15 → 9.4.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/common/components/dialog/Dialog.es.js +36 -36
- package/dist/common/components/dialog/Dialog.es.js.map +1 -1
- package/dist/core/types/localization/InsightsFeedCopy.d.ts +67 -0
- package/dist/core/types/localization/index.d.ts +1 -1
- package/dist/insights-v2/beatActions.d.ts +55 -0
- package/dist/insights-v2/beatActions.es.js +12 -0
- package/dist/insights-v2/beatActions.es.js.map +1 -0
- package/dist/insights-v2/components/BaseLayout.d.ts +7 -1
- package/dist/insights-v2/components/BaseLayout.es.js +102 -68
- package/dist/insights-v2/components/BaseLayout.es.js.map +1 -1
- package/dist/insights-v2/components/DismissInsightDialog.d.ts +18 -0
- package/dist/insights-v2/components/DismissInsightDialog.es.js +109 -0
- package/dist/insights-v2/components/DismissInsightDialog.es.js.map +1 -0
- package/dist/insights-v2/components/FeedbackBar.d.ts +20 -0
- package/dist/insights-v2/components/FeedbackBar.es.js +64 -0
- package/dist/insights-v2/components/FeedbackBar.es.js.map +1 -0
- package/dist/insights-v2/components/FeedbackDialog.d.ts +37 -0
- package/dist/insights-v2/components/FeedbackDialog.es.js +92 -0
- package/dist/insights-v2/components/FeedbackDialog.es.js.map +1 -0
- package/dist/insights-v2/components/Header.es.js +23 -33
- package/dist/insights-v2/components/Header.es.js.map +1 -1
- package/dist/insights-v2/components/HiddenConfirmationCard.d.ts +20 -0
- package/dist/insights-v2/components/HiddenConfirmationCard.es.js +123 -0
- package/dist/insights-v2/components/HiddenConfirmationCard.es.js.map +1 -0
- package/dist/insights-v2/components/InsightOptionsMenu.d.ts +10 -0
- package/dist/insights-v2/components/InsightOptionsMenu.es.js +54 -0
- package/dist/insights-v2/components/InsightOptionsMenu.es.js.map +1 -0
- package/dist/insights-v2/components/OverflowMenu.d.ts +32 -0
- package/dist/insights-v2/components/OverflowMenu.es.js +73 -0
- package/dist/insights-v2/components/OverflowMenu.es.js.map +1 -0
- package/dist/insights-v2/hooks/useBeatFeedbackFlow.d.ts +44 -0
- package/dist/insights-v2/hooks/useBeatFeedbackFlow.es.js +73 -0
- package/dist/insights-v2/hooks/useBeatFeedbackFlow.es.js.map +1 -0
- package/dist/insights-v2/index.d.ts +7 -0
- package/dist/insights-v2/index.es.js +71 -57
- package/package.json +1 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useGlobalCopyStore as m } from "../../common/context/hooks.es.js";
|
|
2
|
+
import { useBeatActions as a } from "../beatActions.es.js";
|
|
3
|
+
import { OverflowMenu as p } from "./OverflowMenu.es.js";
|
|
4
|
+
import { observer as f } from "mobx-react-lite";
|
|
5
|
+
import { Icon as l } from "@mxenabled/mx-icons";
|
|
6
|
+
import { jsx as o } from "react/jsx-runtime";
|
|
7
|
+
var d = f(() => {
|
|
8
|
+
const { onMenuAction: n } = a(), e = m().insights_feed?.overflow_menu;
|
|
9
|
+
if (!n || !e) return null;
|
|
10
|
+
const { onAction: t, onOpen: i, disabled: r } = n, s = [
|
|
11
|
+
{
|
|
12
|
+
key: "helpful",
|
|
13
|
+
icon: /* @__PURE__ */ o(l, {
|
|
14
|
+
name: "thumb_up",
|
|
15
|
+
size: 24,
|
|
16
|
+
sx: { color: "text.primary" }
|
|
17
|
+
}),
|
|
18
|
+
label: e.helpful,
|
|
19
|
+
onSelect: () => t("helpful")
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
key: "not_helpful",
|
|
23
|
+
icon: /* @__PURE__ */ o(l, {
|
|
24
|
+
name: "thumb_down",
|
|
25
|
+
size: 24,
|
|
26
|
+
sx: { color: "text.primary" }
|
|
27
|
+
}),
|
|
28
|
+
label: e.not_helpful,
|
|
29
|
+
onSelect: () => t("not_helpful")
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
key: "hide",
|
|
33
|
+
icon: /* @__PURE__ */ o(l, {
|
|
34
|
+
name: "visibility_off",
|
|
35
|
+
size: 24,
|
|
36
|
+
sx: { color: "text.primary" }
|
|
37
|
+
}),
|
|
38
|
+
label: e.hide,
|
|
39
|
+
onSelect: () => t("hide")
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
return /* @__PURE__ */ o(p, {
|
|
43
|
+
ariaLabel: e.aria_label,
|
|
44
|
+
disabled: r,
|
|
45
|
+
items: s,
|
|
46
|
+
onOpen: i
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
export {
|
|
50
|
+
d as InsightOptionsMenu,
|
|
51
|
+
d as default
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=InsightOptionsMenu.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InsightOptionsMenu.es.js","names":[],"sources":["../../../src/insights-v2/components/InsightOptionsMenu.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport { Icon } from '@mxenabled/mx-icons'\n\nimport { useGlobalCopyStore } from '../../common'\n\nimport { useBeatActions } from '../beatActions'\n\nimport { OverflowMenu, type OverflowMenuItem } from './OverflowMenu'\n\n/**\n * The insight card's \"…\" overflow menu. This repo owns the item set — order,\n * icons, and labels (from `insights_feed.overflow_menu` copy) — while the host\n * supplies the action handler via `beatActions.onMenuAction` (read from\n * context). Renders nothing without a handler or before copy resolves.\n */\nexport const InsightOptionsMenu = observer(() => {\n const { onMenuAction } = useBeatActions()\n const copy = useGlobalCopyStore().insights_feed?.overflow_menu\n\n if (!onMenuAction || !copy) return null\n\n const { onAction, onOpen, disabled } = onMenuAction\n\n const items: OverflowMenuItem[] = [\n {\n key: 'helpful',\n icon: <Icon name=\"thumb_up\" size={24} sx={{ color: 'text.primary' }} />,\n label: copy.helpful,\n onSelect: () => onAction('helpful'),\n },\n {\n key: 'not_helpful',\n icon: <Icon name=\"thumb_down\" size={24} sx={{ color: 'text.primary' }} />,\n label: copy.not_helpful,\n onSelect: () => onAction('not_helpful'),\n },\n {\n key: 'hide',\n icon: <Icon name=\"visibility_off\" size={24} sx={{ color: 'text.primary' }} />,\n label: copy.hide,\n onSelect: () => onAction('hide'),\n },\n ]\n\n return (\n <OverflowMenu ariaLabel={copy.aria_label} disabled={disabled} items={items} onOpen={onOpen} />\n )\n})\n\nexport default InsightOptionsMenu\n"],"mappings":";;;;;;AAgBA,IAAa,IAAqB,EAAA,MAAe;AAC/C,QAAM,EAAE,cAAA,EAAA,IAAiB,EAAe,GAClC,IAAO,EAAmB,EAAE,eAAe;AAEjD,MAAI,CAAC,KAAgB,CAAC,EAAM,QAAO;AAEnC,QAAM,EAAE,UAAA,GAAU,QAAA,GAAQ,UAAA,EAAA,IAAa,GAEjC,IAA4B;AAAA,IAChC;AAAA,MACE,KAAK;AAAA,MACL,MAAM,gBAAA,EAAC,GAAD;AAAA,QAAM,MAAK;AAAA,QAAW,MAAM;AAAA,QAAI,IAAI,EAAE,OAAO,eAAe;AAAA,MAAI,CAAA;AAAA,MACtE,OAAO,EAAK;AAAA,MACZ,UAAA,MAAgB,EAAS,SAAS;AAAA,IACpC;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,MAAM,gBAAA,EAAC,GAAD;AAAA,QAAM,MAAK;AAAA,QAAa,MAAM;AAAA,QAAI,IAAI,EAAE,OAAO,eAAe;AAAA,MAAI,CAAA;AAAA,MACxE,OAAO,EAAK;AAAA,MACZ,UAAA,MAAgB,EAAS,aAAa;AAAA,IACxC;AAAA,IACA;AAAA,MACE,KAAK;AAAA,MACL,MAAM,gBAAA,EAAC,GAAD;AAAA,QAAM,MAAK;AAAA,QAAiB,MAAM;AAAA,QAAI,IAAI,EAAE,OAAO,eAAe;AAAA,MAAI,CAAA;AAAA,MAC5E,OAAO,EAAK;AAAA,MACZ,UAAA,MAAgB,EAAS,MAAM;AAAA,IACjC;AAAA,EACF;AAEA,SACE,gBAAA,EAAC,GAAD;AAAA,IAAc,WAAW,EAAK;AAAA,IAAsB,UAAA;AAAA,IAAiB,OAAA;AAAA,IAAe,QAAA;AAAA,EAAS,CAAA;AAEjG,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
export interface OverflowMenuItem {
|
|
3
|
+
/** Stable identity for the item (also its React key). */
|
|
4
|
+
key: string;
|
|
5
|
+
/** Leading icon node. */
|
|
6
|
+
icon: ReactNode;
|
|
7
|
+
/** Visible label. */
|
|
8
|
+
label: string;
|
|
9
|
+
/** Invoked when the item is chosen (after the menu closes). */
|
|
10
|
+
onSelect: () => void;
|
|
11
|
+
/** Optional per-item disabled state. */
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface OverflowMenuProps {
|
|
15
|
+
/** Items to render, top to bottom. */
|
|
16
|
+
items: OverflowMenuItem[];
|
|
17
|
+
/** Accessible label for the trigger button. */
|
|
18
|
+
ariaLabel: string;
|
|
19
|
+
/** Called when the menu opens (e.g. to fire analytics). */
|
|
20
|
+
onOpen?: () => void;
|
|
21
|
+
/** Disables the trigger entirely (e.g. an obsolete beat). */
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A "…" (MoreHoriz) overflow menu: an icon trigger that opens a list of actions.
|
|
26
|
+
*
|
|
27
|
+
* Presentational only — it owns nothing but the open/close anchor state. The item
|
|
28
|
+
* set and what each item does are supplied by the caller via `items[].onSelect`,
|
|
29
|
+
* so all data/side-effects (analytics, feedback, hide, …) live outside this file.
|
|
30
|
+
*/
|
|
31
|
+
export declare const OverflowMenu: ({ items, ariaLabel, onOpen, disabled }: OverflowMenuProps) => import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export default OverflowMenu;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { useId as v, useState as z } from "react";
|
|
2
|
+
import { MoreHoriz as M } from "@mxenabled/mx-icons";
|
|
3
|
+
import { Fragment as O, jsx as r, jsxs as m } from "react/jsx-runtime";
|
|
4
|
+
import k from "@mui/material/IconButton";
|
|
5
|
+
import C from "@mui/material/ListItemText";
|
|
6
|
+
import L from "@mui/material/ListItemIcon";
|
|
7
|
+
import S from "@mui/material/MenuItem";
|
|
8
|
+
import y from "@mui/material/Menu";
|
|
9
|
+
var P = ({ items: d, ariaLabel: c, onOpen: p, disabled: h = !1 }) => {
|
|
10
|
+
const [e, n] = z(null), t = !!e, i = v(), a = `${i}-button`, l = `${i}-menu`, u = (o) => {
|
|
11
|
+
n(o.currentTarget), p?.();
|
|
12
|
+
}, s = () => n(null), f = (o) => {
|
|
13
|
+
s(), o();
|
|
14
|
+
};
|
|
15
|
+
return /* @__PURE__ */ m(O, { children: [/* @__PURE__ */ r(k, {
|
|
16
|
+
"aria-controls": t ? l : void 0,
|
|
17
|
+
"aria-expanded": t || void 0,
|
|
18
|
+
"aria-haspopup": "true",
|
|
19
|
+
"aria-label": c,
|
|
20
|
+
disabled: h,
|
|
21
|
+
id: a,
|
|
22
|
+
onClick: u,
|
|
23
|
+
sx: {
|
|
24
|
+
minHeight: 24,
|
|
25
|
+
minWidth: 24,
|
|
26
|
+
p: 0
|
|
27
|
+
},
|
|
28
|
+
children: /* @__PURE__ */ r(M, {
|
|
29
|
+
size: 24,
|
|
30
|
+
sx: { color: "neutral.dark" }
|
|
31
|
+
})
|
|
32
|
+
}), /* @__PURE__ */ r(y, {
|
|
33
|
+
MenuListProps: {
|
|
34
|
+
"aria-labelledby": a,
|
|
35
|
+
sx: { width: 212 }
|
|
36
|
+
},
|
|
37
|
+
anchorEl: e,
|
|
38
|
+
anchorOrigin: {
|
|
39
|
+
horizontal: "right",
|
|
40
|
+
vertical: "top"
|
|
41
|
+
},
|
|
42
|
+
disableScrollLock: !0,
|
|
43
|
+
id: l,
|
|
44
|
+
onClose: s,
|
|
45
|
+
open: t,
|
|
46
|
+
transformOrigin: {
|
|
47
|
+
horizontal: "right",
|
|
48
|
+
vertical: "top"
|
|
49
|
+
},
|
|
50
|
+
children: d.map(({ key: o, icon: x, label: g, onSelect: b, disabled: I }) => /* @__PURE__ */ m(S, {
|
|
51
|
+
disabled: I,
|
|
52
|
+
onClick: () => f(b),
|
|
53
|
+
sx: { p: 12 },
|
|
54
|
+
children: [/* @__PURE__ */ r(L, {
|
|
55
|
+
sx: { minWidth: "32px !important" },
|
|
56
|
+
children: x
|
|
57
|
+
}), /* @__PURE__ */ r(C, {
|
|
58
|
+
primary: g,
|
|
59
|
+
slotProps: { primary: {
|
|
60
|
+
fontSize: 15,
|
|
61
|
+
fontWeight: "normal",
|
|
62
|
+
lineHeight: "20px"
|
|
63
|
+
} }
|
|
64
|
+
})]
|
|
65
|
+
}, o))
|
|
66
|
+
})] });
|
|
67
|
+
};
|
|
68
|
+
export {
|
|
69
|
+
P as OverflowMenu,
|
|
70
|
+
P as default
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=OverflowMenu.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OverflowMenu.es.js","names":[],"sources":["../../../src/insights-v2/components/OverflowMenu.tsx"],"sourcesContent":["import { useId, useState, type MouseEvent, type ReactNode } from 'react'\n\nimport IconButton from '@mui/material/IconButton'\nimport ListItemIcon from '@mui/material/ListItemIcon'\nimport ListItemText from '@mui/material/ListItemText'\nimport Menu from '@mui/material/Menu'\nimport MenuItem from '@mui/material/MenuItem'\n\nimport { MoreHoriz } from '@mxenabled/mx-icons'\n\nexport interface OverflowMenuItem {\n /** Stable identity for the item (also its React key). */\n key: string\n /** Leading icon node. */\n icon: ReactNode\n /** Visible label. */\n label: string\n /** Invoked when the item is chosen (after the menu closes). */\n onSelect: () => void\n /** Optional per-item disabled state. */\n disabled?: boolean\n}\n\nexport interface OverflowMenuProps {\n /** Items to render, top to bottom. */\n items: OverflowMenuItem[]\n /** Accessible label for the trigger button. */\n ariaLabel: string\n /** Called when the menu opens (e.g. to fire analytics). */\n onOpen?: () => void\n /** Disables the trigger entirely (e.g. an obsolete beat). */\n disabled?: boolean\n}\n\n/**\n * A \"…\" (MoreHoriz) overflow menu: an icon trigger that opens a list of actions.\n *\n * Presentational only — it owns nothing but the open/close anchor state. The item\n * set and what each item does are supplied by the caller via `items[].onSelect`,\n * so all data/side-effects (analytics, feedback, hide, …) live outside this file.\n */\nexport const OverflowMenu = ({ items, ariaLabel, onOpen, disabled = false }: OverflowMenuProps) => {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null)\n const isOpen = Boolean(anchorEl)\n\n // Unique per instance so multiple menus on a page (one per card) don't share\n // DOM ids or cross-wire their aria relationships.\n const baseId = useId()\n const buttonId = `${baseId}-button`\n const menuId = `${baseId}-menu`\n\n const handleOpen = (event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget)\n onOpen?.()\n }\n\n const handleClose = () => setAnchorEl(null)\n\n // Close before running the caller's handler so the menu never lingers over a\n // dialog/drawer the handler may open.\n const handleSelect = (onSelect: () => void) => {\n handleClose()\n onSelect()\n }\n\n return (\n <>\n <IconButton\n aria-controls={isOpen ? menuId : undefined}\n aria-expanded={isOpen || undefined}\n aria-haspopup=\"true\"\n aria-label={ariaLabel}\n disabled={disabled}\n id={buttonId}\n onClick={handleOpen}\n sx={{ minHeight: 24, minWidth: 24, p: 0 }}\n >\n <MoreHoriz size={24} sx={{ color: 'neutral.dark' }} />\n </IconButton>\n <Menu\n MenuListProps={{ 'aria-labelledby': buttonId, sx: { width: 212 } }}\n anchorEl={anchorEl}\n anchorOrigin={{ horizontal: 'right', vertical: 'top' }}\n disableScrollLock={true}\n id={menuId}\n onClose={handleClose}\n open={isOpen}\n transformOrigin={{ horizontal: 'right', vertical: 'top' }}\n >\n {items.map(({ key, icon, label, onSelect, disabled: itemDisabled }) => (\n <MenuItem\n disabled={itemDisabled}\n key={key}\n onClick={() => handleSelect(onSelect)}\n sx={{ p: 12 }}\n >\n <ListItemIcon sx={{ minWidth: '32px !important' }}>{icon}</ListItemIcon>\n <ListItemText\n primary={label}\n slotProps={{ primary: { fontSize: 15, fontWeight: 'normal', lineHeight: '20px' } }}\n />\n </MenuItem>\n ))}\n </Menu>\n </>\n )\n}\n\nexport default OverflowMenu\n"],"mappings":";;;;;;;;AAyCA,IAAa,IAAA,CAAgB,EAAE,OAAA,GAAO,WAAA,GAAW,QAAA,GAAQ,UAAA,IAAW,GAAA,MAA+B;AACjG,QAAM,CAAC,GAAU,CAAA,IAAe,EAA6B,IAAI,GAC3D,IAAS,EAAQ,GAIjB,IAAS,EAAM,GACf,IAAW,GAAG,CAAA,WACd,IAAS,GAAG,CAAA,SAEZ,IAAA,CAAc,MAAyC;AAC3D,IAAA,EAAY,EAAM,aAAa,GAC/B,IAAS;AAAA,EACX,GAEM,IAAA,MAAoB,EAAY,IAAI,GAIpC,IAAA,CAAgB,MAAyB;AAC7C,IAAA,EAAY,GACZ,EAAS;AAAA,EACX;AAEA,SACE,gBAAA,EAAA,GAAA,EAAA,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,IACE,iBAAe,IAAS,IAAS;AAAA,IACjC,iBAAe,KAAU;AAAA,IACzB,iBAAc;AAAA,IACd,cAAY;AAAA,IACF,UAAA;AAAA,IACV,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,IAAI;AAAA,MAAE,WAAW;AAAA,MAAI,UAAU;AAAA,MAAI,GAAG;AAAA,IAAE;AAAA,IAExC,UAAA,gBAAA,EAAC,GAAD;AAAA,MAAW,MAAM;AAAA,MAAI,IAAI,EAAE,OAAO,eAAe;AAAA,IAAI,CAAA;AAAA,EAC3C,CAAA,GACZ,gBAAA,EAAC,GAAD;AAAA,IACE,eAAe;AAAA,MAAE,mBAAmB;AAAA,MAAU,IAAI,EAAE,OAAO,IAAI;AAAA,IAAE;AAAA,IACvD,UAAA;AAAA,IACV,cAAc;AAAA,MAAE,YAAY;AAAA,MAAS,UAAU;AAAA,IAAM;AAAA,IACrD,mBAAmB;AAAA,IACnB,IAAI;AAAA,IACJ,SAAS;AAAA,IACT,MAAM;AAAA,IACN,iBAAiB;AAAA,MAAE,YAAY;AAAA,MAAS,UAAU;AAAA,IAAM;AAAA,IAEvD,UAAA,EAAM,IAAA,CAAK,EAAE,KAAA,GAAK,MAAA,GAAM,OAAA,GAAO,UAAA,GAAU,UAAU,EAAA,MAClD,gBAAA,EAAC,GAAD;AAAA,MACE,UAAU;AAAA,MAEV,SAAA,MAAe,EAAa,CAAQ;AAAA,MACpC,IAAI,EAAE,GAAG,GAAG;AAAA,MAJd,UAAA,CAME,gBAAA,EAAC,GAAD;AAAA,QAAc,IAAI,EAAE,UAAU,kBAAkB;AAAA,QAAI,UAAA;AAAA,MAAmB,CAAA,GACvE,gBAAA,EAAC,GAAD;AAAA,QACE,SAAS;AAAA,QACT,WAAW,EAAE,SAAS;AAAA,UAAE,UAAU;AAAA,UAAI,YAAY;AAAA,UAAU,YAAY;AAAA,QAAO,EAAE;AAAA,MAClF,CAAA,CACO;AAAA,IATH,GAAA,CASG,CACX;AAAA,EACG,CAAA,CACN,EAAA,CAAA;AAEN"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Beat } from '../../core';
|
|
2
|
+
import { BeatActions, InsightRating } from '../beatActions';
|
|
3
|
+
import { DismissType } from '../components/DismissInsightDialog';
|
|
4
|
+
/** Which flow opened the survey dialog (null = closed): a rating or the hide flow. */
|
|
5
|
+
export type FeedbackVariant = InsightRating | 'hide';
|
|
6
|
+
/**
|
|
7
|
+
* What the card slot shows:
|
|
8
|
+
* - `visible` the original beat card
|
|
9
|
+
* - `confirming` the hidden-confirmation card (grace period after a hide)
|
|
10
|
+
* - `dismissed` nothing (beat stays hidden; the host removes it on refresh)
|
|
11
|
+
*/
|
|
12
|
+
export type CardState = 'visible' | 'confirming' | 'dismissed';
|
|
13
|
+
/**
|
|
14
|
+
* Owns the post-action UI state machine for a beat card: the feedback bar shown
|
|
15
|
+
* after a rating, the "hide this insight" dismiss dialog, the hidden-confirmation
|
|
16
|
+
* card, and the shared feedback survey dialog.
|
|
17
|
+
*
|
|
18
|
+
* Experiences owns this UI; the host only receives callbacks (rate / dismiss /
|
|
19
|
+
* undo / submit-feedback) via `beatActions`. Keeping the machine here leaves
|
|
20
|
+
* BaseLayout as pure layout.
|
|
21
|
+
*/
|
|
22
|
+
export declare const useBeatFeedbackFlow: (beat: Beat, beatActions: BeatActions) => {
|
|
23
|
+
cardState: CardState;
|
|
24
|
+
isDismissOpen: boolean;
|
|
25
|
+
isSurveyOpen: boolean;
|
|
26
|
+
isFeedbackBarShown: boolean;
|
|
27
|
+
survey: {
|
|
28
|
+
characterLimitLabel: string;
|
|
29
|
+
closeAriaLabel: string;
|
|
30
|
+
submitText: string;
|
|
31
|
+
backText: string;
|
|
32
|
+
title: string;
|
|
33
|
+
options: string[];
|
|
34
|
+
};
|
|
35
|
+
wrappedActions: BeatActions;
|
|
36
|
+
openRatingSurvey: () => void;
|
|
37
|
+
openHideSurvey: () => void;
|
|
38
|
+
closeSurvey: () => void;
|
|
39
|
+
submitSurvey: (option: string, detail?: string) => void;
|
|
40
|
+
confirmDismiss: (type: DismissType) => void;
|
|
41
|
+
undoDismiss: () => void;
|
|
42
|
+
collapseConfirmation: () => void;
|
|
43
|
+
closeDismissDialog: () => void;
|
|
44
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { useGlobalCopyStore as S } from "../../common/context/hooks.es.js";
|
|
2
|
+
import { useMemo as y, useState as u } from "react";
|
|
3
|
+
var x = (r, o) => {
|
|
4
|
+
const a = S(), [c, n] = u(null), [i, t] = u(null), [f, d] = u(!1), [p, l] = u("visible"), h = (() => {
|
|
5
|
+
const e = a.insights_feed?.feedback, s = a.insights_feed?.hide_feedback, m = {
|
|
6
|
+
characterLimitLabel: (i === "hide" ? s : e)?.character_limit,
|
|
7
|
+
closeAriaLabel: (i === "hide" ? s : e)?.close_aria ?? "Close",
|
|
8
|
+
submitText: (i === "hide" ? s : e)?.submit ?? "Submit",
|
|
9
|
+
backText: (i === "hide" ? s : e)?.back ?? "Back"
|
|
10
|
+
};
|
|
11
|
+
if (i === "hide" && s) return {
|
|
12
|
+
title: s.title,
|
|
13
|
+
options: Object.values(s.options),
|
|
14
|
+
...m
|
|
15
|
+
};
|
|
16
|
+
const v = Object.values(i === "not_helpful" ? e?.not_helpful_options ?? {} : e?.helpful_options ?? {});
|
|
17
|
+
return {
|
|
18
|
+
title: e?.tell_us_more_title ?? "Tell us more",
|
|
19
|
+
options: v,
|
|
20
|
+
...m
|
|
21
|
+
};
|
|
22
|
+
})(), b = y(() => {
|
|
23
|
+
const e = o.onMenuAction;
|
|
24
|
+
return e ? {
|
|
25
|
+
...o,
|
|
26
|
+
onMenuAction: {
|
|
27
|
+
...e,
|
|
28
|
+
onAction: (s) => {
|
|
29
|
+
s === "helpful" || s === "not_helpful" ? n(s) : s === "hide" && d(!0), e.onAction(s);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
} : o;
|
|
33
|
+
}, [o]);
|
|
34
|
+
return {
|
|
35
|
+
cardState: p,
|
|
36
|
+
isDismissOpen: f,
|
|
37
|
+
isSurveyOpen: i !== null,
|
|
38
|
+
isFeedbackBarShown: c !== null,
|
|
39
|
+
survey: h,
|
|
40
|
+
wrappedActions: b,
|
|
41
|
+
openRatingSurvey: () => {
|
|
42
|
+
c && t(c);
|
|
43
|
+
},
|
|
44
|
+
openHideSurvey: () => t("hide"),
|
|
45
|
+
closeSurvey: () => {
|
|
46
|
+
i !== "hide" && n(null), t(null);
|
|
47
|
+
},
|
|
48
|
+
submitSurvey: (e, s) => {
|
|
49
|
+
i && (o.onSubmitFeedback?.({
|
|
50
|
+
beatGuid: r.guid,
|
|
51
|
+
source: i,
|
|
52
|
+
option: e,
|
|
53
|
+
detail: s
|
|
54
|
+
}), t(null), i === "hide" ? l("dismissed") : n(null));
|
|
55
|
+
},
|
|
56
|
+
confirmDismiss: (e) => {
|
|
57
|
+
o.onDismissInsight?.({
|
|
58
|
+
beatGuid: r.guid,
|
|
59
|
+
type: e
|
|
60
|
+
}), l("confirming");
|
|
61
|
+
},
|
|
62
|
+
undoDismiss: () => {
|
|
63
|
+
o.onUndoDismiss?.({ beatGuid: r.guid }), n(null), l("visible");
|
|
64
|
+
},
|
|
65
|
+
collapseConfirmation: () => l("dismissed"),
|
|
66
|
+
closeDismissDialog: () => d(!1)
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export {
|
|
70
|
+
x as useBeatFeedbackFlow
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=useBeatFeedbackFlow.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBeatFeedbackFlow.es.js","names":[],"sources":["../../../src/insights-v2/hooks/useBeatFeedbackFlow.ts"],"sourcesContent":["import { useMemo, useState } from 'react'\n\nimport { useGlobalCopyStore } from '../../common'\nimport type { Beat } from '../../core'\nimport type { BeatActions, InsightRating } from '../beatActions'\nimport type { DismissType } from '../components/DismissInsightDialog'\n\n/** Which flow opened the survey dialog (null = closed): a rating or the hide flow. */\nexport type FeedbackVariant = InsightRating | 'hide'\n\n/**\n * What the card slot shows:\n * - `visible` the original beat card\n * - `confirming` the hidden-confirmation card (grace period after a hide)\n * - `dismissed` nothing (beat stays hidden; the host removes it on refresh)\n */\nexport type CardState = 'visible' | 'confirming' | 'dismissed'\n\n/**\n * Owns the post-action UI state machine for a beat card: the feedback bar shown\n * after a rating, the \"hide this insight\" dismiss dialog, the hidden-confirmation\n * card, and the shared feedback survey dialog.\n *\n * Experiences owns this UI; the host only receives callbacks (rate / dismiss /\n * undo / submit-feedback) via `beatActions`. Keeping the machine here leaves\n * BaseLayout as pure layout.\n */\nexport const useBeatFeedbackFlow = (beat: Beat, beatActions: BeatActions) => {\n const copyStore = useGlobalCopyStore()\n\n // Rating that surfaced the feedback bar (null = hidden). The bar confirms the\n // vote and offers a follow-up survey.\n const [feedbackRating, setFeedbackRating] = useState<InsightRating | null>(null)\n // Which flow opened the survey dialog (null = closed).\n const [feedbackVariant, setFeedbackVariant] = useState<FeedbackVariant | null>(null)\n // The \"hide this insight\" confirmation dialog (pick once / always).\n const [isDismissOpen, setIsDismissOpen] = useState(false)\n // Drives the card slot through the hide flow (see CardState).\n const [cardState, setCardState] = useState<CardState>('visible')\n\n // Survey title + reasons for the active variant. FeedbackDialog is generic, so\n // the variant-to-copy mapping lives here: hide uses the dismiss reasons; a\n // rating uses its matching helpful / not-helpful reasons.\n //\n // Not memoized on purpose: it reads observable copy fields, and the consumer\n // (BaseLayout) is an observer, so deriving on each render keeps it in sync when\n // copy reloads (a useMemo keyed on the stable store ref would go stale). The\n // work is a few lookups + Object.values on small arrays — cheap.\n const resolveSurvey = () => {\n const feedbackCopy = copyStore.insights_feed?.feedback\n const hideCopy = copyStore.insights_feed?.hide_feedback\n\n // Buttons + labels come from the same block as the reasons, so the hide and\n // rating surveys stay independently localizable (no cross-variant leakage).\n const chrome = {\n characterLimitLabel: (feedbackVariant === 'hide' ? hideCopy : feedbackCopy)?.character_limit,\n closeAriaLabel: (feedbackVariant === 'hide' ? hideCopy : feedbackCopy)?.close_aria ?? 'Close',\n submitText: (feedbackVariant === 'hide' ? hideCopy : feedbackCopy)?.submit ?? 'Submit',\n backText: (feedbackVariant === 'hide' ? hideCopy : feedbackCopy)?.back ?? 'Back',\n }\n\n if (feedbackVariant === 'hide' && hideCopy) {\n return { title: hideCopy.title, options: Object.values(hideCopy.options), ...chrome }\n }\n\n const options =\n feedbackVariant === 'not_helpful'\n ? Object.values(feedbackCopy?.not_helpful_options ?? {})\n : Object.values(feedbackCopy?.helpful_options ?? {})\n\n return { title: feedbackCopy?.tell_us_more_title ?? 'Tell us more', options, ...chrome }\n }\n\n const survey = resolveSurvey()\n\n // Wrap the host's menu handler so experiences owns the post-action UI (feedback\n // bar for a vote, dismiss dialog for hide) while the host still sees the action.\n const wrappedActions = useMemo<BeatActions>(() => {\n const menu = beatActions.onMenuAction\n if (!menu) return beatActions\n return {\n ...beatActions,\n onMenuAction: {\n ...menu,\n onAction: (action) => {\n if (action === 'helpful' || action === 'not_helpful') {\n setFeedbackRating(action)\n } else if (action === 'hide') {\n setIsDismissOpen(true)\n }\n menu.onAction(action)\n },\n },\n }\n }, [beatActions])\n\n // --- Feedback survey ------------------------------------------------------\n\n /** Open the survey from the feedback bar's \"Tell us more\" (rating flow only). */\n const openRatingSurvey = () => {\n if (feedbackRating) setFeedbackVariant(feedbackRating)\n }\n\n /** Open the hide survey from the confirmation card's \"Leave Feedback\". */\n const openHideSurvey = () => setFeedbackVariant('hide')\n\n /** Close the survey (X / Back). A rating survey also clears the feedback bar. */\n const closeSurvey = () => {\n // Intentional asymmetry (matches the host): closing a rating survey also\n // clears the \"Feedback sent\" bar, while the hide flow keeps its confirmation\n // card up (Undo stays reachable). The card guards a destructive hide; the\n // rating bar is just a non-destructive vote confirmation.\n if (feedbackVariant !== 'hide') setFeedbackRating(null)\n setFeedbackVariant(null)\n }\n\n const submitSurvey = (option: string, detail?: string) => {\n if (!feedbackVariant) return\n beatActions.onSubmitFeedback?.({ beatGuid: beat.guid, source: feedbackVariant, option, detail })\n setFeedbackVariant(null)\n // Rating surveys clear the confirmation bar; the hide survey collapses the\n // confirmation card. The beat stays hidden either way — the host removes it.\n if (feedbackVariant === 'hide') {\n setCardState('dismissed')\n } else {\n setFeedbackRating(null)\n }\n }\n\n // --- Hide flow ------------------------------------------------------------\n\n /** Confirm a hide from the dismiss dialog; swaps in the confirmation card. */\n const confirmDismiss = (type: DismissType) => {\n beatActions.onDismissInsight?.({ beatGuid: beat.guid, type })\n setCardState('confirming')\n }\n\n /** Undo a hide from the confirmation card; restores the original card. */\n const undoDismiss = () => {\n beatActions.onUndoDismiss?.({ beatGuid: beat.guid })\n setFeedbackRating(null) // Clear any stale rating-bar state from before the hide\n setCardState('visible')\n }\n\n /** Close the confirmation card without undoing; the beat stays hidden. */\n const collapseConfirmation = () => setCardState('dismissed')\n\n const closeDismissDialog = () => setIsDismissOpen(false)\n\n return {\n cardState,\n isDismissOpen,\n isSurveyOpen: feedbackVariant !== null,\n isFeedbackBarShown: feedbackRating !== null,\n survey,\n wrappedActions,\n // survey actions\n openRatingSurvey,\n openHideSurvey,\n closeSurvey,\n submitSurvey,\n // hide-flow actions\n confirmDismiss,\n undoDismiss,\n collapseConfirmation,\n closeDismissDialog,\n }\n}\n"],"mappings":";;AA2BA,IAAa,IAAA,CAAuB,GAAY,MAA6B;AAC3E,QAAM,IAAY,EAAmB,GAI/B,CAAC,GAAgB,CAAA,IAAqB,EAA+B,IAAI,GAEzE,CAAC,GAAiB,CAAA,IAAsB,EAAiC,IAAI,GAE7E,CAAC,GAAe,CAAA,IAAoB,EAAS,EAAK,GAElD,CAAC,GAAW,CAAA,IAAgB,EAAoB,SAAS,GAmCzD,KAzBA,MAAsB;AAC1B,UAAM,IAAe,EAAU,eAAe,UACxC,IAAW,EAAU,eAAe,eAIpC,IAAS;AAAA,MACb,sBAAsB,MAAoB,SAAS,IAAW,IAAe;AAAA,MAC7E,iBAAiB,MAAoB,SAAS,IAAW,IAAe,cAAc;AAAA,MACtF,aAAa,MAAoB,SAAS,IAAW,IAAe,UAAU;AAAA,MAC9E,WAAW,MAAoB,SAAS,IAAW,IAAe,QAAQ;AAAA,IAC5E;AAEA,QAAI,MAAoB,UAAU,EAChC,QAAO;AAAA,MAAE,OAAO,EAAS;AAAA,MAAO,SAAS,OAAO,OAAO,EAAS,OAAO;AAAA,MAAG,GAAG;AAAA,IAAO;AAGtF,UAAM,IAEA,OAAO,OADX,MAAoB,gBACF,GAAc,uBAAuB,CAAC,IACtC,GAAc,mBAAmB,CAAC,CADK;AAG3D,WAAO;AAAA,MAAE,OAAO,GAAc,sBAAsB;AAAA,MAAgB,SAAA;AAAA,MAAS,GAAG;AAAA,IAAO;AAAA,EACzF,GAE6B,GAIvB,IAAiB,EAAA,MAA2B;AAChD,UAAM,IAAO,EAAY;AACzB,WAAK,IACE;AAAA,MACL,GAAG;AAAA,MACH,cAAc;AAAA,QACZ,GAAG;AAAA,QACH,UAAA,CAAW,MAAW;AACpB,UAAI,MAAW,aAAa,MAAW,gBACrC,EAAkB,CAAM,IACf,MAAW,UACpB,EAAiB,EAAI,GAEvB,EAAK,SAAS,CAAM;AAAA,QACtB;AAAA,MACF;AAAA,IACF,IAdkB;AAAA,EAepB,GAAG,CAAC,CAAW,CAAC;AAuDhB,SAAO;AAAA,IACL,WAAA;AAAA,IACA,eAAA;AAAA,IACA,cAAc,MAAoB;AAAA,IAClC,oBAAoB,MAAmB;AAAA,IACvC,QAAA;AAAA,IACA,gBAAA;AAAA,IAEA,kBA1DI,MAAyB;AAC7B,MAAI,KAAgB,EAAmB,CAAc;AAAA,IACvD;AAAA,IAyDE,gBAtDI,MAAuB,EAAmB,MAAM;AAAA,IAuDpD,aApDI,MAAoB;AAKxB,MAAI,MAAoB,UAAQ,EAAkB,IAAI,GACtD,EAAmB,IAAI;AAAA,IACzB;AAAA,IA8CE,cA5CI,CAAgB,GAAgB,MAAoB;AACxD,MAAK,MACL,EAAY,mBAAmB;AAAA,QAAE,UAAU,EAAK;AAAA,QAAM,QAAQ;AAAA,QAAiB,QAAA;AAAA,QAAQ,QAAA;AAAA,MAAO,CAAC,GAC/F,EAAmB,IAAI,GAGnB,MAAoB,SACtB,EAAa,WAAW,IAExB,EAAkB,IAAI;AAAA,IAE1B;AAAA,IAmCE,gBA9BI,CAAkB,MAAsB;AAC5C,MAAA,EAAY,mBAAmB;AAAA,QAAE,UAAU,EAAK;AAAA,QAAM,MAAA;AAAA,MAAK,CAAC,GAC5D,EAAa,YAAY;AAAA,IAC3B;AAAA,IA4BE,aAzBI,MAAoB;AACxB,MAAA,EAAY,gBAAgB,EAAE,UAAU,EAAK,KAAK,CAAC,GACnD,EAAkB,IAAI,GACtB,EAAa,SAAS;AAAA,IACxB;AAAA,IAsBE,sBAnBI,MAA6B,EAAa,WAAW;AAAA,IAoBzD,oBAlBI,MAA2B,EAAiB,EAAK;AAAA,EAmBvD;AACF"}
|
|
@@ -7,6 +7,13 @@ export { default as StatusMessageCard } from './components/StatusMessageCard';
|
|
|
7
7
|
export { default as TransactionListCard, type FooterRow } from './components/TransactionListCard';
|
|
8
8
|
export { default as InsightTransactionRow, type InsightTransactionRowProps, } from './components/InsightTransactionRow';
|
|
9
9
|
export { default as LogoClusterCard } from './components/LogoClusterCard';
|
|
10
|
+
export { default as OverflowMenu, type OverflowMenuItem, type OverflowMenuProps, } from './components/OverflowMenu';
|
|
11
|
+
export { default as InsightOptionsMenu } from './components/InsightOptionsMenu';
|
|
12
|
+
export { default as DismissInsightDialog, type DismissInsightDialogProps, type DismissType, } from './components/DismissInsightDialog';
|
|
13
|
+
export { default as HiddenConfirmationCard, type HiddenConfirmationCardProps, } from './components/HiddenConfirmationCard';
|
|
14
|
+
export { default as FeedbackDialog, type FeedbackDialogProps } from './components/FeedbackDialog';
|
|
15
|
+
export { default as FeedbackBar, type FeedbackBarProps } from './components/FeedbackBar';
|
|
16
|
+
export { useBeatActions, type BeatActions, type MenuActionHandlers, type UpdateParams, type FeedbackParams, type DismissParams, type InsightMenuAction, type InsightRating, } from './beatActions';
|
|
10
17
|
export { default as LogoTile } from './components/LogoTile';
|
|
11
18
|
export { default as MerchantHighlightCard } from './components/MerchantHighlightCard';
|
|
12
19
|
export { default as P2PLogoStack } from './components/P2PLogoStack';
|
|
@@ -1,63 +1,77 @@
|
|
|
1
|
-
import { BAR_CHART_VARIANTS as
|
|
1
|
+
import { BAR_CHART_VARIANTS as r, barChartVariant as t, buildChartData as m, buildDataSeries as i } from "./blocks/ChartBlocks/BarchartBlock/utils.es.js";
|
|
2
2
|
import { BarchartBlock as p } from "./blocks/ChartBlocks/BarchartBlock/BarchartBlock.es.js";
|
|
3
|
-
import { DoubleBarChartBlock as
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import { BudgetBlock as
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import { CategoryTransactionsBlock as
|
|
16
|
-
import { SVGImageBlock as
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
import J from "./components/
|
|
23
|
-
import Q from "./components/
|
|
24
|
-
import X from "./components/
|
|
25
|
-
import Z from "./components/
|
|
26
|
-
import
|
|
27
|
-
import
|
|
28
|
-
import
|
|
29
|
-
import
|
|
3
|
+
import { DoubleBarChartBlock as e } from "./blocks/ChartBlocks/DoubleBarChartBlock/DoubleBarChartBlock.es.js";
|
|
4
|
+
import c from "./blocks/ChartBlocks/StepChartBlock/StepChartBlock.es.js";
|
|
5
|
+
import l from "./blocks/ChartBlocks/DonutChartBlock/DonutChartBlock.es.js";
|
|
6
|
+
import C from "./blocks/ChartBlocks/DoubleProgressBarBlock/DoubleProgressBarBlock.es.js";
|
|
7
|
+
import d from "./blocks/ComponentBlocks/AccountBlock/AccountBlock.es.js";
|
|
8
|
+
import k from "./components/TransferLogoCard.es.js";
|
|
9
|
+
import S from "./blocks/ComponentBlocks/AccountSwitchBlock/AccountSwitchBlock.es.js";
|
|
10
|
+
import { BudgetBlock as D } from "./blocks/ComponentBlocks/BudgetBlock/BudgetBlock.es.js";
|
|
11
|
+
import T from "./components/SaveAnExtraCard.es.js";
|
|
12
|
+
import v from "./blocks/ComponentBlocks/SaveExtraBlock/SaveExtraBlock.es.js";
|
|
13
|
+
import I from "./components/InsightTransactionRow.es.js";
|
|
14
|
+
import y from "./components/TransactionListCard.es.js";
|
|
15
|
+
import { CategoryTransactionsBlock as R } from "./blocks/ComponentBlocks/TransactionBlock/TransactionBlock.es.js";
|
|
16
|
+
import { SVGImageBlock as x } from "./blocks/ImageBlocks/SVGImageBlock/SVGImageBlock.es.js";
|
|
17
|
+
import O from "./components/AccountHeroCard.es.js";
|
|
18
|
+
import F from "./components/AmountPill.es.js";
|
|
19
|
+
import G from "./components/DesignateEmergencySavingsCard.es.js";
|
|
20
|
+
import { useBeatActions as U } from "./beatActions.es.js";
|
|
21
|
+
import { OverflowMenu as q } from "./components/OverflowMenu.es.js";
|
|
22
|
+
import { InsightOptionsMenu as J } from "./components/InsightOptionsMenu.es.js";
|
|
23
|
+
import { FeedbackBar as Q } from "./components/FeedbackBar.es.js";
|
|
24
|
+
import X from "./components/FeedbackDialog.es.js";
|
|
25
|
+
import { DismissInsightDialog as Z } from "./components/DismissInsightDialog.es.js";
|
|
26
|
+
import { HiddenConfirmationCard as oo } from "./components/HiddenConfirmationCard.es.js";
|
|
27
|
+
import to from "./components/BaseLayout.es.js";
|
|
28
|
+
import io from "./components/StatusMessageCard.es.js";
|
|
29
|
+
import po from "./components/LogoTile.es.js";
|
|
30
|
+
import eo from "./components/LogoClusterCard.es.js";
|
|
31
|
+
import co from "./components/MerchantHighlightCard.es.js";
|
|
32
|
+
import lo from "./components/P2PLogoStack.es.js";
|
|
33
|
+
import Co from "./components/SavingsOpportunityCard.es.js";
|
|
34
|
+
import uo from "./components/StatusPill.es.js";
|
|
35
|
+
import ho from "./components/SubscriptionHeroCard.es.js";
|
|
36
|
+
import Ao from "./components/UpcomingBillCard.es.js";
|
|
30
37
|
export {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
d as AccountBlock,
|
|
39
|
+
O as AccountHeroCard,
|
|
40
|
+
S as AccountSwitchBlock,
|
|
41
|
+
F as AmountPill,
|
|
42
|
+
r as BAR_CHART_VARIANTS,
|
|
36
43
|
p as BarchartBlock,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
Q as
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
44
|
+
to as BaseLayout,
|
|
45
|
+
D as BudgetBlock,
|
|
46
|
+
R as CategoryTransactionsBlock,
|
|
47
|
+
G as DesignateEmergencySavingsCard,
|
|
48
|
+
Z as DismissInsightDialog,
|
|
49
|
+
l as DonutChartBlock,
|
|
50
|
+
e as DoubleBarChartBlock,
|
|
51
|
+
C as DoubleProgressBarBlock,
|
|
52
|
+
Q as FeedbackBar,
|
|
53
|
+
X as FeedbackDialog,
|
|
54
|
+
oo as HiddenConfirmationCard,
|
|
55
|
+
J as InsightOptionsMenu,
|
|
56
|
+
I as InsightTransactionRow,
|
|
57
|
+
eo as LogoClusterCard,
|
|
58
|
+
po as LogoTile,
|
|
59
|
+
co as MerchantHighlightCard,
|
|
60
|
+
q as OverflowMenu,
|
|
61
|
+
lo as P2PLogoStack,
|
|
62
|
+
x as SVGImageBlock,
|
|
63
|
+
T as SaveAnExtraCard,
|
|
64
|
+
v as SaveExtraBlock,
|
|
65
|
+
Co as SavingsOpportunityCard,
|
|
66
|
+
io as StatusMessageCard,
|
|
67
|
+
uo as StatusPill,
|
|
68
|
+
c as StepChartBlock,
|
|
69
|
+
ho as SubscriptionHeroCard,
|
|
70
|
+
y as TransactionListCard,
|
|
71
|
+
k as TransferLogoCard,
|
|
72
|
+
Ao as UpcomingBillCard,
|
|
60
73
|
t as barChartVariant,
|
|
61
74
|
m as buildChartData,
|
|
62
|
-
i as buildDataSeries
|
|
75
|
+
i as buildDataSeries,
|
|
76
|
+
U as useBeatActions
|
|
63
77
|
};
|