Skip to content

Commit

Permalink
Merge pull request #2924 from the-deep/feature/project-summary-rest-g…
Browse files Browse the repository at this point in the history
…raphql

Implement graphql query to fetch project stats (summary)
  • Loading branch information
AdityaKhatri authored May 15, 2024
2 parents 13a37a7 + ae5890b commit 4643781
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 32 deletions.
34 changes: 23 additions & 11 deletions app/views/Home/Activity/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
import {
_cs,
compareDate,
isNotDefined,
} from '@togglecorp/fujs';
import {
AreaChart,
Expand All @@ -20,13 +21,19 @@ import {
} from '@the-deep/deep-ui';

import RechartsLegend from '#components/RechartsLegend';
import { ProjectRecentActivity } from '#types';
import {
ProjectStatSummaryQuery,
} from '#generated/types';

import styles from './styles.css';

type RecentEntriesActivitiesType = NonNullable<NonNullable<ProjectStatSummaryQuery>['userProjectStatSummary']>['recentEntriesActivities'];
type ProjectDetailsType = NonNullable<
NonNullable<ProjectStatSummaryQuery['userProjectStatSummary']>['recentEntriesProjectDetails']>;

function mergeItems<T>(
list: T[],
keySelector: (a: T) => string | number,
keySelector: (a: T) => number,
merge: (a: T, b: T) => T,
) {
const items: { [key: string]: T } = {
Expand Down Expand Up @@ -68,26 +75,31 @@ const dateFormatter = (value: number | string) => {

interface Props {
className?: string;
data?: ProjectRecentActivity;
data?: RecentEntriesActivitiesType;
projectDetails?: ProjectDetailsType;
}

function Activity(props: Props) {
const {
className,
data,
projectDetails,
} = props;

const areaData = useMemo(
() => {
const activitiesByDate: {
if (isNotDefined(data)) {
return undefined;
}

const activitiesByDate: ({
date: number;
[key: number]: number;
}[] = data?.activities.map((item) => ({
[+item.project]: item.count,
[key: string]: number;
}[]) = data?.map((item) => ({
[item.projectId]: item.count,
date: new Date(item.date).getTime(),
})) ?? [];

// NOTE: using projectId as key to read multiple projects' count
return mergeItems(
activitiesByDate,
(item) => item.date,
Expand All @@ -97,13 +109,13 @@ function Activity(props: Props) {
}),
).sort((a, b) => compareDate(a.date, b.date));
},
[data?.activities],
[data],
);

return (
<Card className={_cs(className, styles.activity)}>
<ResponsiveContainer className={styles.container}>
{(areaData.length > 0) ? (
{(areaData && areaData.length > 0) ? (
<AreaChart data={areaData}>
<defs>
{colorScheme.map((color) => (
Expand Down Expand Up @@ -149,7 +161,7 @@ function Activity(props: Props) {
align="left"
content={RechartsLegend}
/>
{data?.projects.map((p, index) => {
{projectDetails?.map((p, index) => {
const color = colorScheme[index % colorScheme.length];
const fillColorScheme = `${color.substring(1)}-gradient`;

Expand Down
20 changes: 11 additions & 9 deletions app/views/Home/Summary/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@ import {

import _ts from '#ts';

import { ProjectsSummary } from '#types';
import {
ProjectStatSummaryQuery,
} from '#generated/types';

import styles from './styles.css';

type SummaryResponseType = NonNullable<ProjectStatSummaryQuery>['userProjectStatSummary']

interface Props {
className?: string;
summaryResponse?: ProjectsSummary;
summaryResponse?: SummaryResponseType;
}

function Summary(props: Props) {
Expand All @@ -31,11 +35,9 @@ function Summary(props: Props) {
summaryResponse,
} = props;

const {
totalLeadsCount: total = 0,
totalLeadsTaggedCount: tagged = 0,
totalLeadsTaggedAndVerifiedCount: verified = 0,
} = summaryResponse ?? {};
const total = summaryResponse?.totalLeadsCount;
const tagged = summaryResponse?.totalLeadsTaggedCount ?? 0;
const verified = summaryResponse?.totalLeadsTaggedAndControlledCount ?? 0;

const taggedPercent = total ? (tagged / total) * 100 : 0;
const verifiedPercent = total ? (verified / total) * 100 : 0;
Expand All @@ -50,14 +52,14 @@ function Summary(props: Props) {
<InformationCard
icon={<IoDocumentTextOutline />}
label={_ts('home', 'projects')}
value={summaryResponse?.projectsCount}
value={summaryResponse?.projectsCount ?? 0}
variant="complement1"
coloredBackground
/>
<InformationCard
icon={<IoBookmarkOutline />}
label={_ts('home', 'totalAddedSources')}
value={summaryResponse?.totalLeadsCount}
value={summaryResponse?.totalLeadsCount ?? 0}
variant="accent"
coloredBackground
/>
Expand Down
46 changes: 34 additions & 12 deletions app/views/Home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import {
useModalState,
} from '@the-deep/deep-ui';

import { useRequest } from '#base/utils/restRequest';

import { Project } from '#base/types/project';
import PageContent from '#components/PageContent';
import ProjectSelectInput from '#components/selections/ProjectSelectInput';
Expand All @@ -30,11 +28,12 @@ import {
FetchProjectQueryVariables,
UserPinnedProjectsQuery,
UserPinnedProjectsQueryVariables,
ProjectStatSummaryQuery,
ProjectStatSummaryQueryVariables,
} from '#generated/types';

import SmartButtonLikeLink from '#base/components/SmartButtonLikeLink';
import { PROJECT_DETAIL_FRAGMENT } from '#gqlFragments';
import { ProjectsSummary } from '#types';

import ProjectItem, { RecentProjectItemProps } from './ProjectItem';
import Summary from './Summary';
Expand Down Expand Up @@ -77,6 +76,27 @@ query userPinnedProjects {
}
`;

const PROJECT_STAT_SUMMARY = gql`
query ProjectStatSummary {
userProjectStatSummary {
projectsCount
recentEntriesActivities {
count
date
projectId
}
recentEntriesProjectDetails {
count
id
title
}
totalLeadsCount
totalLeadsTaggedAndControlledCount
totalLeadsTaggedCount
}
}
`;

type ProjectDetail = NonNullable<FetchProjectQuery>['project'];
export type PinnedProjectDetailType = NonNullable<UserPinnedProjectsQuery>['userPinnedProjects'][number];

Expand Down Expand Up @@ -104,6 +124,7 @@ function Home(props: ViewProps) {
const [projects, setProjects] = useState<
Pick<Project, 'id' | 'title' | 'isPrivate'>[] | undefined | null
>(undefined);

const [
pinButtonDisabled,
setPinButtonDisabled,
Expand Down Expand Up @@ -133,6 +154,12 @@ function Home(props: ViewProps) {
},
);

const {
data: summaryResponse,
} = useQuery<ProjectStatSummaryQuery, ProjectStatSummaryQueryVariables>(
PROJECT_STAT_SUMMARY,
);

const [
pinnedProjects,
setPinnedProjects,
Expand Down Expand Up @@ -165,13 +192,6 @@ function Home(props: ViewProps) {
)
), [pinnedProjectsResponse]);

const {
response: summaryResponse,
} = useRequest<ProjectsSummary>({
url: 'server://projects-stat/summary/',
method: 'GET',
});

const recentProjects: ProjectDetail[] | undefined = useMemo(() => {
if (recentProjectsResponse?.recentProjects) {
return recentProjectsResponse.recentProjects;
Expand Down Expand Up @@ -266,7 +286,7 @@ function Home(props: ViewProps) {
>
<Summary
className={styles.summary}
summaryResponse={summaryResponse}
summaryResponse={summaryResponse?.userProjectStatSummary}
/>
<Container
className={styles.projectTaggingActivity}
Expand All @@ -276,7 +296,9 @@ function Home(props: ViewProps) {
spacing="loose"
>
<Activity
data={summaryResponse?.recentEntriesActivity}
data={summaryResponse?.userProjectStatSummary?.recentEntriesActivities}
projectDetails={summaryResponse?.userProjectStatSummary
?.recentEntriesProjectDetails ?? []}
/>
</Container>
<Container
Expand Down

0 comments on commit 4643781

Please sign in to comment.