@@ -2,7 +2,6 @@ import { useTheme } from "@emotion/react";
2
2
import CancelOutlined from "@mui/icons-material/CancelOutlined" ;
3
3
import CheckCircleOutlined from "@mui/icons-material/CheckCircleOutlined" ;
4
4
import LinkOutlined from "@mui/icons-material/LinkOutlined" ;
5
- import LinearProgress from "@mui/material/LinearProgress" ;
6
5
import Link from "@mui/material/Link" ;
7
6
import Tooltip from "@mui/material/Tooltip" ;
8
7
import chroma from "chroma-js" ;
@@ -58,6 +57,7 @@ import { useEmbeddedMetadata } from "hooks/useEmbeddedMetadata";
58
57
import { useTemplateLayoutContext } from "pages/TemplatePage/TemplateLayout" ;
59
58
import { getLatencyColor } from "utils/latency" ;
60
59
import { getTemplatePageTitle } from "../utils" ;
60
+ import { AppUsageChart } from "./AppUsageChart" ;
61
61
import { DateRange as DailyPicker , type DateRangeValue } from "./DateRange" ;
62
62
import { type InsightsInterval , IntervalMenu } from "./IntervalMenu" ;
63
63
import { lastWeeks } from "./utils" ;
@@ -419,15 +419,15 @@ const TemplateUsagePanel: FC<TemplateUsagePanelProps> = ({
419
419
...panelProps
420
420
} ) => {
421
421
const theme = useTheme ( ) ;
422
- const validUsage = data ?. filter ( ( u ) => u . seconds > 0 ) ;
423
- const totalInSeconds =
424
- validUsage ?. reduce ( ( total , usage ) => total + usage . seconds , 0 ) ?? 1 ;
425
- const usageColors = chroma
426
- . scale ( [ theme . roles . success . fill . solid , theme . roles . notice . fill . solid ] )
427
- . mode ( "lch" )
428
- . colors ( validUsage ?. length ?? 0 ) ;
422
+ const usage = data
423
+ ?. filter ( ( u ) => u . seconds > 0 )
424
+ . sort ( ( a , b ) => b . seconds - a . seconds ) ;
425
+ const colors = chroma
426
+ . scale ( [ theme . palette . primary . dark , "#FFF" ] )
427
+ . classes ( usage ?. length ?? 0 )
428
+ . colors ( usage ?. length ?? 0 ) ;
429
429
// The API returns a row for each app, even if the user didn't use it.
430
- const hasDataAvailable = validUsage && validUsage . length > 0 ;
430
+ const hasDataAvailable = usage && usage . length > 0 ;
431
431
432
432
return (
433
433
< Panel { ...panelProps } css = { { overflowY : "auto" } } >
@@ -438,88 +438,86 @@ const TemplateUsagePanel: FC<TemplateUsagePanelProps> = ({
438
438
{ ! data && < Loader css = { { height : "100%" } } /> }
439
439
{ data && ! hasDataAvailable && < NoDataAvailable /> }
440
440
{ data && hasDataAvailable && (
441
- < div
442
- css = { {
443
- display : "flex" ,
444
- flexDirection : "column" ,
445
- gap : 24 ,
446
- } }
447
- >
448
- { validUsage
449
- . sort ( ( a , b ) => b . seconds - a . seconds )
450
- . map ( ( usage , i ) => {
451
- const percentage = ( usage . seconds / totalInSeconds ) * 100 ;
452
- return (
453
- < div
454
- key = { usage . slug }
455
- css = { { display : "flex" , gap : 24 , alignItems : "center" } }
456
- >
441
+ < Stack direction = "row" spacing = { 4 } alignItems = "center" >
442
+ < div
443
+ css = { {
444
+ padding : "0 16px" ,
445
+ width : 360 ,
446
+ } }
447
+ >
448
+ < AppUsageChart usage = { usage } colors = { colors } />
449
+ </ div >
450
+ < div
451
+ css = { { flex : 1 , display : "grid" , gridAutoRows : "1fr" , gap : 8 } }
452
+ >
453
+ { usage . map ( ( usage , i ) => (
454
+ < Stack
455
+ key = { usage . slug }
456
+ direction = "row"
457
+ alignItems = "center"
458
+ justifyContent = "space-between"
459
+ >
460
+ < div css = { { display : "flex" , alignItems : "center" } } >
457
461
< div
458
- css = { { display : "flex" , alignItems : "center" , gap : 8 } }
459
- >
460
- < div
461
- css = { {
462
- width : 20 ,
463
- height : 20 ,
464
- display : "flex" ,
465
- alignItems : "center" ,
466
- justifyContent : "center" ,
467
- } }
468
- >
469
- < img
470
- src = { usage . icon }
471
- alt = ""
472
- style = { {
473
- objectFit : "contain" ,
474
- width : "100%" ,
475
- height : "100%" ,
476
- } }
477
- />
478
- </ div >
479
- < div css = { { fontSize : 13 , fontWeight : 500 , width : 200 } } >
480
- { usage . display_name }
481
- </ div >
482
- </ div >
483
- < LinearProgress
484
- value = { percentage }
485
- variant = "determinate"
486
462
css = { {
487
- width : "100%" ,
463
+ width : 8 ,
488
464
height : 8 ,
489
- backgroundColor : theme . palette . divider ,
490
- "& .MuiLinearProgress-bar" : {
491
- backgroundColor : usageColors [ i ] ,
492
- borderRadius : 999 ,
493
- } ,
465
+ borderRadius : 999 ,
466
+ backgroundColor : colors [ i ] ,
467
+ marginRight : 16 ,
494
468
} }
495
469
/>
496
- < Stack
497
- spacing = { 0 }
470
+ < div
498
471
css = { {
499
- fontSize : 13 ,
500
- color : theme . palette . text . secondary ,
501
- width : 120 ,
502
- flexShrink : 0 ,
503
- lineHeight : "1.5" ,
472
+ width : 20 ,
473
+ height : 20 ,
474
+ display : "flex" ,
475
+ alignItems : "center" ,
476
+ justifyContent : "center" ,
477
+ marginRight : 8 ,
504
478
} }
505
479
>
506
- { formatTime ( usage . seconds ) }
507
- { usage . times_used > 0 && (
508
- < span
509
- css = { {
510
- fontSize : 12 ,
511
- color : theme . palette . text . disabled ,
512
- } }
513
- >
514
- Opened { usage . times_used . toLocaleString ( ) } { " " }
515
- { usage . times_used === 1 ? "time" : "times" }
516
- </ span >
517
- ) }
518
- </ Stack >
480
+ < img
481
+ src = { usage . icon }
482
+ alt = ""
483
+ style = { {
484
+ objectFit : "contain" ,
485
+ width : "100%" ,
486
+ height : "100%" ,
487
+ } }
488
+ />
489
+ </ div >
490
+ < div css = { { fontSize : 13 , fontWeight : 500 , width : 200 } } >
491
+ { usage . display_name }
492
+ </ div >
519
493
</ div >
520
- ) ;
521
- } ) }
522
- </ div >
494
+ < Stack
495
+ spacing = { 0 }
496
+ css = { {
497
+ fontSize : 13 ,
498
+ color : theme . palette . text . secondary ,
499
+ width : 120 ,
500
+ flexShrink : 0 ,
501
+ lineHeight : "1.5" ,
502
+ } }
503
+ >
504
+ { formatTime ( usage . seconds ) }
505
+ { usage . times_used > 0 && (
506
+ < span
507
+ css = { {
508
+ fontSize : 12 ,
509
+ color : theme . palette . text . disabled ,
510
+ } }
511
+ >
512
+ Opened { usage . times_used . toLocaleString ( ) } { " " }
513
+ { usage . times_used === 1 ? "time" : "times" }
514
+ </ span >
515
+ ) }
516
+ </ Stack >
517
+ </ Stack >
518
+ ) ) }
519
+ </ div >
520
+ </ Stack >
523
521
) }
524
522
</ PanelContent >
525
523
</ Panel >
0 commit comments