@stoker-platform/web-app 0.5.138 → 0.5.139

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 (3) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +1 -1
  3. package/src/List.tsx +100 -126
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @stoker-platform/web-app
2
2
 
3
+ ## 0.5.139
4
+
5
+ ### Patch Changes
6
+
7
+ - fix: improve list chart animation
8
+
3
9
  ## 0.5.138
4
10
 
5
11
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stoker-platform/web-app",
3
- "version": "0.5.138",
3
+ "version": "0.5.139",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "scripts": {
package/src/List.tsx CHANGED
@@ -101,6 +101,96 @@ import { getSortingValue } from "./utils/getSortingValue"
101
101
 
102
102
  export const description = "A list of records in a table. The content area has a search bar in the header."
103
103
 
104
+ type AreaChartData = { date: string; metric1: number; metric2?: number }
105
+
106
+ interface AreaMetricChartProps {
107
+ chartConfig: ChartConfig
108
+ chartData: AreaChartData[]
109
+ timeRange: string | undefined
110
+ timezone: string
111
+ showMetric2: boolean
112
+ showLegend: boolean
113
+ }
114
+
115
+ const AreaMetricChart = ({
116
+ chartConfig,
117
+ chartData,
118
+ timeRange,
119
+ timezone,
120
+ showMetric2,
121
+ showLegend,
122
+ }: AreaMetricChartProps) => {
123
+ const filteredData = useMemo(() => {
124
+ return chartData?.filter((item) => {
125
+ const date = new Date(item.date)
126
+ let daysToSubtract = 90
127
+ if (timeRange === "30d") {
128
+ daysToSubtract = 30
129
+ } else if (timeRange === "7d") {
130
+ daysToSubtract = 7
131
+ }
132
+ const startDate = DateTime.now().setZone(timezone).toJSDate()
133
+ const endDate = DateTime.now().setZone(timezone).toJSDate()
134
+ startDate.setDate(startDate.getDate() - daysToSubtract)
135
+ return date >= startDate && date <= endDate
136
+ })
137
+ }, [chartData, timeRange, timezone])
138
+
139
+ return (
140
+ <ChartContainer config={chartConfig} className="aspect-auto h-[173px] w-full">
141
+ <AreaChart data={filteredData}>
142
+ <defs>
143
+ <linearGradient id="fill1" x1="0" y1="0" x2="0" y2="1">
144
+ <stop offset="5%" stopColor="var(--chart-dark)" stopOpacity={0.8} />
145
+ <stop offset="95%" stopColor="var(--chart-light)" stopOpacity={0.1} />
146
+ </linearGradient>
147
+ <linearGradient id="fill2" x1="0" y1="0" x2="0" y2="1">
148
+ <stop offset="5%" stopColor="var(--chart-dark)" stopOpacity={0.8} />
149
+ <stop offset="95%" stopColor="var(--chart-light)" stopOpacity={0.1} />
150
+ </linearGradient>
151
+ </defs>
152
+ <CartesianGrid vertical={false} className="last:opacity-0" />
153
+ <XAxis
154
+ dataKey="date"
155
+ tickLine={false}
156
+ axisLine={false}
157
+ tickMargin={8}
158
+ minTickGap={32}
159
+ tickFormatter={(value) => {
160
+ const date = new Date(value)
161
+ return date.toLocaleDateString("en-US", {
162
+ month: "short",
163
+ day: "numeric",
164
+ })
165
+ }}
166
+ />
167
+ <YAxis hide padding={{ top: 16 }} />
168
+ <ChartTooltip
169
+ cursor={false}
170
+ content={
171
+ <ChartTooltipContent
172
+ labelFormatter={(value) => {
173
+ return new Date(value).toLocaleDateString("en-US", {
174
+ month: "short",
175
+ day: "numeric",
176
+ })
177
+ }}
178
+ indicator="dot"
179
+ />
180
+ }
181
+ />
182
+ <Area dataKey="metric1" type="natural" fill="url(#fill1)" stroke="var(--chart-dark)" stackId="a" />
183
+ {showMetric2 && (
184
+ <Area dataKey="metric2" type="natural" fill="url(#fill2)" stroke="var(--chart-light)" stackId="a" />
185
+ )}
186
+ {showLegend && <ChartLegend className="pb-3" content={<ChartLegendContent />} />}
187
+ </AreaChart>
188
+ </ChartContainer>
189
+ )
190
+ }
191
+
192
+ const AreaMetricChartMemo = memo(AreaMetricChart)
193
+
104
194
  interface ListProps {
105
195
  collection: CollectionSchema
106
196
  list: StokerRecord[] | undefined
@@ -1427,11 +1517,7 @@ export function List({
1427
1517
 
1428
1518
  const chartData =
1429
1519
  // eslint-disable-next-line security/detect-object-injection
1430
- (metricsValues[index] as {
1431
- date: string
1432
- metric1: number
1433
- metric2?: number
1434
- }[]) || []
1520
+ (metricsValues[index] as AreaChartData[]) || []
1435
1521
 
1436
1522
  const chartConfig = {
1437
1523
  visitors: {
@@ -1447,22 +1533,6 @@ export function List({
1447
1533
  },
1448
1534
  } satisfies ChartConfig
1449
1535
 
1450
- const filteredData = chartData?.filter((item) => {
1451
- const date = new Date(item.date)
1452
- let daysToSubtract = 90
1453
- // eslint-disable-next-line security/detect-object-injection
1454
- if (timeRange[metricTitle] === "30d") {
1455
- daysToSubtract = 30
1456
- // eslint-disable-next-line security/detect-object-injection
1457
- } else if (timeRange[metricTitle] === "7d") {
1458
- daysToSubtract = 7
1459
- }
1460
- const startDate = DateTime.now().setZone(timezone).toJSDate()
1461
- const endDate = DateTime.now().setZone(timezone).toJSDate()
1462
- startDate.setDate(startDate.getDate() - daysToSubtract)
1463
- return date >= startDate && date <= endDate
1464
- })
1465
-
1466
1536
  return (
1467
1537
  <div key={`metric-${index}`} className="grid gap-3 flex-1 min-w-0">
1468
1538
  <Card className="pt-0 w-full" key={`metric-${index}`}>
@@ -1504,111 +1574,15 @@ export function List({
1504
1574
  </Select>
1505
1575
  </CardHeader>
1506
1576
  <CardContent className="flex-1 px-2 sm:px-6 pb-0">
1507
- <ChartContainer
1508
- config={chartConfig}
1509
- className="aspect-auto h-[173px] w-full"
1510
- >
1511
- <AreaChart data={filteredData}>
1512
- <defs>
1513
- <linearGradient
1514
- id="fill1"
1515
- x1="0"
1516
- y1="0"
1517
- x2="0"
1518
- y2="1"
1519
- >
1520
- <stop
1521
- offset="5%"
1522
- stopColor="var(--chart-dark)"
1523
- stopOpacity={0.8}
1524
- />
1525
- <stop
1526
- offset="95%"
1527
- stopColor="var(--chart-light)"
1528
- stopOpacity={0.1}
1529
- />
1530
- </linearGradient>
1531
- <linearGradient
1532
- id="fill2"
1533
- x1="0"
1534
- y1="0"
1535
- x2="0"
1536
- y2="1"
1537
- >
1538
- <stop
1539
- offset="5%"
1540
- stopColor="var(--chart-dark)"
1541
- stopOpacity={0.8}
1542
- />
1543
- <stop
1544
- offset="95%"
1545
- stopColor="var(--chart-light)"
1546
- stopOpacity={0.1}
1547
- />
1548
- </linearGradient>
1549
- </defs>
1550
- <CartesianGrid
1551
- vertical={false}
1552
- className="last:opacity-0"
1553
- />
1554
- <XAxis
1555
- dataKey="date"
1556
- tickLine={false}
1557
- axisLine={false}
1558
- tickMargin={8}
1559
- minTickGap={32}
1560
- tickFormatter={(value) => {
1561
- const date = new Date(value)
1562
- return date.toLocaleDateString(
1563
- "en-US",
1564
- {
1565
- month: "short",
1566
- day: "numeric",
1567
- },
1568
- )
1569
- }}
1570
- />
1571
- <YAxis hide padding={{ top: 16 }} />
1572
- <ChartTooltip
1573
- cursor={false}
1574
- content={
1575
- <ChartTooltipContent
1576
- labelFormatter={(value) => {
1577
- return new Date(
1578
- value,
1579
- ).toLocaleDateString("en-US", {
1580
- month: "short",
1581
- day: "numeric",
1582
- })
1583
- }}
1584
- indicator="dot"
1585
- />
1586
- }
1587
- />
1588
- <Area
1589
- dataKey="metric1"
1590
- type="natural"
1591
- fill="url(#fill1)"
1592
- stroke="var(--chart-dark)"
1593
- stackId="a"
1594
- />
1595
- {metricField2 && (
1596
- <Area
1597
- dataKey="metric2"
1598
- type="natural"
1599
- fill="url(#fill2)"
1600
- stroke="var(--chart-light)"
1601
- stackId="a"
1602
- />
1603
- )}
1604
- {metricField1 && metricField2 && (
1605
- <ChartLegend
1606
- className="pb-3"
1607
- content={<ChartLegendContent />}
1608
- />
1609
- )}
1610
- </AreaChart>
1611
- </ChartContainer>
1577
+ <AreaMetricChartMemo
1578
+ chartConfig={chartConfig}
1579
+ chartData={chartData}
1580
+ // eslint-disable-next-line security/detect-object-injection
1581
+ timeRange={timeRange[metricTitle]}
1582
+ timezone={timezone}
1583
+ showMetric2={!!metricField2}
1584
+ showLegend={!!(metricField1 && metricField2)}
1585
+ />
1612
1586
  </CardContent>
1613
1587
  </div>
1614
1588
  </Card>