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
4 changes: 3 additions & 1 deletion src/common/components/Table/LoadingState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ export const LoadingState = ({
<tbody>
<tr>
<td colSpan={colCount}>
{[...Array(rowCount)].map(() => (
{[...Array(rowCount)].map((k, i) => (
<Skeleton
height={rowHeight || '30px'}
width="100%"
style={{ borderRadius: 4, marginBottom: 0 }}
// eslint-disable-next-line react/no-array-index-key
key={i}
/>
))}
</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export const WorkspacesDropdown = () => {
if (!activeWorkspace || !user) return null;

return workspaces.length > 1 ? (
<DropdownItem>
<DropdownItem id="workspace-dropdown-item">
<Dropdown
inputValue={inputValue}
selectedItem={selectedItem}
Expand Down
7 changes: 6 additions & 1 deletion src/features/api/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import { stringify } from 'qs';
import { Template } from '.';
import {
GetCampaignsByCidApiResponse,
GetProjectsByPidApiResponse,
GetWorkspacesByWidApiResponse,
Template,
} from '.';

export const apiSlice = createApi({
reducerPath: 'api',
Expand Down
57 changes: 57 additions & 0 deletions src/features/api/customEndpoints/getCampaignWithWorkspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { FetchBaseQueryError } from '@reduxjs/toolkit/query';
import type {
GetProjectsByPidApiResponse,
GetWorkspacesByWidApiResponse,
GetCampaignsByCidApiResponse,
GetCampaignsByCidApiArg,
} from '..';
import { apiSlice } from '../api';

type GetCampaignWithWorkspaceResponse = {
campaign: GetCampaignsByCidApiResponse;
workspace: GetWorkspacesByWidApiResponse;
};

const extendedApi = apiSlice.injectEndpoints({
endpoints: (builder) => ({
getCampaignWithWorkspace: builder.query<
GetCampaignWithWorkspaceResponse,
GetCampaignsByCidApiArg
>({
async queryFn(_arg, _queryApi, _extraOptions, fetchWithBQ) {
// get campaign by cid to retrieve project id
const campaignResult = await fetchWithBQ(`/campaigns/${_arg.cid}`);
if (campaignResult.error)
return { error: campaignResult.error as FetchBaseQueryError };
const campaign = campaignResult.data as GetCampaignsByCidApiResponse;

// get project by pid to retrieve workspace id
const projectResult = await fetchWithBQ(
`/projects/${campaign.project.id}`
);
if (projectResult.error)
return { error: projectResult.error as FetchBaseQueryError };
const project = projectResult.data as GetProjectsByPidApiResponse;

// finally get workspace by id
const workspaceResult = await fetchWithBQ(
`/workspaces/${project.workspaceId}`
);

// return campaign with its workspace
return workspaceResult.data
? {
data: {
campaign,
workspace:
workspaceResult.data as GetWorkspacesByWidApiResponse,
},
}
: { error: workspaceResult.error as FetchBaseQueryError };
},
}),
}),
overrideExisting: false,
});

export const { useGetCampaignWithWorkspaceQuery } = extendedApi;
48 changes: 48 additions & 0 deletions src/features/api/customEndpoints/getProjectWithWorkspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { FetchBaseQueryError } from '@reduxjs/toolkit/query';
import type {
GetProjectsByPidApiResponse,
GetWorkspacesByWidApiResponse,
GetProjectsByPidApiArg,
} from '..';
import { apiSlice } from '../api';

type GetProjectWithWorkspaceResponse = {
project: GetProjectsByPidApiResponse;
workspace: GetWorkspacesByWidApiResponse;
};

const extendedApi = apiSlice.injectEndpoints({
endpoints: (builder) => ({
getProjectWithWorkspace: builder.query<
GetProjectWithWorkspaceResponse,
GetProjectsByPidApiArg
>({
async queryFn(_arg, _queryApi, _extraOptions, fetchWithBQ) {
// get project by pid to retrieve workspace id
const projectResult = await fetchWithBQ(`/projects/${_arg.pid}`);
if (projectResult.error)
return { error: projectResult.error as FetchBaseQueryError };
const project = projectResult.data as GetProjectsByPidApiResponse;

// finally get workspace by id
const workspaceResult = await fetchWithBQ(
`/workspaces/${project.workspaceId}`
);

// return project with its workspace
return workspaceResult.data
? {
data: {
project,
workspace:
workspaceResult.data as GetWorkspacesByWidApiResponse,
},
}
: { error: workspaceResult.error as FetchBaseQueryError };
},
}),
}),
overrideExisting: false,
});

export const { useGetProjectWithWorkspaceQuery } = extendedApi;
16 changes: 15 additions & 1 deletion src/pages/Bug/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useGetCampaignsByCidBugsAndBidQuery } from 'src/features/api';
import { Grid, Row, Col } from '@appquality/unguess-design-system';
import { Page } from 'src/features/templates/Page';
import { useLocalizeRoute } from 'src/hooks/useLocalizedRoute';
import { LayoutWrapper } from 'src/common/components/LayoutWrapper';
import { useGetCampaignWithWorkspaceQuery } from 'src/features/api/customEndpoints/getCampaignWithWorkspace';
import { setWorkspace } from 'src/features/navigation/navigationSlice';
import { useAppDispatch } from 'src/app/hooks';
import { Header } from './Header';
import { Content } from './Content';
import { LoadingSkeleton } from './LoadingSkeleton';

const Bug = () => {
const { campaignId, bugId } = useParams();
const navigate = useNavigate();
const dispatch = useAppDispatch();
const notFoundRoute = useLocalizeRoute('oops');
const [showSkeleton, setShowSkeleton] = useState(true);

Expand Down Expand Up @@ -41,6 +45,16 @@ const Bug = () => {
}
);

const { data: { workspace } = {} } = useGetCampaignWithWorkspaceQuery({
cid: campaignId,
});

useEffect(() => {
if (workspace) {
dispatch(setWorkspace(workspace));
}
}, [workspace]);

if (showSkeleton && (isLoading || isFetching)) {
return <LoadingSkeleton />;
}
Expand Down
11 changes: 10 additions & 1 deletion src/pages/Bugs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useCampaign } from './useCampaign';
import {
setCampaignId,
setPermissionSettingsTitle,
setWorkspace,
} from '../../features/navigation/navigationSlice';

const Bugs = () => {
Expand All @@ -26,7 +27,9 @@ const Bugs = () => {
}
useCampaignAnalytics(campaignId);

const { isLoading, isError, campaign } = useCampaign(Number(campaignId));
const { isLoading, isError, campaign, workspace } = useCampaign(
Number(campaignId)
);

useEffect(() => {
if (campaign) {
Expand All @@ -45,6 +48,12 @@ const Bugs = () => {
};
}, [campaign]);

useEffect(() => {
if (workspace) {
dispatch(setWorkspace(workspace));
}
}, [workspace, dispatch]);

if (isError) {
navigate(notFoundRoute);
}
Expand Down
8 changes: 5 additions & 3 deletions src/pages/Bugs/useCampaign.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
useGetCampaignsByCidDevicesQuery,
useGetCampaignsByCidOsQuery,
useGetCampaignsByCidPrioritiesQuery,
useGetCampaignsByCidQuery,
useGetCampaignsByCidReplicabilitiesQuery,
useGetCampaignsByCidSeveritiesQuery,
useGetCampaignsByCidTagsQuery,
Expand All @@ -21,6 +20,7 @@ import { OsFilterType } from 'src/features/bugsPage/osFilter';
import { ReplicabilityFilterType } from 'src/features/bugsPage/replicabilityFilter';
import { PriorityFilterType } from 'src/features/bugsPage/priorityFilter';
import { CustomStatusFilterType } from 'src/features/bugsPage/customStatusFilter';
import { useGetCampaignWithWorkspaceQuery } from 'src/features/api/customEndpoints/getCampaignWithWorkspace';

export const useCampaign = (cid: number) => {
const [campaignData, setCampaignData] = useState<{
Expand All @@ -43,8 +43,8 @@ export const useCampaign = (cid: number) => {
isLoading: isLoadingCampaign,
isFetching: isFetchingCampaign,
isError: isErrorCampaign,
data: campaign,
} = useGetCampaignsByCidQuery({
data: { campaign, workspace } = {},
} = useGetCampaignWithWorkspaceQuery({
cid: cid.toString(),
});

Expand Down Expand Up @@ -106,6 +106,7 @@ export const useCampaign = (cid: number) => {
}
}, [
campaign,
workspace,
campaignTypes,
campaignSeverities,
campaignPriorities,
Expand All @@ -121,5 +122,6 @@ export const useCampaign = (cid: number) => {
isLoading: isLoadingCampaign || isFetchingCampaign,
isError: isErrorCampaign,
campaign: campaignData,
workspace,
};
};
17 changes: 11 additions & 6 deletions src/pages/Campaign/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@ import { Page } from 'src/features/templates/Page';
import { Col, Grid, Row } from '@appquality/unguess-design-system';
import { useNavigate, useParams } from 'react-router-dom';
import { useLocalizeRoute } from 'src/hooks/useLocalizedRoute';
import {
useGetCampaignsByCidQuery,
useGetCampaignsByCidReportsQuery,
} from 'src/features/api';
import { useGetCampaignsByCidReportsQuery } from 'src/features/api';
import { useCampaignAnalytics } from 'src/hooks/useCampaignAnalytics';
import { useTranslation } from 'react-i18next';
import { LayoutWrapper } from 'src/common/components/LayoutWrapper';
import { useGetCampaignWithWorkspaceQuery } from 'src/features/api/customEndpoints/getCampaignWithWorkspace';
import CampaignPageHeader from './pageHeader';
import { HeaderLoader } from './pageHeaderLoading';
import { ReportRowLoading } from './ReportRowLoading';
Expand All @@ -29,6 +27,7 @@ import { WidgetSection } from './WidgetSection';
import {
setCampaignId,
setPermissionSettingsTitle,
setWorkspace,
} from '../../features/navigation/navigationSlice';

const Campaign = () => {
Expand All @@ -48,8 +47,8 @@ const Campaign = () => {
isLoading: isLoadingCampaign,
isFetching: isFetchingCampaign,
isError: isErrorCampaign,
data: campaign,
} = useGetCampaignsByCidQuery({
data: { campaign, workspace } = {},
} = useGetCampaignWithWorkspaceQuery({
cid: campaignId?.toString() ?? '0',
});

Expand Down Expand Up @@ -84,6 +83,12 @@ const Campaign = () => {
};
}, [campaign]);

useEffect(() => {
if (workspace) {
dispatch(setWorkspace(workspace));
}
}, [workspace, dispatch]);

return (
<Page
title={(campaign && campaign.customer_title) ?? 'Campaign'}
Expand Down
27 changes: 19 additions & 8 deletions src/pages/Dashboard/Project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ import { Grid } from '@appquality/unguess-design-system';
import { useAppDispatch } from 'src/app/hooks';
import { useNavigate, useParams } from 'react-router-dom';
import { useLocalizeRoute } from 'src/hooks/useLocalizedRoute';
import { useGetProjectsByPidQuery } from 'src/features/api';
import {
projectFilterChanged,
resetFilters,
} from 'src/features/campaignsFilter/campaignsFilterSlice';
import { useGetProjectWithWorkspaceQuery } from 'src/features/api/customEndpoints/getProjectWithWorkspace';
import { LayoutWrapper } from 'src/common/components/LayoutWrapper';
import { ProjectItems } from './project-items';
import { ProjectPageHeader } from './projectPageHeader';
import { CardRowLoading } from './CardRowLoading';
import {
setPermissionSettingsTitle,
setProjectId,
setWorkspace,
} from '../../features/navigation/navigationSlice';

const Project = () => {
Expand All @@ -30,28 +31,38 @@ const Project = () => {
navigate(notFoundRoute);
}

const project = useGetProjectsByPidQuery({
const {
data: { project, workspace } = {},
isSuccess,
isError,
} = useGetProjectWithWorkspaceQuery({
pid: projectId ?? '0',
});

useEffect(() => {
if (project.isSuccess) {
if (isSuccess) {
dispatch(resetFilters());
dispatch(projectFilterChanged(Number(projectId)));
}

if (project) {
dispatch(setPermissionSettingsTitle(project.data?.name));
dispatch(setProjectId(project.data?.id));
dispatch(setPermissionSettingsTitle(project.name));
dispatch(setProjectId(project.id));
}

return () => {
dispatch(setPermissionSettingsTitle(undefined));
dispatch(setProjectId(undefined));
};
}, [project]);
}, [project, dispatch, projectId]);

if (project.isError) {
useEffect(() => {
if (workspace) {
dispatch(setWorkspace(workspace));
}
}, [workspace, dispatch]);

if (isError) {
navigate(notFoundRoute);
}

Expand All @@ -63,7 +74,7 @@ const Project = () => {
>
<LayoutWrapper>
<Grid>
{project.isSuccess ? (
{isSuccess ? (
<ProjectItems projectId={Number(projectId) || 0} />
) : (
<CardRowLoading />
Expand Down