@servicetitan/marketing-ui 7.2.0 → 7.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/dist/components/ads/ads-stat.js +2 -4
  2. package/dist/components/ads/ads-stat.js.map +1 -1
  3. package/dist/components/charts/common/color-tag.js.map +1 -1
  4. package/dist/components/charts/funnel-chart/components/funnel-chart.js.map +1 -1
  5. package/dist/components/charts/line-chart/components/body.js +8 -8
  6. package/dist/components/charts/line-chart/components/body.js.map +1 -1
  7. package/dist/components/charts/line-chart/components/svg-bars.js +3 -3
  8. package/dist/components/charts/line-chart/components/svg-bars.js.map +1 -1
  9. package/dist/components/charts/line-chart/components/svg-lines.js +2 -2
  10. package/dist/components/charts/line-chart/components/svg-lines.js.map +1 -1
  11. package/dist/components/charts/line-chart/stores/line-chart.store.js +2 -2
  12. package/dist/components/charts/line-chart/stores/line-chart.store.js.map +1 -1
  13. package/dist/components/charts/line-chart/utils/labels.js.map +1 -1
  14. package/dist/components/charts/pie-chart/components/pie.js +2 -2
  15. package/dist/components/charts/pie-chart/components/pie.js.map +1 -1
  16. package/dist/components/charts/pie-chart/utils/const.js +1 -1
  17. package/dist/components/charts/pie-chart/utils/const.js.map +1 -1
  18. package/dist/components/stat/stat-card.js.map +1 -1
  19. package/dist/components/ui/line-text/line-text.js.map +1 -1
  20. package/dist/utils/date/date-range-picker-state.d.ts.map +1 -1
  21. package/dist/utils/date/date-range-picker-state.js.map +1 -1
  22. package/package.json +3 -3
  23. package/src/utils/date/date-range-picker-state.ts +3 -2
@@ -4,9 +4,8 @@ import { StatExtendedCard } from '../stat/stat-extended-card';
4
4
  import { adsStatDescriptions } from '../../utils/ads-texts';
5
5
  import { camelCaseToTitleCase } from '../../utils/string-case';
