@stoker-platform/web-app 0.5.138 → 0.5.140

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @stoker-platform/web-app
2
2
 
3
+ ## 0.5.140
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: improve collection page transition
8
+
9
+ ## 0.5.139
10
+
11
+ ### Patch Changes
12
+
13
+ - fix: improve list chart animation
14
+
3
15
  ## 0.5.138
4
16
 
5
17
  ### 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.140",
4
4
  "type": "module",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "scripts": {
@@ -1722,11 +1722,11 @@ function Collection({
1722
1722
  {icon ? createElement(icon) : null}
1723
1723
  <h1>{collectionTitle}</h1>
1724
1724
  </Card>
1725
- {(connectionStatus === "online" || isPreloadCacheEnabled) && (
1725
+ {isInitialized && (connectionStatus === "online" || isPreloadCacheEnabled) && (
1726
1726
  <>
1727
1727
  {tab !== "calendar" &&
1728
1728
  !relationList?.loadAll &&
1729
- (hasRangeFilter || currentField) && (
1729
+ (hasRangeFilter || currentField || willHaveRangeRow) && (
1730
1730
  <div
1731
1731
  className={cn(
1732
1732
  "hidden",
@@ -1736,12 +1736,22 @@ function Collection({
1736
1736
  "transform -translate-x-1/2",
1737
1737
  )}
1738
1738
  >
1739
- <DateRangeSelector
1740
- collection={collection}
1741
- rangeSelector={rangeSelector}
1742
- setRangeSelector={setRangeSelector}
1743
- relationList={!!relationList}
1744
- />
1739
+ {hasRangeFilter || currentField ? (
1740
+ <DateRangeSelector
1741
+ collection={collection}
1742
+ rangeSelector={rangeSelector}
1743
+ setRangeSelector={setRangeSelector}
1744
+ relationList={!!relationList}
1745
+ />
1746
+ ) : (
1747
+ <div
1748
+ className={cn(
1749
+ "h-9 rounded-md border border-input bg-background shadow-sm",
1750
+ relationList ? "w-[220px]" : "w-[300px]",
1751
+ )}
1752
+ aria-hidden="true"
1753
+ />
1754
+ )}
1745
1755
  </div>
1746
1756
  )}
1747
1757
  <div className="relative ml-auto flex-1 md:grow-0 print:hidden flex items-center">
@@ -1883,7 +1893,7 @@ function Collection({
1883
1893
  {!formList &&
1884
1894
  !relationList?.loadAll &&
1885
1895
  tab !== "calendar" &&
1886
- (hasRangeFilter || currentField) && (
1896
+ (hasRangeFilter || currentField || willHaveRangeRow) && (
1887
1897
  <div
1888
1898
  className={cn(
1889
1899
  relationList
@@ -1891,12 +1901,22 @@ function Collection({
1891
1901
  : "lg:hidden 2xl:flex lg:absolute lg:left-1/2 lg:transform lg:-translate-x-1/2 lg:mt-0 mt-2",
1892
1902
  )}
1893
1903
  >
1894
- <DateRangeSelector
1895
- collection={collection}
1896
- rangeSelector={rangeSelector}
1897
- setRangeSelector={setRangeSelector}
1898
- relationList={!!relationList}
1899
- />
1904
+ {hasRangeFilter || currentField ? (
1905
+ <DateRangeSelector
1906
+ collection={collection}
1907
+ rangeSelector={rangeSelector}
1908
+ setRangeSelector={setRangeSelector}
1909
+ relationList={!!relationList}
1910
+ />
1911
+ ) : (
1912
+ <div
1913
+ className={cn(
1914
+ "h-9 rounded-md border border-input bg-background shadow-sm",
1915
+ relationList ? "w-[220px]" : "w-[300px]",
1916
+ )}
1917
+ aria-hidden="true"
1918
+ />
1919
+ )}
1900
1920
  </div>
1901
1921
  )}
1902
1922
  <div
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>