@mx-cartographer/experiences 9.4.31 → 9.4.33
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 +11 -0
- package/dist/core/api/AccountApi.d.ts +3 -2
- package/dist/core/api/AccountApi.es.js +1 -0
- package/dist/core/api/AccountApi.es.js.map +1 -1
- package/dist/core/stores/NetWorthStore.d.ts +3 -0
- package/dist/core/stores/NetWorthStore.es.js +30 -18
- package/dist/core/stores/NetWorthStore.es.js.map +1 -1
- package/dist/core/types/Account.d.ts +10 -0
- package/dist/core/types/Account.es.js.map +1 -1
- package/dist/core/types/Insights.d.ts +4 -0
- package/dist/core/types/index.d.ts +1 -1
- package/dist/core/utils/NetWorthUtils.d.ts +2 -1
- package/dist/core/utils/NetWorthUtils.es.js +58 -46
- package/dist/core/utils/NetWorthUtils.es.js.map +1 -1
- package/dist/insights-v2/actionBlocks/ActionBlockLayer.es.js +20 -19
- package/dist/insights-v2/actionBlocks/ActionBlockLayer.es.js.map +1 -1
- package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/BarchartBlock.es.js +34 -31
- package/dist/insights-v2/blocks/ChartBlocks/BarchartBlock/BarchartBlock.es.js.map +1 -1
- package/dist/insights-v2/blocks/ChartBlocks/DoubleBarChartBlock/DoubleBarChartBlock.es.js +21 -18
- package/dist/insights-v2/blocks/ChartBlocks/DoubleBarChartBlock/DoubleBarChartBlock.es.js.map +1 -1
- package/dist/insights-v2/components/BaseLayout.es.js +53 -53
- package/dist/insights-v2/components/BaseLayout.es.js.map +1 -1
- package/dist/insights-v2/components/DismissInsightDialog.es.js +34 -32
- package/dist/insights-v2/components/DismissInsightDialog.es.js.map +1 -1
- package/dist/insights-v2/components/FeedbackDialog.es.js +10 -7
- package/dist/insights-v2/components/FeedbackDialog.es.js.map +1 -1
- package/dist/insights-v2/components/InsightOptionsMenu.es.js +23 -23
- package/dist/insights-v2/components/InsightOptionsMenu.es.js.map +1 -1
- package/dist/insights-v2/hooks/useBeatFeedbackFlow.es.js +33 -33
- package/dist/insights-v2/hooks/useBeatFeedbackFlow.es.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DismissInsightDialog.es.js","names":[],"sources":["../../../src/insights-v2/components/DismissInsightDialog.tsx"],"sourcesContent":["import { useEffect, useState } from 'react'\n\nimport FormControlLabel from '@mui/material/FormControlLabel'\nimport Radio from '@mui/material/Radio'\nimport RadioGroup from '@mui/material/RadioGroup'\nimport Stack from '@mui/material/Stack'\n\nimport { observer } from 'mobx-react-lite'\n\nimport { Text } from '@mxenabled/mxui'\n\nimport { Dialog, useGlobalCopyStore } from '../../common'\n\nexport type DismissType = 'once' | 'always'\n\nexport interface DismissInsightDialogProps {\n isOpen: boolean\n onClose: () => void\n onDismiss: (type: DismissType) => void\n}\n\n/** Confirmation dialog for hiding an insight. */\nexport const DismissInsightDialog = observer(\n ({ isOpen, onClose, onDismiss }: DismissInsightDialogProps) => {\n const copy = useGlobalCopyStore().insights_feed?.dismiss\n const [selected, setSelected] = useState<DismissType>('once')\n\n useEffect(() => {\n if (isOpen) setSelected('once')\n }, [isOpen])\n\n if (!copy) return null\n\n return (\n <Dialog\n copy={{ title: copy.title, close_aria: copy.close_aria }}\n isOpen={isOpen}\n onClose={onClose}\n onPrimaryAction={() => onDismiss(selected)}\n primaryText={copy.confirm}\n secondaryText={copy.cancel}\n sx={{\n '& .MuiDialogContent-root': { py: 0 },\n '& .MuiDialog-paperScrollPaper > div:first-child': { pt: 24, pb: 8 },\n '& .MuiDialog-paperScrollPaper > div:first-child .MuiIconButton-root': { my: -10 },\n '& .MuiDialog-paperScrollPaper': {\n bgcolor: 'background.paper',\n
|
|
1
|
+
{"version":3,"file":"DismissInsightDialog.es.js","names":[],"sources":["../../../src/insights-v2/components/DismissInsightDialog.tsx"],"sourcesContent":["import { useEffect, useState } from 'react'\n\nimport FormControlLabel from '@mui/material/FormControlLabel'\nimport Radio from '@mui/material/Radio'\nimport RadioGroup from '@mui/material/RadioGroup'\nimport Stack from '@mui/material/Stack'\nimport { alpha } from '@mui/material/styles'\n\nimport { observer } from 'mobx-react-lite'\n\nimport { Text } from '@mxenabled/mxui'\n\nimport { Dialog, useGlobalCopyStore } from '../../common'\n\nexport type DismissType = 'once' | 'always'\n\nexport interface DismissInsightDialogProps {\n isOpen: boolean\n onClose: () => void\n onDismiss: (type: DismissType) => void\n}\n\n/** Confirmation dialog for hiding an insight. */\nexport const DismissInsightDialog = observer(\n ({ isOpen, onClose, onDismiss }: DismissInsightDialogProps) => {\n const copy = useGlobalCopyStore().insights_feed?.dismiss\n const [selected, setSelected] = useState<DismissType>('once')\n\n useEffect(() => {\n if (isOpen) setSelected('once')\n }, [isOpen])\n\n if (!copy) return null\n\n return (\n <Dialog\n copy={{ title: copy.title, close_aria: copy.close_aria }}\n isOpen={isOpen}\n onClose={onClose}\n onPrimaryAction={() => onDismiss(selected)}\n primaryText={copy.confirm}\n secondaryText={copy.cancel}\n sx={{\n '& .MuiDialogContent-root': { py: 0 },\n '& .MuiDialog-paperScrollPaper > div:first-child': { pt: 24, pb: 8 },\n '& .MuiDialog-paperScrollPaper > div:first-child .MuiIconButton-root': { my: -10 },\n '& .MuiDialog-paperScrollPaper': {\n bgcolor: 'background.paper',\n borderRadius: '4px',\n },\n '&:focus-visible': {\n outline: '2px solid',\n outlineColor: 'primary.main',\n },\n '& .MuiDialog-paper:focus-visible': {\n outline: '2px solid',\n outlineColor: 'primary.main',\n },\n '& .MuiButton-outlined': {\n border: 'none',\n '&:hover': { bgcolor: 'transparent', border: 'none' },\n },\n }}\n >\n <Stack sx={{ gap: 24 }}>\n <Text variant=\"subtitle1\">{copy.description}</Text>\n\n <RadioGroup\n aria-label={copy.title}\n name=\"dismiss-type\"\n onChange={(e) => setSelected(e.target.value as DismissType)}\n sx={{ m: 0, p: 0 }}\n value={selected}\n >\n <Stack sx={{ gap: 16 }}>\n {(['once', 'always'] as const).map((k) => (\n <FormControlLabel\n key={k}\n value={k}\n control={\n <Radio\n inputProps={{ 'aria-label': copy[k].headline }}\n sx={{\n '& .MuiSvgIcon-root': {\n color: selected === k ? 'inherit' : 'action.active',\n },\n }}\n />\n }\n labelPlacement=\"start\"\n label={\n <Stack sx={{ gap: 4, flexGrow: 1 }}>\n <Text bold={true} variant=\"body1\">\n {copy[k].headline}\n </Text>\n <Text variant=\"subtitle2\">{copy[k].description}</Text>\n </Stack>\n }\n sx={{\n alignItems: 'center',\n borderRadius: '8px',\n justifyContent: 'space-between',\n m: 0,\n minHeight: 72,\n px: 16,\n py: 0,\n border: (theme) =>\n selected === k\n ? `2px solid ${alpha(theme.palette.primary.main, 0.5)}`\n : `1px solid ${alpha(theme.palette.divider, 0.5)}`,\n }}\n />\n ))}\n </Stack>\n </RadioGroup>\n </Stack>\n </Dialog>\n )\n },\n)\n\nexport default DismissInsightDialog\n"],"mappings":";;;;;;;;;;;AAuBA,IAAa,IAAuB,EAAA,CACjC,EAAE,QAAA,GAAQ,SAAA,GAAS,WAAA,EAAA,MAA2C;AAC7D,QAAM,IAAO,EAAmB,EAAE,eAAe,SAC3C,CAAC,GAAU,CAAA,IAAe,EAAsB,MAAM;AAM5D,SAJA,EAAA,MAAgB;AACd,IAAI,KAAQ,EAAY,MAAM;AAAA,EAChC,GAAG,CAAC,CAAM,CAAC,GAEN,IAGH,gBAAA,EAAC,GAAD;AAAA,IACE,MAAM;AAAA,MAAE,OAAO,EAAK;AAAA,MAAO,YAAY,EAAK;AAAA,IAAW;AAAA,IAC/C,QAAA;AAAA,IACC,SAAA;AAAA,IACT,iBAAA,MAAuB,EAAU,CAAQ;AAAA,IACzC,aAAa,EAAK;AAAA,IAClB,eAAe,EAAK;AAAA,IACpB,IAAI;AAAA,MACF,4BAA4B,EAAE,IAAI,EAAE;AAAA,MACpC,mDAAmD;AAAA,QAAE,IAAI;AAAA,QAAI,IAAI;AAAA,MAAE;AAAA,MACnE,uEAAuE,EAAE,IAAI,IAAI;AAAA,MACjF,iCAAiC;AAAA,QAC/B,SAAS;AAAA,QACT,cAAc;AAAA,MAChB;AAAA,MACA,mBAAmB;AAAA,QACjB,SAAS;AAAA,QACT,cAAc;AAAA,MAChB;AAAA,MACA,oCAAoC;AAAA,QAClC,SAAS;AAAA,QACT,cAAc;AAAA,MAChB;AAAA,MACA,yBAAyB;AAAA,QACvB,QAAQ;AAAA,QACR,WAAW;AAAA,UAAE,SAAS;AAAA,UAAe,QAAQ;AAAA,QAAO;AAAA,MACtD;AAAA,IACF;AAAA,IAEA,UAAA,gBAAA,EAAC,GAAD;AAAA,MAAO,IAAI,EAAE,KAAK,GAAG;AAAA,MAArB,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,QAAM,SAAQ;AAAA,QAAa,UAAA,EAAK;AAAA,MAAkB,CAAA,GAElD,gBAAA,EAAC,GAAD;AAAA,QACE,cAAY,EAAK;AAAA,QACjB,MAAK;AAAA,QACL,UAAA,CAAW,MAAM,EAAY,EAAE,OAAO,KAAoB;AAAA,QAC1D,IAAI;AAAA,UAAE,GAAG;AAAA,UAAG,GAAG;AAAA,QAAE;AAAA,QACjB,OAAO;AAAA,QAEP,UAAA,gBAAA,EAAC,GAAD;AAAA,UAAO,IAAI,EAAE,KAAK,GAAG;AAAA,UACjB,UAAA,CAAC,QAAQ,QAAQ,EAAY,IAAA,CAAK,MAClC,gBAAA,EAAC,GAAD;AAAA,YAEE,OAAO;AAAA,YACP,SACE,gBAAA,EAAC,GAAD;AAAA,cACE,YAAY,EAAE,cAAc,EAAK,CAAA,EAAG,SAAS;AAAA,cAC7C,IAAI,EACF,sBAAsB,EACpB,OAAO,MAAa,IAAI,YAAY,gBACtC,EACF;AAAA,YACD,CAAA;AAAA,YAEH,gBAAe;AAAA,YACf,OACE,gBAAA,EAAC,GAAD;AAAA,cAAO,IAAI;AAAA,gBAAE,KAAK;AAAA,gBAAG,UAAU;AAAA,cAAE;AAAA,cAAjC,UAAA,CACE,gBAAA,EAAC,GAAD;AAAA,gBAAM,MAAM;AAAA,gBAAM,SAAQ;AAAA,gBACvB,UAAA,EAAK,CAAA,EAAG;AAAA,cACL,CAAA,GACN,gBAAA,EAAC,GAAD;AAAA,gBAAM,SAAQ;AAAA,gBAAa,UAAA,EAAK,CAAA,EAAG;AAAA,cAAkB,CAAA,CAChD;AAAA;YAET,IAAI;AAAA,cACF,YAAY;AAAA,cACZ,cAAc;AAAA,cACd,gBAAgB;AAAA,cAChB,GAAG;AAAA,cACH,WAAW;AAAA,cACX,IAAI;AAAA,cACJ,IAAI;AAAA,cACJ,QAAA,CAAS,MACP,MAAa,IACT,aAAa,EAAM,EAAM,QAAQ,QAAQ,MAAM,GAAG,CAAA,KAClD,aAAa,EAAM,EAAM,QAAQ,SAAS,GAAG,CAAA;AAAA,YACrD;AAAA,UACD,GAlCM,CAkCN,CACF;AAAA,QACI,CAAA;AAAA,MACG,CAAA,CACP;AAAA;EACD,CAAA,IApFQ;AAsFpB,CACF"}
|
|
@@ -8,12 +8,12 @@ import E from "@mui/material/TextField";
|
|
|
8
8
|
import L from "@mui/material/Radio";
|
|
9
9
|
import G from "@mui/material/FormControl";
|
|
10
10
|
import H from "@mui/material/RadioGroup";
|
|
11
|
-
var K = 250, O = ({ isOpen: l, onClose: h, onSubmit: x, title:
|
|
11
|
+
var K = 250, O = ({ isOpen: l, onClose: h, onSubmit: x, title: s, options: r, characterLimit: v = K, characterLimitLabel: u, secondaryText: C, primaryText: S, closeAriaLabel: y, onBackClick: k, onTextInputFocus: F }) => {
|
|
12
12
|
const [t, m] = b(""), [a, d] = b(""), i = p(!1), n = p(!1);
|
|
13
13
|
if (w(() => {
|
|
14
14
|
l && (i.current = !1, n.current = !1);
|
|
15
15
|
}, [l]), r.length === 0) return null;
|
|
16
|
-
const
|
|
16
|
+
const c = t === r[r.length - 1], R = !t || c && !a.trim(), f = () => {
|
|
17
17
|
m(""), d("");
|
|
18
18
|
}, D = (e) => {
|
|
19
19
|
if (e === "backdropClick" || e === "escapeKeyDown") return e;
|
|
@@ -28,14 +28,14 @@ var K = 250, O = ({ isOpen: l, onClose: h, onSubmit: x, title: c, options: r, ch
|
|
|
28
28
|
};
|
|
29
29
|
return /* @__PURE__ */ g(P, {
|
|
30
30
|
copy: {
|
|
31
|
-
title:
|
|
31
|
+
title: s,
|
|
32
32
|
close_aria: y
|
|
33
33
|
},
|
|
34
34
|
disablePrimaryButton: R,
|
|
35
35
|
isOpen: l,
|
|
36
36
|
onClose: M,
|
|
37
37
|
onPrimaryAction: () => {
|
|
38
|
-
n.current = !0, x(t,
|
|
38
|
+
n.current = !0, x(t, c ? a.trim() : void 0), f();
|
|
39
39
|
},
|
|
40
40
|
onSecondaryAction: T,
|
|
41
41
|
primaryText: S,
|
|
@@ -59,12 +59,15 @@ var K = 250, O = ({ isOpen: l, onClose: h, onSubmit: x, title: c, options: r, ch
|
|
|
59
59
|
}
|
|
60
60
|
},
|
|
61
61
|
children: [/* @__PURE__ */ o(G, { children: /* @__PURE__ */ o(H, {
|
|
62
|
-
"aria-label":
|
|
62
|
+
"aria-label": s,
|
|
63
63
|
name: "feedback-radio-group",
|
|
64
64
|
onChange: (e) => m(e.target.value),
|
|
65
65
|
value: t,
|
|
66
66
|
children: r.map((e) => /* @__PURE__ */ o(z, {
|
|
67
|
-
control: /* @__PURE__ */ o(L, { sx: { "& .MuiSvgIcon-root": {
|
|
67
|
+
control: /* @__PURE__ */ o(L, { sx: { "& .MuiSvgIcon-root": {
|
|
68
|
+
fontSize: 22,
|
|
69
|
+
color: "action.active"
|
|
70
|
+
} } }),
|
|
68
71
|
label: e,
|
|
69
72
|
sx: { "& .MuiFormControlLabel-label": {
|
|
70
73
|
color: "text.primary",
|
|
@@ -72,7 +75,7 @@ var K = 250, O = ({ isOpen: l, onClose: h, onSubmit: x, title: c, options: r, ch
|
|
|
72
75
|
} },
|
|
73
76
|
value: e
|
|
74
77
|
}, e))
|
|
75
|
-
}) }),
|
|
78
|
+
}) }), c && /* @__PURE__ */ g(_, {
|
|
76
79
|
sx: {
|
|
77
80
|
gap: 3,
|
|
78
81
|
mt: 4
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeedbackDialog.es.js","names":[],"sources":["../../../src/insights-v2/components/FeedbackDialog.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\n\nimport FormControl from '@mui/material/FormControl'\nimport FormControlLabel from '@mui/material/FormControlLabel'\nimport Radio from '@mui/material/Radio'\nimport RadioGroup from '@mui/material/RadioGroup'\nimport Stack from '@mui/material/Stack'\nimport TextField from '@mui/material/TextField'\n\nimport { Text } from '@mxenabled/mxui'\n\nimport { Dialog } from '../../common'\n\nconst CHARACTER_LIMIT = 250\n\nexport type FeedbackDialogCloseReason = 'closeButton' | 'backdropClick' | 'escapeKeyDown'\n\nexport interface FeedbackDialogProps {\n title: string\n options: string[]\n characterLimit?: number\n characterLimitLabel?: string\n isOpen: boolean\n onSubmit: (option: string, detail?: string) => void\n /** Called on every close; `reason` is set for user-initiated closes (X/backdrop/escape), undefined on submit/back. */\n onClose: (reason?: FeedbackDialogCloseReason) => void\n onBackClick?: () => void\n onTextInputFocus?: () => void\n secondaryText: string\n primaryText: string\n closeAriaLabel: string\n}\n\n/** Generic feedback survey dialog. Last option shows detail text field. */\nconst FeedbackDialog = ({\n isOpen,\n onClose,\n onSubmit,\n title,\n options,\n characterLimit = CHARACTER_LIMIT,\n characterLimitLabel,\n secondaryText,\n primaryText,\n closeAriaLabel,\n onBackClick,\n onTextInputFocus,\n}: FeedbackDialogProps) => {\n const [selected, setSelected] = useState('')\n const [detail, setDetail] = useState('')\n const hasTrackedFocus = useRef(false)\n const skipCloseAnalytics = useRef(false)\n\n useEffect(() => {\n if (isOpen) {\n hasTrackedFocus.current = false\n skipCloseAnalytics.current = false\n }\n }, [isOpen])\n\n if (options.length === 0) return null\n\n const isOther = selected === options[options.length - 1]\n const isSubmitDisabled = !selected || (isOther && !detail.trim())\n\n const reset = () => {\n setSelected('')\n setDetail('')\n }\n\n const resolveCloseReason = (reason?: string): FeedbackDialogCloseReason | undefined => {\n if (reason === 'backdropClick' || reason === 'escapeKeyDown') return reason\n if (!skipCloseAnalytics.current) return 'closeButton'\n return undefined\n }\n\n const handleClose = (_event?: unknown, reason?: string) => {\n const closeReason = resolveCloseReason(reason)\n reset()\n onClose(closeReason)\n }\n\n const handleBack = () => {\n skipCloseAnalytics.current = true\n onBackClick?.()\n }\n\n const handleTextFocus = () => {\n if (!hasTrackedFocus.current) {\n hasTrackedFocus.current = true\n onTextInputFocus?.()\n }\n }\n\n const handleSubmit = () => {\n skipCloseAnalytics.current = true\n onSubmit(selected, isOther ? detail.trim() : undefined)\n reset()\n }\n\n return (\n <Dialog\n copy={{ title, close_aria: closeAriaLabel }}\n disablePrimaryButton={isSubmitDisabled}\n isOpen={isOpen}\n onClose={handleClose}\n onPrimaryAction={handleSubmit}\n onSecondaryAction={handleBack}\n primaryText={primaryText}\n secondaryText={secondaryText}\n sx={{\n '& .MuiDialogContent-root': { py: 0 },\n '& .MuiDialog-paperScrollPaper': { bgcolor: 'background.paper' },\n '& .MuiDialog-paper': {\n outline: 'none',\n '&:focus-visible': {
|
|
1
|
+
{"version":3,"file":"FeedbackDialog.es.js","names":[],"sources":["../../../src/insights-v2/components/FeedbackDialog.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\n\nimport FormControl from '@mui/material/FormControl'\nimport FormControlLabel from '@mui/material/FormControlLabel'\nimport Radio from '@mui/material/Radio'\nimport RadioGroup from '@mui/material/RadioGroup'\nimport Stack from '@mui/material/Stack'\nimport TextField from '@mui/material/TextField'\n\nimport { Text } from '@mxenabled/mxui'\n\nimport { Dialog } from '../../common'\n\nconst CHARACTER_LIMIT = 250\n\nexport type FeedbackDialogCloseReason = 'closeButton' | 'backdropClick' | 'escapeKeyDown'\n\nexport interface FeedbackDialogProps {\n title: string\n options: string[]\n characterLimit?: number\n characterLimitLabel?: string\n isOpen: boolean\n onSubmit: (option: string, detail?: string) => void\n /** Called on every close; `reason` is set for user-initiated closes (X/backdrop/escape), undefined on submit/back. */\n onClose: (reason?: FeedbackDialogCloseReason) => void\n onBackClick?: () => void\n onTextInputFocus?: () => void\n secondaryText: string\n primaryText: string\n closeAriaLabel: string\n}\n\n/** Generic feedback survey dialog. Last option shows detail text field. */\nconst FeedbackDialog = ({\n isOpen,\n onClose,\n onSubmit,\n title,\n options,\n characterLimit = CHARACTER_LIMIT,\n characterLimitLabel,\n secondaryText,\n primaryText,\n closeAriaLabel,\n onBackClick,\n onTextInputFocus,\n}: FeedbackDialogProps) => {\n const [selected, setSelected] = useState('')\n const [detail, setDetail] = useState('')\n const hasTrackedFocus = useRef(false)\n const skipCloseAnalytics = useRef(false)\n\n useEffect(() => {\n if (isOpen) {\n hasTrackedFocus.current = false\n skipCloseAnalytics.current = false\n }\n }, [isOpen])\n\n if (options.length === 0) return null\n\n const isOther = selected === options[options.length - 1]\n const isSubmitDisabled = !selected || (isOther && !detail.trim())\n\n const reset = () => {\n setSelected('')\n setDetail('')\n }\n\n const resolveCloseReason = (reason?: string): FeedbackDialogCloseReason | undefined => {\n if (reason === 'backdropClick' || reason === 'escapeKeyDown') return reason\n if (!skipCloseAnalytics.current) return 'closeButton'\n return undefined\n }\n\n const handleClose = (_event?: unknown, reason?: string) => {\n const closeReason = resolveCloseReason(reason)\n reset()\n onClose(closeReason)\n }\n\n const handleBack = () => {\n skipCloseAnalytics.current = true\n onBackClick?.()\n }\n\n const handleTextFocus = () => {\n if (!hasTrackedFocus.current) {\n hasTrackedFocus.current = true\n onTextInputFocus?.()\n }\n }\n\n const handleSubmit = () => {\n skipCloseAnalytics.current = true\n onSubmit(selected, isOther ? detail.trim() : undefined)\n reset()\n }\n\n return (\n <Dialog\n copy={{ title, close_aria: closeAriaLabel }}\n disablePrimaryButton={isSubmitDisabled}\n isOpen={isOpen}\n onClose={handleClose}\n onPrimaryAction={handleSubmit}\n onSecondaryAction={handleBack}\n primaryText={primaryText}\n secondaryText={secondaryText}\n sx={{\n '& .MuiDialogContent-root': { py: 0 },\n '& .MuiDialog-paperScrollPaper': { bgcolor: 'background.paper' },\n '& .MuiDialog-paper': {\n outline: 'none',\n '&:focus-visible': {\n outline: '2px solid',\n outlineColor: 'primary.main',\n },\n },\n '& .MuiButton-outlined': {\n border: 'none',\n '&:hover': { bgcolor: 'transparent', border: 'none' },\n },\n }}\n >\n <FormControl>\n <RadioGroup\n aria-label={title}\n name=\"feedback-radio-group\"\n onChange={(e) => setSelected(e.target.value)}\n value={selected}\n >\n {options.map((option) => (\n <FormControlLabel\n control={\n <Radio\n sx={{\n '& .MuiSvgIcon-root': {\n fontSize: 22,\n color: 'action.active',\n },\n }}\n />\n }\n key={option}\n label={option}\n sx={{\n '& .MuiFormControlLabel-label': {\n color: 'text.primary',\n fontSize: 15,\n },\n }}\n value={option}\n />\n ))}\n </RadioGroup>\n </FormControl>\n\n {isOther && (\n <Stack sx={{ gap: 3, mt: 4 }}>\n <TextField\n autoFocus\n maxRows={4}\n minRows={4}\n multiline={true}\n onChange={(e) => setDetail(e.target.value)}\n onFocus={handleTextFocus}\n slotProps={{ htmlInput: { maxLength: characterLimit } }}\n value={detail}\n />\n {characterLimitLabel && (\n <Text sx={{ color: 'text.secondary', fontWeight: 400 }} variant=\"subtitle2\">\n {characterLimitLabel}\n </Text>\n )}\n </Stack>\n )}\n </Dialog>\n )\n}\n\nexport default FeedbackDialog\n"],"mappings":"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"}
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
import { useGlobalCopyStore as
|
|
2
|
-
import { useBeatActions as
|
|
3
|
-
import { OverflowMenu as
|
|
4
|
-
import { observer as
|
|
5
|
-
import { Icon as
|
|
1
|
+
import { useGlobalCopyStore as c } from "../../common/context/hooks.es.js";
|
|
2
|
+
import { useBeatActions as s } from "../beatActions.es.js";
|
|
3
|
+
import { OverflowMenu as f } from "./OverflowMenu.es.js";
|
|
4
|
+
import { observer as m } from "mobx-react-lite";
|
|
5
|
+
import { Icon as t } from "@mxenabled/mx-icons";
|
|
6
6
|
import { jsx as o } from "react/jsx-runtime";
|
|
7
|
-
var
|
|
8
|
-
const { onMenuAction:
|
|
9
|
-
if (!
|
|
10
|
-
const { onAction:
|
|
7
|
+
var v = m(() => {
|
|
8
|
+
const { onMenuAction: i } = s(), e = c().insights_feed?.overflow_menu;
|
|
9
|
+
if (!i || !e) return null;
|
|
10
|
+
const { onAction: n, onOpen: l, disabled: r } = i, a = [
|
|
11
11
|
{
|
|
12
12
|
key: "helpful",
|
|
13
|
-
icon: /* @__PURE__ */ o(
|
|
13
|
+
icon: /* @__PURE__ */ o(t, {
|
|
14
14
|
name: "thumb_up",
|
|
15
15
|
size: 24,
|
|
16
|
-
sx: { color: "
|
|
16
|
+
sx: { color: "action.active" }
|
|
17
17
|
}),
|
|
18
18
|
label: e.helpful,
|
|
19
|
-
onSelect: () =>
|
|
19
|
+
onSelect: () => n("helpful")
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
key: "not_helpful",
|
|
23
|
-
icon: /* @__PURE__ */ o(
|
|
23
|
+
icon: /* @__PURE__ */ o(t, {
|
|
24
24
|
name: "thumb_down",
|
|
25
25
|
size: 24,
|
|
26
|
-
sx: { color: "
|
|
26
|
+
sx: { color: "action.active" }
|
|
27
27
|
}),
|
|
28
28
|
label: e.not_helpful,
|
|
29
|
-
onSelect: () =>
|
|
29
|
+
onSelect: () => n("not_helpful")
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
key: "hide",
|
|
33
|
-
icon: /* @__PURE__ */ o(
|
|
33
|
+
icon: /* @__PURE__ */ o(t, {
|
|
34
34
|
name: "visibility_off",
|
|
35
35
|
size: 24,
|
|
36
|
-
sx: { color: "
|
|
36
|
+
sx: { color: "action.active" }
|
|
37
37
|
}),
|
|
38
38
|
label: e.hide,
|
|
39
|
-
onSelect: () =>
|
|
39
|
+
onSelect: () => n("hide")
|
|
40
40
|
}
|
|
41
41
|
];
|
|
42
|
-
return /* @__PURE__ */ o(
|
|
42
|
+
return /* @__PURE__ */ o(f, {
|
|
43
43
|
ariaLabel: e.aria_label,
|
|
44
44
|
disabled: r,
|
|
45
|
-
items:
|
|
46
|
-
onOpen:
|
|
45
|
+
items: a,
|
|
46
|
+
onOpen: l
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
49
|
export {
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
v as InsightOptionsMenu,
|
|
51
|
+
v as default
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
//# sourceMappingURL=InsightOptionsMenu.es.js.map
|
|
@@ -1 +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/** Overflow menu for insight cards. */\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: '
|
|
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/** Overflow menu for insight cards. */\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: 'action.active' }} />,\n label: copy.helpful,\n onSelect: () => onAction('helpful'),\n },\n {\n key: 'not_helpful',\n icon: <Icon name=\"thumb_down\" size={24} sx={{ color: 'action.active' }} />,\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: 'action.active' }} />,\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":";;;;;;AAWA,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,gBAAgB;AAAA,MAAI,CAAA;AAAA,MACvE,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,gBAAgB;AAAA,MAAI,CAAA;AAAA,MACzE,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,gBAAgB;AAAA,MAAI,CAAA;AAAA,MAC7E,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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { useGlobalCopyStore as
|
|
2
|
-
import { useEffect as
|
|
3
|
-
var
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}, [
|
|
8
|
-
const k = p(() =>
|
|
9
|
-
const e =
|
|
1
|
+
import { useGlobalCopyStore as y } from "../../common/context/hooks.es.js";
|
|
2
|
+
import { useEffect as S, useMemo as p, useState as u } from "react";
|
|
3
|
+
var H = (h, n) => {
|
|
4
|
+
const a = y(), [r, t] = u(null), [i, l] = u(null), [b, d] = u(!1), [f, c] = u(!1), o = h.insights_payload;
|
|
5
|
+
S(() => {
|
|
6
|
+
o?.is_dismissed || c(!1);
|
|
7
|
+
}, [o?.is_dismissed]);
|
|
8
|
+
const k = p(() => o?.is_dismissed && f ? "dismissed" : o?.is_dismissed ? "confirming" : "visible", [o?.is_dismissed, f]), _ = (() => {
|
|
9
|
+
const e = a.insights_feed?.feedback, s = a.insights_feed?.hide_feedback, m = {
|
|
10
10
|
characterLimitLabel: (i === "hide" ? s : e)?.character_limit,
|
|
11
11
|
closeAriaLabel: (i === "hide" ? s : e)?.close_aria ?? "Close",
|
|
12
12
|
submitText: (i === "hide" ? s : e)?.submit ?? "Submit",
|
|
@@ -17,67 +17,67 @@ var w = (n, o) => {
|
|
|
17
17
|
options: Object.values(s.options),
|
|
18
18
|
...m
|
|
19
19
|
};
|
|
20
|
-
const
|
|
20
|
+
const g = Object.values(i === "not_helpful" ? e?.not_helpful_options ?? {} : e?.helpful_options ?? {});
|
|
21
21
|
return {
|
|
22
22
|
title: e?.tell_us_more_title ?? "Tell us more",
|
|
23
|
-
options:
|
|
23
|
+
options: g,
|
|
24
24
|
...m
|
|
25
25
|
};
|
|
26
|
-
})(),
|
|
27
|
-
const e =
|
|
26
|
+
})(), v = p(() => {
|
|
27
|
+
const e = n.onMenuAction;
|
|
28
28
|
return e ? {
|
|
29
|
-
...
|
|
29
|
+
...n,
|
|
30
30
|
onMenuAction: {
|
|
31
31
|
...e,
|
|
32
32
|
onAction: (s) => {
|
|
33
|
-
s === "helpful" || s === "not_helpful" ?
|
|
33
|
+
s === "helpful" || s === "not_helpful" ? t(s) : s === "hide" && d(!0), e.onAction(s);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
} :
|
|
37
|
-
}, [
|
|
36
|
+
} : n;
|
|
37
|
+
}, [n]);
|
|
38
38
|
return {
|
|
39
39
|
cardState: k,
|
|
40
|
-
isDismissOpen:
|
|
40
|
+
isDismissOpen: b,
|
|
41
41
|
isSurveyOpen: i !== null,
|
|
42
42
|
isFeedbackBarShown: r !== null,
|
|
43
|
-
survey:
|
|
44
|
-
wrappedActions:
|
|
43
|
+
survey: _,
|
|
44
|
+
wrappedActions: v,
|
|
45
45
|
openRatingSurvey: () => {
|
|
46
|
-
r &&
|
|
46
|
+
r && l(r);
|
|
47
47
|
},
|
|
48
|
-
openHideSurvey: () =>
|
|
48
|
+
openHideSurvey: () => l("hide"),
|
|
49
49
|
closeSurvey: (e) => {
|
|
50
|
-
e &&
|
|
50
|
+
e && n.onFeedbackDialogClose?.(e), i !== "hide" && t(null), l(null);
|
|
51
51
|
},
|
|
52
52
|
submitSurvey: (e, s) => {
|
|
53
|
-
i
|
|
54
|
-
beatGuid:
|
|
53
|
+
!i || !o || (n.onSubmitFeedback?.({
|
|
54
|
+
beatGuid: o.guid,
|
|
55
55
|
source: i,
|
|
56
56
|
option: e,
|
|
57
57
|
detail: s
|
|
58
|
-
}),
|
|
58
|
+
}), l(null), i === "hide" ? c(!0) : t(null));
|
|
59
59
|
},
|
|
60
60
|
confirmDismiss: (e) => {
|
|
61
|
-
o.onDismissInsight?.({
|
|
62
|
-
beatGuid:
|
|
61
|
+
o && n.onDismissInsight?.({
|
|
62
|
+
beatGuid: o.guid,
|
|
63
63
|
type: e
|
|
64
64
|
});
|
|
65
65
|
},
|
|
66
66
|
undoDismiss: () => {
|
|
67
|
-
o.onUndoDismiss?.({ beatGuid:
|
|
67
|
+
o && (n.onUndoDismiss?.({ beatGuid: o.guid }), t(null));
|
|
68
68
|
},
|
|
69
69
|
collapseConfirmation: () => {
|
|
70
70
|
c(!0);
|
|
71
71
|
},
|
|
72
|
-
closeDismissDialog: () =>
|
|
72
|
+
closeDismissDialog: () => d(!1),
|
|
73
73
|
feedbackDialogCallbacks: {
|
|
74
|
-
onBackClick:
|
|
75
|
-
onTextInputFocus:
|
|
74
|
+
onBackClick: n.onFeedbackDialogBack,
|
|
75
|
+
onTextInputFocus: n.onFeedbackTextFocus
|
|
76
76
|
}
|
|
77
77
|
};
|
|
78
78
|
};
|
|
79
79
|
export {
|
|
80
|
-
|
|
80
|
+
H as useBeatFeedbackFlow
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
//# sourceMappingURL=useBeatFeedbackFlow.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBeatFeedbackFlow.es.js","names":[],"sources":["../../../src/insights-v2/hooks/useBeatFeedbackFlow.ts"],"sourcesContent":["import { useEffect, 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'\nimport type { FeedbackDialogCloseReason } from '../components/FeedbackDialog'\n\nexport type FeedbackVariant = InsightRating | 'hide'\nexport type CardState = 'visible' | 'confirming' | 'dismissed'\n\n/**\n * Manages feedback and dismiss UI state for a beat card.\n * Handles feedback bar, dismiss dialog, confirmation card, and survey dialogs.\n */\nexport const useBeatFeedbackFlow = (beat: Beat, beatActions: BeatActions) => {\n const copyStore = useGlobalCopyStore()\n\n const [feedbackRating, setFeedbackRating] = useState<InsightRating | null>(null)\n const [feedbackVariant, setFeedbackVariant] = useState<FeedbackVariant | null>(null)\n const [isDismissOpen, setIsDismissOpen] = useState(false)\n const [hasClosedConfirmation, setHasClosedConfirmation] = useState(false)\n\n // Reset the confirmation-closed flag whenever the beat is no longer dismissed\n // (undo or a host reload flipping is_dismissed), so a fresh dismiss always\n // starts at the confirmation card instead of jumping to 'dismissed'.\n useEffect(() => {\n if (!
|
|
1
|
+
{"version":3,"file":"useBeatFeedbackFlow.es.js","names":[],"sources":["../../../src/insights-v2/hooks/useBeatFeedbackFlow.ts"],"sourcesContent":["import { useEffect, 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'\nimport type { FeedbackDialogCloseReason } from '../components/FeedbackDialog'\n\nexport type FeedbackVariant = InsightRating | 'hide'\nexport type CardState = 'visible' | 'confirming' | 'dismissed'\n\n/**\n * Manages feedback and dismiss UI state for a beat card.\n * Handles feedback bar, dismiss dialog, confirmation card, and survey dialogs.\n */\nexport const useBeatFeedbackFlow = (beat: Beat, beatActions: BeatActions) => {\n const copyStore = useGlobalCopyStore()\n\n const [feedbackRating, setFeedbackRating] = useState<InsightRating | null>(null)\n const [feedbackVariant, setFeedbackVariant] = useState<FeedbackVariant | null>(null)\n const [isDismissOpen, setIsDismissOpen] = useState(false)\n const [hasClosedConfirmation, setHasClosedConfirmation] = useState(false)\n\n const insights_payload = beat.insights_payload\n\n // Reset the confirmation-closed flag whenever the beat is no longer dismissed\n // (undo or a host reload flipping is_dismissed), so a fresh dismiss always\n // starts at the confirmation card instead of jumping to 'dismissed'.\n useEffect(() => {\n if (!insights_payload?.is_dismissed) setHasClosedConfirmation(false)\n }, [insights_payload?.is_dismissed])\n\n const cardState: CardState = useMemo(() => {\n if (insights_payload?.is_dismissed && hasClosedConfirmation) return 'dismissed'\n if (insights_payload?.is_dismissed) return 'confirming'\n return 'visible'\n }, [insights_payload?.is_dismissed, hasClosedConfirmation])\n\n const resolveSurvey = () => {\n const feedbackCopy = copyStore.insights_feed?.feedback\n const hideCopy = copyStore.insights_feed?.hide_feedback\n\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 {\n title: hideCopy.title,\n options: Object.values(hideCopy.options),\n ...chrome,\n }\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 {\n title: feedbackCopy?.tell_us_more_title ?? 'Tell us more',\n options,\n ...chrome,\n }\n }\n\n const survey = resolveSurvey()\n\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 const openRatingSurvey = () => {\n if (feedbackRating) setFeedbackVariant(feedbackRating)\n }\n\n const openHideSurvey = () => setFeedbackVariant('hide')\n\n const closeSurvey = (reason?: FeedbackDialogCloseReason) => {\n if (reason) beatActions.onFeedbackDialogClose?.(reason)\n if (feedbackVariant !== 'hide') setFeedbackRating(null)\n setFeedbackVariant(null)\n }\n\n const submitSurvey = (option: string, detail?: string) => {\n if (!feedbackVariant || !insights_payload) return\n beatActions.onSubmitFeedback?.({\n beatGuid: insights_payload.guid,\n source: feedbackVariant,\n option,\n detail,\n })\n setFeedbackVariant(null)\n if (feedbackVariant === 'hide') {\n setHasClosedConfirmation(true)\n } else {\n setFeedbackRating(null)\n }\n }\n\n const confirmDismiss = (type: DismissType) => {\n if (!insights_payload) return\n beatActions.onDismissInsight?.({ beatGuid: insights_payload.guid, type })\n }\n\n const undoDismiss = () => {\n if (!insights_payload) return\n beatActions.onUndoDismiss?.({ beatGuid: insights_payload.guid })\n setFeedbackRating(null)\n }\n\n const collapseConfirmation = () => {\n setHasClosedConfirmation(true)\n }\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 openRatingSurvey,\n openHideSurvey,\n closeSurvey,\n submitSurvey,\n confirmDismiss,\n undoDismiss,\n collapseConfirmation,\n closeDismissDialog,\n feedbackDialogCallbacks: {\n onBackClick: beatActions.onFeedbackDialogBack,\n onTextInputFocus: beatActions.onFeedbackTextFocus,\n },\n }\n}\n"],"mappings":"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"}
|