6
6
  export const AdsPerformanceStatCard = (props)=>{
7
- var _props_title;
7
+ var _props_title, _props_description;
8
8
  const titleText = (_props_title = props.title) !== null && _props_title !== void 0 ? _props_title : camelCaseToTitleCase(props.stat);
9
- var _props_description;
10
9
  const hintText = (_props_description = props.description) !== null && _props_description !== void 0 ? _props_description : adsStatDescriptions[props.stat];
11
10
  return /*#__PURE__*/ _jsx(StatCard, {
12
11
  ...props,
@@ -15,9 +14,8 @@ export const AdsPerformanceStatCard = (props)=>{
15
14
  });
16
15
  };
17
16
  export const AdsPerformanceStatExtendedCard = (props)=>{
18
- var _props_title;
17
+ var _props_title, _props_description;
19
18
  const titleText = (_props_title = props.title) !== null && _props_title !== void 0 ? _props_title : camelCaseToTitleCase(props.stat);
20
- var _props_description;
21
19
  const hintText = (_props_description = props.description) !== null && _props_description !== void 0 ? _props_description : adsStatDescriptions[props.stat];
22
20
  return /*#__PURE__*/ _jsx(StatExtendedCard, {
23
21
  ...props,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ads/ads-stat.tsx"],"sourcesContent":["import { FC } from 'react';\nimport { StatCard, StatCardProps } from '../stat/stat-card';\nimport { StatExtendedCard, StatExtendedCardProps } from '../stat/stat-extended-card';\nimport { adsStatDescriptions, AdsStatType } from '../../utils/ads-texts';\nimport { camelCaseToTitleCase } from '../../utils/string-case';\n\nexport interface AdsPerformanceStatProps extends Omit<StatCardProps, 'title'> {\n stat: AdsStatType;\n title?: string;\n}\n\nexport const AdsPerformanceStatCard: FC<AdsPerformanceStatProps> = props => {\n const titleText = props.title ?? camelCaseToTitleCase(props.stat);\n const hintText = props.description ?? adsStatDescriptions[props.stat];\n\n return <StatCard {...props} title={titleText} description={hintText} />;\n};\n\nexport interface AdsPerformanceStatExtendedProps extends Omit<StatExtendedCardProps, 'title'> {\n stat: AdsStatType;\n title?: string;\n title2: string;\n}\n\nexport const AdsPerformanceStatExtendedCard: FC<AdsPerformanceStatExtendedProps> = props => {\n const titleText = props.title ?? camelCaseToTitleCase(props.stat);\n const hintText = props.description ?? adsStatDescriptions[props.stat];\n\n return <StatExtendedCard {...props} title={titleText} description={hintText} />;\n};\n"],"names":["StatCard","StatExtendedCard","adsStatDescriptions","camelCaseToTitleCase","AdsPerformanceStatCard","props","titleText","title","stat","hintText","description","AdsPerformanceStatExtendedCard"],"mappings":";AACA,SAASA,QAAQ,QAAuB,oBAAoB;AAC5D,SAASC,gBAAgB,QAA+B,6BAA6B;AACrF,SAASC,mBAAmB,QAAqB,wBAAwB;AACzE,SAASC,oBAAoB,QAAQ,0BAA0B;AAO/D,OAAO,MAAMC,yBAAsDC,CAAAA;QAC7CA;IAAlB,MAAMC,YAAYD,CAAAA,eAAAA,MAAME,KAAK,cAAXF,0BAAAA,eAAeF,qBAAqBE,MAAMG,IAAI;QAC/CH;IAAjB,MAAMI,WAAWJ,CAAAA,qBAAAA,MAAMK,WAAW,cAAjBL,gCAAAA,qBAAqBH,mBAAmB,CAACG,MAAMG,IAAI,CAAC;IAErE,qBAAO,KAACR;QAAU,GAAGK,KAAK;QAAEE,OAAOD;QAAWI,aAAaD;;AAC/D,EAAE;AAQF,OAAO,MAAME,iCAAsEN,CAAAA;QAC7DA;IAAlB,MAAMC,YAAYD,CAAAA,eAAAA,MAAME,KAAK,cAAXF,0BAAAA,eAAeF,qBAAqBE,MAAMG,IAAI;QAC/CH;IAAjB,MAAMI,WAAWJ,CAAAA,qBAAAA,MAAMK,WAAW,cAAjBL,gCAAAA,qBAAqBH,mBAAmB,CAACG,MAAMG,IAAI,CAAC;IAErE,qBAAO,KAACP;QAAkB,GAAGI,KAAK;QAAEE,OAAOD;QAAWI,aAAaD;;AACvE,EAAE"}
1
+ {"version":3,"sources":["../../../src/components/ads/ads-stat.tsx"],"sourcesContent":["import { FC } from 'react';\nimport { StatCard, StatCardProps } from '../stat/stat-card';\nimport { StatExtendedCard, StatExtendedCardProps } from '../stat/stat-extended-card';\nimport { adsStatDescriptions, AdsStatType } from '../../utils/ads-texts';\nimport { camelCaseToTitleCase } from '../../utils/string-case';\n\nexport interface AdsPerformanceStatProps extends Omit<StatCardProps, 'title'> {\n stat: AdsStatType;\n title?: string;\n}\n\nexport const AdsPerformanceStatCard: FC<AdsPerformanceStatProps> = props => {\n const titleText = props.title ?? camelCaseToTitleCase(props.stat);\n const hintText = props.description ?? adsStatDescriptions[props.stat];\n\n return <StatCard {...props} title={titleText} description={hintText} />;\n};\n\nexport interface AdsPerformanceStatExtendedProps extends Omit<StatExtendedCardProps, 'title'> {\n stat: AdsStatType;\n title?: string;\n title2: string;\n}\n\nexport const AdsPerformanceStatExtendedCard: FC<AdsPerformanceStatExtendedProps> = props => {\n const titleText = props.title ?? camelCaseToTitleCase(props.stat);\n const hintText = props.description ?? adsStatDescriptions[props.stat];\n\n return <StatExtendedCard {...props} title={titleText} description={hintText} />;\n};\n"],"names":["StatCard","StatExtendedCard","adsStatDescriptions","camelCaseToTitleCase","AdsPerformanceStatCard","props","titleText","title","stat","hintText","description","AdsPerformanceStatExtendedCard"],"mappings":";AACA,SAASA,QAAQ,QAAuB,oBAAoB;AAC5D,SAASC,gBAAgB,QAA+B,6BAA6B;AACrF,SAASC,mBAAmB,QAAqB,wBAAwB;AACzE,SAASC,oBAAoB,QAAQ,0BAA0B;AAO/D,OAAO,MAAMC,yBAAsDC,CAAAA;QAC7CA,cACDA;IADjB,MAAMC,aAAYD,eAAAA,MAAME,KAAK,cAAXF,0BAAAA,eAAeF,qBAAqBE,MAAMG,IAAI;IAChE,MAAMC,YAAWJ,qBAAAA,MAAMK,WAAW,cAAjBL,gCAAAA,qBAAqBH,mBAAmB,CAACG,MAAMG,IAAI,CAAC;IAErE,qBAAO,KAACR;QAAU,GAAGK,KAAK;QAAEE,OAAOD;QAAWI,aAAaD;;AAC/D,EAAE;AAQF,OAAO,MAAME,iCAAsEN,CAAAA;QAC7DA,cACDA;IADjB,MAAMC,aAAYD,eAAAA,MAAME,KAAK,cAAXF,0BAAAA,eAAeF,qBAAqBE,MAAMG,IAAI;IAChE,MAAMC,YAAWJ,qBAAAA,MAAMK,WAAW,cAAjBL,gCAAAA,qBAAqBH,mBAAmB,CAACG,MAAMG,IAAI,CAAC;IAErE,qBAAO,KAACP;QAAkB,GAAGI,KAAK;QAAEE,OAAOD;QAAWI,aAAaD;;AACvE,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/charts/common/color-tag.tsx"],"sourcesContent":["import { FC, useId } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Stack } from '@servicetitan/design-system';\nimport * as Styles from './color-tag.module.less';\n\ninterface ColorTagProps {\n label: string;\n color: string;\n className?: string;\n colorTagClassName?: string;\n small?: boolean;\n dashed?: boolean;\n strokeColor?: string;\n outlineColor?: string;\n pattern?: 'solid' | 'striped' | 'outline';\n}\n\nexport const ColorTag: FC<ColorTagProps> = ({\n label,\n color,\n className,\n small,\n dashed,\n outlineColor,\n pattern,\n strokeColor,\n colorTagClassName,\n}) => {\n const uid = useId();\n const patternId = `pattern-${uid}`;\n\n const width = small ? 50 : 22;\n const height = small ? 10 : 25;\n const radius = small ? 0 : 3;\n\n return (\n <Stack alignItems=\"center\" className={className} gap={1}>\n {pattern === 'striped' ? (\n <svg\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n className={classNames(Styles.colorTag, colorTagClassName)}\n aria-hidden\n >\n <defs>\n <pattern\n id={patternId}\n patternUnits=\"userSpaceOnUse\"\n width=\"8\"\n height=\"8\"\n patternTransform=\"rotate(45)\"\n >\n <rect width=\"4\" height=\"8\" fill={color} opacity=\"0.08\" />\n <rect width=\"2\" height=\"8\" fill={color} />\n </pattern>\n </defs>\n <rect\n x=\"0\"\n y=\"0\"\n width={width}\n height={height}\n rx={radius}\n ry={radius}\n fill={`url(#${patternId})`}\n stroke={strokeColor ?? color}\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n />\n </svg>\n ) : (\n <div\n className={classNames(\n Styles.colorTag,\n small && Styles.colorTagSmall,\n dashed && Styles.colorTagDashed,\n pattern === 'outline' && Styles.colorTagOutline,\n colorTagClassName\n )}\n style={\n dashed\n ? { borderColor: strokeColor ?? color }\n : pattern === 'outline'\n ? { borderColor: outlineColor ?? color, borderRadius: radius }\n : { backgroundColor: color, borderRadius: radius }\n }\n />\n )}\n <BodyText size={small ? 'xsmall' : 'small'}>{label}</BodyText>\n </Stack>\n );\n};\n"],"names":["useId","classNames","BodyText","Stack","Styles","ColorTag","label","color","className","small","dashed","outlineColor","pattern","strokeColor","colorTagClassName","uid","patternId","width","height","radius","alignItems","gap","svg","viewBox","colorTag","aria-hidden","defs","id","patternUnits","patternTransform","rect","fill","opacity","x","y","rx","ry","stroke","strokeWidth","vectorEffect","div","colorTagSmall","colorTagDashed","colorTagOutline","style","borderColor","borderRadius","backgroundColor","size"],"mappings":";AAAA,SAAaA,KAAK,QAAQ,QAAQ;AAClC,OAAOC,gBAAgB,aAAa;AACpC,SAASC,QAAQ,EAAEC,KAAK,QAAQ,8BAA8B;AAC9D,YAAYC,YAAY,0BAA0B;AAclD,OAAO,MAAMC,WAA8B,CAAC,EACxCC,KAAK,EACLC,KAAK,EACLC,SAAS,EACTC,KAAK,EACLC,MAAM,EACNC,YAAY,EACZC,OAAO,EACPC,WAAW,EACXC,iBAAiB,EACpB;IACG,MAAMC,MAAMf;IACZ,MAAMgB,YAAY,CAAC,QAAQ,EAAED,KAAK;IAElC,MAAME,QAAQR,QAAQ,KAAK;IAC3B,MAAMS,SAAST,QAAQ,KAAK;IAC5B,MAAMU,SAASV,QAAQ,IAAI;IAE3B,qBACI,MAACN;QAAMiB,YAAW;QAASZ,WAAWA;QAAWa,KAAK;;YACjDT,YAAY,0BACT,MAACU;gBACGL,OAAOA;gBACPC,QAAQA;gBACRK,SAAS,CAAC,IAAI,EAAEN,MAAM,CAAC,EAAEC,QAAQ;gBACjCV,WAAWP,WAAWG,OAAOoB,QAAQ,EAAEV;gBACvCW,aAAW;;kCAEX,KAACC;kCACG,cAAA,MAACd;4BACGe,IAAIX;4BACJY,cAAa;4BACbX,OAAM;4BACNC,QAAO;4BACPW,kBAAiB;;8CAEjB,KAACC;oCAAKb,OAAM;oCAAIC,QAAO;oCAAIa,MAAMxB;oCAAOyB,SAAQ;;8CAChD,KAACF;oCAAKb,OAAM;oCAAIC,QAAO;oCAAIa,MAAMxB;;;;;kCAGzC,KAACuB;wBACGG,GAAE;wBACFC,GAAE;wBACFjB,OAAOA;wBACPC,QAAQA;wBACRiB,IAAIhB;wBACJiB,IAAIjB;wBACJY,MAAM,CAAC,KAAK,EAAEf,UAAU,CAAC,CAAC;wBAC1BqB,QAAQxB,wBAAAA,yBAAAA,cAAeN;wBACvB+B,aAAa;wBACbC,cAAa;;;+BAIrB,KAACC;gBACGhC,WAAWP,WACPG,OAAOoB,QAAQ,EACff,SAASL,OAAOqC,aAAa,EAC7B/B,UAAUN,OAAOsC,cAAc,EAC/B9B,YAAY,aAAaR,OAAOuC,eAAe,EAC/C7B;gBAEJ8B,OACIlC,SACM;oBAAEmC,aAAahC,wBAAAA,yBAAAA,cAAeN;gBAAM,IACpCK,YAAY,YACV;oBAAEiC,aAAalC,yBAAAA,0BAAAA,eAAgBJ;oBAAOuC,cAAc3B;gBAAO,IAC3D;oBAAE4B,iBAAiBxC;oBAAOuC,cAAc3B;gBAAO;;0BAInE,KAACjB;gBAAS8C,MAAMvC,QAAQ,WAAW;0BAAUH;;;;AAGzD,EAAE"}
1
+ {"version":3,"sources":["../../../../src/components/charts/common/color-tag.tsx"],"sourcesContent":["import { FC, useId } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Stack } from '@servicetitan/design-system';\nimport * as Styles from './color-tag.module.less';\n\ninterface ColorTagProps {\n label: string;\n color: string;\n className?: string;\n colorTagClassName?: string;\n small?: boolean;\n dashed?: boolean;\n strokeColor?: string;\n outlineColor?: string;\n pattern?: 'solid' | 'striped' | 'outline';\n}\n\nexport const ColorTag: FC<ColorTagProps> = ({\n label,\n color,\n className,\n small,\n dashed,\n outlineColor,\n pattern,\n strokeColor,\n colorTagClassName,\n}) => {\n const uid = useId();\n const patternId = `pattern-${uid}`;\n\n const width = small ? 50 : 22;\n const height = small ? 10 : 25;\n const radius = small ? 0 : 3;\n\n return (\n <Stack alignItems=\"center\" className={className} gap={1}>\n {pattern === 'striped' ? (\n <svg\n width={width}\n height={height}\n viewBox={`0 0 ${width} ${height}`}\n className={classNames(Styles.colorTag, colorTagClassName)}\n aria-hidden\n >\n <defs>\n <pattern\n id={patternId}\n patternUnits=\"userSpaceOnUse\"\n width=\"8\"\n height=\"8\"\n patternTransform=\"rotate(45)\"\n >\n <rect width=\"4\" height=\"8\" fill={color} opacity=\"0.08\" />\n <rect width=\"2\" height=\"8\" fill={color} />\n </pattern>\n </defs>\n <rect\n x=\"0\"\n y=\"0\"\n width={width}\n height={height}\n rx={radius}\n ry={radius}\n fill={`url(#${patternId})`}\n stroke={strokeColor ?? color}\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n />\n </svg>\n ) : (\n <div\n className={classNames(\n Styles.colorTag,\n small && Styles.colorTagSmall,\n dashed && Styles.colorTagDashed,\n pattern === 'outline' && Styles.colorTagOutline,\n colorTagClassName\n )}\n style={\n dashed\n ? { borderColor: strokeColor ?? color }\n : pattern === 'outline'\n ? { borderColor: outlineColor ?? color, borderRadius: radius }\n : { backgroundColor: color, borderRadius: radius }\n }\n />\n )}\n <BodyText size={small ? 'xsmall' : 'small'}>{label}</BodyText>\n </Stack>\n );\n};\n"],"names":["useId","classNames","BodyText","Stack","Styles","ColorTag","label","color","className","small","dashed","outlineColor","pattern","strokeColor","colorTagClassName","uid","patternId","width","height","radius","alignItems","gap","svg","viewBox","colorTag","aria-hidden","defs","id","patternUnits","patternTransform","rect","fill","opacity","x","y","rx","ry","stroke","strokeWidth","vectorEffect","div","colorTagSmall","colorTagDashed","colorTagOutline","style","borderColor","borderRadius","backgroundColor","size"],"mappings":";AAAA,SAAaA,KAAK,QAAQ,QAAQ;AAClC,OAAOC,gBAAgB,aAAa;AACpC,SAASC,QAAQ,EAAEC,KAAK,QAAQ,8BAA8B;AAC9D,YAAYC,YAAY,0BAA0B;AAclD,OAAO,MAAMC,WAA8B,CAAC,EACxCC,KAAK,EACLC,KAAK,EACLC,SAAS,EACTC,KAAK,EACLC,MAAM,EACNC,YAAY,EACZC,OAAO,EACPC,WAAW,EACXC,iBAAiB,EACpB;IACG,MAAMC,MAAMf;IACZ,MAAMgB,YAAY,CAAC,QAAQ,EAAED,KAAK;IAElC,MAAME,QAAQR,QAAQ,KAAK;IAC3B,MAAMS,SAAST,QAAQ,KAAK;IAC5B,MAAMU,SAASV,QAAQ,IAAI;IAE3B,qBACI,MAACN;QAAMiB,YAAW;QAASZ,WAAWA;QAAWa,KAAK;;YACjDT,YAAY,0BACT,MAACU;gBACGL,OAAOA;gBACPC,QAAQA;gBACRK,SAAS,CAAC,IAAI,EAAEN,MAAM,CAAC,EAAEC,QAAQ;gBACjCV,WAAWP,WAAWG,OAAOoB,QAAQ,EAAEV;gBACvCW,aAAW;;kCAEX,KAACC;kCACG,cAAA,MAACd;4BACGe,IAAIX;4BACJY,cAAa;4BACbX,OAAM;4BACNC,QAAO;4BACPW,kBAAiB;;8CAEjB,KAACC;oCAAKb,OAAM;oCAAIC,QAAO;oCAAIa,MAAMxB;oCAAOyB,SAAQ;;8CAChD,KAACF;oCAAKb,OAAM;oCAAIC,QAAO;oCAAIa,MAAMxB;;;;;kCAGzC,KAACuB;wBACGG,GAAE;wBACFC,GAAE;wBACFjB,OAAOA;wBACPC,QAAQA;wBACRiB,IAAIhB;wBACJiB,IAAIjB;wBACJY,MAAM,CAAC,KAAK,EAAEf,UAAU,CAAC,CAAC;wBAC1BqB,MAAM,EAAExB,wBAAAA,yBAAAA,cAAeN;wBACvB+B,aAAa;wBACbC,cAAa;;;+BAIrB,KAACC;gBACGhC,WAAWP,WACPG,OAAOoB,QAAQ,EACff,SAASL,OAAOqC,aAAa,EAC7B/B,UAAUN,OAAOsC,cAAc,EAC/B9B,YAAY,aAAaR,OAAOuC,eAAe,EAC/C7B;gBAEJ8B,OACIlC,SACM;oBAAEmC,WAAW,EAAEhC,wBAAAA,yBAAAA,cAAeN;gBAAM,IACpCK,YAAY,YACV;oBAAEiC,WAAW,EAAElC,yBAAAA,0BAAAA,eAAgBJ;oBAAOuC,cAAc3B;gBAAO,IAC3D;oBAAE4B,iBAAiBxC;oBAAOuC,cAAc3B;gBAAO;;0BAInE,KAACjB;gBAAS8C,MAAMvC,QAAQ,WAAW;0BAAUH;;;;AAGzD,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/funnel-chart/components/funnel-chart.tsx"],"sourcesContent":["import { useMemo, useState, FC, Fragment } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Eyebrow, Icon, Mask, Stack, Tooltip } from '@servicetitan/design-system';\nimport { tokens } from '@servicetitan/tokens/core';\nimport { formatValue } from '../../../../utils/formatters';\nimport { StatDiff } from '../../../stat/stat-card';\nimport { FunnelChartProps } from '../utils/interface';\nimport { defaultBottomSideLength, defaultTopSideLength } from '../utils/const';\nimport { FunnelPyramidSvg } from './funnel-svg';\nimport * as Styles from './funnel-chart.module.less';\nimport { Popover } from '@servicetitan/anvil2';\nimport { ColorTag } from '../../common';\n\nexport const FunnelChart: FC<FunnelChartProps> = ({\n sections,\n format,\n topSideLength = defaultTopSideLength,\n bottomSideLength = defaultBottomSideLength,\n popoverContent: PopoverContent,\n loading,\n className,\n}) => {\n const [popoverShown, setPopoverShown] = useState<number | undefined>(undefined);\n const [rowYs, setRowYs] = useState<number[]>([]);\n const colors = useMemo(() => sections.map(s => s.color), [sections]);\n const outlineColors = useMemo(() => sections.map(s => s.outlineColor), [sections]);\n const hidePopover = () => setPopoverShown(undefined);\n\n const rightStyles = useMemo(\n () => ({\n left: `${100 - topSideLength}%`,\n }),\n [topSideLength]\n );\n\n return (\n <Mask\n className={classNames(\n 'h-100 bg-white border border-radius-2 p-3 of-hidden position-relative',\n className\n )}\n active={!!loading}\n >\n <div className={Styles.pyramidWrapper}>\n <FunnelPyramidSvg\n colors={colors}\n outlineColors={outlineColors}\n topSideLength={topSideLength}\n bottomSideLength={bottomSideLength}\n onRowAnchors={setRowYs}\n />\n </div>\n\n <div\n className={classNames(\n 'd-f flex-column justify-content-around',\n Styles.pyramidBoxRight\n )}\n style={rightStyles}\n >\n {sections.map(({ id, title, value, color, prev, data, outlineColor }) => (\n <Stack\n key={title}\n className={Styles.flex1}\n justifyContent=\"center\"\n alignItems=\"center\"\n onMouseEnter={() => setPopoverShown(id)}\n onMouseLeave={hidePopover}\n >\n <Popover open={popoverShown === id} openOnHover placement=\"right\">\n <Popover.Trigger>\n {props => (\n <span {...props}>\n <div className={Styles.percentTextWrapper}>\n <BodyText\n className={classNames(Styles.percentText)}\n data-cy={`marketing-funnel-section-${id}-value`}\n >\n {formatValue(value, format)}\n </BodyText>\n </div>\n </span>\n )}\n </Popover.Trigger>\n <Popover.Content>\n <Stack\n alignItems=\"flex-start\"\n justifyContent=\"flex-start\"\n direction=\"column\"\n data-cy={`marketing-funnel-popover-${id}-content`}\n >\n <Stack>\n <ColorTag\n label=\"\"\n color={color}\n outlineColor={outlineColor}\n pattern={outlineColor ? 'outline' : 'solid'}\n />\n <BodyText bold className=\"m-r-half\">\n {title} {formatValue(value, format)}\n </BodyText>\n </Stack>\n <Stack.Item>\n <StatDiff\n value={value}\n prev={prev}\n size=\"xsmall\"\n format={format}\n />\n </Stack.Item>\n </Stack>\n\n {!!PopoverContent && (\n <PopoverContent\n id={id}\n value={value}\n text={formatValue(value, format)}\n data={data}\n />\n )}\n </Popover.Content>\n </Popover>\n </Stack>\n ))}\n </div>\n <div className={Styles.pyramidBoxLeft} style={{ width: `${100 - topSideLength}%` }}>\n {sections.map((s, i) => {\n const y = rowYs[i] ?? 0;\n const TITLE_UP = 24;\n const DIFF_DOWN = 4;\n\n return (\n <Fragment key={s.id}>\n <div\n className={Styles.leftTitle}\n style={{ top: `calc(${y}% - ${TITLE_UP}px)` }}\n >\n <Eyebrow\n size=\"small\"\n className={classNames(Styles.statTitle, 'm-r-half')}\n >\n {s.title}\n </Eyebrow>\n <Tooltip direction=\"t\" portal text={s.description}>\n <Icon\n name=\"info\"\n className=\"m-r-1\"\n size=\"14px\"\n color={tokens.colorNeutral90}\n />\n </Tooltip>\n </div>\n\n <div\n className={Styles.leftDiff}\n style={{ top: `calc(${y}% + ${DIFF_DOWN}px)` }}\n >\n <StatDiff\n value={s.value}\n prev={s.prev}\n size=\"small\"\n format={format}\n />\n </div>\n </Fragment>\n );\n })}\n </div>\n </Mask>\n );\n};\n"],"names":["useMemo","useState","Fragment","classNames","BodyText","Eyebrow","Icon","Mask","Stack","Tooltip","tokens","formatValue","StatDiff","defaultBottomSideLength","defaultTopSideLength","FunnelPyramidSvg","Styles","Popover","ColorTag","FunnelChart","sections","format","topSideLength","bottomSideLength","popoverContent","PopoverContent","loading","className","popoverShown","setPopoverShown","undefined","rowYs","setRowYs","colors","map","s","color","outlineColors","outlineColor","hidePopover","rightStyles","left","active","div","pyramidWrapper","onRowAnchors","pyramidBoxRight","style","id","title","value","prev","data","flex1","justifyContent","alignItems","onMouseEnter","onMouseLeave","open","openOnHover","placement","Trigger","props","span","percentTextWrapper","percentText","data-cy","Content","direction","label","pattern","bold","Item","size","text","pyramidBoxLeft","width","i","y","TITLE_UP","DIFF_DOWN","leftTitle","top","statTitle","portal","description","name","colorNeutral90","leftDiff"],"mappings":";AAAA,SAASA,OAAO,EAAEC,QAAQ,EAAMC,QAAQ,QAAQ,QAAQ;AACxD,OAAOC,gBAAgB,aAAa;AACpC,SAASC,QAAQ,EAAEC,OAAO,EAAEC,IAAI,EAAEC,IAAI,EAAEC,KAAK,EAAEC,OAAO,QAAQ,8BAA8B;AAC5F,SAASC,MAAM,QAAQ,4BAA4B;AACnD,SAASC,WAAW,QAAQ,+BAA+B;AAC3D,SAASC,QAAQ,QAAQ,0BAA0B;AAEnD,SAASC,uBAAuB,EAAEC,oBAAoB,QAAQ,iBAAiB;AAC/E,SAASC,gBAAgB,QAAQ,eAAe;AAChD,YAAYC,YAAY,6BAA6B;AACrD,SAASC,OAAO,QAAQ,uBAAuB;AAC/C,SAASC,QAAQ,QAAQ,eAAe;AAExC,OAAO,MAAMC,cAAoC,CAAC,EAC9CC,QAAQ,EACRC,MAAM,EACNC,gBAAgBR,oBAAoB,EACpCS,mBAAmBV,uBAAuB,EAC1CW,gBAAgBC,cAAc,EAC9BC,OAAO,EACPC,SAAS,EACZ;IACG,MAAM,CAACC,cAAcC,gBAAgB,GAAG5B,SAA6B6B;IACrE,MAAM,CAACC,OAAOC,SAAS,GAAG/B,SAAmB,EAAE;IAC/C,MAAMgC,SAASjC,QAAQ,IAAMoB,SAASc,GAAG,CAACC,CAAAA,IAAKA,EAAEC,KAAK,GAAG;QAAChB;KAAS;IACnE,MAAMiB,gBAAgBrC,QAAQ,IAAMoB,SAASc,GAAG,CAACC,CAAAA,IAAKA,EAAEG,YAAY,GAAG;QAAClB;KAAS;IACjF,MAAMmB,cAAc,IAAMV,gBAAgBC;IAE1C,MAAMU,cAAcxC,QAChB,IAAO,CAAA;YACHyC,MAAM,GAAG,MAAMnB,cAAc,CAAC,CAAC;QACnC,CAAA,GACA;QAACA;KAAc;IAGnB,qBACI,MAACf;QACGoB,WAAWxB,WACP,yEACAwB;QAEJe,QAAQ,CAAC,CAAChB;;0BAEV,KAACiB;gBAAIhB,WAAWX,OAAO4B,cAAc;0BACjC,cAAA,KAAC7B;oBACGkB,QAAQA;oBACRI,eAAeA;oBACff,eAAeA;oBACfC,kBAAkBA;oBAClBsB,cAAcb;;;0BAItB,KAACW;gBACGhB,WAAWxB,WACP,0CACAa,OAAO8B,eAAe;gBAE1BC,OAAOP;0BAENpB,SAASc,GAAG,CAAC,CAAC,EAAEc,EAAE,EAAEC,KAAK,EAAEC,KAAK,EAAEd,KAAK,EAAEe,IAAI,EAAEC,IAAI,EAAEd,YAAY,EAAE,iBAChE,KAAC9B;wBAEGmB,WAAWX,OAAOqC,KAAK;wBACvBC,gBAAe;wBACfC,YAAW;wBACXC,cAAc,IAAM3B,gBAAgBmB;wBACpCS,cAAclB;kCAEd,cAAA,MAACtB;4BAAQyC,MAAM9B,iBAAiBoB;4BAAIW,WAAW;4BAACC,WAAU;;8CACtD,KAAC3C,QAAQ4C,OAAO;8CACXC,CAAAA,sBACG,KAACC;4CAAM,GAAGD,KAAK;sDACX,cAAA,KAACnB;gDAAIhB,WAAWX,OAAOgD,kBAAkB;0DACrC,cAAA,KAAC5D;oDACGuB,WAAWxB,WAAWa,OAAOiD,WAAW;oDACxCC,WAAS,CAAC,yBAAyB,EAAElB,GAAG,MAAM,CAAC;8DAE9CrC,YAAYuC,OAAO7B;;;;;8CAMxC,MAACJ,QAAQkD,OAAO;;sDACZ,MAAC3D;4CACG+C,YAAW;4CACXD,gBAAe;4CACfc,WAAU;4CACVF,WAAS,CAAC,yBAAyB,EAAElB,GAAG,QAAQ,CAAC;;8DAEjD,MAACxC;;sEACG,KAACU;4DACGmD,OAAM;4DACNjC,OAAOA;4DACPE,cAAcA;4DACdgC,SAAShC,eAAe,YAAY;;sEAExC,MAAClC;4DAASmE,IAAI;4DAAC5C,WAAU;;gEACpBsB;gEAAM;gEAAEtC,YAAYuC,OAAO7B;;;;;8DAGpC,KAACb,MAAMgE,IAAI;8DACP,cAAA,KAAC5D;wDACGsC,OAAOA;wDACPC,MAAMA;wDACNsB,MAAK;wDACLpD,QAAQA;;;;;wCAKnB,CAAC,CAACI,gCACC,KAACA;4CACGuB,IAAIA;4CACJE,OAAOA;4CACPwB,MAAM/D,YAAYuC,OAAO7B;4CACzB+B,MAAMA;;;;;;uBAvDjBH;;0BA+DjB,KAACN;gBAAIhB,WAAWX,OAAO2D,cAAc;gBAAE5B,OAAO;oBAAE6B,OAAO,GAAG,MAAMtD,cAAc,CAAC,CAAC;gBAAC;0BAC5EF,SAASc,GAAG,CAAC,CAACC,GAAG0C;wBACJ9C;oBAAV,MAAM+C,IAAI/C,CAAAA,WAAAA,KAAK,CAAC8C,EAAE,cAAR9C,sBAAAA,WAAY;oBACtB,MAAMgD,WAAW;oBACjB,MAAMC,YAAY;oBAElB,qBACI,MAAC9E;;0CACG,MAACyC;gCACGhB,WAAWX,OAAOiE,SAAS;gCAC3BlC,OAAO;oCAAEmC,KAAK,CAAC,KAAK,EAAEJ,EAAE,IAAI,EAAEC,SAAS,GAAG,CAAC;gCAAC;;kDAE5C,KAAC1E;wCACGoE,MAAK;wCACL9C,WAAWxB,WAAWa,OAAOmE,SAAS,EAAE;kDAEvChD,EAAEc,KAAK;;kDAEZ,KAACxC;wCAAQ2D,WAAU;wCAAIgB,MAAM;wCAACV,MAAMvC,EAAEkD,WAAW;kDAC7C,cAAA,KAAC/E;4CACGgF,MAAK;4CACL3D,WAAU;4CACV8C,MAAK;4CACLrC,OAAO1B,OAAO6E,cAAc;;;;;0CAKxC,KAAC5C;gCACGhB,WAAWX,OAAOwE,QAAQ;gCAC1BzC,OAAO;oCAAEmC,KAAK,CAAC,KAAK,EAAEJ,EAAE,IAAI,EAAEE,UAAU,GAAG,CAAC;gCAAC;0CAE7C,cAAA,KAACpE;oCACGsC,OAAOf,EAAEe,KAAK;oCACdC,MAAMhB,EAAEgB,IAAI;oCACZsB,MAAK;oCACLpD,QAAQA;;;;uBA7BLc,EAAEa,EAAE;gBAkC3B;;;;AAIhB,EAAE"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/funnel-chart/components/funnel-chart.tsx"],"sourcesContent":["import { useMemo, useState, FC, Fragment } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Eyebrow, Icon, Mask, Stack, Tooltip } from '@servicetitan/design-system';\nimport { tokens } from '@servicetitan/tokens/core';\nimport { formatValue } from '../../../../utils/formatters';\nimport { StatDiff } from '../../../stat/stat-card';\nimport { FunnelChartProps } from '../utils/interface';\nimport { defaultBottomSideLength, defaultTopSideLength } from '../utils/const';\nimport { FunnelPyramidSvg } from './funnel-svg';\nimport * as Styles from './funnel-chart.module.less';\nimport { Popover } from '@servicetitan/anvil2';\nimport { ColorTag } from '../../common';\n\nexport const FunnelChart: FC<FunnelChartProps> = ({\n sections,\n format,\n topSideLength = defaultTopSideLength,\n bottomSideLength = defaultBottomSideLength,\n popoverContent: PopoverContent,\n loading,\n className,\n}) => {\n const [popoverShown, setPopoverShown] = useState<number | undefined>(undefined);\n const [rowYs, setRowYs] = useState<number[]>([]);\n const colors = useMemo(() => sections.map(s => s.color), [sections]);\n const outlineColors = useMemo(() => sections.map(s => s.outlineColor), [sections]);\n const hidePopover = () => setPopoverShown(undefined);\n\n const rightStyles = useMemo(\n () => ({\n left: `${100 - topSideLength}%`,\n }),\n [topSideLength]\n );\n\n return (\n <Mask\n className={classNames(\n 'h-100 bg-white border border-radius-2 p-3 of-hidden position-relative',\n className\n )}\n active={!!loading}\n >\n <div className={Styles.pyramidWrapper}>\n <FunnelPyramidSvg\n colors={colors}\n outlineColors={outlineColors}\n topSideLength={topSideLength}\n bottomSideLength={bottomSideLength}\n onRowAnchors={setRowYs}\n />\n </div>\n\n <div\n className={classNames(\n 'd-f flex-column justify-content-around',\n Styles.pyramidBoxRight\n )}\n style={rightStyles}\n >\n {sections.map(({ id, title, value, color, prev, data, outlineColor }) => (\n <Stack\n key={title}\n className={Styles.flex1}\n justifyContent=\"center\"\n alignItems=\"center\"\n onMouseEnter={() => setPopoverShown(id)}\n onMouseLeave={hidePopover}\n >\n <Popover open={popoverShown === id} openOnHover placement=\"right\">\n <Popover.Trigger>\n {props => (\n <span {...props}>\n <div className={Styles.percentTextWrapper}>\n <BodyText\n className={classNames(Styles.percentText)}\n data-cy={`marketing-funnel-section-${id}-value`}\n >\n {formatValue(value, format)}\n </BodyText>\n </div>\n </span>\n )}\n </Popover.Trigger>\n <Popover.Content>\n <Stack\n alignItems=\"flex-start\"\n justifyContent=\"flex-start\"\n direction=\"column\"\n data-cy={`marketing-funnel-popover-${id}-content`}\n >\n <Stack>\n <ColorTag\n label=\"\"\n color={color}\n outlineColor={outlineColor}\n pattern={outlineColor ? 'outline' : 'solid'}\n />\n <BodyText bold className=\"m-r-half\">\n {title} {formatValue(value, format)}\n </BodyText>\n </Stack>\n <Stack.Item>\n <StatDiff\n value={value}\n prev={prev}\n size=\"xsmall\"\n format={format}\n />\n </Stack.Item>\n </Stack>\n\n {!!PopoverContent && (\n <PopoverContent\n id={id}\n value={value}\n text={formatValue(value, format)}\n data={data}\n />\n )}\n </Popover.Content>\n </Popover>\n </Stack>\n ))}\n </div>\n <div className={Styles.pyramidBoxLeft} style={{ width: `${100 - topSideLength}%` }}>\n {sections.map((s, i) => {\n const y = rowYs[i] ?? 0;\n const TITLE_UP = 24;\n const DIFF_DOWN = 4;\n\n return (\n <Fragment key={s.id}>\n <div\n className={Styles.leftTitle}\n style={{ top: `calc(${y}% - ${TITLE_UP}px)` }}\n >\n <Eyebrow\n size=\"small\"\n className={classNames(Styles.statTitle, 'm-r-half')}\n >\n {s.title}\n </Eyebrow>\n <Tooltip direction=\"t\" portal text={s.description}>\n <Icon\n name=\"info\"\n className=\"m-r-1\"\n size=\"14px\"\n color={tokens.colorNeutral90}\n />\n </Tooltip>\n </div>\n\n <div\n className={Styles.leftDiff}\n style={{ top: `calc(${y}% + ${DIFF_DOWN}px)` }}\n >\n <StatDiff\n value={s.value}\n prev={s.prev}\n size=\"small\"\n format={format}\n />\n </div>\n </Fragment>\n );\n })}\n </div>\n </Mask>\n );\n};\n"],"names":["useMemo","useState","Fragment","classNames","BodyText","Eyebrow","Icon","Mask","Stack","Tooltip","tokens","formatValue","StatDiff","defaultBottomSideLength","defaultTopSideLength","FunnelPyramidSvg","Styles","Popover","ColorTag","FunnelChart","sections","format","topSideLength","bottomSideLength","popoverContent","PopoverContent","loading","className","popoverShown","setPopoverShown","undefined","rowYs","setRowYs","colors","map","s","color","outlineColors","outlineColor","hidePopover","rightStyles","left","active","div","pyramidWrapper","onRowAnchors","pyramidBoxRight","style","id","title","value","prev","data","flex1","justifyContent","alignItems","onMouseEnter","onMouseLeave","open","openOnHover","placement","Trigger","props","span","percentTextWrapper","percentText","data-cy","Content","direction","label","pattern","bold","Item","size","text","pyramidBoxLeft","width","i","y","TITLE_UP","DIFF_DOWN","leftTitle","top","statTitle","portal","description","name","colorNeutral90","leftDiff"],"mappings":"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"}
@@ -18,10 +18,11 @@ export const Body = provide({
18
18
  SvgStore
19
19
  ]
20
20
  })(observer(({ classNameTitle })=>{
21
+ var _ref, _ref1, _ref2;
21
22
  const [{ display, metrics, left, right, periods, resolution, setHoveredIndex }, svgStore] = useDependencies(LineChartStore, SvgStore);
22
23
  useEffect(()=>{
23
- var _left_maxValue, _right_maxValue;
24
- svgStore.init(periods.length, metrics, (_left_maxValue = left === null || left === void 0 ? void 0 : left.maxValue) !== null && _left_maxValue !== void 0 ? _left_maxValue : 0, (_right_maxValue = right === null || right === void 0 ? void 0 : right.maxValue) !== null && _right_maxValue !== void 0 ? _right_maxValue : 0);
24
+ var _ref, _ref1;
25
+ svgStore.init(periods.length, metrics, (_ref = left === null || left === void 0 ? void 0 : left.maxValue) !== null && _ref !== void 0 ? _ref : 0, (_ref1 = right === null || right === void 0 ? void 0 : right.maxValue) !== null && _ref1 !== void 0 ? _ref1 : 0);
25
26
  }, [
26
27
  svgStore,
27
28
  periods,
@@ -37,15 +38,14 @@ export const Body = provide({
37
38
  setHoveredIndex
38
39
  ]);
39
40
  const labels = useMemo(()=>{
40
- var _rect_width;
41
- return display.xLabels ? getXLabels(periods, resolution, (_rect_width = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _rect_width !== void 0 ? _rect_width : 0) : [];
41
+ var _ref;
42
+ return display.xLabels ? getXLabels(periods, resolution, (_ref = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _ref !== void 0 ? _ref : 0) : [];
42
43
  }, [
43
44
  display,
44
45
  periods,
45
46
  resolution,
46
47
  rect
47
48
  ]);
48
- var _rect_width, _left_width, _right_width;
49
49
  return /*#__PURE__*/ _jsxs("div", {
50
50
  className: "d-f flex-column",
51
51
  children: [
@@ -104,9 +104,9 @@ export const Body = provide({
104
104
  }),
105
105
  display.xLabels && /*#__PURE__*/ _jsx(XAxisLabels, {
106
106
  labels: labels,
107
- width: (_rect_width = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _rect_width !== void 0 ? _rect_width : 0,
108
- left: (_left_width = left === null || left === void 0 ? void 0 : left.width) !== null && _left_width !== void 0 ? _left_width : 0,
109
- right: (_right_width = right === null || right === void 0 ? void 0 : right.width) !== null && _right_width !== void 0 ? _right_width : 0,
107
+ width: (_ref = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _ref !== void 0 ? _ref : 0,
108
+ left: (_ref1 = left === null || left === void 0 ? void 0 : left.width) !== null && _ref1 !== void 0 ? _ref1 : 0,
109
+ right: (_ref2 = right === null || right === void 0 ? void 0 : right.width) !== null && _ref2 !== void 0 ? _ref2 : 0,
110
110
  labelsMerged: periods.length !== labels.length,
111
111
  hasBars: !!metrics.filter((m)=>m.type === 'bar' || m.type === 'stacked-bar' || m.type === 'grouped-bar').length
112
112
  }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/body.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, FC, Fragment } from 'react';\nimport { observer } from 'mobx-react';\nimport classNames from 'classnames';\nimport { Stack } from '@servicetitan/design-system';\nimport { provide, useDependencies } from '@servicetitan/react-ioc';\n\nimport { useClientRect } from '../../../../utils/use-client-rect';\nimport { LineChartStore } from '../stores/line-chart.store';\nimport { SvgStore } from '../stores/svg.store';\nimport { getXLabels } from '../utils/labels';\n\nimport { Sidebar } from './sidebar';\nimport { MetricsTitle, XAxisLabels } from './stuff';\nimport { SvgBody, SvgBodyHover } from './svg-body';\nimport { HoverPopover } from './hover-popover';\nimport * as Styles from './body.module.less';\n\nexport const Body: FC<{ classNameTitle?: string }> = provide({ singletons: [SvgStore] })(\n observer(({ classNameTitle }) => {\n const [{ display, metrics, left, right, periods, resolution, setHoveredIndex }, svgStore] =\n useDependencies(LineChartStore, SvgStore);\n\n useEffect(() => {\n svgStore.init(periods.length, metrics, left?.maxValue ?? 0, right?.maxValue ?? 0);\n }, [svgStore, periods, metrics, left, right]);\n const [rect, ref] = useClientRect();\n\n const onBarHover = useCallback(\n (ind: number) => setHoveredIndex(ind, true),\n [setHoveredIndex]\n );\n\n const onBarLeave = useCallback(\n (ind: number) => setHoveredIndex(ind, false),\n [setHoveredIndex]\n );\n\n const labels = useMemo(\n () => (display.xLabels ? getXLabels(periods, resolution, rect?.width ?? 0) : []),\n [display, periods, resolution, rect]\n );\n\n return (\n <div className=\"d-f flex-column\">\n <Stack alignItems=\"stretch\">\n {left && <Sidebar settings={left} classNameTitle={classNameTitle} />}\n <Stack.Item fill>\n <div\n ref={ref}\n className={classNames(Styles.chartWrapper, 'border-bottom', {\n 'border-left': !!left && display.yLeft,\n 'border-right': !!right && display.yRight,\n })}\n >\n {periods.length ? (\n <Fragment>\n {periods.length !== labels.length && (\n <div className={Styles.labelBorders}>\n {labels\n .map(([text, flex], ind) => [flex, `${ind}${text}`])\n .map(([flex, key]) => (\n <div key={key} style={{ flex }} />\n ))}\n </div>\n )}\n\n <SvgBody horizontalGrid={display.yGrid} metrics={metrics} />\n <HoverPopover />\n <SvgBodyHover\n onValueHover={onBarHover}\n onValueLeave={onBarLeave}\n />\n </Fragment>\n ) : (\n <Stack\n className=\"h-100\"\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n No Data\n </Stack>\n )}\n </div>\n </Stack.Item>\n {right && <Sidebar settings={right} right classNameTitle={classNameTitle} />}\n </Stack>\n {display.xLabels && (\n <XAxisLabels\n labels={labels}\n width={rect?.width ?? 0}\n left={left?.width ?? 0}\n right={right?.width ?? 0}\n labelsMerged={periods.length !== labels.length}\n hasBars={\n !!metrics.filter(\n m =>\n m.type === 'bar' ||\n m.type === 'stacked-bar' ||\n m.type === 'grouped-bar'\n ).length\n }\n />\n )}\n {display.metricsTitlePosition === 'bottom' && (\n <Stack direction=\"row\" justifyContent=\"flex-start\" className=\"p-t-3 p-x-5\">\n <MetricsTitle metrics={metrics} />\n </Stack>\n )}\n </div>\n );\n })\n);\n"],"names":["useCallback","useEffect","useMemo","Fragment","observer","classNames","Stack","provide","useDependencies","useClientRect","LineChartStore","SvgStore","getXLabels","Sidebar","MetricsTitle","XAxisLabels","SvgBody","SvgBodyHover","HoverPopover","Styles","Body","singletons","classNameTitle","display","metrics","left","right","periods","resolution","setHoveredIndex","svgStore","init","length","maxValue","rect","ref","onBarHover","ind","onBarLeave","labels","xLabels","width","div","className","alignItems","settings","Item","fill","chartWrapper","yLeft","yRight","labelBorders","map","text","flex","key","style","horizontalGrid","yGrid","onValueHover","onValueLeave","justifyContent","labelsMerged","hasBars","filter","m","type","metricsTitlePosition","direction"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/body.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, FC, Fragment } from 'react';\nimport { observer } from 'mobx-react';\nimport classNames from 'classnames';\nimport { Stack } from '@servicetitan/design-system';\nimport { provide, useDependencies } from '@servicetitan/react-ioc';\n\nimport { useClientRect } from '../../../../utils/use-client-rect';\nimport { LineChartStore } from '../stores/line-chart.store';\nimport { SvgStore } from '../stores/svg.store';\nimport { getXLabels } from '../utils/labels';\n\nimport { Sidebar } from './sidebar';\nimport { MetricsTitle, XAxisLabels } from './stuff';\nimport { SvgBody, SvgBodyHover } from './svg-body';\nimport { HoverPopover } from './hover-popover';\nimport * as Styles from './body.module.less';\n\nexport const Body: FC<{ classNameTitle?: string }> = provide({ singletons: [SvgStore] })(\n observer(({ classNameTitle }) => {\n const [{ display, metrics, left, right, periods, resolution, setHoveredIndex }, svgStore] =\n useDependencies(LineChartStore, SvgStore);\n\n useEffect(() => {\n svgStore.init(periods.length, metrics, left?.maxValue ?? 0, right?.maxValue ?? 0);\n }, [svgStore, periods, metrics, left, right]);\n const [rect, ref] = useClientRect();\n\n const onBarHover = useCallback(\n (ind: number) => setHoveredIndex(ind, true),\n [setHoveredIndex]\n );\n\n const onBarLeave = useCallback(\n (ind: number) => setHoveredIndex(ind, false),\n [setHoveredIndex]\n );\n\n const labels = useMemo(\n () => (display.xLabels ? getXLabels(periods, resolution, rect?.width ?? 0) : []),\n [display, periods, resolution, rect]\n );\n\n return (\n <div className=\"d-f flex-column\">\n <Stack alignItems=\"stretch\">\n {left && <Sidebar settings={left} classNameTitle={classNameTitle} />}\n <Stack.Item fill>\n <div\n ref={ref}\n className={classNames(Styles.chartWrapper, 'border-bottom', {\n 'border-left': !!left && display.yLeft,\n 'border-right': !!right && display.yRight,\n })}\n >\n {periods.length ? (\n <Fragment>\n {periods.length !== labels.length && (\n <div className={Styles.labelBorders}>\n {labels\n .map(([text, flex], ind) => [flex, `${ind}${text}`])\n .map(([flex, key]) => (\n <div key={key} style={{ flex }} />\n ))}\n </div>\n )}\n\n <SvgBody horizontalGrid={display.yGrid} metrics={metrics} />\n <HoverPopover />\n <SvgBodyHover\n onValueHover={onBarHover}\n onValueLeave={onBarLeave}\n />\n </Fragment>\n ) : (\n <Stack\n className=\"h-100\"\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n No Data\n </Stack>\n )}\n </div>\n </Stack.Item>\n {right && <Sidebar settings={right} right classNameTitle={classNameTitle} />}\n </Stack>\n {display.xLabels && (\n <XAxisLabels\n labels={labels}\n width={rect?.width ?? 0}\n left={left?.width ?? 0}\n right={right?.width ?? 0}\n labelsMerged={periods.length !== labels.length}\n hasBars={\n !!metrics.filter(\n m =>\n m.type === 'bar' ||\n m.type === 'stacked-bar' ||\n m.type === 'grouped-bar'\n ).length\n }\n />\n )}\n {display.metricsTitlePosition === 'bottom' && (\n <Stack direction=\"row\" justifyContent=\"flex-start\" className=\"p-t-3 p-x-5\">\n <MetricsTitle metrics={metrics} />\n </Stack>\n )}\n </div>\n );\n })\n);\n"],"names":["useCallback","useEffect","useMemo","Fragment","observer","classNames","Stack","provide","useDependencies","useClientRect","LineChartStore","SvgStore","getXLabels","Sidebar","MetricsTitle","XAxisLabels","SvgBody","SvgBodyHover","HoverPopover","Styles","Body","singletons","classNameTitle","display","metrics","left","right","periods","resolution","setHoveredIndex","svgStore","init","length","maxValue","rect","ref","onBarHover","ind","onBarLeave","labels","xLabels","width","div","className","alignItems","settings","Item","fill","chartWrapper","yLeft","yRight","labelBorders","map","text","flex","key","style","horizontalGrid","yGrid","onValueHover","onValueLeave","justifyContent","labelsMerged","hasBars","filter","m","type","metricsTitlePosition","direction"],"mappings":"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"}
@@ -41,11 +41,11 @@ export const SvgBars = observer(({ metrics, isStackedBarChart, isGroupedBarChart
41
41
  for(let i = 0; i < length; i++){
42
42
  const x = store.periodX(i);
43
43
  const values = metrics.map((m)=>{
44
+ var _ref;
44
45
  var _m_valuesOpts_i, _m_valuesOpts, _m_opts, _m_opts1, _m_opts2;
45
- var _m_valuesOpts_i_color;
46
46
  return {
47
47
  id: m.id,
48
- color: (_m_valuesOpts_i_color = (_m_valuesOpts = m.valuesOpts) === null || _m_valuesOpts === void 0 ? void 0 : (_m_valuesOpts_i = _m_valuesOpts[i]) === null || _m_valuesOpts_i === void 0 ? void 0 : _m_valuesOpts_i.color) !== null && _m_valuesOpts_i_color !== void 0 ? _m_valuesOpts_i_color : m.color,
48
+ color: (_ref = (_m_valuesOpts = m.valuesOpts) === null || _m_valuesOpts === void 0 ? void 0 : (_m_valuesOpts_i = _m_valuesOpts[i]) === null || _m_valuesOpts_i === void 0 ? void 0 : _m_valuesOpts_i.color) !== null && _ref !== void 0 ? _ref : m.color,
49
49
  opacity: m.opacity,
50
50
  val: store.periodY(m, i),
51
51
  pattern: (_m_opts = m.opts) === null || _m_opts === void 0 ? void 0 : _m_opts.pattern,
@@ -94,6 +94,7 @@ export const SvgBars = observer(({ metrics, isStackedBarChart, isGroupedBarChart
94
94
  }, `total-${i}`));
95
95
  }
96
96
  for(let j = 0; j < values.length; j++){
97
+ var _value_strokeColor;
97
98
  const value = values[j];
98
99
  stackedBarHeight -= spacingBetweenSegments;
99
100
  const TOP_RADIUS = 1;
@@ -117,7 +118,6 @@ export const SvgBars = observer(({ metrics, isStackedBarChart, isGroupedBarChart
117
118
  `L ${xLeft + width} ${yTop + height}`,
118
119
  'Z'
119
120
  ].join(' ');
120
- var _value_strokeColor;
121
121
  paths.push(/*#__PURE__*/ _jsx("path", {
122
122
  d: d,
123
123
  fill: value.pattern === 'striped' ? `url(#stripe-pattern-${value.id})` : value.color,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/svg-bars.tsx"],"sourcesContent":["import { FC } from 'react';\nimport { observer } from 'mobx-react';\nimport { useDependencies } from '@servicetitan/react-ioc';\nimport { ChartMetric } from '../utils/internal-interfaces';\nimport { keyVal } from '../utils/key';\nimport { SvgStore } from '../stores/svg.store';\n\ninterface SvgBarsProps {\n metrics: ChartMetric[];\n isStackedBarChart?: boolean;\n isGroupedBarChart?: boolean;\n}\n\nexport const SvgBars: FC<SvgBarsProps> = observer(\n ({ metrics, isStackedBarChart, isGroupedBarChart }) => {\n const [store] = useDependencies(SvgStore);\n const { fpx, fpy, barWidth, length } = store;\n const barWidthHalf = barWidth / 2;\n const paths = [];\n\n const patternDefs = metrics\n .filter(m => m.opts?.pattern === 'striped')\n .map(m => {\n const rotation = 20;\n const tileW = 0.6;\n const tileH = 0.6;\n const stripeWidth = Math.max(0.1, Math.floor(tileW / 20));\n const tintOpacity = 0.06;\n\n return (\n <pattern\n key={`pattern-${m.id}`}\n id={`stripe-pattern-${m.id}`}\n patternUnits=\"userSpaceOnUse\"\n width={tileW}\n height={tileH}\n patternTransform={`rotate(${rotation})`}\n >\n <rect width={tileW} height={tileH} fill={m.color} opacity={tintOpacity} />\n <rect width={stripeWidth} height={tileH} fill={m.color} />\n </pattern>\n );\n });\n\n for (let i = 0; i < length; i++) {\n const x = store.periodX(i);\n const values = metrics.map(m => ({\n id: m.id,\n color: m.valuesOpts?.[i]?.color ?? m.color,\n opacity: m.opacity,\n val: store.periodY(m, i),\n pattern: m.opts?.pattern,\n strokeColor: m.opts?.strokeColor,\n outlineColor: m.opts?.outlineColor,\n value: m.values[i],\n }));\n\n if (isStackedBarChart) {\n // Use ORIGINAL calculations - keep all spacing/positioning unchanged\n const spacingBetweenSegments = 1;\n const totalSpacing = (values.length - 1) * spacingBetweenSegments;\n let stackedBarHeight =\n values.reduce((sum, curr) => sum + curr.val, 0) + totalSpacing;\n\n // Find first/last non-zero indices for visual styling\n const firstNonZeroIdx = values.findIndex(v => v.value > 0);\n const lastNonZeroIdx = values.reduce(\n (last, v, idx) => (v.value > 0 ? idx : last),\n -1\n );\n\n // Count 0-value segments below first non-zero (for text position adjustment)\n const zeroSegmentsBelowFirst =\n firstNonZeroIdx >= 0\n ? values.slice(firstNonZeroIdx + 1).filter(v => v.value <= 0).length\n : 0;\n\n const totalValue = values.reduce((sum, curr) => sum + curr.value, 0);\n if (totalValue > 0) {\n /*\n * Adjust text position to maintain consistent gap with first rendered segment:\n * 1. Subtract spacing for skipped segments from fpy argument\n * 2. Add pixel offset for zeros below first non-zero\n */\n const textStackedBarHeight =\n stackedBarHeight -\n (firstNonZeroIdx > 0 ? firstNonZeroIdx : 0) * spacingBetweenSegments;\n const yTop =\n +fpy(textStackedBarHeight) +\n zeroSegmentsBelowFirst * spacingBetweenSegments;\n const scaleX = 0.3;\n const scaleY = 1;\n\n paths.push(\n <g\n key={`total-${i}`}\n transform={`translate(${x},${yTop}) scale(${scaleX},${scaleY})`}\n pointerEvents=\"none\"\n >\n <text\n x={0}\n y={0}\n textAnchor=\"middle\"\n dominantBaseline=\"alphabetic\"\n fontSize=\"2.5\"\n fontWeight={600}\n fill=\"#111827\"\n stroke=\"white\"\n strokeWidth={0.8}\n paintOrder=\"stroke\"\n fontFamily=\"Nunito Sans\"\n >\n {Math.round(totalValue)}\n </text>\n </g>\n );\n }\n\n for (let j = 0; j < values.length; j++) {\n const value = values[j];\n stackedBarHeight -= spacingBetweenSegments;\n\n const TOP_RADIUS = 1;\n const xLeft = +fpx(x - barWidth / 2);\n const width = +fpx(barWidth);\n\n if (value.value <= 0) {\n stackedBarHeight -= value.val;\n continue;\n }\n const zeroSegments = values.slice(j + 1).filter(v => v.value <= 0).length;\n\n // Adjust yTop: move down by the space 0-value segments would occupy\n const yTop =\n +fpy(stackedBarHeight) +\n (values.length - 2) +\n zeroSegments * spacingBetweenSegments;\n const height = j === lastNonZeroIdx ? +fpx(value.val - 2) : +fpx(value.val);\n const r = j === firstNonZeroIdx ? TOP_RADIUS : 0;\n\n const d = [\n `M ${xLeft} ${yTop + height}`, // bottom-left\n `L ${xLeft} ${yTop + r}`, // up left edge\n `Q ${xLeft} ${yTop} ${xLeft + r / 2} ${yTop}`, // top-left corner\n `L ${xLeft + width - r / 2} ${yTop}`, // across top\n `Q ${xLeft + width} ${yTop} ${xLeft + width} ${yTop + r}`, // top-right corner\n `L ${xLeft + width} ${yTop + height}`, // down right edge\n 'Z',\n ].join(' ');\n paths.push(\n <path\n key={keyVal(value.id, i)}\n d={d}\n fill={\n value.pattern === 'striped'\n ? `url(#stripe-pattern-${value.id})`\n : value.color\n }\n stroke={\n value.pattern === 'outline'\n ? value.outlineColor\n : (value.strokeColor ?? value.color)\n }\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n strokeLinejoin=\"round\"\n />\n );\n\n stackedBarHeight -= value.val;\n }\n } else if (isGroupedBarChart) {\n for (let j = 0; j < values.length; j++) {\n const groupedBarX = (j * barWidth) / values.length;\n const value = values[j];\n\n paths.push(\n <rect\n key={keyVal(value.id, i)}\n x={x + groupedBarX - barWidthHalf}\n y={fpy(value.val)}\n width={barWidth / values.length - 0.1}\n height={fpx(value.val)}\n fill={value.color}\n opacity={value.opacity}\n />\n );\n }\n } else {\n values.sort((a, b) => b.val - a.val);\n for (const value of values) {\n paths.push(\n <rect\n key={keyVal(value.id, i)}\n x={fpx(x - barWidthHalf)}\n y={fpy(value.val)}\n width={fpx(barWidth)}\n height={fpx(value.val)}\n fill={value.color}\n />\n );\n }\n }\n }\n\n return (\n <g>\n {patternDefs.length > 0 && <defs>{patternDefs}</defs>}\n {paths}\n </g>\n );\n }\n);\n\ninterface SvgBarsHoverProps {\n onHover(ind: number): void;\n onLeave(ind: number): void;\n}\n\nexport const SvgBarsHover: FC<SvgBarsHoverProps> = observer(({ onHover, onLeave }) => {\n const [store] = useDependencies(SvgStore);\n const { fpx, fpy, barWidth, length } = store;\n const barWidthHalf = barWidth / 2;\n const paths = [];\n\n for (let i = 0; i < length; i++) {\n const x = store.periodX(i);\n\n paths.push(\n <rect\n key={keyVal('_', i)}\n onMouseEnter={() => onHover(i)}\n onMouseLeave={() => onLeave(i)}\n x={fpx(x - barWidthHalf)}\n y={fpy(100)}\n width={fpx(barWidth)}\n height=\"100%\"\n fill=\"white\"\n fillOpacity=\"0\"\n />\n );\n }\n\n return <g>{paths}</g>;\n});\n"],"names":["observer","useDependencies","keyVal","SvgStore","SvgBars","metrics","isStackedBarChart","isGroupedBarChart","store","fpx","fpy","barWidth","length","barWidthHalf","paths","patternDefs","filter","m","opts","pattern","map","rotation","tileW","tileH","stripeWidth","Math","max","floor","tintOpacity","id","patternUnits","width","height","patternTransform","rect","fill","color","opacity","i","x","periodX","values","valuesOpts","val","periodY","strokeColor","outlineColor","value","spacingBetweenSegments","totalSpacing","stackedBarHeight","reduce","sum","curr","firstNonZeroIdx","findIndex","v","lastNonZeroIdx","last","idx","zeroSegmentsBelowFirst","slice","totalValue","textStackedBarHeight","yTop","scaleX","scaleY","push","g","transform","pointerEvents","text","y","textAnchor","dominantBaseline","fontSize","fontWeight","stroke","strokeWidth","paintOrder","fontFamily","round","j","TOP_RADIUS","xLeft","zeroSegments","r","d","join","path","vectorEffect","strokeLinejoin","groupedBarX","sort","a","b","defs","SvgBarsHover","onHover","onLeave","onMouseEnter","onMouseLeave","fillOpacity"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/svg-bars.tsx"],"sourcesContent":["import { FC } from 'react';\nimport { observer } from 'mobx-react';\nimport { useDependencies } from '@servicetitan/react-ioc';\nimport { ChartMetric } from '../utils/internal-interfaces';\nimport { keyVal } from '../utils/key';\nimport { SvgStore } from '../stores/svg.store';\n\ninterface SvgBarsProps {\n metrics: ChartMetric[];\n isStackedBarChart?: boolean;\n isGroupedBarChart?: boolean;\n}\n\nexport const SvgBars: FC<SvgBarsProps> = observer(\n ({ metrics, isStackedBarChart, isGroupedBarChart }) => {\n const [store] = useDependencies(SvgStore);\n const { fpx, fpy, barWidth, length } = store;\n const barWidthHalf = barWidth / 2;\n const paths = [];\n\n const patternDefs = metrics\n .filter(m => m.opts?.pattern === 'striped')\n .map(m => {\n const rotation = 20;\n const tileW = 0.6;\n const tileH = 0.6;\n const stripeWidth = Math.max(0.1, Math.floor(tileW / 20));\n const tintOpacity = 0.06;\n\n return (\n <pattern\n key={`pattern-${m.id}`}\n id={`stripe-pattern-${m.id}`}\n patternUnits=\"userSpaceOnUse\"\n width={tileW}\n height={tileH}\n patternTransform={`rotate(${rotation})`}\n >\n <rect width={tileW} height={tileH} fill={m.color} opacity={tintOpacity} />\n <rect width={stripeWidth} height={tileH} fill={m.color} />\n </pattern>\n );\n });\n\n for (let i = 0; i < length; i++) {\n const x = store.periodX(i);\n const values = metrics.map(m => ({\n id: m.id,\n color: m.valuesOpts?.[i]?.color ?? m.color,\n opacity: m.opacity,\n val: store.periodY(m, i),\n pattern: m.opts?.pattern,\n strokeColor: m.opts?.strokeColor,\n outlineColor: m.opts?.outlineColor,\n value: m.values[i],\n }));\n\n if (isStackedBarChart) {\n // Use ORIGINAL calculations - keep all spacing/positioning unchanged\n const spacingBetweenSegments = 1;\n const totalSpacing = (values.length - 1) * spacingBetweenSegments;\n let stackedBarHeight =\n values.reduce((sum, curr) => sum + curr.val, 0) + totalSpacing;\n\n // Find first/last non-zero indices for visual styling\n const firstNonZeroIdx = values.findIndex(v => v.value > 0);\n const lastNonZeroIdx = values.reduce(\n (last, v, idx) => (v.value > 0 ? idx : last),\n -1\n );\n\n // Count 0-value segments below first non-zero (for text position adjustment)\n const zeroSegmentsBelowFirst =\n firstNonZeroIdx >= 0\n ? values.slice(firstNonZeroIdx + 1).filter(v => v.value <= 0).length\n : 0;\n\n const totalValue = values.reduce((sum, curr) => sum + curr.value, 0);\n if (totalValue > 0) {\n /*\n * Adjust text position to maintain consistent gap with first rendered segment:\n * 1. Subtract spacing for skipped segments from fpy argument\n * 2. Add pixel offset for zeros below first non-zero\n */\n const textStackedBarHeight =\n stackedBarHeight -\n (firstNonZeroIdx > 0 ? firstNonZeroIdx : 0) * spacingBetweenSegments;\n const yTop =\n +fpy(textStackedBarHeight) +\n zeroSegmentsBelowFirst * spacingBetweenSegments;\n const scaleX = 0.3;\n const scaleY = 1;\n\n paths.push(\n <g\n key={`total-${i}`}\n transform={`translate(${x},${yTop}) scale(${scaleX},${scaleY})`}\n pointerEvents=\"none\"\n >\n <text\n x={0}\n y={0}\n textAnchor=\"middle\"\n dominantBaseline=\"alphabetic\"\n fontSize=\"2.5\"\n fontWeight={600}\n fill=\"#111827\"\n stroke=\"white\"\n strokeWidth={0.8}\n paintOrder=\"stroke\"\n fontFamily=\"Nunito Sans\"\n >\n {Math.round(totalValue)}\n </text>\n </g>\n );\n }\n\n for (let j = 0; j < values.length; j++) {\n const value = values[j];\n stackedBarHeight -= spacingBetweenSegments;\n\n const TOP_RADIUS = 1;\n const xLeft = +fpx(x - barWidth / 2);\n const width = +fpx(barWidth);\n\n if (value.value <= 0) {\n stackedBarHeight -= value.val;\n continue;\n }\n const zeroSegments = values.slice(j + 1).filter(v => v.value <= 0).length;\n\n // Adjust yTop: move down by the space 0-value segments would occupy\n const yTop =\n +fpy(stackedBarHeight) +\n (values.length - 2) +\n zeroSegments * spacingBetweenSegments;\n const height = j === lastNonZeroIdx ? +fpx(value.val - 2) : +fpx(value.val);\n const r = j === firstNonZeroIdx ? TOP_RADIUS : 0;\n\n const d = [\n `M ${xLeft} ${yTop + height}`, // bottom-left\n `L ${xLeft} ${yTop + r}`, // up left edge\n `Q ${xLeft} ${yTop} ${xLeft + r / 2} ${yTop}`, // top-left corner\n `L ${xLeft + width - r / 2} ${yTop}`, // across top\n `Q ${xLeft + width} ${yTop} ${xLeft + width} ${yTop + r}`, // top-right corner\n `L ${xLeft + width} ${yTop + height}`, // down right edge\n 'Z',\n ].join(' ');\n paths.push(\n <path\n key={keyVal(value.id, i)}\n d={d}\n fill={\n value.pattern === 'striped'\n ? `url(#stripe-pattern-${value.id})`\n : value.color\n }\n stroke={\n value.pattern === 'outline'\n ? value.outlineColor\n : (value.strokeColor ?? value.color)\n }\n strokeWidth={1}\n vectorEffect=\"non-scaling-stroke\"\n strokeLinejoin=\"round\"\n />\n );\n\n stackedBarHeight -= value.val;\n }\n } else if (isGroupedBarChart) {\n for (let j = 0; j < values.length; j++) {\n const groupedBarX = (j * barWidth) / values.length;\n const value = values[j];\n\n paths.push(\n <rect\n key={keyVal(value.id, i)}\n x={x + groupedBarX - barWidthHalf}\n y={fpy(value.val)}\n width={barWidth / values.length - 0.1}\n height={fpx(value.val)}\n fill={value.color}\n opacity={value.opacity}\n />\n );\n }\n } else {\n values.sort((a, b) => b.val - a.val);\n for (const value of values) {\n paths.push(\n <rect\n key={keyVal(value.id, i)}\n x={fpx(x - barWidthHalf)}\n y={fpy(value.val)}\n width={fpx(barWidth)}\n height={fpx(value.val)}\n fill={value.color}\n />\n );\n }\n }\n }\n\n return (\n <g>\n {patternDefs.length > 0 && <defs>{patternDefs}</defs>}\n {paths}\n </g>\n );\n }\n);\n\ninterface SvgBarsHoverProps {\n onHover(ind: number): void;\n onLeave(ind: number): void;\n}\n\nexport const SvgBarsHover: FC<SvgBarsHoverProps> = observer(({ onHover, onLeave }) => {\n const [store] = useDependencies(SvgStore);\n const { fpx, fpy, barWidth, length } = store;\n const barWidthHalf = barWidth / 2;\n const paths = [];\n\n for (let i = 0; i < length; i++) {\n const x = store.periodX(i);\n\n paths.push(\n <rect\n key={keyVal('_', i)}\n onMouseEnter={() => onHover(i)}\n onMouseLeave={() => onLeave(i)}\n x={fpx(x - barWidthHalf)}\n y={fpy(100)}\n width={fpx(barWidth)}\n height=\"100%\"\n fill=\"white\"\n fillOpacity=\"0\"\n />\n );\n }\n\n return <g>{paths}</g>;\n});\n"],"names":["observer","useDependencies","keyVal","SvgStore","SvgBars","metrics","isStackedBarChart","isGroupedBarChart","store","fpx","fpy","barWidth","length","barWidthHalf","paths","patternDefs","filter","m","opts","pattern","map","rotation","tileW","tileH","stripeWidth","Math","max","floor","tintOpacity","id","patternUnits","width","height","patternTransform","rect","fill","color","opacity","i","x","periodX","values","valuesOpts","val","periodY","strokeColor","outlineColor","value","spacingBetweenSegments","totalSpacing","stackedBarHeight","reduce","sum","curr","firstNonZeroIdx","findIndex","v","lastNonZeroIdx","last","idx","zeroSegmentsBelowFirst","slice","totalValue","textStackedBarHeight","yTop","scaleX","scaleY","push","g","transform","pointerEvents","text","y","textAnchor","dominantBaseline","fontSize","fontWeight","stroke","strokeWidth","paintOrder","fontFamily","round","j","TOP_RADIUS","xLeft","zeroSegments","r","d","join","path","vectorEffect","strokeLinejoin","groupedBarX","sort","a","b","defs","SvgBarsHover","onHover","onLeave","onMouseEnter","onMouseLeave","fillOpacity"],"mappings":"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"}
@@ -15,6 +15,7 @@ const SvgLine = ({ color, points, dashed })=>/*#__PURE__*/ _jsx("path", {
15
15
  export const SvgLines = observer(({ metrics })=>{
16
16
  const [store] = useDependencies(SvgStore);
17
17
  const lines = useMemo(()=>metrics.map((m)=>{
18
+ var _ref;
18
19
  var _m_opts;
19
20
  const points = m.values.map((val, ind)=>[
20
21
  store.periodX(ind),
@@ -29,7 +30,6 @@ export const SvgLines = observer(({ metrics })=>{
29
30
  points[l][1] = (x1 * points[l][1] - x2 * points[l - 1][1]) / (x1 - x2);
30
31
  points[l][0] = 100;
31
32
  }
32
- var _m_opts_dashed;
33
33
  return {
34
34
  id: m.id,
35
35
  color: m.color,
@@ -37,7 +37,7 @@ export const SvgLines = observer(({ metrics })=>{
37
37
  store.fpx(x),
38
38
  store.fpy(y)
39
39
  ]),
40
- dashed: (_m_opts_dashed = (_m_opts = m.opts) === null || _m_opts === void 0 ? void 0 : _m_opts.dashed) !== null && _m_opts_dashed !== void 0 ? _m_opts_dashed : false
40
+ dashed: (_ref = (_m_opts = m.opts) === null || _m_opts === void 0 ? void 0 : _m_opts.dashed) !== null && _ref !== void 0 ? _ref : false
41
41
  };
42
42
  }), [
43
43
  store,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/svg-lines.tsx"],"sourcesContent":["import { useMemo, FC } from 'react';\nimport { observer } from 'mobx-react';\nimport { useDependencies } from '@servicetitan/react-ioc';\nimport { ChartMetric } from '../utils/internal-interfaces';\nimport { SvgStore } from '../stores/svg.store';\nimport * as Styles from './svg.module.less';\n\ninterface SvgLineProps {\n color: string;\n points: string[][];\n dashed: boolean;\n}\n\nconst SvgLine: FC<SvgLineProps> = ({ color, points, dashed }) => (\n <path\n className={Styles.line}\n d={points.map(([px, py], ind) => (ind === 0 ? 'M' : 'L') + `${px} ${py}`).join(' ')}\n fill=\"transparent\"\n stroke={color}\n strokeWidth=\"3\"\n strokeDasharray={dashed ? '5,5' : undefined}\n />\n);\n\ninterface SvgLinesProps {\n metrics: ChartMetric[];\n}\n\nexport const SvgLines: FC<SvgLinesProps> = observer(({ metrics }) => {\n const [store] = useDependencies(SvgStore);\n\n const lines = useMemo(\n () =>\n metrics.map(m => {\n const points = m.values.map((val, ind) => [\n store.periodX(ind),\n store.periodY(m, ind),\n ]);\n\n if (store.xOffset && points.length > 1) {\n points[0][1] =\n (points[1][0] * points[0][1] - points[0][0] * points[1][1]) /\n (points[1][0] - points[0][0]);\n points[0][0] = 0;\n\n const l = points.length - 1;\n const x1 = 100 - points[l - 1][0];\n const x2 = 100 - points[l][0];\n\n points[l][1] = (x1 * points[l][1] - x2 * points[l - 1][1]) / (x1 - x2);\n points[l][0] = 100;\n }\n\n return {\n id: m.id,\n color: m.color,\n points: points.map(([x, y]) => [store.fpx(x), store.fpy(y)]),\n dashed: m.opts?.dashed ?? false,\n };\n }),\n [store, metrics]\n );\n\n return (\n <g>\n {lines.map(({ id, color, points, dashed }) => (\n <SvgLine key={id} color={color} points={points} dashed={dashed} />\n ))}\n </g>\n );\n});\n"],"names":["useMemo","observer","useDependencies","SvgStore","Styles","SvgLine","color","points","dashed","path","className","line","d","map","px","py","ind","join","fill","stroke","strokeWidth","strokeDasharray","undefined","SvgLines","metrics","store","lines","m","values","val","periodX","periodY","xOffset","length","l","x1","x2","id","x","y","fpx","fpy","opts","g"],"mappings":";AAAA,SAASA,OAAO,QAAY,QAAQ;AACpC,SAASC,QAAQ,QAAQ,aAAa;AACtC,SAASC,eAAe,QAAQ,0BAA0B;AAE1D,SAASC,QAAQ,QAAQ,sBAAsB;AAC/C,YAAYC,YAAY,oBAAoB;AAQ5C,MAAMC,UAA4B,CAAC,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAE,iBACxD,KAACC;QACGC,WAAWN,OAAOO,IAAI;QACtBC,GAAGL,OAAOM,GAAG,CAAC,CAAC,CAACC,IAAIC,GAAG,EAAEC,MAAQ,AAACA,CAAAA,QAAQ,IAAI,MAAM,GAAE,IAAK,GAAGF,GAAG,CAAC,EAAEC,IAAI,EAAEE,IAAI,CAAC;QAC/EC,MAAK;QACLC,QAAQb;QACRc,aAAY;QACZC,iBAAiBb,SAAS,QAAQc;;AAQ1C,OAAO,MAAMC,WAA8BtB,SAAS,CAAC,EAAEuB,OAAO,EAAE;IAC5D,MAAM,CAACC,MAAM,GAAGvB,gBAAgBC;IAEhC,MAAMuB,QAAQ1B,QACV,IACIwB,QAAQX,GAAG,CAACc,CAAAA;gBAwBIA;YAvBZ,MAAMpB,SAASoB,EAAEC,MAAM,CAACf,GAAG,CAAC,CAACgB,KAAKb,MAAQ;oBACtCS,MAAMK,OAAO,CAACd;oBACdS,MAAMM,OAAO,CAACJ,GAAGX;iBACpB;YAED,IAAIS,MAAMO,OAAO,IAAIzB,OAAO0B,MAAM,GAAG,GAAG;gBACpC1B,MAAM,CAAC,EAAE,CAAC,EAAE,GACR,AAACA,CAAAA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAGA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAGA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAGA,MAAM,CAAC,EAAE,CAAC,EAAE,AAAD,IACxDA,CAAAA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAGA,MAAM,CAAC,EAAE,CAAC,EAAE,AAAD;gBAC/BA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG;gBAEf,MAAM2B,IAAI3B,OAAO0B,MAAM,GAAG;gBAC1B,MAAME,KAAK,MAAM5B,MAAM,CAAC2B,IAAI,EAAE,CAAC,EAAE;gBACjC,MAAME,KAAK,MAAM7B,MAAM,CAAC2B,EAAE,CAAC,EAAE;gBAE7B3B,MAAM,CAAC2B,EAAE,CAAC,EAAE,GAAG,AAACC,CAAAA,KAAK5B,MAAM,CAAC2B,EAAE,CAAC,EAAE,GAAGE,KAAK7B,MAAM,CAAC2B,IAAI,EAAE,CAAC,EAAE,AAAD,IAAMC,CAAAA,KAAKC,EAAC;gBACpE7B,MAAM,CAAC2B,EAAE,CAAC,EAAE,GAAG;YACnB;gBAMYP;YAJZ,OAAO;gBACHU,IAAIV,EAAEU,EAAE;gBACR/B,OAAOqB,EAAErB,KAAK;gBACdC,QAAQA,OAAOM,GAAG,CAAC,CAAC,CAACyB,GAAGC,EAAE,GAAK;wBAACd,MAAMe,GAAG,CAACF;wBAAIb,MAAMgB,GAAG,CAACF;qBAAG;gBAC3D/B,QAAQmB,CAAAA,kBAAAA,UAAAA,EAAEe,IAAI,cAANf,8BAAAA,QAAQnB,MAAM,cAAdmB,4BAAAA,iBAAkB;YAC9B;QACJ,IACJ;QAACF;QAAOD;KAAQ;IAGpB,qBACI,KAACmB;kBACIjB,MAAMb,GAAG,CAAC,CAAC,EAAEwB,EAAE,EAAE/B,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAE,iBACrC,KAACH;gBAAiBC,OAAOA;gBAAOC,QAAQA;gBAAQC,QAAQA;eAA1C6B;;AAI9B,GAAG"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/line-chart/components/svg-lines.tsx"],"sourcesContent":["import { useMemo, FC } from 'react';\nimport { observer } from 'mobx-react';\nimport { useDependencies } from '@servicetitan/react-ioc';\nimport { ChartMetric } from '../utils/internal-interfaces';\nimport { SvgStore } from '../stores/svg.store';\nimport * as Styles from './svg.module.less';\n\ninterface SvgLineProps {\n color: string;\n points: string[][];\n dashed: boolean;\n}\n\nconst SvgLine: FC<SvgLineProps> = ({ color, points, dashed }) => (\n <path\n className={Styles.line}\n d={points.map(([px, py], ind) => (ind === 0 ? 'M' : 'L') + `${px} ${py}`).join(' ')}\n fill=\"transparent\"\n stroke={color}\n strokeWidth=\"3\"\n strokeDasharray={dashed ? '5,5' : undefined}\n />\n);\n\ninterface SvgLinesProps {\n metrics: ChartMetric[];\n}\n\nexport const SvgLines: FC<SvgLinesProps> = observer(({ metrics }) => {\n const [store] = useDependencies(SvgStore);\n\n const lines = useMemo(\n () =>\n metrics.map(m => {\n const points = m.values.map((val, ind) => [\n store.periodX(ind),\n store.periodY(m, ind),\n ]);\n\n if (store.xOffset && points.length > 1) {\n points[0][1] =\n (points[1][0] * points[0][1] - points[0][0] * points[1][1]) /\n (points[1][0] - points[0][0]);\n points[0][0] = 0;\n\n const l = points.length - 1;\n const x1 = 100 - points[l - 1][0];\n const x2 = 100 - points[l][0];\n\n points[l][1] = (x1 * points[l][1] - x2 * points[l - 1][1]) / (x1 - x2);\n points[l][0] = 100;\n }\n\n return {\n id: m.id,\n color: m.color,\n points: points.map(([x, y]) => [store.fpx(x), store.fpy(y)]),\n dashed: m.opts?.dashed ?? false,\n };\n }),\n [store, metrics]\n );\n\n return (\n <g>\n {lines.map(({ id, color, points, dashed }) => (\n <SvgLine key={id} color={color} points={points} dashed={dashed} />\n ))}\n </g>\n );\n});\n"],"names":["useMemo","observer","useDependencies","SvgStore","Styles","SvgLine","color","points","dashed","path","className","line","d","map","px","py","ind","join","fill","stroke","strokeWidth","strokeDasharray","undefined","SvgLines","metrics","store","lines","m","values","val","periodX","periodY","xOffset","length","l","x1","x2","id","x","y","fpx","fpy","opts","g"],"mappings":";AAAA,SAASA,OAAO,QAAY,QAAQ;AACpC,SAASC,QAAQ,QAAQ,aAAa;AACtC,SAASC,eAAe,QAAQ,0BAA0B;AAE1D,SAASC,QAAQ,QAAQ,sBAAsB;AAC/C,YAAYC,YAAY,oBAAoB;AAQ5C,MAAMC,UAA4B,CAAC,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAE,iBACxD,KAACC;QACGC,WAAWN,OAAOO,IAAI;QACtBC,GAAGL,OAAOM,GAAG,CAAC,CAAC,CAACC,IAAIC,GAAG,EAAEC,MAAQ,AAACA,CAAAA,QAAQ,IAAI,MAAM,GAAE,IAAK,GAAGF,GAAG,CAAC,EAAEC,IAAI,EAAEE,IAAI,CAAC;QAC/EC,MAAK;QACLC,QAAQb;QACRc,aAAY;QACZC,iBAAiBb,SAAS,QAAQc;;AAQ1C,OAAO,MAAMC,WAA8BtB,SAAS,CAAC,EAAEuB,OAAO,EAAE;IAC5D,MAAM,CAACC,MAAM,GAAGvB,gBAAgBC;IAEhC,MAAMuB,QAAQ1B,QACV,IACIwB,QAAQX,GAAG,CAACc,CAAAA;;gBAwBIA;YAvBZ,MAAMpB,SAASoB,EAAEC,MAAM,CAACf,GAAG,CAAC,CAACgB,KAAKb,MAAQ;oBACtCS,MAAMK,OAAO,CAACd;oBACdS,MAAMM,OAAO,CAACJ,GAAGX;iBACpB;YAED,IAAIS,MAAMO,OAAO,IAAIzB,OAAO0B,MAAM,GAAG,GAAG;gBACpC1B,MAAM,CAAC,EAAE,CAAC,EAAE,GACR,AAACA,CAAAA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAGA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAGA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAGA,MAAM,CAAC,EAAE,CAAC,EAAE,AAAD,IACxDA,CAAAA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAGA,MAAM,CAAC,EAAE,CAAC,EAAE,AAAD;gBAC/BA,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG;gBAEf,MAAM2B,IAAI3B,OAAO0B,MAAM,GAAG;gBAC1B,MAAME,KAAK,MAAM5B,MAAM,CAAC2B,IAAI,EAAE,CAAC,EAAE;gBACjC,MAAME,KAAK,MAAM7B,MAAM,CAAC2B,EAAE,CAAC,EAAE;gBAE7B3B,MAAM,CAAC2B,EAAE,CAAC,EAAE,GAAG,AAACC,CAAAA,KAAK5B,MAAM,CAAC2B,EAAE,CAAC,EAAE,GAAGE,KAAK7B,MAAM,CAAC2B,IAAI,EAAE,CAAC,EAAE,AAAD,IAAMC,CAAAA,KAAKC,EAAC;gBACpE7B,MAAM,CAAC2B,EAAE,CAAC,EAAE,GAAG;YACnB;YAEA,OAAO;gBACHG,IAAIV,EAAEU,EAAE;gBACR/B,OAAOqB,EAAErB,KAAK;gBACdC,QAAQA,OAAOM,GAAG,CAAC,CAAC,CAACyB,GAAGC,EAAE,GAAK;wBAACd,MAAMe,GAAG,CAACF;wBAAIb,MAAMgB,GAAG,CAACF;qBAAG;gBAC3D/B,MAAM,WAAEmB,UAAAA,EAAEe,IAAI,cAANf,8BAAAA,QAAQnB,MAAM,uCAAI;YAC9B;QACJ,IACJ;QAACiB;QAAOD;KAAQ;IAGpB,qBACI,KAACmB;kBACIjB,MAAMb,GAAG,CAAC,CAAC,EAAEwB,EAAE,EAAE/B,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAE,iBACrC,KAACH;gBAAiBC,OAAOA;gBAAOC,QAAQA;gBAAQC,QAAQA;eAA1C6B;;AAI9B,GAAG"}
@@ -106,14 +106,14 @@ export class LineChartStore {
106
106
  ...(_props_display = props.display) !== null && _props_display !== void 0 ? _props_display : {}
107
107
  };
108
108
  this.metrics = props.metrics.map((m)=>{
109
+ var _m_type, _m_opts, _ref;
109
110
  const mv = props.metricValues.find((mv)=>mv.metricId === m.id);
110
- var _m_type, _m_opts, _mv_values;
111
111
  return {
112
112
  ...m,
113
113
  isRight: !!m.isRight,
114
114
  type: (_m_type = m.type) !== null && _m_type !== void 0 ? _m_type : 'line',
115
115
  opts: (_m_opts = m.opts) !== null && _m_opts !== void 0 ? _m_opts : {},
116
- values: (_mv_values = mv === null || mv === void 0 ? void 0 : mv.values) !== null && _mv_values !== void 0 ? _mv_values : [],
116
+ values: (_ref = mv === null || mv === void 0 ? void 0 : mv.values) !== null && _ref !== void 0 ? _ref : [],
117
117
  valuesOpts: mv === null || mv === void 0 ? void 0 : mv.opts
118
118
  };
119
119
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/line-chart/stores/line-chart.store.ts"],"sourcesContent":["import { injectable } from '@servicetitan/react-ioc';\nimport { action, observable, makeObservable, computed } from 'mobx';\nimport type {\n LineChartDisplay,\n LineChartDisplayValueFormat,\n LineChartMetricValues,\n LineChartPeriod,\n LineChartProps,\n LineChartResolution,\n} from '../utils/interfaces';\nimport { defaultDisplay } from '../utils/const';\nimport type { ChartMetric, SideMetricsSettings } from '../utils/internal-interfaces';\nimport { getFormatter } from '../utils/formatters';\n\nconst getSideMetricsSettings = (\n metrics: ChartMetric[],\n values: LineChartMetricValues[],\n range?: number,\n title?: string,\n format?: LineChartDisplayValueFormat\n): SideMetricsSettings | undefined => {\n let maxRange = range ?? 0;\n const lineBarMetricIDs = metrics\n .filter(m => m.type === 'line' || m.type === 'bar' || m.type === 'grouped-bar')\n .map(m => m.id);\n const stackedBarMetricIDs = metrics.filter(m => m.type === 'stacked-bar').map(m => m.id);\n\n if (!maxRange) {\n maxRange = values.reduce(\n (sum, metricValues) =>\n lineBarMetricIDs.includes(metricValues.metricId)\n ? Math.max(\n sum,\n metricValues.values.reduce((acc, v) => Math.max(acc, v), 0)\n )\n : sum,\n 0\n );\n }\n\n if (stackedBarMetricIDs.length) {\n const stackChartMetricValues = values\n .filter(metricValues => stackedBarMetricIDs.includes(metricValues.metricId))\n .map(metric => metric.values);\n\n const summedStackedMetrics = stackChartMetricValues[0]?.map((value, i) =>\n stackChartMetricValues.reduce((sum, metricValues) => sum + metricValues[i], 0)\n );\n\n if (summedStackedMetrics?.length) {\n maxRange = Math.max(...summedStackedMetrics, maxRange);\n }\n }\n\n if (!maxRange) {\n if (!lineBarMetricIDs.length && !stackedBarMetricIDs.length) {\n return undefined;\n }\n\n maxRange = 10;\n }\n\n maxRange = Math.max(maxRange, 10);\n\n if (format === 'moneyShort' && maxRange > 1000 && maxRange < 10000) {\n maxRange = 10000;\n }\n\n const sums = [];\n const step = maxRange / 10;\n const formatter = getFormatter(format);\n\n for (let i = 0; i < 10; i++) {\n sums.push(formatter(maxRange - i * step));\n }\n\n const width = title ? 64 : 48;\n\n return { maxRange, maxValue: 1.1 * maxRange, title: title ?? '', values: sums, width };\n};\n\n@injectable()\nexport class LineChartStore {\n @observable isInit = false;\n @observable display: LineChartDisplay = defaultDisplay();\n @observable metrics: ChartMetric[] = [];\n @observable periods: LineChartPeriod[] = [];\n @observable resolution: LineChartResolution = 'day';\n @observable totalMetricName?: string;\n\n @observable left?: SideMetricsSettings;\n @observable right?: SideMetricsSettings;\n\n @observable hoveredIndex = -1;\n\n @computed get stackedTotals(): number[] | undefined {\n const stackedSeries = this.metrics.filter(m => m.type === 'stacked-bar');\n if (stackedSeries.length === 0) {\n return undefined;\n }\n const length = Math.max(this.periods.length, ...stackedSeries.map(s => s.values.length));\n if (length === 0) {\n return [];\n }\n\n const totals = Array.from({ length }, () => 0);\n\n for (let i = 0; i < length; i++) {\n for (const s of stackedSeries) {\n const v = s.values[i];\n totals[i] += !Number.isNaN(v) ? v : 0;\n }\n }\n\n return totals;\n }\n\n get totalLabel(): string {\n return this.totalMetricName ?? 'Total';\n }\n\n constructor() {\n makeObservable(this);\n }\n\n @action init = (props: LineChartProps) => {\n this.display = {\n ...defaultDisplay(),\n ...(props.display ?? {}),\n };\n\n this.metrics = props.metrics.map(m => {\n const mv = props.metricValues.find(mv => mv.metricId === m.id);\n\n return {\n ...m,\n isRight: !!m.isRight,\n type: m.type ?? 'line',\n opts: m.opts ?? {},\n values: mv?.values ?? [],\n valuesOpts: mv?.opts,\n };\n });\n\n this.left = getSideMetricsSettings(\n this.metrics.filter(m => !m.isRight),\n props.metricValues,\n props.maxRange,\n props.titleY,\n this.display.yLeftFormat\n );\n this.right = getSideMetricsSettings(\n this.metrics.filter(m => m.isRight),\n props.metricValues,\n props.maxRangeRight,\n props.titleYRight,\n this.display.yRightFormat\n );\n\n this.resolution = props.resolution;\n this.totalMetricName = props.totalMetricName;\n this.periods = props.periods || [];\n this.hoveredIndex = -1;\n this.isInit = true;\n };\n\n @action setHoveredIndex = (index: number, isHovered: boolean) => {\n if (isHovered) {\n this.hoveredIndex = index;\n } else if (index === this.hoveredIndex) {\n this.hoveredIndex = -1;\n }\n };\n\n formattedTotalAt = (index: number): string => {\n const formatter = getFormatter(this.display.yLeftFormat);\n return formatter(this.totalAt(index));\n };\n\n private totalAt = (index: number): number =>\n this.stackedTotals && index >= 0 && index < this.stackedTotals.length\n ? this.stackedTotals[index]\n : 0;\n}\n"],"names":["injectable","action","observable","makeObservable","computed","defaultDisplay","getFormatter","getSideMetricsSettings","metrics","values","range","title","format","maxRange","lineBarMetricIDs","filter","m","type","map","id","stackedBarMetricIDs","reduce","sum","metricValues","includes","metricId","Math","max","acc","v","length","stackChartMetricValues","metric","summedStackedMetrics","value","i","undefined","sums","step","formatter","push","width","maxValue","LineChartStore","stackedTotals","stackedSeries","periods","s","totals","Array","from","Number","isNaN","totalLabel","totalMetricName","isInit","display","resolution","left","right","hoveredIndex","init","props","mv","find","isRight","opts","valuesOpts","titleY","yLeftFormat","maxRangeRight","titleYRight","yRightFormat","setHoveredIndex","index","isHovered","formattedTotalAt","totalAt"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/line-chart/stores/line-chart.store.ts"],"sourcesContent":["import { injectable } from '@servicetitan/react-ioc';\nimport { action, observable, makeObservable, computed } from 'mobx';\nimport type {\n LineChartDisplay,\n LineChartDisplayValueFormat,\n LineChartMetricValues,\n LineChartPeriod,\n LineChartProps,\n LineChartResolution,\n} from '../utils/interfaces';\nimport { defaultDisplay } from '../utils/const';\nimport type { ChartMetric, SideMetricsSettings } from '../utils/internal-interfaces';\nimport { getFormatter } from '../utils/formatters';\n\nconst getSideMetricsSettings = (\n metrics: ChartMetric[],\n values: LineChartMetricValues[],\n range?: number,\n title?: string,\n format?: LineChartDisplayValueFormat\n): SideMetricsSettings | undefined => {\n let maxRange = range ?? 0;\n const lineBarMetricIDs = metrics\n .filter(m => m.type === 'line' || m.type === 'bar' || m.type === 'grouped-bar')\n .map(m => m.id);\n const stackedBarMetricIDs = metrics.filter(m => m.type === 'stacked-bar').map(m => m.id);\n\n if (!maxRange) {\n maxRange = values.reduce(\n (sum, metricValues) =>\n lineBarMetricIDs.includes(metricValues.metricId)\n ? Math.max(\n sum,\n metricValues.values.reduce((acc, v) => Math.max(acc, v), 0)\n )\n : sum,\n 0\n );\n }\n\n if (stackedBarMetricIDs.length) {\n const stackChartMetricValues = values\n .filter(metricValues => stackedBarMetricIDs.includes(metricValues.metricId))\n .map(metric => metric.values);\n\n const summedStackedMetrics = stackChartMetricValues[0]?.map((value, i) =>\n stackChartMetricValues.reduce((sum, metricValues) => sum + metricValues[i], 0)\n );\n\n if (summedStackedMetrics?.length) {\n maxRange = Math.max(...summedStackedMetrics, maxRange);\n }\n }\n\n if (!maxRange) {\n if (!lineBarMetricIDs.length && !stackedBarMetricIDs.length) {\n return undefined;\n }\n\n maxRange = 10;\n }\n\n maxRange = Math.max(maxRange, 10);\n\n if (format === 'moneyShort' && maxRange > 1000 && maxRange < 10000) {\n maxRange = 10000;\n }\n\n const sums = [];\n const step = maxRange / 10;\n const formatter = getFormatter(format);\n\n for (let i = 0; i < 10; i++) {\n sums.push(formatter(maxRange - i * step));\n }\n\n const width = title ? 64 : 48;\n\n return { maxRange, maxValue: 1.1 * maxRange, title: title ?? '', values: sums, width };\n};\n\n@injectable()\nexport class LineChartStore {\n @observable isInit = false;\n @observable display: LineChartDisplay = defaultDisplay();\n @observable metrics: ChartMetric[] = [];\n @observable periods: LineChartPeriod[] = [];\n @observable resolution: LineChartResolution = 'day';\n @observable totalMetricName?: string;\n\n @observable left?: SideMetricsSettings;\n @observable right?: SideMetricsSettings;\n\n @observable hoveredIndex = -1;\n\n @computed get stackedTotals(): number[] | undefined {\n const stackedSeries = this.metrics.filter(m => m.type === 'stacked-bar');\n if (stackedSeries.length === 0) {\n return undefined;\n }\n const length = Math.max(this.periods.length, ...stackedSeries.map(s => s.values.length));\n if (length === 0) {\n return [];\n }\n\n const totals = Array.from({ length }, () => 0);\n\n for (let i = 0; i < length; i++) {\n for (const s of stackedSeries) {\n const v = s.values[i];\n totals[i] += !Number.isNaN(v) ? v : 0;\n }\n }\n\n return totals;\n }\n\n get totalLabel(): string {\n return this.totalMetricName ?? 'Total';\n }\n\n constructor() {\n makeObservable(this);\n }\n\n @action init = (props: LineChartProps) => {\n this.display = {\n ...defaultDisplay(),\n ...(props.display ?? {}),\n };\n\n this.metrics = props.metrics.map(m => {\n const mv = props.metricValues.find(mv => mv.metricId === m.id);\n\n return {\n ...m,\n isRight: !!m.isRight,\n type: m.type ?? 'line',\n opts: m.opts ?? {},\n values: mv?.values ?? [],\n valuesOpts: mv?.opts,\n };\n });\n\n this.left = getSideMetricsSettings(\n this.metrics.filter(m => !m.isRight),\n props.metricValues,\n props.maxRange,\n props.titleY,\n this.display.yLeftFormat\n );\n this.right = getSideMetricsSettings(\n this.metrics.filter(m => m.isRight),\n props.metricValues,\n props.maxRangeRight,\n props.titleYRight,\n this.display.yRightFormat\n );\n\n this.resolution = props.resolution;\n this.totalMetricName = props.totalMetricName;\n this.periods = props.periods || [];\n this.hoveredIndex = -1;\n this.isInit = true;\n };\n\n @action setHoveredIndex = (index: number, isHovered: boolean) => {\n if (isHovered) {\n this.hoveredIndex = index;\n } else if (index === this.hoveredIndex) {\n this.hoveredIndex = -1;\n }\n };\n\n formattedTotalAt = (index: number): string => {\n const formatter = getFormatter(this.display.yLeftFormat);\n return formatter(this.totalAt(index));\n };\n\n private totalAt = (index: number): number =>\n this.stackedTotals && index >= 0 && index < this.stackedTotals.length\n ? this.stackedTotals[index]\n : 0;\n}\n"],"names":["injectable","action","observable","makeObservable","computed","defaultDisplay","getFormatter","getSideMetricsSettings","metrics","values","range","title","format","maxRange","lineBarMetricIDs","filter","m","type","map","id","stackedBarMetricIDs","reduce","sum","metricValues","includes","metricId","Math","max","acc","v","length","stackChartMetricValues","metric","summedStackedMetrics","value","i","undefined","sums","step","formatter","push","width","maxValue","LineChartStore","stackedTotals","stackedSeries","periods","s","totals","Array","from","Number","isNaN","totalLabel","totalMetricName","isInit","display","resolution","left","right","hoveredIndex","init","props","mv","find","isRight","opts","valuesOpts","titleY","yLeftFormat","maxRangeRight","titleYRight","yRightFormat","setHoveredIndex","index","isHovered","formattedTotalAt","totalAt"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/line-chart/utils/labels.ts"],"sourcesContent":["import moment from 'moment';\nimport { LineChartPeriod, LineChartResolution } from './interfaces';\nimport { ChartXLabels } from './internal-interfaces';\n\nconst xLabelFormats = {\n hour: 'HH:mm',\n day: 'MM/DD',\n month: 'MMM',\n};\n\nexport const getXLabels = (\n periods: LineChartPeriod[],\n resolution: LineChartResolution,\n width: number\n): ChartXLabels => {\n let labels: [string, number][] = [];\n\n if (resolution === 'hour') {\n if (width / periods.length < 76) {\n let day = -1;\n\n for (const p of periods) {\n const d = p.from.getDay();\n\n if (d === day) {\n labels[labels.length - 1][1]++;\n\n continue;\n }\n\n day = d;\n labels.push([moment(p.from).format(xLabelFormats.day), 1]);\n }\n } else {\n labels = periods.map(p => [\n moment(p.from).format(xLabelFormats.hour) +\n ' - ' +\n moment(p.to ?? p.from).format(xLabelFormats.hour),\n 1,\n ]);\n }\n } else if (resolution === 'day') {\n if (width / periods.length < 40) {\n let month = -1;\n\n for (const p of periods) {\n const m = p.from.getMonth();\n\n if (m === month) {\n labels[labels.length - 1][1]++;\n\n continue;\n }\n\n month = m;\n labels.push([moment(p.from).format(xLabelFormats.month), 1]);\n }\n } else {\n labels = periods.map(p => [moment(p.from).format(xLabelFormats.day), 1]);\n }\n } else if (resolution === 'week') {\n if (width / periods.length < 76) {\n let month = -1;\n\n for (const p of periods) {\n const m = p.from.getMonth();\n\n if (m === month || (month > 0 && p.from.getDate() < 4)) {\n labels[labels.length - 1][1]++;\n\n continue;\n }\n\n if (p.to && p.to.getDate() > 3) {\n month = p.to.getMonth();\n labels.push([moment(p.to).format(xLabelFormats.month), 1]);\n } else {\n month = m;\n labels.push([moment(p.from).format(xLabelFormats.month), 1]);\n }\n }\n } else {\n labels = periods.map(p => [\n moment(p.from).format(xLabelFormats.day) +\n ' - ' +\n moment(p.to ?? p.from).format(xLabelFormats.day),\n 1,\n ]);\n }\n } else if (resolution === 'month') {\n labels = periods.map(p => [moment(p.from).format(xLabelFormats.month), 1]);\n }\n\n return labels;\n};\n\nexport const periodDateTitleFormatter: Record<\n LineChartResolution,\n (period: LineChartPeriod) => string\n> = {\n hour: period =>\n moment(period.from).format('MM/DD') +\n ' ' +\n moment(period.from).format('HH:mm') +\n ' - ' +\n moment(period.to).format('HH:mm'),\n day: period => moment(period.from).format('MMM DD, YYYY'),\n month: period => moment(period.from).format('MMMM YYYY'),\n week: period =>\n moment(period.from).format('MM/DD/YYYY') + '-' + moment(period.to).format('MM/DD/YYYY'),\n};\n"],"names":["moment","xLabelFormats","hour","day","month","getXLabels","periods","resolution","width","labels","length","p","d","from","getDay","push","format","map","to","m","getMonth","getDate","periodDateTitleFormatter","period","week"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/line-chart/utils/labels.ts"],"sourcesContent":["import moment from 'moment';\nimport { LineChartPeriod, LineChartResolution } from './interfaces';\nimport { ChartXLabels } from './internal-interfaces';\n\nconst xLabelFormats = {\n hour: 'HH:mm',\n day: 'MM/DD',\n month: 'MMM',\n};\n\nexport const getXLabels = (\n periods: LineChartPeriod[],\n resolution: LineChartResolution,\n width: number\n): ChartXLabels => {\n let labels: [string, number][] = [];\n\n if (resolution === 'hour') {\n if (width / periods.length < 76) {\n let day = -1;\n\n for (const p of periods) {\n const d = p.from.getDay();\n\n if (d === day) {\n labels[labels.length - 1][1]++;\n\n continue;\n }\n\n day = d;\n labels.push([moment(p.from).format(xLabelFormats.day), 1]);\n }\n } else {\n labels = periods.map(p => [\n moment(p.from).format(xLabelFormats.hour) +\n ' - ' +\n moment(p.to ?? p.from).format(xLabelFormats.hour),\n 1,\n ]);\n }\n } else if (resolution === 'day') {\n if (width / periods.length < 40) {\n let month = -1;\n\n for (const p of periods) {\n const m = p.from.getMonth();\n\n if (m === month) {\n labels[labels.length - 1][1]++;\n\n continue;\n }\n\n month = m;\n labels.push([moment(p.from).format(xLabelFormats.month), 1]);\n }\n } else {\n labels = periods.map(p => [moment(p.from).format(xLabelFormats.day), 1]);\n }\n } else if (resolution === 'week') {\n if (width / periods.length < 76) {\n let month = -1;\n\n for (const p of periods) {\n const m = p.from.getMonth();\n\n if (m === month || (month > 0 && p.from.getDate() < 4)) {\n labels[labels.length - 1][1]++;\n\n continue;\n }\n\n if (p.to && p.to.getDate() > 3) {\n month = p.to.getMonth();\n labels.push([moment(p.to).format(xLabelFormats.month), 1]);\n } else {\n month = m;\n labels.push([moment(p.from).format(xLabelFormats.month), 1]);\n }\n }\n } else {\n labels = periods.map(p => [\n moment(p.from).format(xLabelFormats.day) +\n ' - ' +\n moment(p.to ?? p.from).format(xLabelFormats.day),\n 1,\n ]);\n }\n } else if (resolution === 'month') {\n labels = periods.map(p => [moment(p.from).format(xLabelFormats.month), 1]);\n }\n\n return labels;\n};\n\nexport const periodDateTitleFormatter: Record<\n LineChartResolution,\n (period: LineChartPeriod) => string\n> = {\n hour: period =>\n moment(period.from).format('MM/DD') +\n ' ' +\n moment(period.from).format('HH:mm') +\n ' - ' +\n moment(period.to).format('HH:mm'),\n day: period => moment(period.from).format('MMM DD, YYYY'),\n month: period => moment(period.from).format('MMMM YYYY'),\n week: period =>\n moment(period.from).format('MM/DD/YYYY') + '-' + moment(period.to).format('MM/DD/YYYY'),\n};\n"],"names":["moment","xLabelFormats","hour","day","month","getXLabels","periods","resolution","width","labels","length","p","d","from","getDay","push","format","map","to","m","getMonth","getDate","periodDateTitleFormatter","period","week"],"mappings":"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"}
@@ -171,8 +171,8 @@ export const Pie = ({ pieces, popoverContent: PopoverContent, content: PieConten
171
171
  setSelectedIndex
172
172
  ]);
173
173
  const container = useMemo(()=>{
174
- var _rect_height;
175
- const height = (_rect_height = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _rect_height !== void 0 ? _rect_height : 0;
174
+ var _ref;
175
+ const height = (_ref = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _ref !== void 0 ? _ref : 0;
176
176
  return {
177
177
  height,
178
178
  internal: height ? height - chartPadding * 2 : 0,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/pie-chart/components/pie.tsx"],"sourcesContent":["import { useCallback, useMemo, useState, FC, Fragment } from 'react';\nimport { tokens } from '@servicetitan/tokens/core';\nimport { BodyText, Popover, Stack } from '@servicetitan/design-system';\n\nimport { useClientRect } from '../../../../utils/use-client-rect';\nimport { PieChartPopoverContentType, PiePiece, PopoverDirection } from '../utils/interface';\nimport { ColorTag } from '../../common';\nimport * as Styles from './pie-chart.module.less';\n\nconst chartPadding = 8;\nconst px = (value?: number) => `${value ?? 0}px`;\nconst GAP_PX = 4;\n\nconst PiePieceSvg: FC<{\n piece: PiePiece;\n selected?: boolean;\n}> = ({ piece: { id, color, points, text, path }, selected }) =>\n points && path ? (\n <g id={id}>\n {selected && (\n <path\n d={path}\n fill={tokens.colorWhite}\n stroke={tokens.colorBlue200}\n strokeOpacity=\"50%\"\n strokeWidth=\"3\"\n paintOrder=\"stroke\"\n />\n )}\n <path d={path} fill={color} />\n {points[4] && (\n <g transform={`translate(${points[4][0]}, ${points[4][1]})`} pointerEvents=\"none\">\n {(() => {\n const fontSize = 3;\n const height = 6;\n const radius = height / 2;\n\n const width = Math.max(8, text.length);\n\n return (\n <Fragment>\n <rect\n x={-width / 2}\n y={-height / 2}\n width={width}\n height={height}\n rx={radius}\n ry={radius}\n fill=\"rgba(255,255,255,0.80)\"\n strokeWidth={0.6}\n />\n <text\n x=\"0\"\n y=\"0\"\n fontSize={fontSize}\n fontWeight={600}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill={tokens.colorBlack}\n >\n {text}\n </text>\n </Fragment>\n );\n })()}\n </g>\n )}\n </g>\n ) : null;\n\nconst PiePieceHover: FC<{\n piece: PiePiece;\n onMouse(id: string, isEnter: boolean): void;\n}> = ({ piece, onMouse }) => {\n const onMouseEnter = useCallback(() => onMouse(piece.id, true), [onMouse, piece.id]);\n const onMouseLeave = useCallback(() => onMouse(piece.id, false), [onMouse, piece.id]);\n\n return (\n <path\n d={piece.path}\n fill=\"white\"\n opacity=\"0\"\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n />\n );\n};\n\nconst PieSvg: FC<{\n pieces: PiePiece[];\n selectedIndex: number;\n radiusRelative: number;\n}> = ({ pieces, selectedIndex, radiusRelative }) => {\n const piePiece = pieces.find(p => p.points);\n const innerR = piePiece ? Math.hypot(piePiece.points![3][0], piePiece.points![3][1]) : 0;\n const outerR = piePiece ? Math.hypot(piePiece.points![1][0], piePiece.points![1][1]) : 0;\n\n const nonZeroPieces = pieces.filter(p => p.points && p.path);\n const boundaries = nonZeroPieces.map(p => {\n const [outerX, outerY] = p.points![1];\n const len = Math.hypot(outerX, outerY) || 1;\n return { x: outerX / len, y: outerY / len };\n });\n\n return (\n <svg\n className=\"position-absolute\"\n style={{ inset: `${chartPadding}px` }}\n viewBox={`-${radiusRelative} -${radiusRelative} ${radiusRelative * 2} ${radiusRelative * 2}`}\n >\n {pieces.map((p, i) =>\n p.path ? <PiePieceSvg piece={p} key={p.id} selected={i === selectedIndex} /> : null\n )}\n {nonZeroPieces.length > 1 && innerR > 0 && outerR > 0 && (\n <Fragment>\n <defs>\n <mask id=\"ring-mask\">\n <rect\n x={-outerR}\n y={-outerR}\n width={outerR * 2}\n height={outerR * 2}\n fill=\"black\"\n />\n <circle cx=\"0\" cy=\"0\" r={outerR} fill=\"white\" />\n <circle cx=\"0\" cy=\"0\" r={innerR} fill=\"black\" />\n </mask>\n </defs>\n <g mask=\"url(#ring-mask)\" pointerEvents=\"none\">\n {boundaries.map(boundary => (\n <line\n key={`sep-${boundary.x}-${boundary.y}`}\n x1={boundary.x * innerR}\n y1={boundary.y * innerR}\n x2={boundary.x * outerR}\n y2={boundary.y * outerR}\n stroke=\"#fff\"\n strokeWidth={GAP_PX}\n vectorEffect=\"non-scaling-stroke\"\n strokeLinecap=\"round\"\n />\n ))}\n </g>\n </Fragment>\n )}\n {selectedIndex >= 0 && selectedIndex < pieces.length && (\n <use xlinkHref={`#${pieces[selectedIndex].id}`} />\n )}\n </svg>\n );\n};\n\nconst PieSvgHover: FC<{\n pieces: PiePiece[];\n radiusRelative: number;\n onMouse(id: string, isEnter: boolean): void;\n}> = ({ pieces, onMouse, radiusRelative }) => (\n <svg\n className=\"position-absolute z-global-nav\"\n style={{ inset: px(chartPadding) }}\n viewBox={\n `-${radiusRelative} -${radiusRelative} ` + `${radiusRelative * 2} ${radiusRelative * 2}`\n }\n >\n {pieces.map(p =>\n p.path ? <PiePieceHover piece={p} key={p.id} onMouse={onMouse} /> : null\n )}\n </svg>\n);\n\nexport const Pie: FC<{\n title: string;\n pieces: PiePiece[];\n radiusRelative: number;\n content?: FC;\n popoverContent?: PieChartPopoverContentType;\n hideTitles?: boolean;\n popoverDirection?: PopoverDirection;\n}> = ({\n pieces,\n popoverContent: PopoverContent,\n content: PieContent,\n radiusRelative,\n hideTitles,\n popoverDirection,\n}) => {\n const [selectedIndex, setSelectedIndex] = useState(-1);\n const [rect, ref] = useClientRect();\n\n const onMouse = useCallback(\n (id: string, isEnter: boolean) => {\n setSelectedIndex(isEnter ? pieces.findIndex(p => p.id === id) : -1);\n },\n [pieces, setSelectedIndex]\n );\n\n const container = useMemo(() => {\n const height = rect?.height ?? 0;\n\n return {\n height,\n internal: height ? height - chartPadding * 2 : 0,\n styles: height\n ? {\n width: px(Math.max(250, height)),\n }\n : {},\n };\n }, [rect]);\n\n const triggersStyles = useMemo(\n () =>\n container.height\n ? pieces.map(p =>\n p.points\n ? {\n key: p.key,\n top: px(\n (container.height * (radiusRelative + p.points[4][1])) /\n (radiusRelative * 2)\n ),\n left: px(\n (container.height * (radiusRelative + p.points[4][0])) /\n (radiusRelative * 2) +\n 20\n ),\n }\n : { top: '', left: '' }\n )\n : [],\n [pieces, container, radiusRelative]\n );\n\n return (\n <div ref={ref} style={container.styles} className=\"position-relative h-100\">\n {pieces.every(p => !p.path) ? (\n <Stack className=\"h-100\" justifyContent=\"center\" alignItems=\"center\">\n No Data\n </Stack>\n ) : (\n <Fragment>\n {triggersStyles\n .filter(ts => !!ts.left && !!ts.top)\n .map((ts, ind) => (\n <div key={ts.left + ts.top} style={ts} className=\"position-absolute\">\n {(!!PopoverContent || !hideTitles) && (\n <Popover\n portal\n trigger={<span> </span>}\n open={selectedIndex === ind}\n direction={popoverDirection}\n padding=\"s\"\n width=\"auto\"\n className={Styles.popover}\n >\n {selectedIndex === ind && (\n <Stack\n direction=\"column\"\n data-cy={`customer-lead-rate-section-${ts.key}-popover`}\n >\n {!hideTitles && (\n <Stack alignItems=\"center\">\n <ColorTag\n label=\"\"\n color={pieces[ind].color}\n />\n <BodyText size=\"small\" bold>\n {pieces[ind].title}\n </BodyText>\n </Stack>\n )}\n {!!PopoverContent && (\n <Stack.Item className=\"m-l-1\">\n <PopoverContent\n index={ind}\n data={pieces[ind]?.data}\n text={pieces[ind]?.text}\n value={pieces[ind]?.value}\n />\n </Stack.Item>\n )}\n </Stack>\n )}\n </Popover>\n )}\n </div>\n ))}\n {!!PieContent && <PieContent />}\n <PieSvg\n pieces={pieces}\n selectedIndex={selectedIndex}\n radiusRelative={radiusRelative}\n />\n <PieSvgHover\n pieces={pieces}\n onMouse={onMouse}\n radiusRelative={radiusRelative}\n />\n </Fragment>\n )}\n </div>\n );\n};\n"],"names":["useCallback","useMemo","useState","Fragment","tokens","BodyText","Popover","Stack","useClientRect","ColorTag","Styles","chartPadding","px","value","GAP_PX","PiePieceSvg","piece","id","color","points","text","path","selected","g","d","fill","colorWhite","stroke","colorBlue200","strokeOpacity","strokeWidth","paintOrder","transform","pointerEvents","fontSize","height","radius","width","Math","max","length","rect","x","y","rx","ry","fontWeight","textAnchor","dominantBaseline","colorBlack","PiePieceHover","onMouse","onMouseEnter","onMouseLeave","opacity","PieSvg","pieces","selectedIndex","radiusRelative","piePiece","find","p","innerR","hypot","outerR","nonZeroPieces","filter","boundaries","map","outerX","outerY","len","svg","className","style","inset","viewBox","i","defs","mask","circle","cx","cy","r","boundary","line","x1","y1","x2","y2","vectorEffect","strokeLinecap","use","xlinkHref","PieSvgHover","Pie","popoverContent","PopoverContent","content","PieContent","hideTitles","popoverDirection","setSelectedIndex","ref","isEnter","findIndex","container","internal","styles","triggersStyles","key","top","left","div","every","justifyContent","alignItems","ts","ind","portal","trigger","span","open","direction","padding","popover","data-cy","label","size","bold","title","Item","index","data"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/pie-chart/components/pie.tsx"],"sourcesContent":["import { useCallback, useMemo, useState, FC, Fragment } from 'react';\nimport { tokens } from '@servicetitan/tokens/core';\nimport { BodyText, Popover, Stack } from '@servicetitan/design-system';\n\nimport { useClientRect } from '../../../../utils/use-client-rect';\nimport { PieChartPopoverContentType, PiePiece, PopoverDirection } from '../utils/interface';\nimport { ColorTag } from '../../common';\nimport * as Styles from './pie-chart.module.less';\n\nconst chartPadding = 8;\nconst px = (value?: number) => `${value ?? 0}px`;\nconst GAP_PX = 4;\n\nconst PiePieceSvg: FC<{\n piece: PiePiece;\n selected?: boolean;\n}> = ({ piece: { id, color, points, text, path }, selected }) =>\n points && path ? (\n <g id={id}>\n {selected && (\n <path\n d={path}\n fill={tokens.colorWhite}\n stroke={tokens.colorBlue200}\n strokeOpacity=\"50%\"\n strokeWidth=\"3\"\n paintOrder=\"stroke\"\n />\n )}\n <path d={path} fill={color} />\n {points[4] && (\n <g transform={`translate(${points[4][0]}, ${points[4][1]})`} pointerEvents=\"none\">\n {(() => {\n const fontSize = 3;\n const height = 6;\n const radius = height / 2;\n\n const width = Math.max(8, text.length);\n\n return (\n <Fragment>\n <rect\n x={-width / 2}\n y={-height / 2}\n width={width}\n height={height}\n rx={radius}\n ry={radius}\n fill=\"rgba(255,255,255,0.80)\"\n strokeWidth={0.6}\n />\n <text\n x=\"0\"\n y=\"0\"\n fontSize={fontSize}\n fontWeight={600}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill={tokens.colorBlack}\n >\n {text}\n </text>\n </Fragment>\n );\n })()}\n </g>\n )}\n </g>\n ) : null;\n\nconst PiePieceHover: FC<{\n piece: PiePiece;\n onMouse(id: string, isEnter: boolean): void;\n}> = ({ piece, onMouse }) => {\n const onMouseEnter = useCallback(() => onMouse(piece.id, true), [onMouse, piece.id]);\n const onMouseLeave = useCallback(() => onMouse(piece.id, false), [onMouse, piece.id]);\n\n return (\n <path\n d={piece.path}\n fill=\"white\"\n opacity=\"0\"\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n />\n );\n};\n\nconst PieSvg: FC<{\n pieces: PiePiece[];\n selectedIndex: number;\n radiusRelative: number;\n}> = ({ pieces, selectedIndex, radiusRelative }) => {\n const piePiece = pieces.find(p => p.points);\n const innerR = piePiece ? Math.hypot(piePiece.points![3][0], piePiece.points![3][1]) : 0;\n const outerR = piePiece ? Math.hypot(piePiece.points![1][0], piePiece.points![1][1]) : 0;\n\n const nonZeroPieces = pieces.filter(p => p.points && p.path);\n const boundaries = nonZeroPieces.map(p => {\n const [outerX, outerY] = p.points![1];\n const len = Math.hypot(outerX, outerY) || 1;\n return { x: outerX / len, y: outerY / len };\n });\n\n return (\n <svg\n className=\"position-absolute\"\n style={{ inset: `${chartPadding}px` }}\n viewBox={`-${radiusRelative} -${radiusRelative} ${radiusRelative * 2} ${radiusRelative * 2}`}\n >\n {pieces.map((p, i) =>\n p.path ? <PiePieceSvg piece={p} key={p.id} selected={i === selectedIndex} /> : null\n )}\n {nonZeroPieces.length > 1 && innerR > 0 && outerR > 0 && (\n <Fragment>\n <defs>\n <mask id=\"ring-mask\">\n <rect\n x={-outerR}\n y={-outerR}\n width={outerR * 2}\n height={outerR * 2}\n fill=\"black\"\n />\n <circle cx=\"0\" cy=\"0\" r={outerR} fill=\"white\" />\n <circle cx=\"0\" cy=\"0\" r={innerR} fill=\"black\" />\n </mask>\n </defs>\n <g mask=\"url(#ring-mask)\" pointerEvents=\"none\">\n {boundaries.map(boundary => (\n <line\n key={`sep-${boundary.x}-${boundary.y}`}\n x1={boundary.x * innerR}\n y1={boundary.y * innerR}\n x2={boundary.x * outerR}\n y2={boundary.y * outerR}\n stroke=\"#fff\"\n strokeWidth={GAP_PX}\n vectorEffect=\"non-scaling-stroke\"\n strokeLinecap=\"round\"\n />\n ))}\n </g>\n </Fragment>\n )}\n {selectedIndex >= 0 && selectedIndex < pieces.length && (\n <use xlinkHref={`#${pieces[selectedIndex].id}`} />\n )}\n </svg>\n );\n};\n\nconst PieSvgHover: FC<{\n pieces: PiePiece[];\n radiusRelative: number;\n onMouse(id: string, isEnter: boolean): void;\n}> = ({ pieces, onMouse, radiusRelative }) => (\n <svg\n className=\"position-absolute z-global-nav\"\n style={{ inset: px(chartPadding) }}\n viewBox={\n `-${radiusRelative} -${radiusRelative} ` + `${radiusRelative * 2} ${radiusRelative * 2}`\n }\n >\n {pieces.map(p =>\n p.path ? <PiePieceHover piece={p} key={p.id} onMouse={onMouse} /> : null\n )}\n </svg>\n);\n\nexport const Pie: FC<{\n title: string;\n pieces: PiePiece[];\n radiusRelative: number;\n content?: FC;\n popoverContent?: PieChartPopoverContentType;\n hideTitles?: boolean;\n popoverDirection?: PopoverDirection;\n}> = ({\n pieces,\n popoverContent: PopoverContent,\n content: PieContent,\n radiusRelative,\n hideTitles,\n popoverDirection,\n}) => {\n const [selectedIndex, setSelectedIndex] = useState(-1);\n const [rect, ref] = useClientRect();\n\n const onMouse = useCallback(\n (id: string, isEnter: boolean) => {\n setSelectedIndex(isEnter ? pieces.findIndex(p => p.id === id) : -1);\n },\n [pieces, setSelectedIndex]\n );\n\n const container = useMemo(() => {\n const height = rect?.height ?? 0;\n\n return {\n height,\n internal: height ? height - chartPadding * 2 : 0,\n styles: height\n ? {\n width: px(Math.max(250, height)),\n }\n : {},\n };\n }, [rect]);\n\n const triggersStyles = useMemo(\n () =>\n container.height\n ? pieces.map(p =>\n p.points\n ? {\n key: p.key,\n top: px(\n (container.height * (radiusRelative + p.points[4][1])) /\n (radiusRelative * 2)\n ),\n left: px(\n (container.height * (radiusRelative + p.points[4][0])) /\n (radiusRelative * 2) +\n 20\n ),\n }\n : { top: '', left: '' }\n )\n : [],\n [pieces, container, radiusRelative]\n );\n\n return (\n <div ref={ref} style={container.styles} className=\"position-relative h-100\">\n {pieces.every(p => !p.path) ? (\n <Stack className=\"h-100\" justifyContent=\"center\" alignItems=\"center\">\n No Data\n </Stack>\n ) : (\n <Fragment>\n {triggersStyles\n .filter(ts => !!ts.left && !!ts.top)\n .map((ts, ind) => (\n <div key={ts.left + ts.top} style={ts} className=\"position-absolute\">\n {(!!PopoverContent || !hideTitles) && (\n <Popover\n portal\n trigger={<span> </span>}\n open={selectedIndex === ind}\n direction={popoverDirection}\n padding=\"s\"\n width=\"auto\"\n className={Styles.popover}\n >\n {selectedIndex === ind && (\n <Stack\n direction=\"column\"\n data-cy={`customer-lead-rate-section-${ts.key}-popover`}\n >\n {!hideTitles && (\n <Stack alignItems=\"center\">\n <ColorTag\n label=\"\"\n color={pieces[ind].color}\n />\n <BodyText size=\"small\" bold>\n {pieces[ind].title}\n </BodyText>\n </Stack>\n )}\n {!!PopoverContent && (\n <Stack.Item className=\"m-l-1\">\n <PopoverContent\n index={ind}\n data={pieces[ind]?.data}\n text={pieces[ind]?.text}\n value={pieces[ind]?.value}\n />\n </Stack.Item>\n )}\n </Stack>\n )}\n </Popover>\n )}\n </div>\n ))}\n {!!PieContent && <PieContent />}\n <PieSvg\n pieces={pieces}\n selectedIndex={selectedIndex}\n radiusRelative={radiusRelative}\n />\n <PieSvgHover\n pieces={pieces}\n onMouse={onMouse}\n radiusRelative={radiusRelative}\n />\n </Fragment>\n )}\n </div>\n );\n};\n"],"names":["useCallback","useMemo","useState","Fragment","tokens","BodyText","Popover","Stack","useClientRect","ColorTag","Styles","chartPadding","px","value","GAP_PX","PiePieceSvg","piece","id","color","points","text","path","selected","g","d","fill","colorWhite","stroke","colorBlue200","strokeOpacity","strokeWidth","paintOrder","transform","pointerEvents","fontSize","height","radius","width","Math","max","length","rect","x","y","rx","ry","fontWeight","textAnchor","dominantBaseline","colorBlack","PiePieceHover","onMouse","onMouseEnter","onMouseLeave","opacity","PieSvg","pieces","selectedIndex","radiusRelative","piePiece","find","p","innerR","hypot","outerR","nonZeroPieces","filter","boundaries","map","outerX","outerY","len","svg","className","style","inset","viewBox","i","defs","mask","circle","cx","cy","r","boundary","line","x1","y1","x2","y2","vectorEffect","strokeLinecap","use","xlinkHref","PieSvgHover","Pie","popoverContent","PopoverContent","content","PieContent","hideTitles","popoverDirection","setSelectedIndex","ref","isEnter","findIndex","container","internal","styles","triggersStyles","key","top","left","div","every","justifyContent","alignItems","ts","ind","portal","trigger","span","open","direction","padding","popover","data-cy","label","size","bold","title","Item","index","data"],"mappings":"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"}
@@ -24,6 +24,7 @@ export const convertSessionsToPieces = (sections, radiusRelative)=>{
24
24
  const radiusExt = getRadiusExt(radiusRelative);
25
25
  const radiusMid = getRadiusMid(radiusRelative);
26
26
  const pieces = sections.slice().sort((a, b)=>b.value - a.value).map((s, index)=>{
27
+ var _s_color;
27
28
  const percent = total ? s.value / total : 0;
28
29
  const angle = 2 * Math.PI * percent;
29
30
  const angleStart = angleInitial + angleSum;
@@ -53,7 +54,6 @@ export const convertSessionsToPieces = (sections, radiusRelative)=>{
53
54
  ]
54
55
  ] : undefined;
55
56
  angleSum += angle;
56
- var _s_color;
57
57
  return {
58
58
  id: `pie${index}-${Math.round(Math.random() * 10000)}`,
59
59
  key: s.key,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/components/charts/pie-chart/utils/const.ts"],"sourcesContent":["import { PiecePoints, PieChartSection, PiePiece } from './interface';\nimport { formatNumber } from 'accounting';\n\nexport const radiusRelativeDefault = 50;\nconst radiusInt = 20;\nconst getRadiusExt = (radiusRelative: number) => radiusRelative - 5; // need to have some space to stroke selected piece\nconst getRadiusMid = (radiusRelative: number) => (2.75 * radiusRelative) / 4;\n\nconst angleInitial = -0.5;\nconst lowestOpacity = 0.1;\n\nconst formatValue = (val: number): string => {\n if (!val) {\n return '0%';\n }\n\n const valueMain = val ? Math.abs(Math.round(val)) : 0;\n\n if (valueMain > 0) {\n return formatNumber(valueMain, 0) + '%';\n }\n\n const valueDecimal = Math.max(Math.floor(val * 10) - valueMain * 10, 1);\n\n return `0.${valueDecimal}%`;\n};\n\nconst convertPointsToPath = (points: PiecePoints, wideAngle: boolean, radiusExt: number): string =>\n `M ${points[3][0]},${points[3][1]} ` +\n `L ${points[0][0]},${points[0][1]} ` +\n `A ${radiusExt},${radiusExt} 0 ${wideAngle ? 1 : 0} 1 ${points[1][0]},${points[1][1]} ` +\n `L ${points[2][0]},${points[2][1]} ` +\n `A ${radiusInt},${radiusInt} 0 ${wideAngle ? 1 : 0} 0 ${points[3][0]},${points[3][1]} ` +\n `L ${points[0][0]},${points[0][1]} `;\n\nexport const convertSessionsToPieces = <T>(\n sections: PieChartSection<T>[],\n radiusRelative: number\n): PiePiece<T>[] => {\n const total = sections.reduce((sum, curr) => sum + curr.value, 0);\n const opacityStep = (1 - lowestOpacity) / (Math.max(sections.length, 2) - 1);\n let angleSum = 0;\n const radiusExt = getRadiusExt(radiusRelative);\n const radiusMid = getRadiusMid(radiusRelative);\n\n const pieces = sections\n .slice()\n .sort((a, b) => b.value - a.value)\n .map((s, index) => {\n const percent = total ? s.value / total : 0;\n const angle = 2 * Math.PI * percent;\n const angleStart = angleInitial + angleSum;\n const angleMid = angleStart + angle / 2;\n const angleEnd = angleStart + angle;\n const opacity = 1 - opacityStep * index;\n\n const points: PiecePoints | undefined = s.value\n ? [\n [radiusExt * Math.sin(angleStart), -1 * radiusExt * Math.cos(angleStart)],\n [radiusExt * Math.sin(angleEnd), -1 * radiusExt * Math.cos(angleEnd)],\n [radiusInt * Math.sin(angleEnd), -1 * radiusInt * Math.cos(angleEnd)],\n [radiusInt * Math.sin(angleStart), -1 * radiusInt * Math.cos(angleStart)],\n [radiusMid * Math.sin(angleMid), -1 * radiusMid * Math.cos(angleMid)],\n ]\n : undefined;\n\n angleSum += angle;\n\n return {\n id: `pie${index}-${Math.round(Math.random() * 10000)}`,\n key: s.key,\n title: s.title,\n text: formatValue(percent * 100),\n data: s.data,\n color: s.color ?? `rgba(0,76,195,${opacity.toFixed(2)})`,\n opacity,\n value: s.value,\n points,\n path: points\n ? convertPointsToPath(points, angleEnd - angleStart >= Math.PI, radiusExt)\n : undefined,\n };\n });\n\n if (sections.filter(s => !!s.value).length === 1) {\n const piece = pieces.find(p => !!p.points);\n\n if (piece) {\n piece.points = [\n [-radiusExt, radiusExt],\n [radiusExt, radiusExt],\n [radiusInt, -radiusInt],\n [-radiusInt, -radiusInt],\n [0, 0],\n ];\n\n piece.path =\n `M ${-radiusExt},${0} ` +\n `A ${radiusExt},${radiusExt} 0 1 1 ${radiusExt},${0} ` +\n `A ${radiusExt},${radiusExt} 0 1 1 ${-radiusExt},${0} `;\n }\n }\n\n return pieces;\n};\n"],"names":["formatNumber","radiusRelativeDefault","radiusInt","getRadiusExt","radiusRelative","getRadiusMid","angleInitial","lowestOpacity","formatValue","val","valueMain","Math","abs","round","valueDecimal","max","floor","convertPointsToPath","points","wideAngle","radiusExt","convertSessionsToPieces","sections","total","reduce","sum","curr","value","opacityStep","length","angleSum","radiusMid","pieces","slice","sort","a","b","map","s","index","percent","angle","PI","angleStart","angleMid","angleEnd","opacity","sin","cos","undefined","id","random","key","title","text","data","color","toFixed","path","filter","piece","find","p"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/components/charts/pie-chart/utils/const.ts"],"sourcesContent":["import { PiecePoints, PieChartSection, PiePiece } from './interface';\nimport { formatNumber } from 'accounting';\n\nexport const radiusRelativeDefault = 50;\nconst radiusInt = 20;\nconst getRadiusExt = (radiusRelative: number) => radiusRelative - 5; // need to have some space to stroke selected piece\nconst getRadiusMid = (radiusRelative: number) => (2.75 * radiusRelative) / 4;\n\nconst angleInitial = -0.5;\nconst lowestOpacity = 0.1;\n\nconst formatValue = (val: number): string => {\n if (!val) {\n return '0%';\n }\n\n const valueMain = val ? Math.abs(Math.round(val)) : 0;\n\n if (valueMain > 0) {\n return formatNumber(valueMain, 0) + '%';\n }\n\n const valueDecimal = Math.max(Math.floor(val * 10) - valueMain * 10, 1);\n\n return `0.${valueDecimal}%`;\n};\n\nconst convertPointsToPath = (points: PiecePoints, wideAngle: boolean, radiusExt: number): string =>\n `M ${points[3][0]},${points[3][1]} ` +\n `L ${points[0][0]},${points[0][1]} ` +\n `A ${radiusExt},${radiusExt} 0 ${wideAngle ? 1 : 0} 1 ${points[1][0]},${points[1][1]} ` +\n `L ${points[2][0]},${points[2][1]} ` +\n `A ${radiusInt},${radiusInt} 0 ${wideAngle ? 1 : 0} 0 ${points[3][0]},${points[3][1]} ` +\n `L ${points[0][0]},${points[0][1]} `;\n\nexport const convertSessionsToPieces = <T>(\n sections: PieChartSection<T>[],\n radiusRelative: number\n): PiePiece<T>[] => {\n const total = sections.reduce((sum, curr) => sum + curr.value, 0);\n const opacityStep = (1 - lowestOpacity) / (Math.max(sections.length, 2) - 1);\n let angleSum = 0;\n const radiusExt = getRadiusExt(radiusRelative);\n const radiusMid = getRadiusMid(radiusRelative);\n\n const pieces = sections\n .slice()\n .sort((a, b) => b.value - a.value)\n .map((s, index) => {\n const percent = total ? s.value / total : 0;\n const angle = 2 * Math.PI * percent;\n const angleStart = angleInitial + angleSum;\n const angleMid = angleStart + angle / 2;\n const angleEnd = angleStart + angle;\n const opacity = 1 - opacityStep * index;\n\n const points: PiecePoints | undefined = s.value\n ? [\n [radiusExt * Math.sin(angleStart), -1 * radiusExt * Math.cos(angleStart)],\n [radiusExt * Math.sin(angleEnd), -1 * radiusExt * Math.cos(angleEnd)],\n [radiusInt * Math.sin(angleEnd), -1 * radiusInt * Math.cos(angleEnd)],\n [radiusInt * Math.sin(angleStart), -1 * radiusInt * Math.cos(angleStart)],\n [radiusMid * Math.sin(angleMid), -1 * radiusMid * Math.cos(angleMid)],\n ]\n : undefined;\n\n angleSum += angle;\n\n return {\n id: `pie${index}-${Math.round(Math.random() * 10000)}`,\n key: s.key,\n title: s.title,\n text: formatValue(percent * 100),\n data: s.data,\n color: s.color ?? `rgba(0,76,195,${opacity.toFixed(2)})`,\n opacity,\n value: s.value,\n points,\n path: points\n ? convertPointsToPath(points, angleEnd - angleStart >= Math.PI, radiusExt)\n : undefined,\n };\n });\n\n if (sections.filter(s => !!s.value).length === 1) {\n const piece = pieces.find(p => !!p.points);\n\n if (piece) {\n piece.points = [\n [-radiusExt, radiusExt],\n [radiusExt, radiusExt],\n [radiusInt, -radiusInt],\n [-radiusInt, -radiusInt],\n [0, 0],\n ];\n\n piece.path =\n `M ${-radiusExt},${0} ` +\n `A ${radiusExt},${radiusExt} 0 1 1 ${radiusExt},${0} ` +\n `A ${radiusExt},${radiusExt} 0 1 1 ${-radiusExt},${0} `;\n }\n }\n\n return pieces;\n};\n"],"names":["formatNumber","radiusRelativeDefault","radiusInt","getRadiusExt","radiusRelative","getRadiusMid","angleInitial","lowestOpacity","formatValue","val","valueMain","Math","abs","round","valueDecimal","max","floor","convertPointsToPath","points","wideAngle","radiusExt","convertSessionsToPieces","sections","total","reduce","sum","curr","value","opacityStep","length","angleSum","radiusMid","pieces","slice","sort","a","b","map","s","index","percent","angle","PI","angleStart","angleMid","angleEnd","opacity","sin","cos","undefined","id","random","key","title","text","data","color","toFixed","path","filter","piece","find","p"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/stat/stat-card.tsx"],"sourcesContent":["import { FC, ReactNode, useState } from 'react';\nimport classNames from 'classnames';\nimport {\n BodyText,\n BodyTextPropsStrict,\n Eyebrow,\n Popover,\n Stack,\n Tooltip,\n} from '@servicetitan/design-system';\nimport * as Styles from './stat-card.module.less';\nimport { formatValue, NumberFormatter } from '../../utils/formatters';\nimport { Icon } from '@servicetitan/anvil2';\nimport TrendingUpSVG from '@servicetitan/anvil2/assets/icons/material/round/trending_up.svg';\nimport TrendingDownSVG from '@servicetitan/anvil2/assets/icons/material/round/trending_down.svg';\n\nconst calculateDiff = (\n value: number,\n prev: number,\n percents?: boolean\n): [number, number, boolean] => {\n const diff = (value - prev) * (percents ? 100 : 1);\n const absDiff = Math.abs(diff);\n let diffPercent = 0;\n\n if (percents) {\n diffPercent = diff;\n } else if (absDiff) {\n diffPercent = prev ? (100 * absDiff) / prev : 100;\n }\n\n return [absDiff, diffPercent, diff >= 0];\n};\n\nconst formatDifference = (value: number, isPlus: boolean, format: NumberFormatter): string => {\n return (isPlus ? '+' : '-') + formatValue(value, format);\n};\n\nconst formatDifferencePercentage = (value: number, isPlus: boolean): string => {\n if (!value) {\n return '';\n }\n\n return (isPlus ? '+' : '-') + formatValue(value, 'percent-100');\n};\n\ninterface StatDiffProps {\n value?: number;\n prev?: number;\n size?: BodyTextPropsStrict['size'];\n format: NumberFormatter;\n inverted?: boolean;\n neutral?: boolean;\n className?: string;\n diffPercentOnly?: boolean;\n}\n\nexport const StatDiff: FC<StatDiffProps> = ({\n value,\n prev,\n size,\n format,\n inverted,\n neutral,\n className,\n diffPercentOnly = false,\n}) => {\n const percents = format === 'percent';\n const [absDiff, diffPercent, isIncrease] = calculateDiff(value ?? 0, prev ?? 0, percents);\n const diff =\n absDiff === 0 ? (\n ''\n ) : (\n <Icon\n svg={isIncrease ? TrendingUpSVG : TrendingDownSVG}\n color={\n neutral\n ? 'neutral-200'\n : inverted\n ? isIncrease\n ? 'red'\n : 'green'\n : isIncrease\n ? 'green'\n : 'red'\n }\n />\n );\n let text = '';\n\n if (percents) {\n text += formatDifferencePercentage(absDiff, isIncrease);\n } else {\n const diffPercentage = formatDifferencePercentage(diffPercent, isIncrease);\n\n if (diffPercentOnly) {\n text += `${diffPercentage}`;\n } else {\n text += `${formatDifference(absDiff, isIncrease, format)}`;\n\n if (diffPercent !== 0) {\n text += ` (${diffPercentage})`;\n }\n }\n }\n\n return (\n <Stack\n className={classNames(Styles.statDiff, className)}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <Stack.Item className=\"m-r-half m-t-half\">\n <span>{diff}</span>\n </Stack.Item>\n <Stack.Item>\n <BodyText\n size={size ?? 'small'}\n data-cy=\"stat-diff-value\"\n className={classNames({\n 'c-red-500': !neutral && (inverted ? isIncrease : !isIncrease),\n 'c-green-500': !neutral && (inverted ? !isIncrease : isIncrease),\n 'c-neutral-200': !!neutral,\n })}\n >\n {value === undefined ? '\\u00A0' : text}\n </BodyText>\n </Stack.Item>\n </Stack>\n );\n};\n\nexport interface StatCardProps {\n title: string;\n description?: string;\n popoverContent?: ReactNode;\n value?: number;\n prev?: number;\n percent?: boolean;\n money?: boolean;\n rate?: boolean;\n clean?: boolean;\n inverted?: boolean;\n neutral?: boolean;\n fill?: boolean;\n valueOnly?: boolean;\n className?: string;\n diffPercentOnly?: boolean;\n}\n\nexport const StatCard: FC<StatCardProps> = ({\n title,\n description,\n popoverContent,\n value,\n percent,\n money,\n rate,\n prev,\n clean,\n inverted,\n neutral,\n fill,\n valueOnly,\n className,\n diffPercentOnly = false,\n}) => {\n const [popoverShown, setPopoverShown] = useState(false);\n const format = money ? 'money' : percent ? 'percent' : rate ? 'rate' : 'number';\n const val = value === undefined ? '\\u00A0' : formatValue(value, format);\n\n const eyebrow = (\n <Eyebrow\n className={classNames(Styles.title, 'ta-center')}\n data-cy={`marketing-stat-${title}-title`}\n onMouseEnter={() => {\n setPopoverShown(true);\n }}\n >\n {title}\n </Eyebrow>\n );\n\n return (\n <Stack\n direction=\"column\"\n alignItems=\"center\"\n className={classNames(\n 'p-y-3',\n {\n 'bg-white border-radius-2 border': !clean,\n 'flex-grow-1 flex-basis-0': fill,\n },\n className\n )}\n onMouseLeave={() => setPopoverShown(false)}\n >\n {popoverContent ? (\n <Popover open={popoverShown} trigger={eyebrow}>\n {popoverContent}\n </Popover>\n ) : description ? (\n <Tooltip text={description} data-cy={`marketing-stat-${title}-tooltip`}>\n {eyebrow}\n </Tooltip>\n ) : (\n eyebrow\n )}\n <BodyText className=\"fs-6-i ff-display\" data-cy={`marketing-stat-${title}-value`}>\n {val}\n </BodyText>\n {!valueOnly && (\n <StatDiff\n value={value}\n prev={prev}\n format={format}\n inverted={inverted}\n neutral={neutral}\n diffPercentOnly={diffPercentOnly}\n />\n )}\n </Stack>\n );\n};\n"],"names":["useState","classNames","BodyText","Eyebrow","Popover","Stack","Tooltip","Styles","formatValue","Icon","TrendingUpSVG","TrendingDownSVG","calculateDiff","value","prev","percents","diff","absDiff","Math","abs","diffPercent","formatDifference","isPlus","format","formatDifferencePercentage","StatDiff","size","inverted","neutral","className","diffPercentOnly","isIncrease","svg","color","text","diffPercentage","statDiff","justifyContent","alignItems","Item","span","data-cy","undefined","StatCard","title","description","popoverContent","percent","money","rate","clean","fill","valueOnly","popoverShown","setPopoverShown","val","eyebrow","onMouseEnter","direction","onMouseLeave","open","trigger"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/stat/stat-card.tsx"],"sourcesContent":["import { FC, ReactNode, useState } from 'react';\nimport classNames from 'classnames';\nimport {\n BodyText,\n BodyTextPropsStrict,\n Eyebrow,\n Popover,\n Stack,\n Tooltip,\n} from '@servicetitan/design-system';\nimport * as Styles from './stat-card.module.less';\nimport { formatValue, NumberFormatter } from '../../utils/formatters';\nimport { Icon } from '@servicetitan/anvil2';\nimport TrendingUpSVG from '@servicetitan/anvil2/assets/icons/material/round/trending_up.svg';\nimport TrendingDownSVG from '@servicetitan/anvil2/assets/icons/material/round/trending_down.svg';\n\nconst calculateDiff = (\n value: number,\n prev: number,\n percents?: boolean\n): [number, number, boolean] => {\n const diff = (value - prev) * (percents ? 100 : 1);\n const absDiff = Math.abs(diff);\n let diffPercent = 0;\n\n if (percents) {\n diffPercent = diff;\n } else if (absDiff) {\n diffPercent = prev ? (100 * absDiff) / prev : 100;\n }\n\n return [absDiff, diffPercent, diff >= 0];\n};\n\nconst formatDifference = (value: number, isPlus: boolean, format: NumberFormatter): string => {\n return (isPlus ? '+' : '-') + formatValue(value, format);\n};\n\nconst formatDifferencePercentage = (value: number, isPlus: boolean): string => {\n if (!value) {\n return '';\n }\n\n return (isPlus ? '+' : '-') + formatValue(value, 'percent-100');\n};\n\ninterface StatDiffProps {\n value?: number;\n prev?: number;\n size?: BodyTextPropsStrict['size'];\n format: NumberFormatter;\n inverted?: boolean;\n neutral?: boolean;\n className?: string;\n diffPercentOnly?: boolean;\n}\n\nexport const StatDiff: FC<StatDiffProps> = ({\n value,\n prev,\n size,\n format,\n inverted,\n neutral,\n className,\n diffPercentOnly = false,\n}) => {\n const percents = format === 'percent';\n const [absDiff, diffPercent, isIncrease] = calculateDiff(value ?? 0, prev ?? 0, percents);\n const diff =\n absDiff === 0 ? (\n ''\n ) : (\n <Icon\n svg={isIncrease ? TrendingUpSVG : TrendingDownSVG}\n color={\n neutral\n ? 'neutral-200'\n : inverted\n ? isIncrease\n ? 'red'\n : 'green'\n : isIncrease\n ? 'green'\n : 'red'\n }\n />\n );\n let text = '';\n\n if (percents) {\n text += formatDifferencePercentage(absDiff, isIncrease);\n } else {\n const diffPercentage = formatDifferencePercentage(diffPercent, isIncrease);\n\n if (diffPercentOnly) {\n text += `${diffPercentage}`;\n } else {\n text += `${formatDifference(absDiff, isIncrease, format)}`;\n\n if (diffPercent !== 0) {\n text += ` (${diffPercentage})`;\n }\n }\n }\n\n return (\n <Stack\n className={classNames(Styles.statDiff, className)}\n justifyContent=\"center\"\n alignItems=\"center\"\n >\n <Stack.Item className=\"m-r-half m-t-half\">\n <span>{diff}</span>\n </Stack.Item>\n <Stack.Item>\n <BodyText\n size={size ?? 'small'}\n data-cy=\"stat-diff-value\"\n className={classNames({\n 'c-red-500': !neutral && (inverted ? isIncrease : !isIncrease),\n 'c-green-500': !neutral && (inverted ? !isIncrease : isIncrease),\n 'c-neutral-200': !!neutral,\n })}\n >\n {value === undefined ? '\\u00A0' : text}\n </BodyText>\n </Stack.Item>\n </Stack>\n );\n};\n\nexport interface StatCardProps {\n title: string;\n description?: string;\n popoverContent?: ReactNode;\n value?: number;\n prev?: number;\n percent?: boolean;\n money?: boolean;\n rate?: boolean;\n clean?: boolean;\n inverted?: boolean;\n neutral?: boolean;\n fill?: boolean;\n valueOnly?: boolean;\n className?: string;\n diffPercentOnly?: boolean;\n}\n\nexport const StatCard: FC<StatCardProps> = ({\n title,\n description,\n popoverContent,\n value,\n percent,\n money,\n rate,\n prev,\n clean,\n inverted,\n neutral,\n fill,\n valueOnly,\n className,\n diffPercentOnly = false,\n}) => {\n const [popoverShown, setPopoverShown] = useState(false);\n const format = money ? 'money' : percent ? 'percent' : rate ? 'rate' : 'number';\n const val = value === undefined ? '\\u00A0' : formatValue(value, format);\n\n const eyebrow = (\n <Eyebrow\n className={classNames(Styles.title, 'ta-center')}\n data-cy={`marketing-stat-${title}-title`}\n onMouseEnter={() => {\n setPopoverShown(true);\n }}\n >\n {title}\n </Eyebrow>\n );\n\n return (\n <Stack\n direction=\"column\"\n alignItems=\"center\"\n className={classNames(\n 'p-y-3',\n {\n 'bg-white border-radius-2 border': !clean,\n 'flex-grow-1 flex-basis-0': fill,\n },\n className\n )}\n onMouseLeave={() => setPopoverShown(false)}\n >\n {popoverContent ? (\n <Popover open={popoverShown} trigger={eyebrow}>\n {popoverContent}\n </Popover>\n ) : description ? (\n <Tooltip text={description} data-cy={`marketing-stat-${title}-tooltip`}>\n {eyebrow}\n </Tooltip>\n ) : (\n eyebrow\n )}\n <BodyText className=\"fs-6-i ff-display\" data-cy={`marketing-stat-${title}-value`}>\n {val}\n </BodyText>\n {!valueOnly && (\n <StatDiff\n value={value}\n prev={prev}\n format={format}\n inverted={inverted}\n neutral={neutral}\n diffPercentOnly={diffPercentOnly}\n />\n )}\n </Stack>\n );\n};\n"],"names":["useState","classNames","BodyText","Eyebrow","Popover","Stack","Tooltip","Styles","formatValue","Icon","TrendingUpSVG","TrendingDownSVG","calculateDiff","value","prev","percents","diff","absDiff","Math","abs","diffPercent","formatDifference","isPlus","format","formatDifferencePercentage","StatDiff","size","inverted","neutral","className","diffPercentOnly","isIncrease","svg","color","text","diffPercentage","statDiff","justifyContent","alignItems","Item","span","data-cy","undefined","StatCard","title","description","popoverContent","percent","money","rate","clean","fill","valueOnly","popoverShown","setPopoverShown","val","eyebrow","onMouseEnter","direction","onMouseLeave","open","trigger"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/ui/line-text/line-text.tsx"],"sourcesContent":["import { useMemo, FC } from 'react';\nimport classNames from 'classnames';\nimport {\n BodyText,\n BodyTextPropsStrict,\n Headline,\n HeadlinePropsStrict,\n MoreDetails,\n} from '@servicetitan/design-system';\nimport { useClientRect } from '../../../utils/use-client-rect';\nimport * as Styles from './line-text.module.less';\n\nconst useLimited = (): [\n (node: HTMLElement | null) => void,\n (node: HTMLElement | null) => void,\n boolean,\n] => {\n const [rect1, ref1] = useClientRect();\n const [rect2, ref2] = useClientRect();\n const limited = useMemo(\n () => !!rect1?.width && !!rect2?.width && (rect2?.width || 0) > (rect1?.width || 0),\n [rect1, rect2]\n );\n\n return [ref1, ref2, limited];\n};\n\nexport interface BodyTextLineProps extends BodyTextPropsStrict {\n wrapperClassName?: string;\n children?: string;\n}\n\nexport const BodyTextLine: FC<BodyTextLineProps> = ({ children, wrapperClassName, ...props }) => {\n const [ref1, ref2, limited] = useLimited();\n\n return (\n <div\n ref={ref1}\n className={classNames(\n wrapperClassName,\n 'w-100 position-relative d-f flex-row of-x-hidden'\n )}\n >\n <BodyText\n {...props}\n className={classNames(props.className, Styles.mainText, {\n [Styles.mainTextHidden]: limited,\n })}\n ref={ref2}\n >\n {children}\n </BodyText>\n\n {limited && (\n <div className={Styles.moreDetailsWrapper}>\n <BodyText\n {...props}\n className={classNames(\n props.className,\n Styles.moreDetailsText,\n 't-truncate'\n )}\n >\n {children}\n </BodyText>\n <MoreDetails full={children ?? ''} short=\"\" size={props.size} />\n </div>\n )}\n </div>\n );\n};\n\nexport interface HeadlineLineProps extends HeadlinePropsStrict {\n wrapperClassName?: string;\n children?: string;\n}\n\nexport const HeadlineLine: FC<HeadlineLineProps> = ({ children, wrapperClassName, ...props }) => {\n const [ref1, ref2, limited] = useLimited();\n\n return (\n <div\n ref={ref1}\n className={classNames(wrapperClassName, 'w-100 position-relative d-f flex-row')}\n >\n <Headline\n {...props}\n className={classNames(props.className, Styles.mainText, {\n [Styles.mainTextHidden]: limited,\n })}\n ref={ref2}\n >\n {children}\n </Headline>\n\n {limited && (\n <div className={Styles.moreDetailsWrapper}>\n <Headline\n {...props}\n className={classNames(\n props.className,\n Styles.moreDetailsText,\n 't-truncate'\n )}\n >\n {children}\n </Headline>\n <MoreDetails full={children ?? ''} short=\"\" />\n </div>\n )}\n </div>\n );\n};\n"],"names":["useMemo","classNames","BodyText","Headline","MoreDetails","useClientRect","Styles","useLimited","rect1","ref1","rect2","ref2","limited","width","BodyTextLine","children","wrapperClassName","props","div","ref","className","mainText","mainTextHidden","moreDetailsWrapper","moreDetailsText","full","short","size","HeadlineLine"],"mappings":";AAAA,SAASA,OAAO,QAAY,QAAQ;AACpC,OAAOC,gBAAgB,aAAa;AACpC,SACIC,QAAQ,EAERC,QAAQ,EAERC,WAAW,QACR,8BAA8B;AACrC,SAASC,aAAa,QAAQ,iCAAiC;AAC/D,YAAYC,YAAY,0BAA0B;AAElD,MAAMC,aAAa;IAKf,MAAM,CAACC,OAAOC,KAAK,GAAGJ;IACtB,MAAM,CAACK,OAAOC,KAAK,GAAGN;IACtB,MAAMO,UAAUZ,QACZ,IAAM,CAAC,EAACQ,kBAAAA,4BAAAA,MAAOK,KAAK,KAAI,CAAC,EAACH,kBAAAA,4BAAAA,MAAOG,KAAK,KAAI,AAACH,CAAAA,CAAAA,kBAAAA,4BAAAA,MAAOG,KAAK,KAAI,CAAA,IAAML,CAAAA,CAAAA,kBAAAA,4BAAAA,MAAOK,KAAK,KAAI,CAAA,GACjF;QAACL;QAAOE;KAAM;IAGlB,OAAO;QAACD;QAAME;QAAMC;KAAQ;AAChC;AAOA,OAAO,MAAME,eAAsC,CAAC,EAAEC,QAAQ,EAAEC,gBAAgB,EAAE,GAAGC,OAAO;IACxF,MAAM,CAACR,MAAME,MAAMC,QAAQ,GAAGL;IAE9B,qBACI,MAACW;QACGC,KAAKV;QACLW,WAAWnB,WACPe,kBACA;;0BAGJ,KAACd;gBACI,GAAGe,KAAK;gBACTG,WAAWnB,WAAWgB,MAAMG,SAAS,EAAEd,OAAOe,QAAQ,EAAE;oBACpD,CAACf,OAAOgB,cAAc,CAAC,EAAEV;gBAC7B;gBACAO,KAAKR;0BAEJI;;YAGJH,yBACG,MAACM;gBAAIE,WAAWd,OAAOiB,kBAAkB;;kCACrC,KAACrB;wBACI,GAAGe,KAAK;wBACTG,WAAWnB,WACPgB,MAAMG,SAAS,EACfd,OAAOkB,eAAe,EACtB;kCAGHT;;kCAEL,KAACX;wBAAYqB,MAAMV,qBAAAA,sBAAAA,WAAY;wBAAIW,OAAM;wBAAGC,MAAMV,MAAMU,IAAI;;;;;;AAKhF,EAAE;AAOF,OAAO,MAAMC,eAAsC,CAAC,EAAEb,QAAQ,EAAEC,gBAAgB,EAAE,GAAGC,OAAO;IACxF,MAAM,CAACR,MAAME,MAAMC,QAAQ,GAAGL;IAE9B,qBACI,MAACW;QACGC,KAAKV;QACLW,WAAWnB,WAAWe,kBAAkB;;0BAExC,KAACb;gBACI,GAAGc,KAAK;gBACTG,WAAWnB,WAAWgB,MAAMG,SAAS,EAAEd,OAAOe,QAAQ,EAAE;oBACpD,CAACf,OAAOgB,cAAc,CAAC,EAAEV;gBAC7B;gBACAO,KAAKR;0BAEJI;;YAGJH,yBACG,MAACM;gBAAIE,WAAWd,OAAOiB,kBAAkB;;kCACrC,KAACpB;wBACI,GAAGc,KAAK;wBACTG,WAAWnB,WACPgB,MAAMG,SAAS,EACfd,OAAOkB,eAAe,EACtB;kCAGHT;;kCAEL,KAACX;wBAAYqB,MAAMV,qBAAAA,sBAAAA,WAAY;wBAAIW,OAAM;;;;;;AAK7D,EAAE"}
1
+ {"version":3,"sources":["../../../../src/components/ui/line-text/line-text.tsx"],"sourcesContent":["import { useMemo, FC } from 'react';\nimport classNames from 'classnames';\nimport {\n BodyText,\n BodyTextPropsStrict,\n Headline,\n HeadlinePropsStrict,\n MoreDetails,\n} from '@servicetitan/design-system';\nimport { useClientRect } from '../../../utils/use-client-rect';\nimport * as Styles from './line-text.module.less';\n\nconst useLimited = (): [\n (node: HTMLElement | null) => void,\n (node: HTMLElement | null) => void,\n boolean,\n] => {\n const [rect1, ref1] = useClientRect();\n const [rect2, ref2] = useClientRect();\n const limited = useMemo(\n () => !!rect1?.width && !!rect2?.width && (rect2?.width || 0) > (rect1?.width || 0),\n [rect1, rect2]\n );\n\n return [ref1, ref2, limited];\n};\n\nexport interface BodyTextLineProps extends BodyTextPropsStrict {\n wrapperClassName?: string;\n children?: string;\n}\n\nexport const BodyTextLine: FC<BodyTextLineProps> = ({ children, wrapperClassName, ...props }) => {\n const [ref1, ref2, limited] = useLimited();\n\n return (\n <div\n ref={ref1}\n className={classNames(\n wrapperClassName,\n 'w-100 position-relative d-f flex-row of-x-hidden'\n )}\n >\n <BodyText\n {...props}\n className={classNames(props.className, Styles.mainText, {\n [Styles.mainTextHidden]: limited,\n })}\n ref={ref2}\n >\n {children}\n </BodyText>\n\n {limited && (\n <div className={Styles.moreDetailsWrapper}>\n <BodyText\n {...props}\n className={classNames(\n props.className,\n Styles.moreDetailsText,\n 't-truncate'\n )}\n >\n {children}\n </BodyText>\n <MoreDetails full={children ?? ''} short=\"\" size={props.size} />\n </div>\n )}\n </div>\n );\n};\n\nexport interface HeadlineLineProps extends HeadlinePropsStrict {\n wrapperClassName?: string;\n children?: string;\n}\n\nexport const HeadlineLine: FC<HeadlineLineProps> = ({ children, wrapperClassName, ...props }) => {\n const [ref1, ref2, limited] = useLimited();\n\n return (\n <div\n ref={ref1}\n className={classNames(wrapperClassName, 'w-100 position-relative d-f flex-row')}\n >\n <Headline\n {...props}\n className={classNames(props.className, Styles.mainText, {\n [Styles.mainTextHidden]: limited,\n })}\n ref={ref2}\n >\n {children}\n </Headline>\n\n {limited && (\n <div className={Styles.moreDetailsWrapper}>\n <Headline\n {...props}\n className={classNames(\n props.className,\n Styles.moreDetailsText,\n 't-truncate'\n )}\n >\n {children}\n </Headline>\n <MoreDetails full={children ?? ''} short=\"\" />\n </div>\n )}\n </div>\n );\n};\n"],"names":["useMemo","classNames","BodyText","Headline","MoreDetails","useClientRect","Styles","useLimited","rect1","ref1","rect2","ref2","limited","width","BodyTextLine","children","wrapperClassName","props","div","ref","className","mainText","mainTextHidden","moreDetailsWrapper","moreDetailsText","full","short","size","HeadlineLine"],"mappings":";AAAA,SAASA,OAAO,QAAY,QAAQ;AACpC,OAAOC,gBAAgB,aAAa;AACpC,SACIC,QAAQ,EAERC,QAAQ,EAERC,WAAW,QACR,8BAA8B;AACrC,SAASC,aAAa,QAAQ,iCAAiC;AAC/D,YAAYC,YAAY,0BAA0B;AAElD,MAAMC,aAAa;IAKf,MAAM,CAACC,OAAOC,KAAK,GAAGJ;IACtB,MAAM,CAACK,OAAOC,KAAK,GAAGN;IACtB,MAAMO,UAAUZ,QACZ,IAAM,CAAC,EAACQ,kBAAAA,4BAAAA,MAAOK,KAAK,KAAI,CAAC,EAACH,kBAAAA,4BAAAA,MAAOG,KAAK,KAAI,AAACH,CAAAA,CAAAA,kBAAAA,4BAAAA,MAAOG,KAAK,KAAI,CAAA,IAAML,CAAAA,CAAAA,kBAAAA,4BAAAA,MAAOK,KAAK,KAAI,CAAA,GACjF;QAACL;QAAOE;KAAM;IAGlB,OAAO;QAACD;QAAME;QAAMC;KAAQ;AAChC;AAOA,OAAO,MAAME,eAAsC,CAAC,EAAEC,QAAQ,EAAEC,gBAAgB,EAAE,GAAGC,OAAO;IACxF,MAAM,CAACR,MAAME,MAAMC,QAAQ,GAAGL;IAE9B,qBACI,MAACW;QACGC,KAAKV;QACLW,WAAWnB,WACPe,kBACA;;0BAGJ,KAACd;gBACI,GAAGe,KAAK;gBACTG,WAAWnB,WAAWgB,MAAMG,SAAS,EAAEd,OAAOe,QAAQ,EAAE;oBACpD,CAACf,OAAOgB,cAAc,CAAC,EAAEV;gBAC7B;gBACAO,KAAKR;0BAEJI;;YAGJH,yBACG,MAACM;gBAAIE,WAAWd,OAAOiB,kBAAkB;;kCACrC,KAACrB;wBACI,GAAGe,KAAK;wBACTG,WAAWnB,WACPgB,MAAMG,SAAS,EACfd,OAAOkB,eAAe,EACtB;kCAGHT;;kCAEL,KAACX;wBAAYqB,IAAI,EAAEV,qBAAAA,sBAAAA,WAAY;wBAAIW,OAAM;wBAAGC,MAAMV,MAAMU,IAAI;;;;;;AAKhF,EAAE;AAOF,OAAO,MAAMC,eAAsC,CAAC,EAAEb,QAAQ,EAAEC,gBAAgB,EAAE,GAAGC,OAAO;IACxF,MAAM,CAACR,MAAME,MAAMC,QAAQ,GAAGL;IAE9B,qBACI,MAACW;QACGC,KAAKV;QACLW,WAAWnB,WAAWe,kBAAkB;;0BAExC,KAACb;gBACI,GAAGc,KAAK;gBACTG,WAAWnB,WAAWgB,MAAMG,SAAS,EAAEd,OAAOe,QAAQ,EAAE;oBACpD,CAACf,OAAOgB,cAAc,CAAC,EAAEV;gBAC7B;gBACAO,KAAKR;0BAEJI;;YAGJH,yBACG,MAACM;gBAAIE,WAAWd,OAAOiB,kBAAkB;;kCACrC,KAACpB;wBACI,GAAGc,KAAK;wBACTG,WAAWnB,WACPgB,MAAMG,SAAS,EACfd,OAAOkB,eAAe,EACtB;kCAGHT;;kCAEL,KAACX;wBAAYqB,IAAI,EAAEV,qBAAAA,sBAAAA,WAAY;wBAAIW,OAAM;;;;;;AAK7D,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"file":"date-range-picker-state.d.ts","sourceRoot":"","sources":["../../../src/utils/date/date-range-picker-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,UAAU,0BAA0B;IAChC,YAAY,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACrC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,+BAA+B,CAAC,UAAU,SAAS,MAAM,CACtE,SAAQ,wBAAwB;IAChC,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IACrD,QAAQ,CAAC,cAAc,CAAC,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAC;CAC/D;AAED,qBAAa,oBAAoB,CAAC,UAAU,SAAS,MAAM,GAAG,KAAK;IACnD,KAAK,CAAC,EAAE,SAAS,CAAC;IAE9B,QAAQ,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAEtD,IAAc,cAAc,IAAI,qBAAqB,CAAC,UAAU,CAAC,GAAG,SAAS,CAM5E;gBAEW,MAAM,CAAC,EAAE,0BAA0B,EAAE,OAAO,CAAC,EAAE,sBAAsB,CAAC,UAAU,CAAC;IAY7F,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,0BAA0B,GAAG,wBAAwB;IAI5E,MAAM,CAAC,iBAAiB,CAAC,UAAU,SAAS,MAAM,EAC9C,OAAO,EAAE,sBAAsB,CAAC,UAAU,CAAC,EAC3C,MAAM,CAAC,EAAE,0BAA0B,GACpC,+BAA+B,CAAC,UAAU,CAAC;IAOtC,QAAQ,GAAI,MAAM,SAAS,UAEjC;CACL"}
1
+ {"version":3,"file":"date-range-picker-state.d.ts","sourceRoot":"","sources":["../../../src/utils/date/date-range-picker-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAGrE,UAAU,0BAA0B;IAChC,YAAY,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACrC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,+BAA+B,CAC5C,UAAU,SAAS,MAAM,CAC3B,SAAQ,wBAAwB;IAC9B,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IACrD,QAAQ,CAAC,cAAc,CAAC,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAC;CAC/D;AAED,qBAAa,oBAAoB,CAAC,UAAU,SAAS,MAAM,GAAG,KAAK;IACnD,KAAK,CAAC,EAAE,SAAS,CAAC;IAE9B,QAAQ,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAEtD,IAAc,cAAc,IAAI,qBAAqB,CAAC,UAAU,CAAC,GAAG,SAAS,CAM5E;gBAEW,MAAM,CAAC,EAAE,0BAA0B,EAAE,OAAO,CAAC,EAAE,sBAAsB,CAAC,UAAU,CAAC;IAY7F,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,0BAA0B,GAAG,wBAAwB;IAI5E,MAAM,CAAC,iBAAiB,CAAC,UAAU,SAAS,MAAM,EAC9C,OAAO,EAAE,sBAAsB,CAAC,UAAU,CAAC,EAC3C,MAAM,CAAC,EAAE,0BAA0B,GACpC,+BAA+B,CAAC,UAAU,CAAC;IAOtC,QAAQ,GAAI,MAAM,SAAS,UAEjC;CACL"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/date/date-range-picker-state.ts"],"sourcesContent":["import type { DateRangePickerOption } from './date-range-picker-options';\nimport type { DateRange } from './date';\nimport { DateRangePickerOptions } from './date-range-picker-options';\nimport { action, computed, makeObservable, observable } from 'mobx';\n\ninterface DateRangePickerStateConfig {\n defaultValue?: DateRange;\n}\n\nexport interface DateRangePickerStateType {\n value?: DateRange;\n onChange(val?: DateRange): void;\n}\n\nexport interface DateRangePickerOptionsStateType<OptionKeys extends string>\n extends DateRangePickerStateType {\n readonly options: DateRangePickerOptions<OptionKeys>;\n readonly selectedOption?: DateRangePickerOption<OptionKeys>;\n}\n\nexport class DateRangePickerState<OptionKeys extends string = never> {\n @observable value?: DateRange;\n\n readonly options?: DateRangePickerOptions<OptionKeys>;\n\n @computed get selectedOption(): DateRangePickerOption<OptionKeys> | undefined {\n if (!this.value || !this.options) {\n return undefined;\n }\n\n return this.options.findOption(this.value);\n }\n\n constructor(config?: DateRangePickerStateConfig, options?: DateRangePickerOptions<OptionKeys>) {\n makeObservable(this);\n\n this.options = options;\n\n if (config?.defaultValue) {\n this.value = config.defaultValue;\n } else if (this.options?.defaultOption) {\n this.value = this.options.findOption(this.options.defaultOption)?.value;\n }\n }\n\n static create(config?: DateRangePickerStateConfig): DateRangePickerStateType {\n return new DateRangePickerState(config);\n }\n\n static createWithOptions<OptionKeys extends string>(\n options: DateRangePickerOptions<OptionKeys>,\n config?: DateRangePickerStateConfig\n ): DateRangePickerOptionsStateType<OptionKeys> {\n return new DateRangePickerState(\n config,\n options\n ) as DateRangePickerOptionsStateType<OptionKeys>;\n }\n\n @action onChange = (val?: DateRange) => {\n this.value = val;\n };\n}\n"],"names":["action","computed","makeObservable","observable","DateRangePickerState","selectedOption","value","options","undefined","findOption","create","config","createWithOptions","onChange","val","defaultValue","defaultOption"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAGA,SAASA,MAAM,EAAEC,QAAQ,EAAEC,cAAc,EAAEC,UAAU,QAAQ,OAAO;AAiBpE,OAAO,MAAMC;IAKT,IAAcC,iBAAgE;QAC1E,IAAI,CAAC,IAAI,CAACC,KAAK,IAAI,CAAC,IAAI,CAACC,OAAO,EAAE;YAC9B,OAAOC;QACX;QAEA,OAAO,IAAI,CAACD,OAAO,CAACE,UAAU,CAAC,IAAI,CAACH,KAAK;IAC7C;IAcA,OAAOI,OAAOC,MAAmC,EAA4B;QACzE,OAAO,IAAIP,qBAAqBO;IACpC;IAEA,OAAOC,kBACHL,OAA2C,EAC3CI,MAAmC,EACQ;QAC3C,OAAO,IAAIP,qBACPO,QACAJ;IAER;IAxBA,YAAYI,MAAmC,EAAEJ,OAA4C,CAAE;YAOhF;QAnBf,uBAAYD,SAAZ,KAAA;QAEA,uBAASC,WAAT,KAAA;QAoCA,uBAAQM,YAAW,CAACC;YAChB,IAAI,CAACR,KAAK,GAAGQ;QACjB;QA3BIZ,eAAe,IAAI;QAEnB,IAAI,CAACK,OAAO,GAAGA;QAEf,IAAII,mBAAAA,6BAAAA,OAAQI,YAAY,EAAE;YACtB,IAAI,CAACT,KAAK,GAAGK,OAAOI,YAAY;QACpC,OAAO,KAAI,gBAAA,IAAI,CAACR,OAAO,cAAZ,oCAAA,cAAcS,aAAa,EAAE;gBACvB;YAAb,IAAI,CAACV,KAAK,IAAG,2BAAA,IAAI,CAACC,OAAO,CAACE,UAAU,CAAC,IAAI,CAACF,OAAO,CAACS,aAAa,eAAlD,+CAAA,yBAAqDV,KAAK;QAC3E;IACJ;AAmBJ"}
1
+ {"version":3,"sources":["../../../src/utils/date/date-range-picker-state.ts"],"sourcesContent":["import type { DateRangePickerOption } from './date-range-picker-options';\nimport type { DateRange } from './date';\nimport { DateRangePickerOptions } from './date-range-picker-options';\nimport { action, computed, makeObservable, observable } from 'mobx';\n\ninterface DateRangePickerStateConfig {\n defaultValue?: DateRange;\n}\n\nexport interface DateRangePickerStateType {\n value?: DateRange;\n onChange(val?: DateRange): void;\n}\n\nexport interface DateRangePickerOptionsStateType<\n OptionKeys extends string,\n> extends DateRangePickerStateType {\n readonly options: DateRangePickerOptions<OptionKeys>;\n readonly selectedOption?: DateRangePickerOption<OptionKeys>;\n}\n\nexport class DateRangePickerState<OptionKeys extends string = never> {\n @observable value?: DateRange;\n\n readonly options?: DateRangePickerOptions<OptionKeys>;\n\n @computed get selectedOption(): DateRangePickerOption<OptionKeys> | undefined {\n if (!this.value || !this.options) {\n return undefined;\n }\n\n return this.options.findOption(this.value);\n }\n\n constructor(config?: DateRangePickerStateConfig, options?: DateRangePickerOptions<OptionKeys>) {\n makeObservable(this);\n\n this.options = options;\n\n if (config?.defaultValue) {\n this.value = config.defaultValue;\n } else if (this.options?.defaultOption) {\n this.value = this.options.findOption(this.options.defaultOption)?.value;\n }\n }\n\n static create(config?: DateRangePickerStateConfig): DateRangePickerStateType {\n return new DateRangePickerState(config);\n }\n\n static createWithOptions<OptionKeys extends string>(\n options: DateRangePickerOptions<OptionKeys>,\n config?: DateRangePickerStateConfig\n ): DateRangePickerOptionsStateType<OptionKeys> {\n return new DateRangePickerState(\n config,\n options\n ) as DateRangePickerOptionsStateType<OptionKeys>;\n }\n\n @action onChange = (val?: DateRange) => {\n this.value = val;\n };\n}\n"],"names":["action","computed","makeObservable","observable","DateRangePickerState","selectedOption","value","options","undefined","findOption","create","config","createWithOptions","onChange","val","defaultValue","defaultOption"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAGA,SAASA,MAAM,EAAEC,QAAQ,EAAEC,cAAc,EAAEC,UAAU,QAAQ,OAAO;AAkBpE,OAAO,MAAMC;IAKT,IAAcC,iBAAgE;QAC1E,IAAI,CAAC,IAAI,CAACC,KAAK,IAAI,CAAC,IAAI,CAACC,OAAO,EAAE;YAC9B,OAAOC;QACX;QAEA,OAAO,IAAI,CAACD,OAAO,CAACE,UAAU,CAAC,IAAI,CAACH,KAAK;IAC7C;IAcA,OAAOI,OAAOC,MAAmC,EAA4B;QACzE,OAAO,IAAIP,qBAAqBO;IACpC;IAEA,OAAOC,kBACHL,OAA2C,EAC3CI,MAAmC,EACQ;QAC3C,OAAO,IAAIP,qBACPO,QACAJ;IAER;IAxBA,YAAYI,MAAmC,EAAEJ,OAA4C,CAAE;YAOhF;QAnBf,uBAAYD,SAAZ,KAAA;QAEA,uBAASC,WAAT,KAAA;QAoCA,uBAAQM,YAAW,CAACC;YAChB,IAAI,CAACR,KAAK,GAAGQ;QACjB;QA3BIZ,eAAe,IAAI;QAEnB,IAAI,CAACK,OAAO,GAAGA;QAEf,IAAII,mBAAAA,6BAAAA,OAAQI,YAAY,EAAE;YACtB,IAAI,CAACT,KAAK,GAAGK,OAAOI,YAAY;QACpC,OAAO,KAAI,gBAAA,IAAI,CAACR,OAAO,cAAZ,oCAAA,cAAcS,aAAa,EAAE;gBACvB;YAAb,IAAI,CAACV,KAAK,IAAG,2BAAA,IAAI,CAACC,OAAO,CAACE,UAAU,CAAC,IAAI,CAACF,OAAO,CAACS,aAAa,eAAlD,+CAAA,yBAAqDV,KAAK;QAC3E;IACJ;AAmBJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/marketing-ui",
3
- "version": "7.2.0",
3
+ "version": "7.3.0",
4
4
  "description": "Marketing UI component and utils",
5
5
  "repository": {
6
6
  "type": "git",
@@ -32,7 +32,7 @@
32
32
  "devDependencies": {
33
33
  "@servicetitan/anvil2": "^2.0.1",
34
34
  "@servicetitan/design-system": "~14.5.1",
35
- "@servicetitan/react-ioc": "^33.1.1",
35
+ "@servicetitan/react-ioc": "^34.0.1",
36
36
  "@servicetitan/tokens": ">=12.2.1",
37
37
  "@testing-library/react": "^14.2.1",
38
38
  "@types/accounting": "~0.4.2",
@@ -53,5 +53,5 @@
53
53
  "less": true,
54
54
  "webpack": false
55
55
  },
56
- "gitHead": "a44925e37020acb2153c7e10215a31cd22d054c1"
56
+ "gitHead": "b013c9f39c05c44f888a5bca5ff6aadb89cd7a6f"
57
57
  }
@@ -12,8 +12,9 @@ export interface DateRangePickerStateType {
12
12
  onChange(val?: DateRange): void;
13
13
  }
14
14
 
15
- export interface DateRangePickerOptionsStateType<OptionKeys extends string>
16
- extends DateRangePickerStateType {
15
+ export interface DateRangePickerOptionsStateType<
16
+ OptionKeys extends string,
17
+ > extends DateRangePickerStateType {
17
18
  readonly options: DateRangePickerOptions<OptionKeys>;
18
19
  readonly selectedOption?: DateRangePickerOption<OptionKeys>;
19
20
  }