Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 182 additions & 0 deletions web-server/src/content/DoraMetrics/DoraCards/SkeletalCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
import { Paper, Grid, Divider, useTheme } from '@mui/material';
import Link from 'next/link';
import { FC, useEffect } from 'react';

import { FlexBox } from '@/components/FlexBox';
import { Line } from '@/components/Text';
import { useBoolState } from '@/hooks/useEasyState';
import { OPEN_IN_NEW_TAB_PROPS } from '@/utils/url';

import { LoaderCore } from '../DoraMetricsBody';

const ANIMATON_DURATION = 1000;

export const DataStillSyncing = () => {
const flickerAnimation = useBoolState();

useEffect(() => {
const flickerInterval = setInterval(
flickerAnimation.toggle,
ANIMATON_DURATION
);

return () => {
clearInterval(flickerInterval);
};
}, [flickerAnimation.toggle]);
return (
<FlexBox col gap2>
<ScoreSkeleton />
<LoaderCore />
<Divider />
<Grid container spacing={4}>
<Grid item xs={12} md={6} order={1}>
<SkeletalCard animation={flickerAnimation.value} />
</Grid>
<Grid item xs={12} md={6} order={2}>
<SkeletalCard animation={flickerAnimation.value} />
</Grid>
<Grid item xs={12} md={6} order={3}>
<SkeletalCard animation={flickerAnimation.value} />
</Grid>
<Grid item xs={12} md={6} order={4}>
<SkeletalCard animation={flickerAnimation.value} />
</Grid>
</Grid>
</FlexBox>
);
};

const SkeletalCard: FC<{ animation?: boolean }> = ({ animation }) => {
return (
<FlexBox
minHeight={'15em'}
component={Paper}
col
relative
width={'100%'}
flexGrow={1}
overflow={'hidden'}
height={'100%'}
p={2}
>
<FlexBox
col
justifyBetween
height={'100%'}
sx={{
filter: `brightness(${animation ? 0.7 : 1})`,
transition: `all ${ANIMATON_DURATION}ms linear`
}}
>
<FlexBox fullWidth justifyBetween>
<FlexBox gap1>
<Skeleton width="200px" />
<Skeleton width="30px" />
</FlexBox>
<Skeleton width="75px" />
</FlexBox>
<FlexBox col gap2>
<Skeleton width="100px" height="20px" />
<Skeleton width="200px" />
<Skeleton width="100px" height="20px" />
</FlexBox>
</FlexBox>
</FlexBox>
);
};

const ScoreSkeleton: FC<{ animation?: boolean }> = ({ animation }) => {
const theme = useTheme();
const stats = {
avg: 2,
standard: 6.3,
lt: 4,
df: 5,
cfr: 6,
mttr: 7
};

return (
<FlexBox>
<FlexBox centered gap={1.5}>
<FlexBox col>
<Line bigish bold white>
Your DORA
</Line>
<Line bigish bold white>
Performance
</Line>
</FlexBox>

<FlexBox
col
height={'50px'}
centered
gap={'14px'}
ml={1}
sx={{
filter: `brightness(${animation ? 0.7 : 1})`,
transition: `all ${ANIMATON_DURATION}ms linear`
}}
>
<Skeleton height="12px" width="90px" />
<Skeleton height="12px" width="90px" />
</FlexBox>

<FlexBox col ml={4}>
<Line bigish bold white>
Industry
</Line>
<Line bigish bold white>
Standard
</Line>
</FlexBox>

<FlexBox
corner={theme.spacing(1)}
px={1.5}
sx={{
background: `linear-gradient(30deg,#8C7CF0, #3E2EA4)`
}}
>
<Line fontSize={'2.4em'} bold white>
{stats.standard}{' '}
<Line fontSize="0.8rem" ml="-4px">
/ 10
</Line>
</Line>
</FlexBox>

<FlexBox col>
<Line bigish medium>
Based on data available
</Line>
<Line bigish>
at{' '}
<Line info semibold>
<Link
href="https://dora.dev/quickcheck"
{...OPEN_IN_NEW_TAB_PROPS}
>
dora.dev
</Link>
</Line>
</Line>
</FlexBox>
</FlexBox>
</FlexBox>
);
};

