Skip to content

Commit

Permalink
feat(view): add pagination for servers with too many drives
Browse files Browse the repository at this point in the history
  • Loading branch information
MauriceNino committed Jun 15, 2022
1 parent 3cf8774 commit bb6fbfb
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 12 deletions.
65 changes: 57 additions & 8 deletions apps/view/src/components/hardware-info-container.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { faArrowLeft, faArrowRight } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { motion } from 'framer-motion';
import React, { forwardRef } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { Children, forwardRef, ReactNode, useState } from 'react';
import styled from 'styled-components';
import { useIsMobile } from '../services/mobile';
import { InfoTable, InfoTableProps } from './info-table';
Expand Down Expand Up @@ -85,26 +86,47 @@ const InfoIcon = styled.div<HardwareInfoProps>`
}
`;

const InfoHeadingContainer = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
margin: 30px 30px 10px 30px;
`;

const InfoHeading = styled(ThemedText)`
font-size: 1.5rem;
font-weight: bold;
margin: 30px 30px 10px 30px;
`;

const Controls = styled.div`
display: flex;
flex-direction: row;
gap: 15px;
svg {
cursor: pointer;
color: ${props => props.theme.colors.text};
}
`;

const IconContainer = styled(motion.div)``;

type HardwareInfoProps = {
color: string;
heading: string;
icon: IconProp;
extraContent?: JSX.Element;
columns?: number;
gap?: number;
children?: React.ReactNode;
children?: ReactNode;
infosPerPage: number;
} & InfoTableProps;

export const HardwareInfoContainer = motion(
forwardRef<HTMLDivElement, HardwareInfoProps>((props, ref) => {
const isMobile = useIsMobile();
const childrenLength = React.Children.count(props.children);
const childrenLength = Children.count(props.children);
const [page, setPage] = useState(0);

return (
<Container mobile={isMobile}>
Expand All @@ -114,9 +136,36 @@ export const HardwareInfoContainer = motion(

<ContentContainer mobile={isMobile}>
<InfoContainer>
<InfoHeading>{props.heading}</InfoHeading>

<InfoTable infos={props.infos} />
<InfoHeadingContainer>
<InfoHeading>{props.heading}</InfoHeading>

<Controls>
<AnimatePresence>
{page > 0 && (
<IconContainer layout>
<FontAwesomeIcon
icon={faArrowLeft}
onClick={() => setPage(p => p - 1)}
/>
</IconContainer>
)}
{(page + 1) * props.infosPerPage < props.infos.length && (
<IconContainer layout>
<FontAwesomeIcon
icon={faArrowRight}
onClick={() => setPage(p => p + 1)}
/>
</IconContainer>
)}
</AnimatePresence>
</Controls>
</InfoHeadingContainer>

<InfoTable
infos={props.infos}
page={page}
itemsPerPage={props.infosPerPage}
/>
</InfoContainer>

{props.extraContent}
Expand Down
37 changes: 33 additions & 4 deletions apps/view/src/components/info-table.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import { motion, Variants } from 'framer-motion';
import { FC } from 'react';
import styled from 'styled-components';
import { InfoTableArr } from '../utils/format';
import { ThemedText } from './text';

const itemVariants: Variants = {
initial: {
opacity: 0,
scale: 0.9,
},
animate: {
opacity: 1,
scale: 1,
},
};

export const InfoTextContainer = styled.div<{ noPadding?: boolean }>`
display: table;
padding: 30px;
color: ${props => props.theme.colors.text};
`;

const InfoTextRow = styled.div`
const InfoTextRow = styled(motion.div)`
display: table-row;
`;

Expand Down Expand Up @@ -37,11 +49,28 @@ export type InfoTableProps = {
className?: string;
};

export const InfoTable: FC<InfoTableProps> = props => {
export const InfoTable: FC<
InfoTableProps & {
page: number;
itemsPerPage: number;
}
> = props => {
const itemsStart = props.page * props.itemsPerPage;
const items = props.infos.slice(
itemsStart,
Math.min(itemsStart + props.itemsPerPage, props.infos.length)
);

return (
<InfoTextContainer className={props.className}>
{props.infos.map((info, i) => (
<InfoTextRow key={i.toString() + info.label}>
{items.map((info, i) => (
<InfoTextRow
key={(itemsStart + i).toString()}
variants={itemVariants}
initial='initial'
animate='animate'
exit='initial'
>
<InfoTextLabel>{info.label}</InfoTextLabel>
<InfoTextValue>
{info.value == null || info.value.trim().length === 0
Expand Down
1 change: 1 addition & 0 deletions apps/view/src/widgets/cpu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ export const CpuWidget: FC<CpuWidgetProps> = ({ load, data, config }) => {
},
]
)}
infosPerPage={7}
icon={faMicrochip}
extraContent={
<WidgetSwitch
Expand Down
1 change: 1 addition & 0 deletions apps/view/src/widgets/network.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ export const NetworkWidget: FC<NetworkWidgetProps> = ({
},
]
)}
infosPerPage={7}
icon={faNetworkWired}
>
<ChartContainer
Expand Down
1 change: 1 addition & 0 deletions apps/view/src/widgets/ram.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export const RamWidget: FC<RamWidgetProps> = ({ load, data, config }) => {
},
]
)}
infosPerPage={7}
icon={faMemory}
>
<ChartContainer
Expand Down
2 changes: 2 additions & 0 deletions apps/view/src/widgets/server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ export const ServerWidget: FC<ServerWidgetProps> = ({ data, config }) => {
dateInfos,
]
)}
page={0}
itemsPerPage={7}
/>

<ServerIcon
Expand Down
1 change: 1 addition & 0 deletions apps/view/src/widgets/storage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export const StorageWidget: FC<StorageWidgetProps> = ({
color={theme.colors.storagePrimary}
heading='Storage'
infos={infos}
infosPerPage={3}
icon={faHdd}
>
<ChartContainer
Expand Down

0 comments on commit bb6fbfb

Please sign in to comment.