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
13 changes: 5 additions & 8 deletions web-server/src/components/OverlayComponents/TeamEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ import { FC } from 'react';
import { CRUDProps } from '@/components/Teams/CreateTeams';

import { FlexBox } from '../FlexBox';
import { useOverlayPage } from '../OverlayPageContext';
import { CreateEditTeams } from '../Teams/CreateTeams';

export const TeamEdit: FC<CRUDProps> = ({
teamId,
hideCardComponents,
onSave,
onDiscard
}) => {
export const TeamEdit: FC<CRUDProps> = ({ teamId, hideCardComponents }) => {
const { removeAll } = useOverlayPage();
return (
<FlexBox>
<CreateEditTeams
teamId={teamId}
hideCardComponents={hideCardComponents}
onDiscard={onDiscard}
onSave={onSave}
onDiscard={removeAll}
onSave={removeAll}
/>
</FlexBox>
);
Expand Down
52 changes: 44 additions & 8 deletions web-server/src/components/TeamsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import {
import { useSnackbar } from 'notistack';
import pluralize from 'pluralize';
import { ascend } from 'ramda';
import { FC, MouseEventHandler, useCallback, useMemo } from 'react';
import { FC, MouseEventHandler, useCallback, useEffect, useMemo } from 'react';

import { Integration } from '@/constants/integrations';
import { ROUTES } from '@/constants/routes';
import { FetchState } from '@/constants/ui-states';
import { useAuth } from '@/hooks/useAuth';
import { useBoolState, useEasyState } from '@/hooks/useEasyState';
import { deleteTeam, fetchTeams } from '@/slices/team';
Expand Down Expand Up @@ -47,27 +48,62 @@ export const TeamsList = () => {
}, [searchQuery.value, teamsArray]);

const showCreate = useBoolState(false);
const showCreateTeam = useCallback(() => {
const handleShowCreateTeam = useCallback(() => {
depFn(showCreate.toggle);
}, [showCreate.toggle]);

const isLoadingTeams = useSelector(
(state) =>
state.team?.requests?.teams === FetchState.REQUEST ||
state.team?.requests?.orgRepos === FetchState.REQUEST
);
const animateFlicker = useBoolState(false);

useEffect(() => {
if (isLoadingTeams) {
const flickerInterval = setInterval(() => {
depFn(animateFlicker.toggle);
}, 500);
return () => clearInterval(flickerInterval);
}
}, [animateFlicker.toggle, isLoadingTeams]);

return (
<>
<SearchFilter
searchQuery={searchQuery.value}
onChange={searchQuery.set}
showCreateTeam={showCreateTeam}
handleShowCreateTeam={handleShowCreateTeam}
showCreate={showCreate.value}
/>
{!teamsArrayFiltered.length && teamsArray.length ? (
<FlexBox fullWidth>
<Line secondary>No teams found</Line>
</FlexBox>
) : null}
<FlexBox gap={4} grid gridTemplateColumns={'1fr 1fr '} maxWidth={'900px'}>
<FlexBox
gap={4}
grid
gridTemplateColumns={'1fr 1fr '}
maxWidth={'900px'}
relative
sx={{
opacity: isLoadingTeams ? (animateFlicker.value ? 0.2 : 0.5) : 1,
transition: 'opacity 0.5s linear'
}}
>
{teamsArrayFiltered.map((team, index) => (
<TeamCard onEdit={showCreate.false} key={index} team={team} />
))}
{isLoadingTeams && (
<FlexBox
fullWidth
height={'100%'}
sx={{ position: 'absolute' }}
top={0}
left={0}
/>
)}
</FlexBox>
</>
);
Expand All @@ -76,9 +112,9 @@ export const TeamsList = () => {
const SearchFilter: FC<{
searchQuery: string;
onChange: (value: string) => void;
showCreateTeam: () => void;
handleShowCreateTeam: () => void;
showCreate: boolean;
}> = ({ searchQuery, onChange, showCreateTeam, showCreate }) => {
}> = ({ searchQuery, onChange, handleShowCreateTeam, showCreate }) => {
return (
<FlexBox col gap={4}>
<FlexBox width={'900px'} gap={4}>
Expand All @@ -95,7 +131,7 @@ const SearchFilter: FC<{
<FlexBox flex1 alignCenter gap={4}>
<FlexBox flex1>
<Button
onClick={showCreateTeam}
onClick={handleShowCreateTeam}
sx={{ width: '100%' }}
variant="outlined"
>
Expand All @@ -117,7 +153,7 @@ const SearchFilter: FC<{
</FlexBox>
</FlexBox>
</FlexBox>
{showCreate && <CreateEditTeams onDiscard={showCreateTeam} />}
{showCreate && <CreateEditTeams onDiscard={handleShowCreateTeam} />}
</FlexBox>
);
};
Expand Down
60 changes: 46 additions & 14 deletions web-server/src/content/DoraMetrics/DoraMetricsBody.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,36 @@ export const DoraMetricsBody = () => {

const stats = useDoraStats();

const { isFreshOrg } = useFreshOrgCalculator();

if (!firstLoadDone) return <MiniLoader label={getRandomLoadMsg()} />;

if (isTeamInsightsEmpty)
return (
<EmptyState
type="NO_DATA_IN_DORA_METRICS"
title="Dora's not exploring today"
desc="We couldn't find any data to present. Perhaps you need to configure team repos."
>
<Link passHref href={ROUTES.TEAMS.PATH}>
<Button variant="contained" size="small">
Check Team Repos
</Button>
</Link>
<FixedContentRefreshLoader show={isLoading} />
</EmptyState>
);
if (isFreshOrg)
return (
<EmptyState
type="SYNC_IN_PROGRESS"
title="Sync in progress"
desc="Your data is syncing. Please reload in a few minutes."
>
<FixedContentRefreshLoader show={isLoading} />
</EmptyState>
);
else
return (
<EmptyState
type="NO_DATA_IN_DORA_METRICS"
title="Dora's not exploring today"
desc="We couldn't find any data to present. Perhaps you need to configure team repos."
>
<Link passHref href={ROUTES.TEAMS.PATH}>
<Button variant="contained" size="small">
Check Team Repos
</Button>
</Link>
<FixedContentRefreshLoader show={isLoading} />
</EmptyState>
);

return (
<FlexBox col gap2>
Expand Down Expand Up @@ -144,3 +157,22 @@ export const DoraMetricsBody = () => {
</FlexBox>
);
};

const FRESH_ORG_THRESHOLD = 5; // in minutes

export const useFreshOrgCalculator = () => {
const result = { isFreshOrg: false };
const { org } = useAuth();
const createdAt = org?.created_at;
if (!createdAt) return result;
result.isFreshOrg = calculateIsFreshOrg(createdAt);
return result;
};

export const calculateIsFreshOrg = (createdAt: string | Date): boolean => {
const now = Date.now();
const date = new Date(createdAt);
const timeDiffMs = now - date.getTime();

return timeDiffMs <= FRESH_ORG_THRESHOLD * 60 * 1000;
};