-
Notifications
You must be signed in to change notification settings - Fork 432
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #377 from tailwarden/feature/tech-800
Cost explorer widget + API plugged for Cloud Map & Resources Manager
- Loading branch information
Showing
20 changed files
with
1,043 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
dashboard/components/dashboard/components/cost-explorer/DashboardCostExplorer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import DashboardCostExplorerCard from './DashboardCostExplorerCard'; | ||
import DashboardCostExplorerError from './DashboardCostExplorerError'; | ||
import DashboardCostExplorerSkeleton from './DashboardCostExplorerSkeleton'; | ||
import useCostExplorer from './hooks/useCostExplorer'; | ||
|
||
function DashboardCostExplorer() { | ||
const { | ||
loading, | ||
data, | ||
error, | ||
fetch, | ||
queryGroup, | ||
setQueryGroup, | ||
queryGranularity, | ||
setQueryGranularity, | ||
queryDate, | ||
setQueryDate | ||
} = useCostExplorer(); | ||
|
||
if (loading) return <DashboardCostExplorerSkeleton />; | ||
|
||
if (error) return <DashboardCostExplorerError fetch={fetch} />; | ||
|
||
return ( | ||
<DashboardCostExplorerCard | ||
data={data} | ||
queryGroup={queryGroup} | ||
setQueryGroup={setQueryGroup} | ||
queryGranularity={queryGranularity} | ||
setQueryGranularity={setQueryGranularity} | ||
queryDate={queryDate} | ||
setQueryDate={setQueryDate} | ||
/> | ||
); | ||
} | ||
|
||
export default DashboardCostExplorer; |
109 changes: 109 additions & 0 deletions
109
dashboard/components/dashboard/components/cost-explorer/DashboardCostExplorerCard.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { | ||
Chart as ChartJS, | ||
CategoryScale, | ||
LinearScale, | ||
BarElement, | ||
Title, | ||
Tooltip, | ||
Legend | ||
} from 'chart.js'; | ||
import { Dispatch, SetStateAction } from 'react'; | ||
import { Bar } from 'react-chartjs-2'; | ||
import Select from '../select/Select'; | ||
import { | ||
CostExplorerQueryDateProps, | ||
CostExplorerQueryGranularityProps, | ||
CostExplorerQueryGroupProps, | ||
DashboardCostExplorerData | ||
} from './hooks/useCostExplorer'; | ||
import useCostExplorerChart from './hooks/useCostExplorerChart'; | ||
|
||
ChartJS.register( | ||
CategoryScale, | ||
LinearScale, | ||
BarElement, | ||
Title, | ||
Tooltip, | ||
Legend | ||
); | ||
|
||
type DashboardCostExplorerCardProps = { | ||
data: DashboardCostExplorerData | undefined; | ||
queryGroup: CostExplorerQueryGroupProps; | ||
setQueryGroup: Dispatch<SetStateAction<CostExplorerQueryGroupProps>>; | ||
queryGranularity: CostExplorerQueryGranularityProps; | ||
setQueryGranularity: Dispatch< | ||
SetStateAction<CostExplorerQueryGranularityProps> | ||
>; | ||
queryDate: CostExplorerQueryDateProps; | ||
setQueryDate: Dispatch<SetStateAction<CostExplorerQueryDateProps>>; | ||
}; | ||
|
||
function DashboardCostExplorerCard({ | ||
data, | ||
queryGroup, | ||
setQueryGroup, | ||
queryGranularity, | ||
setQueryGranularity, | ||
queryDate, | ||
setQueryDate | ||
}: DashboardCostExplorerCardProps) { | ||
const { | ||
chartData, | ||
options, | ||
groupBySelect, | ||
granularitySelect, | ||
dateSelect, | ||
handleFilterChange | ||
} = useCostExplorerChart({ | ||
data, | ||
setQueryGroup, | ||
queryGranularity, | ||
setQueryGranularity, | ||
setQueryDate | ||
}); | ||
|
||
return ( | ||
<div className="w-full rounded-lg bg-white py-4 px-6 pb-6"> | ||
<div className=" -mx-6 flex flex-wrap items-center justify-between gap-4 border-b border-black-200/40 px-6 pb-4"> | ||
<div> | ||
<p className="text-sm font-semibold text-black-900">Cost explorer</p> | ||
<div className="mt-1"></div> | ||
<p className="text-xs text-black-300"> | ||
Visualise, understand, and manage your infrastructure costs and | ||
usage | ||
</p> | ||
</div> | ||
<div className="flex w-full flex-col gap-4 md:w-auto md:flex-row"> | ||
<Select | ||
label="Group by" | ||
options={groupBySelect.values} | ||
value={queryGroup} | ||
displayValues={groupBySelect.displayValues} | ||
onChange={e => handleFilterChange(e, 'group')} | ||
/> | ||
<Select | ||
label="Granularity" | ||
options={granularitySelect.values} | ||
value={queryGranularity} | ||
displayValues={granularitySelect.displayValues} | ||
onChange={e => handleFilterChange(e, 'granularity')} | ||
/> | ||
<Select | ||
label="Period" | ||
options={dateSelect.values} | ||
value={queryDate} | ||
displayValues={dateSelect.displayValues} | ||
onChange={e => handleFilterChange(e, 'date')} | ||
/> | ||
</div> | ||
</div> | ||
<div className="mt-8"></div> | ||
<div className="h-full min-h-[22rem]"> | ||
{chartData && <Bar data={chartData} options={options} />} | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default DashboardCostExplorerCard; |
83 changes: 83 additions & 0 deletions
83
dashboard/components/dashboard/components/cost-explorer/DashboardCostExplorerError.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import Button from '../../../button/Button'; | ||
import { | ||
CostExplorerQueryGranularityProps, | ||
CostExplorerQueryGroupProps | ||
} from './hooks/useCostExplorer'; | ||
|
||
type DashboardCostExplorerErrorProps = { | ||
fetch: ( | ||
provider?: CostExplorerQueryGroupProps, | ||
granularity?: CostExplorerQueryGranularityProps, | ||
startDate?: string, | ||
endDate?: string | ||
) => void; | ||
}; | ||
|
||
function DashboardCostExplorerError({ | ||
fetch | ||
}: DashboardCostExplorerErrorProps) { | ||
const rows: number[] = Array.from(Array(8).keys()); | ||
|
||
return ( | ||
<div className="w-full rounded-lg bg-white py-4 px-6 pb-6"> | ||
<div className="-mx-6 flex items-center justify-center gap-6 border-b border-black-200/40 px-6 pb-4"> | ||
<p className="text-sm text-black-400"> | ||
There was an error loading the cost explorer. | ||
</p> | ||
<div className="flex-shrink-0"> | ||
<Button style="outline" size="sm" onClick={() => fetch()}> | ||
<svg | ||
xmlns="http://www.w3.org/2000/svg" | ||
width="16" | ||
height="16" | ||
fill="none" | ||
viewBox="0 0 24 24" | ||
> | ||
<path | ||
stroke="currentColor" | ||
strokeLinecap="round" | ||
strokeLinejoin="round" | ||
strokeWidth="1.5" | ||
d="M22 12c0 5.52-4.48 10-10 10s-8.89-5.56-8.89-5.56m0 0h4.52m-4.52 0v5M2 12C2 6.48 6.44 2 12 2c6.67 0 10 5.56 10 5.56m0 0v-5m0 5h-4.44" | ||
></path> | ||
</svg> | ||
Try again | ||
</Button> | ||
</div> | ||
<div className="h-[60px]"></div> | ||
</div> | ||
<div className="mt-8"></div> | ||
<div className="h-[22rem]"> | ||
<table className="h-[90%] w-full table-auto"> | ||
<tbody> | ||
{rows.map(idx => ( | ||
<tr key={idx}> | ||
<td className="border-black-150 border"></td> | ||
<td className="border-black-150 border"></td> | ||
<td className="border-black-150 border"></td> | ||
<td className="border-black-150 border"></td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</table> | ||
<div className="mt-4"></div> | ||
<div className="flex justify-center gap-8"> | ||
<div className="flex items-center gap-2"> | ||
<div className="h-5 w-5 rounded-full bg-black-200/50"></div> | ||
<div className="h-3 w-24 rounded-lg bg-black-200/50"></div> | ||
</div> | ||
<div className="flex items-center gap-2"> | ||
<div className="h-5 w-5 rounded-full bg-black-200/50"></div> | ||
<div className="h-3 w-12 rounded-lg bg-black-200/50"></div> | ||
</div> | ||
<div className="flex items-center gap-2"> | ||
<div className="h-5 w-5 rounded-full bg-black-200/50"></div> | ||
<div className="h-3 w-36 rounded-lg bg-black-200/50"></div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default DashboardCostExplorerError; |
51 changes: 51 additions & 0 deletions
51
dashboard/components/dashboard/components/cost-explorer/DashboardCostExplorerSkeleton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
function DashboardCostExplorerSkeleton() { | ||
const rows: number[] = Array.from(Array(8).keys()); | ||
return ( | ||
<div className="w-full animate-pulse rounded-lg bg-white py-4 px-6 pb-6"> | ||
<div className="-mx-6 flex flex-wrap items-center justify-between border-b border-black-200/40"> | ||
<div className="px-6 pb-4"> | ||
<div className="h-3 w-24 rounded-lg bg-komiser-200/50"></div> | ||
<div className="mt-2"></div> | ||
<div className="h-3 w-36 rounded-lg bg-komiser-200/50"></div> | ||
</div> | ||
<div className="flex flex-col gap-4 px-6 pb-4 md:flex-row md:flex-wrap"> | ||
<div className="h-[60px] w-[177.5px] rounded-lg bg-komiser-200/50"></div> | ||
<div className="h-[60px] w-[177.5px] rounded-lg bg-komiser-200/50"></div> | ||
<div className="h-[60px] w-[177.5px] rounded-lg bg-komiser-200/50"></div> | ||
</div> | ||
</div> | ||
<div className="mt-8"></div> | ||
<div className="h-[22rem]"> | ||
<table className="h-[90%] w-full table-auto"> | ||
<tbody> | ||
{rows.map(idx => ( | ||
<tr key={idx}> | ||
<td className="border-black-150 border"></td> | ||
<td className="border-black-150 border"></td> | ||
<td className="border-black-150 border"></td> | ||
<td className="border-black-150 border"></td> | ||
</tr> | ||
))} | ||
</tbody> | ||
</table> | ||
<div className="mt-4"></div> | ||
<div className="flex justify-center gap-8"> | ||
<div className="flex items-center gap-2"> | ||
<div className="h-5 w-5 rounded-full bg-komiser-200/50"></div> | ||
<div className="h-3 w-24 rounded-lg bg-komiser-200/50"></div> | ||
</div> | ||
<div className="flex items-center gap-2"> | ||
<div className="h-5 w-5 rounded-full bg-komiser-200/50"></div> | ||
<div className="h-3 w-12 rounded-lg bg-komiser-200/50"></div> | ||
</div> | ||
<div className="flex items-center gap-2"> | ||
<div className="h-5 w-5 rounded-full bg-komiser-200/50"></div> | ||
<div className="h-3 w-36 rounded-lg bg-komiser-200/50"></div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default DashboardCostExplorerSkeleton; |
Oops, something went wrong.