From a90e554dbbd6229003cf50b4e7635da535801a53 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 29 Jan 2025 14:03:28 +0100 Subject: [PATCH 1/8] feat(1-3281): begin stubbing out some stuff --- .../NetworkTrafficUsage.tsx | 17 ++ .../NetworkTrafficUsage/PeriodSelector.tsx | 201 ++++++++++++------ 2 files changed, 157 insertions(+), 61 deletions(-) diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx index 041f9b9eabfb..e3fd0af38c8d 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx @@ -165,6 +165,9 @@ const NewNetworkTrafficUsage: FC = () => { record, newPeriod, setNewPeriod, + selectablePeriods, + period, + setPeriod, toTrafficUsageSum, calculateOverageCost, calculateEstimatedMonthlyCost, @@ -209,6 +212,7 @@ const NewNetworkTrafficUsage: FC = () => { const data = newToChartData(traffic.usage); + // these states can also be calculated without useEffect const [usageTotal, setUsageTotal] = useState(0); const [overageCost, setOverageCost] = useState(0); @@ -291,6 +295,19 @@ const NewNetworkTrafficUsage: FC = () => { overageCost={overageCost} estimatedMonthlyCost={estimatedMonthlyCost} /> + + setPeriod(e.target.value)} - style={{ - minWidth: '100%', - marginBottom: theme.spacing(2), - }} - formControlStyles={{ width: '100%' }} - /> { return selectablePeriods; }; -// function SingleSelectConfigButton({ onChange, ...props }) { -// const [anchorEl, setAnchorEl] = useState(); -// const [recentlyClosed, setRecentlyClosed] = useState(false); - -// const handleChange = (value: T) => { -// onChange(value); -// setAnchorEl(null); -// props.onClose?.(); - -// setRecentlyClosed(true); -// // this is a hack to prevent the button from being -// // auto-clicked after you select an item by pressing enter -// // in the search bar for single-select lists. -// setTimeout(() => setRecentlyClosed(false), 1); -// }; - -// return ( -// -// {...props} onChange={handleChange} /> -// -// ); -// } - const Wrapper = styled('article')(({ theme }) => ({ - borderRadius: theme.shape.borderRadiusLarge, - border: `2px solid ${theme.palette.divider}`, + // borderRadius: theme.shape.borderRadiusLarge, + // border: `2px solid ${theme.palette.divider}`, + width: dropdownWidth, padding: theme.spacing(3), display: 'flex', flexFlow: 'column', @@ -184,19 +161,46 @@ type Props = { const StyledPopover = styled(Popover)(({ theme }) => ({ '& .MuiPaper-root': { - borderRadius: `${theme.shape.borderRadiusMedium}px`, + // borderRadius: `${theme.shape.borderRadiusMedium}px`, + borderRadius: theme.shape.borderRadiusLarge, + border: `2px solid ${theme.palette.divider}`, }, })); -const DropdownButton: FC = (props) => { +export const PeriodSelector: FC = ({ selectedPeriod, setPeriod }) => { + const selectablePeriods = getSelectablePeriods(); + const { locationSettings } = useLocationSettings(); + + const rangeOptions = [3, 6, 12].map((monthsBack) => ({ + value: monthsBack, + label: `Last ${monthsBack} months`, + })); + const [open, setOpen] = useState(false); const ref = useRef(null); + + const selectPeriod = (period: ChartDataSelection) => { + setPeriod(period); + setOpen(false); + }; + + const buttonText = + selectedPeriod.grouping === 'daily' + ? selectedPeriod.month === format(new Date(), 'yyyy-MM') + ? 'Current month' + : new Date(selectedPeriod.month).toLocaleDateString('en-US', { + month: 'long', + year: 'numeric', + }) + : `Last ${selectedPeriod.monthsBack} months`; + return ( setOpen(false)} anchorOrigin={{ vertical: 'bottom', - horizontal: 'left', + horizontal: 'center', }} transformOrigin={{ vertical: 'top', - horizontal: 'left', + horizontal: 'center', }} > - PeriodSelecto + + +
+

Select month

+

Last 12 months

+
+ + {selectablePeriods.map((period, index) => ( +
  • + +
  • + ))} +
    +
    + +

    Range

    + + + {rangeOptions.map((option) => ( +
  • + +
  • + ))} +
    +
    +
    {' '}
    ); }; - -export const PeriodSelector: FC = ({ selectedPeriod, setPeriod }) => { - const selectablePeriods = getSelectablePeriods(); - - const rangeOptions = [3, 6, 12].map((monthsBack) => ({ - value: monthsBack, - label: `Last ${monthsBack} months`, - })); - - return ( -
    - - - -
    -

    Select month

    -

    Last 12 months

    -
    - - {selectablePeriods.map((period, index) => ( -
  • - -
  • - ))} -
    -
    - -

    Range

    - - - {rangeOptions.map((option) => ( -
  • - -
  • - ))} -
    -
    -
    {' '} -
    - ); -}; From b58cf08b17abe84bedc2e407e327f7cd3317fa1b Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 29 Jan 2025 14:38:11 +0100 Subject: [PATCH 3/8] feat(1-3281): minor adjustments --- .../NetworkTrafficUsage/PeriodSelector.tsx | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx index 53b94618fc0b..30c751590199 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx @@ -94,6 +94,9 @@ const Wrapper = styled('article')(({ theme }) => ({ 'button:hover': { backgroundColor: theme.palette.action.hover, }, + 'button:focus': { + outline: `2px solid ${theme.palette.primary.main}`, + }, })); const MonthSelector = styled('article')(({ theme }) => ({ @@ -144,16 +147,6 @@ const RangeList = styled('ul')(({ theme }) => ({ }, })); -type Selection = - | { - type: 'month'; - value: string; - } - | { - type: 'range'; - monthsBack: number; - }; - type Props = { selectedPeriod: ChartDataSelection; setPeriod: (period: ChartDataSelection) => void; @@ -161,9 +154,8 @@ type Props = { const StyledPopover = styled(Popover)(({ theme }) => ({ '& .MuiPaper-root': { - // borderRadius: `${theme.shape.borderRadiusMedium}px`, borderRadius: theme.shape.borderRadiusLarge, - border: `2px solid ${theme.palette.divider}`, + border: `1px solid ${theme.palette.divider}`, }, })); @@ -205,6 +197,10 @@ export const PeriodSelector: FC = ({ selectedPeriod, setPeriod }) => { fontWeight: 'normal', color: theme.palette.text.primary, borderColor: theme.palette.divider, + borderWidth: '2px', + ':focus-within': { + borderColor: theme.palette.primary.main, + }, })} variant='outlined' disableRipple From 99d39833ac0ee192e1ae8915e3048ef92a8476a1 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 29 Jan 2025 14:41:28 +0100 Subject: [PATCH 4/8] feat(1-3281): sort hover styles --- .../admin/network/NetworkTrafficUsage/PeriodSelector.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx index 30c751590199..671f5a68240b 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx @@ -201,10 +201,13 @@ export const PeriodSelector: FC = ({ selectedPeriod, setPeriod }) => { ':focus-within': { borderColor: theme.palette.primary.main, }, + ':hover': { + borderWidth: '2px', // Prevent the border from changing width on hover + }, })} variant='outlined' disableRipple - onClick={() => setOpen(!open)} + onClick={() => setOpen(true)} > {buttonText} From da15ac41e08d8232e066fd4c5c850a1aa22d476a Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 29 Jan 2025 15:03:47 +0100 Subject: [PATCH 5/8] feat(1-3281): adjust dropdown further --- .../NetworkTrafficUsage/PeriodSelector.tsx | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx index 671f5a68240b..44b9beb4d9b0 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx @@ -1,12 +1,12 @@ -import { styled, Button, Popover, Box } from '@mui/material'; +import { styled, Button, Popover, Box, type Theme } from '@mui/material'; import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp'; import type { ChartDataSelection } from 'hooks/api/getters/useInstanceTrafficMetrics/useInstanceTrafficMetrics'; import { useRef, useState, type FC } from 'react'; -import { useLocationSettings } from 'hooks/useLocationSettings'; import { format } from 'date-fns'; const dropdownWidth = '15rem'; +const dropdownInlinePadding = (theme: Theme) => theme.spacing(3); export type Period = { key: string; @@ -69,7 +69,7 @@ const Wrapper = styled('article')(({ theme }) => ({ // borderRadius: theme.shape.borderRadiusLarge, // border: `2px solid ${theme.palette.divider}`, width: dropdownWidth, - padding: theme.spacing(3), + paddingBlock: theme.spacing(2), display: 'flex', flexFlow: 'column', gap: theme.spacing(2), @@ -91,7 +91,7 @@ const Wrapper = styled('article')(({ theme }) => ({ cursor: 'default', color: theme.palette.text.disabled, }, - 'button:hover': { + 'button:hover:not(:disabled)': { backgroundColor: theme.palette.action.hover, }, 'button:focus': { @@ -101,6 +101,7 @@ const Wrapper = styled('article')(({ theme }) => ({ const MonthSelector = styled('article')(({ theme }) => ({ border: 'none', + paddingInline: dropdownInlinePadding(theme), hgroup: { h3: { margin: 0, @@ -126,9 +127,11 @@ const MonthGrid = styled('ul')(({ theme }) => ({ const RangeSelector = styled('article')(({ theme }) => ({ display: 'flex', + width: '100%', flexFlow: 'column', - gap: theme.spacing(0.5), + gap: theme.spacing(0), h4: { + paddingInline: dropdownInlinePadding(theme), fontSize: theme.typography.body2.fontSize, margin: 0, color: theme.palette.text.secondary, @@ -137,13 +140,19 @@ const RangeSelector = styled('article')(({ theme }) => ({ const RangeList = styled('ul')(({ theme }) => ({ listStyle: 'none', + margin: 0, padding: 0, - 'li + li': { - marginTop: theme.spacing(1), + width: '100%', + li: { + width: '100%', }, button: { - marginLeft: `-${theme.spacing(0.5)}`, + width: '100%', + paddingBlock: theme.spacing(1), + textAlign: 'left', + borderRadius: 0, + paddingInline: dropdownInlinePadding(theme), }, })); @@ -161,7 +170,6 @@ const StyledPopover = styled(Popover)(({ theme }) => ({ export const PeriodSelector: FC = ({ selectedPeriod, setPeriod }) => { const selectablePeriods = getSelectablePeriods(); - const { locationSettings } = useLocationSettings(); const rangeOptions = [3, 6, 12].map((monthsBack) => ({ value: monthsBack, From 8059ee89b2cc638892895d771263bd4989fa20ee Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 29 Jan 2025 15:09:58 +0100 Subject: [PATCH 6/8] feat(1-3281): remove unused code --- .../admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx index bc89daa65f2e..d66bf8311fd3 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx @@ -165,9 +165,6 @@ const NewNetworkTrafficUsage: FC = () => { record, newPeriod, setNewPeriod, - selectablePeriods, - period, - setPeriod, toTrafficUsageSum, calculateOverageCost, calculateEstimatedMonthlyCost, @@ -212,7 +209,6 @@ const NewNetworkTrafficUsage: FC = () => { const data = newToChartData(traffic.usage); - // these states can also be calculated without useEffect const [usageTotal, setUsageTotal] = useState(0); const [overageCost, setOverageCost] = useState(0); From ac2c0eeb59d3cd4ceb4f3d28c721556e025b0d9f Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 29 Jan 2025 15:13:15 +0100 Subject: [PATCH 7/8] feat(1-3281): remove unused styles --- .../admin/network/NetworkTrafficUsage/PeriodSelector.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx index 44b9beb4d9b0..b56e421c8c62 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/PeriodSelector.tsx @@ -66,8 +66,6 @@ const getSelectablePeriods = (): Period[] => { }; const Wrapper = styled('article')(({ theme }) => ({ - // borderRadius: theme.shape.borderRadiusLarge, - // border: `2px solid ${theme.palette.divider}`, width: dropdownWidth, paddingBlock: theme.spacing(2), display: 'flex', From bfd76cfddaaa0900bbeb7abc8038ddc44926b7a5 Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Wed, 29 Jan 2025 15:13:59 +0100 Subject: [PATCH 8/8] Chore: delete line --- .../admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx index d66bf8311fd3..041f9b9eabfb 100644 --- a/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx +++ b/frontend/src/component/admin/network/NetworkTrafficUsage/NetworkTrafficUsage.tsx @@ -291,7 +291,6 @@ const NewNetworkTrafficUsage: FC = () => { overageCost={overageCost} estimatedMonthlyCost={estimatedMonthlyCost} /> -