6
6
7
7
import { useContext , useEffect , useState } from "react" ;
8
8
import { Redirect , useLocation } from "react-router" ;
9
- import { PageWithSubMenu } from "../components/PageWithSubMenu" ;
10
9
import { getCurrentTeam , TeamsContext } from "./teams-context" ;
11
- import { getTeamSettingsMenu } from "./TeamSettings" ;
12
10
import { PaymentContext } from "../payment-context" ;
13
11
import { getGitpodService } from "../service/service" ;
14
12
import { BillableSession , BillableWorkspaceType } from "@gitpod/gitpod-protocol/lib/usage" ;
15
13
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution" ;
16
14
import { Item , ItemField , ItemsList } from "../components/ItemsList" ;
17
15
import moment from "moment" ;
18
- import Property from "../admin/Property " ;
19
- import Arrow from "../components/Arrow " ;
16
+ import Pagination from "../components/Pagination " ;
17
+ import Header from "../components/Header " ;
20
18
21
19
function TeamUsage ( ) {
22
20
const { teams } = useContext ( TeamsContext ) ;
23
- const { showPaymentUI , showUsageBasedUI } = useContext ( PaymentContext ) ;
21
+ const { showUsageBasedUI } = useContext ( PaymentContext ) ;
24
22
const location = useLocation ( ) ;
25
23
const team = getCurrentTeam ( location , teams ) ;
26
24
const [ billedUsage , setBilledUsage ] = useState < BillableSession [ ] > ( [ ] ) ;
25
+ const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
26
+ const [ resultsPerPage ] = useState ( 10 ) ;
27
27
28
28
useEffect ( ( ) => {
29
29
if ( ! team ) {
@@ -47,77 +47,100 @@ function TeamUsage() {
47
47
return "Prebuild" ;
48
48
} ;
49
49
50
- const getHours = ( endTime : number | undefined , startTime : number ) => {
51
- if ( ! endTime ) return "" ;
50
+ const getMinutes = ( endTime : number , startTime : number ) => {
51
+ return Math . floor ( endTime - startTime ) / ( 1000 * 60 ) + " min" ;
52
+ } ;
52
53
53
- return ( ( endTime - startTime ) / ( 1000 * 60 * 60 ) ) . toFixed ( 1 ) + "hrs" ;
54
+ const calculateTotalUsage = ( ) => {
55
+ let totalCredits = 0 ;
56
+ billedUsage . forEach ( ( session ) => ( totalCredits += session . credits ) ) ;
57
+ return totalCredits ;
54
58
} ;
55
59
60
+ const lastResultOnCurrentPage = currentPage * resultsPerPage ;
61
+ const firstResultOnCurrentPage = lastResultOnCurrentPage - resultsPerPage ;
62
+ const numberOfPages = Math . ceil ( billedUsage . length / resultsPerPage ) ;
63
+ const currentPaginatedResults = billedUsage . slice ( firstResultOnCurrentPage , lastResultOnCurrentPage ) ;
64
+
56
65
return (
57
- < PageWithSubMenu
58
- subMenu = { getTeamSettingsMenu ( { team, showPaymentUI, showUsageBasedUI } ) }
59
- title = "Usage"
60
- subtitle = "Manage team usage."
61
- >
62
- < div className = "flex flex-col w-full" >
63
- < div className = "flex w-full mt-6 mb-6" >
64
- < Property name = "Last 30 days" > Jun 1 - June 30</ Property >
65
- < Property name = "Workspaces" > 4,200 Min</ Property >
66
- < Property name = "Prebuilds" > 12,334 Min</ Property >
67
- </ div >
68
- </ div >
69
- < ItemsList className = "mt-2 text-gray-500" >
70
- < Item header = { false } className = "grid grid-cols-6 bg-gray-100" >
71
- < ItemField className = "my-auto" >
72
- < span > Type</ span >
73
- </ ItemField >
74
- < ItemField className = "my-auto" >
75
- < span > Class</ span >
76
- </ ItemField >
77
- < ItemField className = "my-auto" >
78
- < span > Amount</ span >
79
- </ ItemField >
80
- < ItemField className = "my-auto" >
81
- < span > Credits</ span >
82
- </ ItemField >
83
- < ItemField className = "my-auto" />
84
- </ Item >
85
- { billedUsage . map ( ( usage ) => (
86
- < div
87
- key = { usage . instanceId }
88
- className = "flex p-3 grid grid-cols-6 justify-between transition ease-in-out rounded-xl focus:bg-gitpod-kumquat-light"
89
- >
90
- < div className = "my-auto" >
91
- < span className = { usage . workspaceType === "prebuild" ? "text-orange-400" : "text-green-500" } >
92
- { getType ( usage . workspaceType ) }
93
- </ span >
94
- </ div >
95
- < div className = "my-auto" >
96
- < span className = "text-gray-400" > { usage . workspaceClass } </ span >
97
- </ div >
98
- < div className = "my-auto" >
99
- < span className = "text-gray-700" >
100
- { getHours (
101
- usage . endTime ? new Date ( usage . endTime ) . getTime ( ) : undefined ,
102
- new Date ( usage . startTime ) . getTime ( ) ,
103
- ) }
104
- </ span >
105
- </ div >
106
- < div className = "my-auto" >
107
- < span className = "text-gray-700" > { usage . credits . toFixed ( 1 ) } </ span >
108
- </ div >
109
- < div className = "my-auto" >
110
- < span className = "text-gray-400" >
111
- { moment ( new Date ( usage . startTime ) . toDateString ( ) ) . fromNow ( ) }
112
- </ span >
113
- </ div >
114
- < div className = "pr-2" >
115
- < Arrow up = { false } />
66
+ < >
67
+ < Header title = "Usage" subtitle = "Manage team usage." />
68
+ < div className = "app-container" >
69
+ < div className = "flex space-x-16" >
70
+ < div className = "flex" >
71
+ < div className = "space-y-8 mt-6 mb-6" >
72
+ < div className = "flex flex-col truncate" >
73
+ < div className = "text-base text-gray-500 truncate" > Period</ div >
74
+ < div className = "mr-3 text-lg text-gray-600 font-semibold truncate" > June 2022</ div >
75
+ </ div >
76
+ < div className = "flex flex-col truncate" >
77
+ < div className = "text-base text-gray-500 truncate" > Monthly usage</ div >
78
+ < div className = "mr-3 text-lg text-gray-600 font-semibold truncate" >
79
+ { calculateTotalUsage ( ) } Total Credits
80
+ </ div >
81
+ </ div >
116
82
</ div >
117
83
</ div >
118
- ) ) }
119
- </ ItemsList >
120
- </ PageWithSubMenu >
84
+ < div className = "flex flex-col w-full mb-8" >
85
+ < h3 > All Usage</ h3 >
86
+ < span className = "text-gray-500 mb-5" > View usage details of all team members.</ span >
87
+ < ItemsList className = "mt-2 text-gray-500" >
88
+ < Item header = { false } className = "grid grid-cols-5 bg-gray-100 mb-5" >
89
+ < ItemField className = "my-auto" >
90
+ < span > Type</ span >
91
+ </ ItemField >
92
+ < ItemField className = "my-auto" >
93
+ < span > Class</ span >
94
+ </ ItemField >
95
+ < ItemField className = "my-auto" >
96
+ < span > Usage</ span >
97
+ </ ItemField >
98
+ < ItemField className = "my-auto" >
99
+ < span > Credits</ span >
100
+ </ ItemField >
101
+ < ItemField className = "my-auto" />
102
+ </ Item >
103
+ { currentPaginatedResults . map ( ( usage ) => (
104
+ < div
105
+ key = { usage . instanceId }
106
+ className = "flex p-3 grid grid-cols-5 justify-between transition ease-in-out rounded-xl focus:bg-gitpod-kumquat-light"
107
+ >
108
+ < div className = "my-auto" >
109
+ < span > { getType ( usage . workspaceType ) } </ span >
110
+ </ div >
111
+ < div className = "my-auto" >
112
+ < span className = "text-gray-400" > { usage . workspaceClass } </ span >
113
+ </ div >
114
+ < div className = "my-auto" >
115
+ < span className = "text-gray-700" >
116
+ { getMinutes (
117
+ new Date ( usage . endTime ) . getTime ( ) ,
118
+ new Date ( usage . startTime ) . getTime ( ) ,
119
+ ) }
120
+ </ span >
121
+ </ div >
122
+ < div className = "my-auto" >
123
+ < span className = "text-gray-700" > { usage . credits . toFixed ( 1 ) } </ span >
124
+ </ div >
125
+ < div className = "my-auto" >
126
+ < span className = "text-gray-400" >
127
+ { moment ( new Date ( usage . startTime ) . toDateString ( ) ) . fromNow ( ) }
128
+ </ span >
129
+ </ div >
130
+ </ div >
131
+ ) ) }
132
+ </ ItemsList >
133
+ { billedUsage . length > resultsPerPage && (
134
+ < Pagination
135
+ currentPage = { currentPage }
136
+ setCurrentPage = { setCurrentPage }
137
+ numberOfPages = { numberOfPages }
138
+ />
139
+ ) }
140
+ </ div >
141
+ </ div >
142
+ </ div >
143
+ </ >
121
144
) ;
122
145
}
123
146
0 commit comments