@mx-cartographer/experiences 9.4.32 → 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 +7 -0
- package/dist/core/types/Insights.d.ts +4 -0
- 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
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [9.4.33] - 09-21-2026
|
|
2
|
+
|
|
3
|
+
- **CHANGED** - Insights V2 components and hooks migrated to use `insights_payload` keys instead of accessing properties directly from `beat`. `BaseLayout`, `ActionBlockLayer`, and the `useBeatFeedbackFlow` hook now destructure and read content properties (`guid`, `user_guid`, `dismissed_at`, `title`, `sub_title`, `description.html_text`, etc.) from `insights_payload` instead of `beat`. `BaseLayout` also updated to use `insights_payload.guid` instead of `beat.guid` when passing to block components. Updated `InsightsPayload` type with mandatory fields (`guid`, `user_guid`, `dismissed_at`, `is_dismissed`), component implementations, test fixtures (BaseLayout tests cover 37 scenarios), and mock data. Added TODO comment for `in_description_cta` migration pending backend support (WEC-1807)
|
|
4
|
+
- **CHANGED** - `BarchartBlock` and `DoubleBarChartBlock` now guard drawer opening on `widget_type !== 'full'`, preventing drilldown on mini/micro widgets. Added `widget_type` to payload destructuring, formatted `onBarClick` handlers, and added comprehensive test coverage for widget_type behavior in both blocks (WEC-1807)
|
|
5
|
+
- **CHANGED** - `DismissInsightDialog`, `FeedbackDialog`, and `InsightOptionsMenu` UI improvements: updated styling for better accessibility and consistency (color theme adjustments for Radio buttons, dialog borders, and icon colors) (WEC-1807)
|
|
6
|
+
- **CHANGED** - Updated 16 Storybook story files with proper `insights_payload` mock data structure to support component testing and documentation (WEC-1807)
|
|
7
|
+
|
|
1
8
|
## [9.4.32] - 09-18-2026
|
|
2
9
|
|
|
3
10
|
- **ADDED** - Historical account balances to net worth widget
|
|
@@ -1,36 +1,37 @@
|
|
|
1
|
-
import { useGlobalCopyStore as
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { getDynamicCtaBasedOnTriggers as
|
|
5
|
-
import { actionBlocks as _, hasDrawerBlock as
|
|
6
|
-
import { observer as
|
|
7
|
-
import
|
|
8
|
-
import { Text as
|
|
1
|
+
import { useGlobalCopyStore as g, useGlobalUiStore as k, useInsightsV2Store as C } from "../../common/context/hooks.es.js";
|
|
2
|
+
import h from "../../common/components/drawer/Drawer.es.js";
|
|
3
|
+
import B from "../../common/components/Loader.es.js";
|
|
4
|
+
import { getDynamicCtaBasedOnTriggers as b } from "./util.es.js";
|
|
5
|
+
import { actionBlocks as _, hasDrawerBlock as w } from "../mappings/blocks.es.js";
|
|
6
|
+
import { observer as D } from "mobx-react-lite";
|
|
7
|
+
import v from "@mui/material/Stack";
|
|
8
|
+
import { Text as L } from "@mxenabled/mxui";
|
|
9
9
|
import { jsx as e } from "react/jsx-runtime";
|
|
10
|
-
var
|
|
10
|
+
var x = ({ actionBlock: s, ...o }) => {
|
|
11
11
|
const { Component: n, usePrepare: t } = s;
|
|
12
12
|
return t(o), /* @__PURE__ */ e(n, { ...o });
|
|
13
|
-
},
|
|
14
|
-
const n =
|
|
15
|
-
if (!m) return l ? /* @__PURE__ */ e(h, {}) : null;
|
|
13
|
+
}, U = D(function({ beat: o }) {
|
|
14
|
+
const n = g(), t = n.common, { isCopyLoaded: m } = k(), { actionDrawer: a, closeActionDrawer: p } = C();
|
|
16
15
|
if (!o.insights_payload) return null;
|
|
17
|
-
const { primary_cta: u, secondary_cta: d } = o.insights_payload,
|
|
18
|
-
return /* @__PURE__ */ e(
|
|
16
|
+
const { primary_cta: u, secondary_cta: d, guid: f } = o.insights_payload, l = a.isDrawerOpen && a.guid === f;
|
|
17
|
+
if (!m) return l ? /* @__PURE__ */ e(B, {}) : null;
|
|
18
|
+
const r = b(a, u, d), c = w(r?.block), i = c ? _[r?.block] : void 0, y = i ? i.title?.(r?.variant, n) ?? r?.label ?? "" : c ? t.error_heading : r?.label ?? "";
|
|
19
|
+
return /* @__PURE__ */ e(h, {
|
|
19
20
|
ariaLabelClose: t.close_aria,
|
|
20
21
|
isOpen: l,
|
|
21
22
|
onClose: p,
|
|
22
|
-
title:
|
|
23
|
-
children: i ? /* @__PURE__ */ e(
|
|
23
|
+
title: y,
|
|
24
|
+
children: i ? /* @__PURE__ */ e(x, {
|
|
24
25
|
actionBlock: i,
|
|
25
26
|
beat: o
|
|
26
|
-
}, r?.block) : c ? /* @__PURE__ */ e(
|
|
27
|
+
}, r?.block) : c ? /* @__PURE__ */ e(v, {
|
|
27
28
|
sx: { p: 24 },
|
|
28
|
-
children: /* @__PURE__ */ e(
|
|
29
|
+
children: /* @__PURE__ */ e(L, { children: t.error_message })
|
|
29
30
|
}) : null
|
|
30
31
|
});
|
|
31
32
|
});
|
|
32
33
|
export {
|
|
33
|
-
|
|
34
|
+
U as ActionBlockLayer
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
//# sourceMappingURL=ActionBlockLayer.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionBlockLayer.es.js","names":[],"sources":["../../../src/insights-v2/actionBlocks/ActionBlockLayer.tsx"],"sourcesContent":["import Stack from '@mui/material/Stack'\n\nimport { Text } from '@mxenabled/mxui'\nimport { observer } from 'mobx-react-lite'\n\nimport {\n Drawer,\n Loader,\n useGlobalCopyStore,\n useGlobalUiStore,\n useInsightsV2Store,\n} from '../../common'\nimport { type Beat } from '../../core'\nimport {\n actionBlocks,\n hasDrawerBlock,\n type ActionBlockEntry,\n type ActionBlockProps,\n} from '../mappings/blocks'\nimport { getDynamicCtaBasedOnTriggers } from './util'\n\ninterface ActionBlockLayerProps {\n beat: Beat\n}\n\n/**\n * Renders a registered action block. Callers MUST key this per block name — a\n * block with `usePrepare` and one without run a different number of hooks, so\n * reusing the same fiber across a block switch violates the rules of hooks.\n */\nconst ActionBlockRunner = ({\n actionBlock,\n ...blockProps\n}: ActionBlockProps & { actionBlock: ActionBlockEntry }) => {\n const { Component, usePrepare } = actionBlock\n\n usePrepare(blockProps)\n\n return <Component {...blockProps} />\n}\n\n// `observer` is required: this reads `isCopyLoaded` off GlobalUiStore and the\n// action drawer off InsightsV2Store. Without it the component never re-renders\n// and stays stuck on <Loader /> forever.\nexport const ActionBlockLayer = observer(function ActionBlockLayer({\n beat,\n}: ActionBlockLayerProps) {\n const copy = useGlobalCopyStore()\n const commonCopy = copy.common\n const { isCopyLoaded } = useGlobalUiStore()\n const { actionDrawer, closeActionDrawer } = useInsightsV2Store()\n\n // Every card in the feed renders its own layer against the shared store, so\n // this card's drawer only opens when its beat is the one that triggered it.\n const isCurrentBeatOpen = actionDrawer.isDrawerOpen && actionDrawer.guid ===
|
|
1
|
+
{"version":3,"file":"ActionBlockLayer.es.js","names":[],"sources":["../../../src/insights-v2/actionBlocks/ActionBlockLayer.tsx"],"sourcesContent":["import Stack from '@mui/material/Stack'\n\nimport { Text } from '@mxenabled/mxui'\nimport { observer } from 'mobx-react-lite'\n\nimport {\n Drawer,\n Loader,\n useGlobalCopyStore,\n useGlobalUiStore,\n useInsightsV2Store,\n} from '../../common'\nimport { type Beat } from '../../core'\nimport {\n actionBlocks,\n hasDrawerBlock,\n type ActionBlockEntry,\n type ActionBlockProps,\n} from '../mappings/blocks'\nimport { getDynamicCtaBasedOnTriggers } from './util'\n\ninterface ActionBlockLayerProps {\n beat: Beat\n}\n\n/**\n * Renders a registered action block. Callers MUST key this per block name — a\n * block with `usePrepare` and one without run a different number of hooks, so\n * reusing the same fiber across a block switch violates the rules of hooks.\n */\nconst ActionBlockRunner = ({\n actionBlock,\n ...blockProps\n}: ActionBlockProps & { actionBlock: ActionBlockEntry }) => {\n const { Component, usePrepare } = actionBlock\n\n usePrepare(blockProps)\n\n return <Component {...blockProps} />\n}\n\n// `observer` is required: this reads `isCopyLoaded` off GlobalUiStore and the\n// action drawer off InsightsV2Store. Without it the component never re-renders\n// and stays stuck on <Loader /> forever.\nexport const ActionBlockLayer = observer(function ActionBlockLayer({\n beat,\n}: ActionBlockLayerProps) {\n const copy = useGlobalCopyStore()\n const commonCopy = copy.common\n const { isCopyLoaded } = useGlobalUiStore()\n const { actionDrawer, closeActionDrawer } = useInsightsV2Store()\n\n // Mirrors BaseLayout's guard — the layer is exported, so callers are not\n // guaranteed to have narrowed this already.\n if (!beat.insights_payload) return null\n\n const { primary_cta, secondary_cta, guid } = beat.insights_payload\n\n // Every card in the feed renders its own layer against the shared store, so\n // this card's drawer only opens when its beat is the one that triggered it.\n const isCurrentBeatOpen = actionDrawer.isDrawerOpen && actionDrawer.guid === guid\n\n if (!isCopyLoaded) return isCurrentBeatOpen ? <Loader /> : null\n\n const currentCta = getDynamicCtaBasedOnTriggers(actionDrawer, primary_cta, secondary_cta)\n\n // A CTA without a real block never opens a drawer (BaseLayout won't trigger it);\n // a real-but-unknown block shows the error (\"oops\") content.\n const blockValid = hasDrawerBlock(currentCta?.block)\n const actionBlock = blockValid\n ? actionBlocks[currentCta?.block as keyof typeof actionBlocks]\n : undefined\n\n const drawerTitle = actionBlock\n ? (actionBlock.title?.(currentCta?.variant, copy) ?? currentCta?.label ?? '')\n : blockValid\n ? commonCopy.error_heading\n : (currentCta?.label ?? '')\n\n return (\n <Drawer\n ariaLabelClose={commonCopy.close_aria}\n isOpen={isCurrentBeatOpen}\n onClose={closeActionDrawer}\n title={drawerTitle}\n >\n {actionBlock ? (\n <ActionBlockRunner actionBlock={actionBlock} beat={beat} key={currentCta?.block} />\n ) : blockValid ? (\n <Stack sx={{ p: 24 }}>\n <Text>{commonCopy.error_message}</Text>\n </Stack>\n ) : null}\n </Drawer>\n )\n})\n"],"mappings":";;;;;;;;;AA8BA,IAAM,IAAA,CAAqB,EACzB,aAAA,GACA,GAAG,EAAA,MACuD;AAC1D,QAAM,EAAE,WAAA,GAAW,YAAA,EAAA,IAAe;AAElC,SAAA,EAAW,CAAU,GAEd,gBAAA,EAAC,GAAD,EAAW,GAAI,EAAa,CAAA;AACrC,GAKa,IAAmB,EAAS,SAA0B,EACjE,MAAA,EAAA,GACwB;AACxB,QAAM,IAAO,EAAmB,GAC1B,IAAa,EAAK,QAClB,EAAE,cAAA,EAAA,IAAiB,EAAiB,GACpC,EAAE,cAAA,GAAc,mBAAA,EAAA,IAAsB,EAAmB;AAI/D,MAAI,CAAC,EAAK,iBAAkB,QAAO;AAEnC,QAAM,EAAE,aAAA,GAAa,eAAA,GAAe,MAAA,EAAA,IAAS,EAAK,kBAI5C,IAAoB,EAAa,gBAAgB,EAAa,SAAS;AAE7E,MAAI,CAAC,EAAc,QAAO,IAAoB,gBAAA,EAAC,GAAD,CAAS,CAAA,IAAI;AAE3D,QAAM,IAAa,EAA6B,GAAc,GAAa,CAAa,GAIlF,IAAa,EAAe,GAAY,KAAK,GAC7C,IAAc,IAChB,EAAa,GAAY,KAAA,IACzB,QAEE,IAAc,IACf,EAAY,QAAQ,GAAY,SAAS,CAAI,KAAK,GAAY,SAAS,KACxE,IACE,EAAW,gBACV,GAAY,SAAS;AAE5B,SACE,gBAAA,EAAC,GAAD;AAAA,IACE,gBAAgB,EAAW;AAAA,IAC3B,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO;AAAA,IAEN,UAAA,IACC,gBAAA,EAAC,GAAD;AAAA,MAAgC,aAAA;AAAA,MAAmB,MAAA;AAAA,IAA+B,GAApB,GAAY,KAAQ,IAChF,IACF,gBAAA,EAAC,GAAD;AAAA,MAAO,IAAI,EAAE,GAAG,GAAG;AAAA,MACjB,UAAA,gBAAA,EAAC,GAAD,EAAA,UAAO,EAAW,cAAoB,CAAA;AAAA,IACjC,CAAA,IACL;AAAA,EACE,CAAA;AAEZ,CAAC"}
|
|
@@ -1,40 +1,43 @@
|
|
|
1
|
-
import { useGlobalCopyStore as B, useGlobalUiStore as
|
|
2
|
-
import { formatCurrency as
|
|
3
|
-
import
|
|
4
|
-
import { BarChartV2 as
|
|
5
|
-
import { EmptyBarChart as
|
|
6
|
-
import { barChartVariant as
|
|
7
|
-
import { actionBlocksKey as
|
|
8
|
-
import
|
|
9
|
-
import { observer as
|
|
10
|
-
import { jsx as
|
|
11
|
-
import { useTheme as
|
|
12
|
-
var
|
|
13
|
-
const l =
|
|
14
|
-
if (!d) return /* @__PURE__ */
|
|
15
|
-
const
|
|
16
|
-
return t.length ? /* @__PURE__ */
|
|
1
|
+
import { useGlobalCopyStore as B, useGlobalUiStore as A, useInsightsV2Store as L } from "../../../../common/context/hooks.es.js";
|
|
2
|
+
import { formatCurrency as S } from "../../../../core/utils/NumberFormatting.es.js";
|
|
3
|
+
import I from "../../../../common/components/Loader.es.js";
|
|
4
|
+
import { BarChartV2 as T } from "../../../components/chartblocks/BarchartV2.es.js";
|
|
5
|
+
import { EmptyBarChart as k } from "../../../components/chartblocks/EmptyBarChart.es.js";
|
|
6
|
+
import { barChartVariant as v, buildChartData as x, buildDataSeries as D } from "./utils.es.js";
|
|
7
|
+
import { actionBlocksKey as O } from "../../../mappings/actionBlocksKey.es.js";
|
|
8
|
+
import N from "react";
|
|
9
|
+
import { observer as R } from "mobx-react-lite";
|
|
10
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
11
|
+
import { useTheme as V } from "@mui/material/styles";
|
|
12
|
+
var J = R(({ payload: m, beatGuid: i = "" }) => {
|
|
13
|
+
const l = V(), { openActionDrawer: c } = L(), { insights_feed: o } = B(), { isCopyLoaded: d } = A(), { instance_slot: f, instance_slot_data: a, widget_type: p } = m, { data_series: h, ariaLabel: u = "", average_amount: n = 0, legends: s = [] } = a, t = x(D(h), u), [g] = N.useState(t.length - 1), { color: b } = v(f, a, l);
|
|
14
|
+
if (!d) return /* @__PURE__ */ e(I, {});
|
|
15
|
+
const C = [o.general.monthly_amount, o.general.trend], [_, y] = s.length ? s.map((r) => r.label) : C;
|
|
16
|
+
return t.length ? /* @__PURE__ */ e(T, {
|
|
17
17
|
amounts: {
|
|
18
18
|
average: n,
|
|
19
|
-
formattedAverage:
|
|
19
|
+
formattedAverage: S(n, "0,0")
|
|
20
20
|
},
|
|
21
|
-
color:
|
|
21
|
+
color: b,
|
|
22
22
|
data: t,
|
|
23
|
-
monthlyAmountLabel:
|
|
24
|
-
onBarClick: (r) =>
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
monthlyAmountLabel: _,
|
|
24
|
+
onBarClick: (r) => {
|
|
25
|
+
if (p !== "full") return !1;
|
|
26
|
+
c({
|
|
27
|
+
guid: i,
|
|
28
|
+
trigger: "chartBar",
|
|
29
|
+
context: {
|
|
30
|
+
chartBarIndex: r,
|
|
31
|
+
block: O.TRANSCATION_HISTORY_ACTION_BLOCK
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
selectedTabIndex: g,
|
|
36
|
+
trendAmountLabel: y
|
|
37
|
+
}) : /* @__PURE__ */ e(k, {});
|
|
35
38
|
});
|
|
36
39
|
export {
|
|
37
|
-
|
|
40
|
+
J as BarchartBlock
|
|
38
41
|
};
|
|
39
42
|
|
|
40
43
|
//# sourceMappingURL=BarchartBlock.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BarchartBlock.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ChartBlocks/BarchartBlock/BarchartBlock.tsx"],"sourcesContent":["import React from 'react'\nimport { useTheme } from '@mui/material/styles'\nimport { observer } from 'mobx-react-lite'\n\nimport {\n formatCurrency,\n Loader,\n useGlobalCopyStore,\n useGlobalUiStore,\n useInsightsV2Store,\n} from '../../../../common'\nimport type { DataSeries, DrilldownPayload } from '../../../../core'\nimport type { BarChartBlockData } from '../../../../core/types/InsightsInstanceSlotData'\n\nimport { BarChartV2 } from '../../../components/chartblocks/BarchartV2'\nimport { EmptyBarChart } from '../../../components/chartblocks/EmptyBarChart'\n\nimport type { BlockProps } from '../../types'\n\nimport { barChartVariant, buildChartData, buildDataSeries } from './utils'\nimport { actionBlocksKey } from '../../../mappings/actionBlocksKey'\n\nexport const BarchartBlock = observer(\n ({ payload, beatGuid = '' }: BlockProps<BarChartBlockData>) => {\n const theme = useTheme()\n const { openActionDrawer } = useInsightsV2Store()\n const { insights_feed: insightsFeedCopy } = useGlobalCopyStore()\n const { isCopyLoaded } = useGlobalUiStore()\n const { instance_slot, instance_slot_data } = payload\n const { data_series, ariaLabel = '', average_amount = 0, legends = [] } = instance_slot_data\n const chartData = buildChartData(buildDataSeries(data_series as DataSeries), ariaLabel)\n const [selectedTabIndex] = React.useState(chartData.length - 1)\n const { color } = barChartVariant(instance_slot, instance_slot_data, theme)\n\n if (!isCopyLoaded) {\n return <Loader />\n }\n\n // TODO: Temporary fallback while the backend doesn't always send `legends` on every beat/variant.\n // Remove this once the backend guarantees `legends` on the payload.\n const fallbackLabels = [insightsFeedCopy.general.monthly_amount, insightsFeedCopy.general.trend]\n\n const [monthlyAmountLabel, trendAmountLabel] = legends.length\n ? legends.map((legend) => legend.label)\n : fallbackLabels\n\n return chartData.length ? (\n <BarChartV2\n amounts={{\n average: average_amount,\n formattedAverage: formatCurrency(average_amount, '0,0'),\n }}\n color={color}\n data={chartData}\n monthlyAmountLabel={monthlyAmountLabel}\n onBarClick={(index)
|
|
1
|
+
{"version":3,"file":"BarchartBlock.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ChartBlocks/BarchartBlock/BarchartBlock.tsx"],"sourcesContent":["import React from 'react'\nimport { useTheme } from '@mui/material/styles'\nimport { observer } from 'mobx-react-lite'\n\nimport {\n formatCurrency,\n Loader,\n useGlobalCopyStore,\n useGlobalUiStore,\n useInsightsV2Store,\n} from '../../../../common'\nimport type { DataSeries, DrilldownPayload } from '../../../../core'\nimport type { BarChartBlockData } from '../../../../core/types/InsightsInstanceSlotData'\n\nimport { BarChartV2 } from '../../../components/chartblocks/BarchartV2'\nimport { EmptyBarChart } from '../../../components/chartblocks/EmptyBarChart'\n\nimport type { BlockProps } from '../../types'\n\nimport { barChartVariant, buildChartData, buildDataSeries } from './utils'\nimport { actionBlocksKey } from '../../../mappings/actionBlocksKey'\n\nexport const BarchartBlock = observer(\n ({ payload, beatGuid = '' }: BlockProps<BarChartBlockData>) => {\n const theme = useTheme()\n const { openActionDrawer } = useInsightsV2Store()\n const { insights_feed: insightsFeedCopy } = useGlobalCopyStore()\n const { isCopyLoaded } = useGlobalUiStore()\n const { instance_slot, instance_slot_data, widget_type } = payload\n const { data_series, ariaLabel = '', average_amount = 0, legends = [] } = instance_slot_data\n const chartData = buildChartData(buildDataSeries(data_series as DataSeries), ariaLabel)\n const [selectedTabIndex] = React.useState(chartData.length - 1)\n const { color } = barChartVariant(instance_slot, instance_slot_data, theme)\n\n if (!isCopyLoaded) {\n return <Loader />\n }\n\n // TODO: Temporary fallback while the backend doesn't always send `legends` on every beat/variant.\n // Remove this once the backend guarantees `legends` on the payload.\n const fallbackLabels = [insightsFeedCopy.general.monthly_amount, insightsFeedCopy.general.trend]\n\n const [monthlyAmountLabel, trendAmountLabel] = legends.length\n ? legends.map((legend) => legend.label)\n : fallbackLabels\n\n return chartData.length ? (\n <BarChartV2\n amounts={{\n average: average_amount,\n formattedAverage: formatCurrency(average_amount, '0,0'),\n }}\n color={color}\n data={chartData}\n monthlyAmountLabel={monthlyAmountLabel}\n onBarClick={(index) => {\n if (widget_type !== 'full') return false\n\n openActionDrawer({\n guid: beatGuid,\n trigger: 'chartBar',\n context: {\n chartBarIndex: index,\n block: actionBlocksKey.TRANSCATION_HISTORY_ACTION_BLOCK,\n } satisfies DrilldownPayload,\n })\n }}\n selectedTabIndex={selectedTabIndex}\n trendAmountLabel={trendAmountLabel}\n />\n ) : (\n <EmptyBarChart />\n )\n },\n)\n"],"mappings":";;;;;;;;;;;AAsBA,IAAa,IAAgB,EAAA,CAC1B,EAAE,SAAA,GAAS,UAAA,IAAW,GAAA,MAAwC;AAC7D,QAAM,IAAQ,EAAS,GACjB,EAAE,kBAAA,EAAA,IAAqB,EAAmB,GAC1C,EAAE,eAAe,EAAA,IAAqB,EAAmB,GACzD,EAAE,cAAA,EAAA,IAAiB,EAAiB,GACpC,EAAE,eAAA,GAAe,oBAAA,GAAoB,aAAA,EAAA,IAAgB,GACrD,EAAE,aAAA,GAAa,WAAA,IAAY,IAAI,gBAAA,IAAiB,GAAG,SAAA,IAAU,CAAC,EAAA,IAAM,GACpE,IAAY,EAAe,EAAgB,CAAyB,GAAG,CAAS,GAChF,CAAC,CAAA,IAAoB,EAAM,SAAS,EAAU,SAAS,CAAC,GACxD,EAAE,OAAA,EAAA,IAAU,EAAgB,GAAe,GAAoB,CAAK;AAE1E,MAAI,CAAC,EACH,QAAO,gBAAA,EAAC,GAAD,CAAS,CAAA;AAKlB,QAAM,IAAiB,CAAC,EAAiB,QAAQ,gBAAgB,EAAiB,QAAQ,KAAK,GAEzF,CAAC,GAAoB,CAAA,IAAoB,EAAQ,SACnD,EAAQ,IAAA,CAAK,MAAW,EAAO,KAAK,IACpC;AAEJ,SAAO,EAAU,SACf,gBAAA,EAAC,GAAD;AAAA,IACE,SAAS;AAAA,MACP,SAAS;AAAA,MACT,kBAAkB,EAAe,GAAgB,KAAK;AAAA,IACxD;AAAA,IACO,OAAA;AAAA,IACP,MAAM;AAAA,IACc,oBAAA;AAAA,IACpB,YAAA,CAAa,MAAU;AACrB,UAAI,MAAgB,OAAQ,QAAO;AAEnC,MAAA,EAAiB;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP,eAAe;AAAA,UACf,OAAO,EAAgB;AAAA,QACzB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACkB,kBAAA;AAAA,IACA,kBAAA;AAAA,EACnB,CAAA,IAED,gBAAA,EAAC,GAAD,CAAgB,CAAA;AAEpB,CACF"}
|
|
@@ -1,30 +1,33 @@
|
|
|
1
1
|
import { useInsightsV2Store as B } from "../../../../common/context/hooks.es.js";
|
|
2
2
|
import { actionBlocksKey as C } from "../../../mappings/actionBlocksKey.es.js";
|
|
3
3
|
import { DoubleBarChart as b } from "../../../components/chartblocks/DoubleBarChart.es.js";
|
|
4
|
-
import { buildComparisonSeries as
|
|
5
|
-
import { getLayoutConfig as
|
|
6
|
-
import { jsx as
|
|
4
|
+
import { buildComparisonSeries as h } from "./comparisonUtils.es.js";
|
|
5
|
+
import { getLayoutConfig as d } from "./layout.es.js";
|
|
6
|
+
import { jsx as g } from "react/jsx-runtime";
|
|
7
7
|
import { useTheme as I } from "@mui/material/styles";
|
|
8
|
-
var
|
|
9
|
-
const
|
|
10
|
-
return /* @__PURE__ */
|
|
8
|
+
var L = ({ payload: { instance_slot: o, instance_slot_data: t, widget_type: r }, beatGuid: a = "" }) => {
|
|
9
|
+
const e = I(), { openActionDrawer: i } = B(), { variant: n } = o, { ariaLabel: s = "", data_series: m, legends: c } = t, l = h(m, s), f = d(e, n)?.color ?? [];
|
|
10
|
+
return /* @__PURE__ */ g(b, {
|
|
11
11
|
bars: l,
|
|
12
|
-
colors:
|
|
13
|
-
isMini:
|
|
12
|
+
colors: f,
|
|
13
|
+
isMini: r === "mini",
|
|
14
14
|
legends: c,
|
|
15
|
-
onBarClick: (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
onBarClick: (p, u) => {
|
|
16
|
+
if (r !== "full") return !1;
|
|
17
|
+
i({
|
|
18
|
+
guid: a,
|
|
19
|
+
trigger: "chartBar",
|
|
20
|
+
context: {
|
|
21
|
+
chartBarIndex: p,
|
|
22
|
+
tabIndex: u,
|
|
23
|
+
block: C.TRANSCATION_HISTORY_ACTION_BLOCK
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
24
27
|
});
|
|
25
28
|
};
|
|
26
29
|
export {
|
|
27
|
-
|
|
30
|
+
L as DoubleBarChartBlock
|
|
28
31
|
};
|
|
29
32
|
|
|
30
33
|
//# sourceMappingURL=DoubleBarChartBlock.es.js.map
|
package/dist/insights-v2/blocks/ChartBlocks/DoubleBarChartBlock/DoubleBarChartBlock.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoubleBarChartBlock.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ChartBlocks/DoubleBarChartBlock/DoubleBarChartBlock.tsx"],"sourcesContent":["import { useTheme } from '@mui/material/styles'\n\nimport { useInsightsV2Store } from '../../../../common'\nimport type { DataSeries, DrilldownPayload } from '../../../../core'\nimport { DoubleBarChart } from '../../../components/chartblocks/DoubleBarChart'\n\nimport type { BlockProps } from '../../types'\n\nimport { buildComparisonSeries } from './comparisonUtils'\nimport { getLayoutConfig } from './layout'\nimport { actionBlocksKey } from '../../../mappings/actionBlocksKey'\n\n/**\n * Card block for the double-bar chart. Mirrors BarchartBlock: it builds the shaped series\n * (buildComparisonSeries) and resolves the card palette (getLayoutConfig), then renders the reusable\n * DoubleBarChart and injects the card click behavior \\u2014 open the shared drawer scoped to this beat\n * (chartBarIndex = clicked column, tabIndex = clicked sub-series).\n */\nexport const DoubleBarChartBlock = ({\n payload: { instance_slot, instance_slot_data, widget_type },\n beatGuid = '',\n}: BlockProps) => {\n const theme = useTheme()\n const { openActionDrawer } = useInsightsV2Store()\n const { variant } = instance_slot\n const { ariaLabel = '', data_series, legends } = instance_slot_data\n const bars = buildComparisonSeries(data_series as DataSeries, ariaLabel)\n // getLayoutConfig returns undefined for an unknown/unsupported variant; fall back to an empty\n // palette so an unregistered beat can't throw on mount.\n const colors = getLayoutConfig(theme, variant)?.color ?? []\n\n return (\n <DoubleBarChart\n bars={bars}\n colors={colors}\n isMini={widget_type === 'mini'}\n legends={legends}\n onBarClick={(columnIndex, subIndex)
|
|
1
|
+
{"version":3,"file":"DoubleBarChartBlock.es.js","names":[],"sources":["../../../../../src/insights-v2/blocks/ChartBlocks/DoubleBarChartBlock/DoubleBarChartBlock.tsx"],"sourcesContent":["import { useTheme } from '@mui/material/styles'\n\nimport { useInsightsV2Store } from '../../../../common'\nimport type { DataSeries, DrilldownPayload } from '../../../../core'\nimport { DoubleBarChart } from '../../../components/chartblocks/DoubleBarChart'\n\nimport type { BlockProps } from '../../types'\n\nimport { buildComparisonSeries } from './comparisonUtils'\nimport { getLayoutConfig } from './layout'\nimport { actionBlocksKey } from '../../../mappings/actionBlocksKey'\n\n/**\n * Card block for the double-bar chart. Mirrors BarchartBlock: it builds the shaped series\n * (buildComparisonSeries) and resolves the card palette (getLayoutConfig), then renders the reusable\n * DoubleBarChart and injects the card click behavior \\u2014 open the shared drawer scoped to this beat\n * (chartBarIndex = clicked column, tabIndex = clicked sub-series).\n */\nexport const DoubleBarChartBlock = ({\n payload: { instance_slot, instance_slot_data, widget_type },\n beatGuid = '',\n}: BlockProps) => {\n const theme = useTheme()\n const { openActionDrawer } = useInsightsV2Store()\n const { variant } = instance_slot\n const { ariaLabel = '', data_series, legends } = instance_slot_data\n const bars = buildComparisonSeries(data_series as DataSeries, ariaLabel)\n // getLayoutConfig returns undefined for an unknown/unsupported variant; fall back to an empty\n // palette so an unregistered beat can't throw on mount.\n const colors = getLayoutConfig(theme, variant)?.color ?? []\n\n return (\n <DoubleBarChart\n bars={bars}\n colors={colors}\n isMini={widget_type === 'mini'}\n legends={legends}\n onBarClick={(columnIndex, subIndex) => {\n if (widget_type !== 'full') return false\n\n openActionDrawer({\n guid: beatGuid,\n trigger: 'chartBar',\n context: {\n chartBarIndex: columnIndex,\n tabIndex: subIndex,\n block: actionBlocksKey.TRANSCATION_HISTORY_ACTION_BLOCK,\n } satisfies DrilldownPayload,\n })\n }}\n />\n )\n}\n"],"mappings":";;;;;;;AAkBA,IAAa,IAAA,CAAuB,EAClC,SAAS,EAAE,eAAA,GAAe,oBAAA,GAAoB,aAAA,EAAA,GAC9C,UAAA,IAAW,GAAA,MACK;AAChB,QAAM,IAAQ,EAAS,GACjB,EAAE,kBAAA,EAAA,IAAqB,EAAmB,GAC1C,EAAE,SAAA,EAAA,IAAY,GACd,EAAE,WAAA,IAAY,IAAI,aAAA,GAAa,SAAA,EAAA,IAAY,GAC3C,IAAO,EAAsB,GAA2B,CAAS,GAGjE,IAAS,EAAgB,GAAO,CAAO,GAAG,SAAS,CAAC;AAE1D,SACE,gBAAA,EAAC,GAAD;AAAA,IACQ,MAAA;AAAA,IACE,QAAA;AAAA,IACR,QAAQ,MAAgB;AAAA,IACf,SAAA;AAAA,IACT,YAAA,CAAa,GAAa,MAAa;AACrC,UAAI,MAAgB,OAAQ,QAAO;AAEnC,MAAA,EAAiB;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP,eAAe;AAAA,UACf,UAAU;AAAA,UACV,OAAO,EAAgB;AAAA,QACzB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACD,CAAA;AAEL"}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { useAppConfig as
|
|
2
|
-
import { sendBeatCta as
|
|
3
|
-
import { blocks as
|
|
4
|
-
import
|
|
5
|
-
import { BeatActionsProvider as
|
|
6
|
-
import
|
|
7
|
-
import { FeedbackBar as
|
|
8
|
-
import
|
|
9
|
-
import { DismissInsightDialog as
|
|
10
|
-
import { HiddenConfirmationCard as
|
|
11
|
-
import { ObsolesceBanner as
|
|
12
|
-
import { ActionBlockLayer as
|
|
13
|
-
import { useBeatFeedbackFlow as
|
|
14
|
-
import { observer as
|
|
1
|
+
import { useAppConfig as T, useGlobalCopyStore as F, useInsightsV2Store as A } from "../../common/context/hooks.es.js";
|
|
2
|
+
import { sendBeatCta as I } from "../../common/utils/PostMessage.es.js";
|
|
3
|
+
import { blocks as E, hasDrawerBlock as H } from "../mappings/blocks.es.js";
|
|
4
|
+
import M from "./Footer.es.js";
|
|
5
|
+
import { BeatActionsProvider as G } from "../beatActions.es.js";
|
|
6
|
+
import R from "./Header.es.js";
|
|
7
|
+
import { FeedbackBar as j } from "./FeedbackBar.es.js";
|
|
8
|
+
import z from "./FeedbackDialog.es.js";
|
|
9
|
+
import { DismissInsightDialog as N } from "./DismissInsightDialog.es.js";
|
|
10
|
+
import { HiddenConfirmationCard as U } from "./HiddenConfirmationCard.es.js";
|
|
11
|
+
import { ObsolesceBanner as V } from "./ObsolesceBanner.es.js";
|
|
12
|
+
import { ActionBlockLayer as P } from "../actionBlocks/ActionBlockLayer.es.js";
|
|
13
|
+
import { useBeatFeedbackFlow as W } from "../hooks/useBeatFeedbackFlow.es.js";
|
|
14
|
+
import { observer as X } from "mobx-react-lite";
|
|
15
15
|
import m from "@mui/material/Stack";
|
|
16
16
|
import d from "@mui/material/Button";
|
|
17
|
-
import { ChevronRight as
|
|
18
|
-
import { Fragment as
|
|
19
|
-
import
|
|
20
|
-
import
|
|
21
|
-
var
|
|
17
|
+
import { ChevronRight as Y } from "@mxenabled/mx-icons";
|
|
18
|
+
import { Fragment as q, jsx as o, jsxs as r } from "react/jsx-runtime";
|
|
19
|
+
import J from "@mui/material/Box";
|
|
20
|
+
import K from "@mui/material/Card";
|
|
21
|
+
var Q = {}, Z = {
|
|
22
22
|
position: "absolute",
|
|
23
23
|
top: 0,
|
|
24
24
|
left: 0,
|
|
@@ -27,29 +27,29 @@ var q = {}, J = {
|
|
|
27
27
|
backgroundColor: "background.default",
|
|
28
28
|
opacity: 0.7,
|
|
29
29
|
zIndex: 1
|
|
30
|
-
},
|
|
31
|
-
const { openCtaDrawer:
|
|
32
|
-
if (!
|
|
33
|
-
const { instance_slot:
|
|
34
|
-
|
|
35
|
-
isMobileWebview:
|
|
36
|
-
webviewScheme:
|
|
37
|
-
userGuid:
|
|
30
|
+
}, ke = X(({ beat: i, beatActions: h = Q, obsolete: s }) => {
|
|
31
|
+
const { openCtaDrawer: y } = A(), g = F(), { is_mobile_webview: k, clientConfig: v } = T(), e = W(i, h), t = i.insights_payload;
|
|
32
|
+
if (!t || e.cardState === "dismissed") return null;
|
|
33
|
+
const { instance_slot: _, primary_cta: n, secondary_cta: a, sub_title: C, title: x, widget_type: S, guid: p, user_guid: w, dismissed_at: B } = t, { block: D } = _, u = (L, O) => {
|
|
34
|
+
H(L) ? y(p, O) : I(i, {
|
|
35
|
+
isMobileWebview: k,
|
|
36
|
+
webviewScheme: v?.master?.ui_message_webview_url_scheme,
|
|
37
|
+
userGuid: w
|
|
38
38
|
});
|
|
39
|
-
},
|
|
40
|
-
return /* @__PURE__ */ o(
|
|
39
|
+
}, f = E[D], b = S === "mini", l = g.insights_feed?.general, c = s?.state === "not_refreshable" && !B && !!l;
|
|
40
|
+
return /* @__PURE__ */ o(G, {
|
|
41
41
|
value: e.wrappedActions,
|
|
42
|
-
children: /* @__PURE__ */
|
|
42
|
+
children: /* @__PURE__ */ r(m, {
|
|
43
43
|
sx: { mb: 16 },
|
|
44
44
|
children: [
|
|
45
|
-
e.cardState === "confirming" ? /* @__PURE__ */ o(
|
|
45
|
+
e.cardState === "confirming" ? /* @__PURE__ */ o(U, {
|
|
46
46
|
onClose: e.collapseConfirmation,
|
|
47
47
|
onLeaveFeedback: e.openHideSurvey,
|
|
48
48
|
onUndo: e.undoDismiss
|
|
49
|
-
}) : /* @__PURE__ */
|
|
49
|
+
}) : /* @__PURE__ */ r(q, { children: [s && l && /* @__PURE__ */ o(V, {
|
|
50
50
|
...s,
|
|
51
51
|
copy: l
|
|
52
|
-
}), /* @__PURE__ */
|
|
52
|
+
}), /* @__PURE__ */ r(K, {
|
|
53
53
|
inert: c,
|
|
54
54
|
sx: { ...c && {
|
|
55
55
|
position: "relative",
|
|
@@ -57,17 +57,17 @@ var q = {}, J = {
|
|
|
57
57
|
pointerEvents: "none"
|
|
58
58
|
} },
|
|
59
59
|
children: [
|
|
60
|
-
c && /* @__PURE__ */ o(
|
|
61
|
-
/* @__PURE__ */ o(
|
|
62
|
-
isMini:
|
|
63
|
-
subtitle:
|
|
64
|
-
title:
|
|
60
|
+
c && /* @__PURE__ */ o(J, { sx: Z }),
|
|
61
|
+
/* @__PURE__ */ o(R, {
|
|
62
|
+
isMini: b,
|
|
63
|
+
subtitle: C,
|
|
64
|
+
title: x ?? ""
|
|
65
65
|
}),
|
|
66
|
-
|
|
67
|
-
beatGuid:
|
|
68
|
-
payload:
|
|
66
|
+
f && /* @__PURE__ */ o(f, {
|
|
67
|
+
beatGuid: p,
|
|
68
|
+
payload: t
|
|
69
69
|
}),
|
|
70
|
-
/* @__PURE__ */
|
|
70
|
+
/* @__PURE__ */ r(m, {
|
|
71
71
|
sx: {
|
|
72
72
|
gap: 6,
|
|
73
73
|
pb: 16,
|
|
@@ -76,10 +76,10 @@ var q = {}, J = {
|
|
|
76
76
|
pt: 12
|
|
77
77
|
},
|
|
78
78
|
children: [/* @__PURE__ */ o("div", {
|
|
79
|
-
dangerouslySetInnerHTML: { __html:
|
|
79
|
+
dangerouslySetInnerHTML: { __html: t.description.html_text },
|
|
80
80
|
style: { paddingLeft: 4 }
|
|
81
81
|
}), i?.in_description_cta && /* @__PURE__ */ o(d, {
|
|
82
|
-
endIcon: /* @__PURE__ */ o(
|
|
82
|
+
endIcon: /* @__PURE__ */ o(Y, {}),
|
|
83
83
|
onClick: () => {
|
|
84
84
|
},
|
|
85
85
|
sx: {
|
|
@@ -90,35 +90,35 @@ var q = {}, J = {
|
|
|
90
90
|
children: i.in_description_cta
|
|
91
91
|
})]
|
|
92
92
|
}),
|
|
93
|
-
!
|
|
93
|
+
!b && n?.label && /* @__PURE__ */ r(m, {
|
|
94
94
|
sx: {
|
|
95
95
|
gap: 8,
|
|
96
96
|
pb: 16,
|
|
97
97
|
px: 16
|
|
98
98
|
},
|
|
99
99
|
children: [/* @__PURE__ */ o(d, {
|
|
100
|
-
onClick: () =>
|
|
100
|
+
onClick: () => u(n.block, "primaryCta"),
|
|
101
101
|
variant: "outlined",
|
|
102
102
|
children: n.label
|
|
103
103
|
}), a?.label && /* @__PURE__ */ o(d, {
|
|
104
104
|
color: "secondary",
|
|
105
|
-
onClick: () =>
|
|
105
|
+
onClick: () => u(a.block, "secondaryCta"),
|
|
106
106
|
children: a.label
|
|
107
107
|
})]
|
|
108
108
|
}),
|
|
109
|
-
/* @__PURE__ */ o(
|
|
109
|
+
/* @__PURE__ */ o(j, {
|
|
110
110
|
onTellUsMore: e.openRatingSurvey,
|
|
111
111
|
show: e.isFeedbackBarShown
|
|
112
112
|
})
|
|
113
113
|
]
|
|
114
114
|
})] }),
|
|
115
|
-
/* @__PURE__ */ o(
|
|
116
|
-
/* @__PURE__ */ o(
|
|
115
|
+
/* @__PURE__ */ o(P, { beat: i }),
|
|
116
|
+
/* @__PURE__ */ o(N, {
|
|
117
117
|
isOpen: e.isDismissOpen,
|
|
118
118
|
onClose: e.closeDismissDialog,
|
|
119
119
|
onDismiss: e.confirmDismiss
|
|
120
120
|
}),
|
|
121
|
-
e.isSurveyOpen && /* @__PURE__ */ o(
|
|
121
|
+
e.isSurveyOpen && /* @__PURE__ */ o(z, {
|
|
122
122
|
characterLimitLabel: e.survey.characterLimitLabel,
|
|
123
123
|
closeAriaLabel: e.survey.closeAriaLabel,
|
|
124
124
|
isOpen: !0,
|
|
@@ -131,13 +131,13 @@ var q = {}, J = {
|
|
|
131
131
|
secondaryText: e.survey.backText,
|
|
132
132
|
title: e.survey.title
|
|
133
133
|
}),
|
|
134
|
-
e.cardState === "visible" &&
|
|
134
|
+
e.cardState === "visible" && t.footer && /* @__PURE__ */ o(M, { footer: t.footer })
|
|
135
135
|
]
|
|
136
136
|
})
|
|
137
137
|
});
|
|
138
138
|
});
|
|
139
139
|
export {
|
|
140
|
-
|
|
140
|
+
ke as default
|
|
141
141
|
};
|
|
142
142
|
|
|
143
143
|
//# sourceMappingURL=BaseLayout.es.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseLayout.es.js","names":[],"sources":["../../../src/insights-v2/components/BaseLayout.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport Box from '@mui/material/Box'\nimport Button from '@mui/material/Button'\nimport Card from '@mui/material/Card'\nimport Stack from '@mui/material/Stack'\n\nimport { ChevronRight } from '@mxenabled/mx-icons'\n\nimport { blocks, hasDrawerBlock } from '../mappings/blocks'\n\nimport Footer from './Footer'\nimport Header from './Header'\nimport FeedbackBar from './FeedbackBar'\nimport FeedbackDialog from './FeedbackDialog'\nimport DismissInsightDialog from './DismissInsightDialog'\nimport HiddenConfirmationCard from './HiddenConfirmationCard'\nimport { ObsolesceBanner, type ObsolesceBannerState } from './ObsolesceBanner'\nimport { useAppConfig, useGlobalCopyStore, useInsightsV2Store } from '../../common'\nimport { sendBeatCta } from '../../common/utils/PostMessage'\nimport type { Beat } from '../../core'\nimport { BeatActionsProvider, type BeatActions } from '../beatActions'\nimport { ActionBlockLayer } from '../actionBlocks/ActionBlockLayer'\nimport { useBeatFeedbackFlow } from '../hooks/useBeatFeedbackFlow'\n\nexport interface ObsoleteState {\n state: ObsolesceBannerState\n onRefresh: () => void\n onDismiss: () => void\n}\n\ninterface BaseLayoutProps {\n beat: Beat\n beatActions?: BeatActions\n obsolete?: ObsoleteState\n}\n\nconst NO_BEAT_ACTIONS: BeatActions = {}\n\nconst OBSOLETE_OVERLAY_SX = {\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n backgroundColor: 'background.default',\n opacity: 0.7,\n zIndex: 1,\n} as const\n\nconst BaseLayout = observer(\n ({ beat, beatActions = NO_BEAT_ACTIONS, obsolete }: BaseLayoutProps) => {\n const { openCtaDrawer } = useInsightsV2Store()\n const copy = useGlobalCopyStore()\n const { is_mobile_webview, clientConfig } = useAppConfig()\n const flow = useBeatFeedbackFlow(beat, beatActions)\n\n const insights_payload = beat.insights_payload\n\n if (!insights_payload) return null\n if (flow.cardState === 'dismissed') return null\n\n const { instance_slot, primary_cta, secondary_cta, sub_title, title, widget_type } =\n insights_payload\n const { block } = instance_slot\n\n // A CTA with a real drilldown `block` opens a drawer; otherwise it notifies\n // the host app via a beat/cta post message (the \"Make a Transfer\" CTA on the\n // Save an extra $100 beat). Mirrors Pulse's SaveAnExtra100Dollars beat.\n const handleCtaClick = (\n ctaBlock: string | null | undefined,\n source: 'primaryCta' | 'secondaryCta',\n ) => {\n if (hasDrawerBlock(ctaBlock)) {\n openCtaDrawer(beat.guid, source)\n } else {\n sendBeatCta(beat, {\n isMobileWebview: is_mobile_webview,\n webviewScheme: clientConfig?.master?.ui_message_webview_url_scheme,\n userGuid: beat.user_guid,\n })\n }\n }\n\n const Block = blocks[block as keyof typeof blocks]\n\n const isMini = widget_type === 'mini'\n const obsoleteCopy = copy.insights_feed?.general\n const isObsoleteDimmed =\n obsolete?.state === 'not_refreshable' && !beat.dismissed_at && !!obsoleteCopy\n\n return (\n <BeatActionsProvider value={flow.wrappedActions}>\n <Stack sx={{ mb: 16 }}>\n {flow.cardState === 'confirming' ? (\n <HiddenConfirmationCard\n onClose={flow.collapseConfirmation}\n onLeaveFeedback={flow.openHideSurvey}\n onUndo={flow.undoDismiss}\n />\n ) : (\n <>\n {obsolete && obsoleteCopy && <ObsolesceBanner {...obsolete} copy={obsoleteCopy} />}\n <Card\n inert={isObsoleteDimmed}\n sx={{\n ...(isObsoleteDimmed && {\n position: 'relative',\n zIndex: 2,\n pointerEvents: 'none',\n }),\n }}\n >\n {isObsoleteDimmed && <Box sx={OBSOLETE_OVERLAY_SX} />}\n <Header isMini={isMini} subtitle={sub_title} title={title ?? ''} />\n {Block && <Block beatGuid={beat.guid} payload={insights_payload} />}\n\n <Stack sx={{ gap: 6, pb: 16, pl: 12, pr: 16, pt: 12 }}>\n <div\n dangerouslySetInnerHTML={{\n __html: beat.html_description as string,\n }}\n style={{ paddingLeft: 4 }}\n />\n {beat?.in_description_cta && (\n <Button\n endIcon={<ChevronRight />}\n onClick={() => {}}\n sx={{ height: 24, p: 4, width: 'max-content' }}\n >\n {beat.in_description_cta}\n </Button>\n )}\n </Stack>\n\n {!isMini && primary_cta?.label && (\n <Stack sx={{ gap: 8, pb: 16, px: 16 }}>\n <Button\n onClick={() => handleCtaClick(primary_cta.block, 'primaryCta')}\n variant=\"outlined\"\n >\n {primary_cta.label}\n </Button>\n {secondary_cta?.label && (\n <Button\n color=\"secondary\"\n onClick={() => handleCtaClick(secondary_cta.block, 'secondaryCta')}\n >\n {secondary_cta.label}\n </Button>\n )}\n </Stack>\n )}\n\n <FeedbackBar onTellUsMore={flow.openRatingSurvey} show={flow.isFeedbackBarShown} />\n </Card>\n </>\n )}\n\n <ActionBlockLayer beat={beat} />\n\n <DismissInsightDialog\n isOpen={flow.isDismissOpen}\n onClose={flow.closeDismissDialog}\n onDismiss={flow.confirmDismiss}\n />\n\n {flow.isSurveyOpen && (\n <FeedbackDialog\n characterLimitLabel={flow.survey.characterLimitLabel}\n closeAriaLabel={flow.survey.closeAriaLabel}\n isOpen={true}\n onBackClick={flow.feedbackDialogCallbacks.onBackClick}\n onClose={flow.closeSurvey}\n onSubmit={flow.submitSurvey}\n onTextInputFocus={flow.feedbackDialogCallbacks.onTextInputFocus}\n options={flow.survey.options}\n primaryText={flow.survey.submitText}\n secondaryText={flow.survey.backText}\n title={flow.survey.title}\n />\n )}\n\n {flow.cardState === 'visible' && insights_payload.footer && (\n <Footer footer={insights_payload.footer} />\n )}\n </Stack>\n </BeatActionsProvider>\n )\n },\n)\n\nexport default BaseLayout\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"BaseLayout.es.js","names":[],"sources":["../../../src/insights-v2/components/BaseLayout.tsx"],"sourcesContent":["import { observer } from 'mobx-react-lite'\n\nimport Box from '@mui/material/Box'\nimport Button from '@mui/material/Button'\nimport Card from '@mui/material/Card'\nimport Stack from '@mui/material/Stack'\n\nimport { ChevronRight } from '@mxenabled/mx-icons'\n\nimport { blocks, hasDrawerBlock } from '../mappings/blocks'\n\nimport Footer from './Footer'\nimport Header from './Header'\nimport FeedbackBar from './FeedbackBar'\nimport FeedbackDialog from './FeedbackDialog'\nimport DismissInsightDialog from './DismissInsightDialog'\nimport HiddenConfirmationCard from './HiddenConfirmationCard'\nimport { ObsolesceBanner, type ObsolesceBannerState } from './ObsolesceBanner'\nimport { useAppConfig, useGlobalCopyStore, useInsightsV2Store } from '../../common'\nimport { sendBeatCta } from '../../common/utils/PostMessage'\nimport type { Beat } from '../../core'\nimport { BeatActionsProvider, type BeatActions } from '../beatActions'\nimport { ActionBlockLayer } from '../actionBlocks/ActionBlockLayer'\nimport { useBeatFeedbackFlow } from '../hooks/useBeatFeedbackFlow'\n\nexport interface ObsoleteState {\n state: ObsolesceBannerState\n onRefresh: () => void\n onDismiss: () => void\n}\n\ninterface BaseLayoutProps {\n beat: Beat\n beatActions?: BeatActions\n obsolete?: ObsoleteState\n}\n\nconst NO_BEAT_ACTIONS: BeatActions = {}\n\nconst OBSOLETE_OVERLAY_SX = {\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: '100%',\n backgroundColor: 'background.default',\n opacity: 0.7,\n zIndex: 1,\n} as const\n\nconst BaseLayout = observer(\n ({ beat, beatActions = NO_BEAT_ACTIONS, obsolete }: BaseLayoutProps) => {\n const { openCtaDrawer } = useInsightsV2Store()\n const copy = useGlobalCopyStore()\n const { is_mobile_webview, clientConfig } = useAppConfig()\n const flow = useBeatFeedbackFlow(beat, beatActions)\n\n const insights_payload = beat.insights_payload\n\n if (!insights_payload) return null\n if (flow.cardState === 'dismissed') return null\n\n const {\n instance_slot,\n primary_cta,\n secondary_cta,\n sub_title,\n title,\n widget_type,\n guid,\n user_guid,\n dismissed_at,\n } = insights_payload\n const { block } = instance_slot\n\n // A CTA with a real drilldown `block` opens a drawer; otherwise it notifies\n // the host app via a beat/cta post message (the \"Make a Transfer\" CTA on the\n // Save an extra $100 beat). Mirrors Pulse's SaveAnExtra100Dollars beat.\n const handleCtaClick = (\n ctaBlock: string | null | undefined,\n source: 'primaryCta' | 'secondaryCta',\n ) => {\n if (hasDrawerBlock(ctaBlock)) {\n openCtaDrawer(guid, source)\n } else {\n sendBeatCta(beat, {\n isMobileWebview: is_mobile_webview,\n webviewScheme: clientConfig?.master?.ui_message_webview_url_scheme,\n userGuid: user_guid,\n })\n }\n }\n\n const Block = blocks[block as keyof typeof blocks]\n\n const isMini = widget_type === 'mini'\n const obsoleteCopy = copy.insights_feed?.general\n const isObsoleteDimmed =\n obsolete?.state === 'not_refreshable' && !dismissed_at && !!obsoleteCopy\n\n return (\n <BeatActionsProvider value={flow.wrappedActions}>\n <Stack sx={{ mb: 16 }}>\n {flow.cardState === 'confirming' ? (\n <HiddenConfirmationCard\n onClose={flow.collapseConfirmation}\n onLeaveFeedback={flow.openHideSurvey}\n onUndo={flow.undoDismiss}\n />\n ) : (\n <>\n {obsolete && obsoleteCopy && <ObsolesceBanner {...obsolete} copy={obsoleteCopy} />}\n <Card\n inert={isObsoleteDimmed}\n sx={{\n ...(isObsoleteDimmed && {\n position: 'relative',\n zIndex: 2,\n pointerEvents: 'none',\n }),\n }}\n >\n {isObsoleteDimmed && <Box sx={OBSOLETE_OVERLAY_SX} />}\n <Header isMini={isMini} subtitle={sub_title} title={title ?? ''} />\n {Block && <Block beatGuid={guid} payload={insights_payload} />}\n\n <Stack sx={{ gap: 6, pb: 16, pl: 12, pr: 16, pt: 12 }}>\n <div\n dangerouslySetInnerHTML={{\n __html: insights_payload.description.html_text,\n }}\n style={{ paddingLeft: 4 }}\n />\n {/* TODO: Migrate to insights_payload.in_description_cta once backend provides it */}\n {beat?.in_description_cta && (\n <Button\n endIcon={<ChevronRight />}\n onClick={() => {}}\n sx={{ height: 24, p: 4, width: 'max-content' }}\n >\n {beat.in_description_cta}\n </Button>\n )}\n </Stack>\n\n {!isMini && primary_cta?.label && (\n <Stack sx={{ gap: 8, pb: 16, px: 16 }}>\n <Button\n onClick={() => handleCtaClick(primary_cta.block, 'primaryCta')}\n variant=\"outlined\"\n >\n {primary_cta.label}\n </Button>\n {secondary_cta?.label && (\n <Button\n color=\"secondary\"\n onClick={() => handleCtaClick(secondary_cta.block, 'secondaryCta')}\n >\n {secondary_cta.label}\n </Button>\n )}\n </Stack>\n )}\n\n <FeedbackBar onTellUsMore={flow.openRatingSurvey} show={flow.isFeedbackBarShown} />\n </Card>\n </>\n )}\n\n <ActionBlockLayer beat={beat} />\n\n <DismissInsightDialog\n isOpen={flow.isDismissOpen}\n onClose={flow.closeDismissDialog}\n onDismiss={flow.confirmDismiss}\n />\n\n {flow.isSurveyOpen && (\n <FeedbackDialog\n characterLimitLabel={flow.survey.characterLimitLabel}\n closeAriaLabel={flow.survey.closeAriaLabel}\n isOpen={true}\n onBackClick={flow.feedbackDialogCallbacks.onBackClick}\n onClose={flow.closeSurvey}\n onSubmit={flow.submitSurvey}\n onTextInputFocus={flow.feedbackDialogCallbacks.onTextInputFocus}\n options={flow.survey.options}\n primaryText={flow.survey.submitText}\n secondaryText={flow.survey.backText}\n title={flow.survey.title}\n />\n )}\n\n {flow.cardState === 'visible' && insights_payload.footer && (\n <Footer footer={insights_payload.footer} />\n )}\n </Stack>\n </BeatActionsProvider>\n )\n },\n)\n\nexport default BaseLayout\n"],"mappings":"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"}
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
-
import { useGlobalCopyStore as
|
|
2
|
-
import
|
|
3
|
-
import { useEffect as b, useState as
|
|
4
|
-
import { observer as
|
|
1
|
+
import { useGlobalCopyStore as u } from "../../common/context/hooks.es.js";
|
|
2
|
+
import f from "../../common/components/dialog/Dialog.es.js";
|
|
3
|
+
import { useEffect as b, useState as x } from "react";
|
|
4
|
+
import { observer as g } from "mobx-react-lite";
|
|
5
5
|
import a from "@mui/material/Stack";
|
|
6
6
|
import { Text as l } from "@mxenabled/mxui";
|
|
7
|
-
import { jsx as
|
|
8
|
-
import
|
|
9
|
-
import h from "@mui/material/
|
|
7
|
+
import { jsx as i, jsxs as s } from "react/jsx-runtime";
|
|
8
|
+
import { alpha as c } from "@mui/material/styles";
|
|
9
|
+
import h from "@mui/material/FormControlLabel";
|
|
10
|
+
import v from "@mui/material/Radio";
|
|
10
11
|
import y from "@mui/material/RadioGroup";
|
|
11
|
-
var
|
|
12
|
-
const o =
|
|
12
|
+
var _ = g(({ isOpen: t, onClose: d, onDismiss: m }) => {
|
|
13
|
+
const o = u().insights_feed?.dismiss, [e, n] = x("once");
|
|
13
14
|
return b(() => {
|
|
14
|
-
|
|
15
|
-
}, [
|
|
15
|
+
t && n("once");
|
|
16
|
+
}, [t]), o ? /* @__PURE__ */ i(f, {
|
|
16
17
|
copy: {
|
|
17
18
|
title: o.title,
|
|
18
19
|
close_aria: o.close_aria
|
|
19
20
|
},
|
|
20
|
-
isOpen:
|
|
21
|
+
isOpen: t,
|
|
21
22
|
onClose: d,
|
|
22
|
-
onPrimaryAction: () =>
|
|
23
|
+
onPrimaryAction: () => m(e),
|
|
23
24
|
primaryText: o.confirm,
|
|
24
25
|
secondaryText: o.cancel,
|
|
25
26
|
sx: {
|
|
@@ -31,9 +32,7 @@ var R = x(({ isOpen: i, onClose: d, onDismiss: c }) => {
|
|
|
31
32
|
"& .MuiDialog-paperScrollPaper > div:first-child .MuiIconButton-root": { my: -10 },
|
|
32
33
|
"& .MuiDialog-paperScrollPaper": {
|
|
33
34
|
bgcolor: "background.paper",
|
|
34
|
-
|
|
35
|
-
borderColor: "divider",
|
|
36
|
-
boxShadow: "none"
|
|
35
|
+
borderRadius: "4px"
|
|
37
36
|
},
|
|
38
37
|
"&:focus-visible": {
|
|
39
38
|
outline: "2px solid",
|
|
@@ -53,36 +52,39 @@ var R = x(({ isOpen: i, onClose: d, onDismiss: c }) => {
|
|
|
53
52
|
},
|
|
54
53
|
children: /* @__PURE__ */ s(a, {
|
|
55
54
|
sx: { gap: 24 },
|
|
56
|
-
children: [/* @__PURE__ */
|
|
55
|
+
children: [/* @__PURE__ */ i(l, {
|
|
57
56
|
variant: "subtitle1",
|
|
58
57
|
children: o.description
|
|
59
|
-
}), /* @__PURE__ */
|
|
58
|
+
}), /* @__PURE__ */ i(y, {
|
|
60
59
|
"aria-label": o.title,
|
|
61
60
|
name: "dismiss-type",
|
|
62
|
-
onChange: (
|
|
61
|
+
onChange: (r) => n(r.target.value),
|
|
63
62
|
sx: {
|
|
64
63
|
m: 0,
|
|
65
64
|
p: 0
|
|
66
65
|
},
|
|
67
|
-
value:
|
|
68
|
-
children: /* @__PURE__ */
|
|
66
|
+
value: e,
|
|
67
|
+
children: /* @__PURE__ */ i(a, {
|
|
69
68
|
sx: { gap: 16 },
|
|
70
|
-
children: ["once", "always"].map((
|
|
71
|
-
value:
|
|
72
|
-
control: /* @__PURE__ */
|
|
69
|
+
children: ["once", "always"].map((r) => /* @__PURE__ */ i(h, {
|
|
70
|
+
value: r,
|
|
71
|
+
control: /* @__PURE__ */ i(v, {
|
|
72
|
+
inputProps: { "aria-label": o[r].headline },
|
|
73
|
+
sx: { "& .MuiSvgIcon-root": { color: e === r ? "inherit" : "action.active" } }
|
|
74
|
+
}),
|
|
73
75
|
labelPlacement: "start",
|
|
74
76
|
label: /* @__PURE__ */ s(a, {
|
|
75
77
|
sx: {
|
|
76
78
|
gap: 4,
|
|
77
79
|
flexGrow: 1
|
|
78
80
|
},
|
|
79
|
-
children: [/* @__PURE__ */
|
|
81
|
+
children: [/* @__PURE__ */ i(l, {
|
|
80
82
|
bold: !0,
|
|
81
83
|
variant: "body1",
|
|
82
|
-
children: o[
|
|
83
|
-
}), /* @__PURE__ */
|
|
84
|
+
children: o[r].headline
|
|
85
|
+
}), /* @__PURE__ */ i(l, {
|
|
84
86
|
variant: "subtitle2",
|
|
85
|
-
children: o[
|
|
87
|
+
children: o[r].description
|
|
86
88
|
})]
|
|
87
89
|
}),
|
|
88
90
|
sx: {
|
|
@@ -93,17 +95,17 @@ var R = x(({ isOpen: i, onClose: d, onDismiss: c }) => {
|
|
|
93
95
|
minHeight: 72,
|
|
94
96
|
px: 16,
|
|
95
97
|
py: 0,
|
|
96
|
-
|
|
98
|
+
border: (p) => e === r ? `2px solid ${c(p.palette.primary.main, 0.5)}` : `1px solid ${c(p.palette.divider, 0.5)}`
|
|
97
99
|
}
|
|
98
|
-
},
|
|
100
|
+
}, r))
|
|
99
101
|
})
|
|
100
102
|
})]
|
|
101
103
|
})
|
|
102
104
|
}) : null;
|
|
103
105
|
});
|
|
104
106
|
export {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
_ as DismissInsightDialog,
|
|
108
|
+
_ as default
|
|
107
109
|
};
|
|
108
110
|
|
|
109
111
|
//# sourceMappingURL=DismissInsightDialog.es.js.map
|
|
@@ -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":"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"}
|
|
@@ -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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"}
|