const Skeleton: FC<{ width?: string; height?: string }> = ({
width = '150px',
height = '30px'
}) => (
<FlexBox
height={height}
bgcolor={'#262E5E'}
width={width}
borderRadius={'20px'}
/>
);
47 changes: 24 additions & 23 deletions web-server/src/content/DoraMetrics/DoraMetricsBody.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Grid, Divider, Button } from '@mui/material';
import Link from 'next/link';
import { useEffect, useMemo } from 'react';
import { FC, useEffect, useMemo } from 'react';

import { DoraMetricsConfigurationSettings } from '@/components/DoraMetricsConfigurationSettings';
import { DoraScore } from '@/components/DoraScore';
Expand Down Expand Up @@ -30,6 +30,7 @@ import { ClassificationPills } from './ClassificationPills';
import { ChangeFailureRateCard } from './DoraCards/ChangeFailureRateCard';
import { ChangeTimeCard } from './DoraCards/ChangeTimeCard';
import { MeanTimeToRestoreCard } from './DoraCards/MeanTimeToRestoreCard';
import { DataStillSyncing } from './DoraCards/SkeletalCard';
import { WeeklyDeliveryVolumeCard } from './DoraCards/WeeklyDeliveryVolumeCard';

export const DoraMetricsBody = () => {
Expand Down Expand Up @@ -103,22 +104,7 @@ export const DoraMetricsBody = () => {
);
if (!firstLoadDone) return <MiniLoader label={getRandomLoadMsg()} />;
if (isTeamInsightsEmpty)
if (isSyncing)
return (
<EmptyState
type="SYNC_IN_PROGRESS"
title="Sync in progress"
desc={
<FlexBox gap={1}>
<MiniLoader
label={'Your repos are syncing, please wait for a few minutes'}
/>
</FlexBox>
}
>
<FixedContentRefreshLoader show={isLoading} />
</EmptyState>
);
if (isSyncing) return <DataStillSyncing />;
else
return (
<EmptyState
Expand Down Expand Up @@ -224,9 +210,9 @@ export const useSyncedRepos = () => {
};
};

const ANIMATON_DURATION = 700;
const ANIMATON_DURATION = 1000;

const Syncing = () => {
export const Syncing = () => {
const flickerAnimation = useBoolState(false);
const { isSyncing } = useSyncedRepos();

Expand All @@ -240,11 +226,26 @@ const Syncing = () => {

return (
<FlexBox
gap={4}
sx={{
height: isSyncing ? '66px' : '0px',
opacity: flickerAnimation.value ? 1 : 0.6,
transition: `all ${isSyncing ? ANIMATON_DURATION : 200}ms linear`
mb: isSyncing ? 0 : -2,
transition: `opacity ${ANIMATON_DURATION}ms linear, height 300ms ease, margin 300ms ease`
}}
>
<LoaderCore animation={flickerAnimation.value} />
</FlexBox>
);
};

export const LoaderCore: FC<{
animation?: boolean;
}> = ({ animation }) => {
return (
<FlexBox
gap={4}
sx={{
transition: `opacity ${ANIMATON_DURATION}ms linear, height 300ms ease, margin 300ms ease`,
opacity: !animation ? 1 : 0.6
}}
overflow={'hidden'}
>
Expand All @@ -267,7 +268,7 @@ const Syncing = () => {
height={'100%'}
/>
<FlexBox height={'25px'} centered>
{isSyncing && <LoadingWrapper />}
{<LoadingWrapper />}
</FlexBox>
<Line color={'#1AE579'} medium big>
Calculating Dora
Expand Down
15 changes: 15 additions & 0 deletions web-server/src/slices/dora_metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ export const doraMetricsSlice = createSlice({
'deploymentPrs',
(state, action) => (state.deploymentPrs = action.payload)
);
addFetchCasesToReducer(
builder,
getSyncedRepos,
'bookmarkedRepos',
(state, action) => (state.bookmarkedRepos = action.payload)
);
}
});

Expand Down Expand Up @@ -207,3 +213,12 @@ export const fetchDeploymentPRs = createAsyncThunk(
return await handleApi<PR[]>(`/internal/deployments/prs`, { params });
}
);

export const getSyncedRepos = createAsyncThunk(
'dora_metrics/getSyncedRepos',
async (params: { team_id: ID }) => {
return await handleApi<ID[]>(
`/resources/teams/${params.team_id}/bookmarked_repos`
);
}
);