Skip to content

Commit

Permalink
feat: update entity detail page to view entities from other catalogs (#…
Browse files Browse the repository at this point in the history
…573) (#590)

* feat: update entity detail page to view entities from other catalogs (#573)

* refactor: catalog response entity (#573)

---------

Co-authored-by: Fran McDade <[email protected]>
  • Loading branch information
frano-m and Fran McDade authored Mar 14, 2024
1 parent ea95366 commit 76d78f2
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 19 deletions.
23 changes: 23 additions & 0 deletions packages/data-explorer-ui/src/apis/azul/common/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,35 @@
* Set of end point paths accepted by Azul.
*/
export enum APIEndpoints {
CATALOGS = "/index/catalogs",
FETCH = "/fetch", // Required in path for entity matrix downloads and direct file downloads
FILES = "/files",
INDEX_STATUS = "/health/progress",
SUMMARY = "/summary",
}

/**
* Model of response returned from /index/catalogs API endpoint.
*/
export interface AzulCatalogResponse {
catalogs: AzulCatalogs;
default_catalog: string;
}

/**
* Model of catalog returned from Azul catalogs endpoint (e.g. index/catalogs).
*/
export interface AzulCatalog {
internal: boolean;
}

/**
* Model of catalogs returned from Azul catalogs endpoint (e.g. index/catalogs).
*/
export interface AzulCatalogs {
[key: string]: AzulCatalog;
}

/**
* Model of index (list) responses from Azul, such as projects (index/projects), samples (index/samples) and
* files (index/files).
Expand Down
57 changes: 43 additions & 14 deletions packages/data-explorer-ui/src/entity/api/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
*/
// TODO move to Azul APIs section
import {
APIEndpoints,
AzulCatalogResponse,
AzulEntitiesResponse,
AzulListParams,
AzulSummaryResponse,
Expand Down Expand Up @@ -48,17 +50,22 @@ export const fetchEntitiesFromQuery = async (
/**
* Recursively call the endpoint to get a list of entities. This will iterate over the entity list until the next entity comes null
* @param apiPath - Path that will be used to compose the API url
* @param accessToken - Access token.
* @param catalog - Catalog.
* @param listParams - Params to be used on the request.
* @returns @see ListResponseType
*/
export const fetchAllEntities = async (
apiPath: string
apiPath: string,
accessToken: string | undefined,
catalog?: string,
listParams?: AzulListParams
): Promise<AzulEntitiesResponse> => {
const listParams = {};
const result = await fetchEntitiesFromQuery(
apiPath,
listParams,
undefined,
undefined
listParams ?? {},
catalog,
accessToken
);
let hits = result.hits;
let nextPage = result.pagination.next;
Expand All @@ -72,34 +79,56 @@ export const fetchAllEntities = async (
return { ...result, hits } as AzulEntitiesResponse;
};

/**
* Fetch all catalogs and default catalog from given URL.
* @returns name of the default catalog and all available catalogs.
*/
export const fetchCatalog = async (): Promise<AzulCatalogResponse> => {
const res = await api().get(APIEndpoints.CATALOGS);
return res.data;
};

/**
* Request to get a single project.
* @param id - entity's uuid.
* @param apiPath - API endpoint URL.
* @param catalog - Catalog.
* @param accessToken - Access token.
* @param defaultParams - Default parameters.
* @param swallow404 - Swallow 404 error.
* @returns @see ProjectResponse
*/
export const fetchEntityDetail = async (
id: string,
apiPath: string,
catalog: string | undefined,
accessToken: string | undefined,
defaultParams = getDefaultDetailParams()
defaultParams = getDefaultDetailParams(),
swallow404 = false
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- this response type can't be determined beforehand
): Promise<any> => {
const catalogParam = catalog ? { [AZUL_PARAM.CATALOG]: catalog } : undefined;
const options = getAxiosRequestOptions(accessToken);
const baseURL = getEntityURL();
const res = await api(baseURL).get(
`${apiPath}/${id}?${convertUrlParams({
...defaultParams,
...catalogParam,
})}`,
options
);
return res.data;
return await api(baseURL)
.get(
`${apiPath}/${id}?${convertUrlParams({
...defaultParams,
...catalogParam,
})}`,
options
)
.then((res) => {
return res.data;
})
.catch((error) => {
if (swallow404) {
// skipping 404 error.
console.log(`Building stub page for ${id}.`);
} else {
throw error;
}
});
};

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/data-explorer-ui/src/entity/common/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ export const configureInterceptors = (api: AxiosInstance): void => {
return new Promise((resolve) => {
setTimeout(() => resolve(api(config)), waitingTime);
});
} else {
return Promise.reject(error);
}

Promise.reject(error);
}
);
};
Expand Down
8 changes: 6 additions & 2 deletions packages/data-explorer-ui/src/entity/service/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import { FilterState } from "../../hooks/useCategoryFilter";
export interface EntityService {
fetchAllEntities: (
apiPath: string,
accessToken: string | undefined
accessToken: string | undefined,
catalog?: string,
listParams?: AzulListParams
) => Promise<AzulEntitiesResponse>;

fetchEntitiesFromQuery: (
Expand All @@ -40,9 +42,11 @@ export interface EntityService {
apiPath: string,
catalog: string | undefined,
accessToken: string | undefined,
defaultParams?:
defaultParams:
| DataSourceConfig["defaultDetailParams"]
| DataSourceConfig["defaultParams"]
| undefined,
swallow404?: boolean
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This type can't be known before hand
) => Promise<any>;

Expand Down
2 changes: 1 addition & 1 deletion packages/data-explorer-ui/src/hooks/useFetchEntity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const useFetchEntity = <T,>(
useEffect(() => {
// Fetch entity if entity data originates from a request, and has not yet been requested.
if (shouldFetchEntity && uuid) {
run(fetchEntityDetail(uuid, path, catalog, token));
run(fetchEntityDetail(uuid, path, catalog, token, undefined));
}
}, [catalog, fetchEntityDetail, path, run, shouldFetchEntity, token, uuid]);

Expand Down
21 changes: 21 additions & 0 deletions packages/data-explorer-ui/src/hooks/useUpdateURLCatalogParam.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Router, { useRouter } from "next/router";
import { useEffect } from "react";
import { useExploreState } from "./useExploreState";

/**
* Updates URL catalog params.
*/
export const useUpdateURLCatalogParams = (): void => {
const { exploreState } = useExploreState();
const { basePath, pathname, query } = useRouter();
const { catalogState } = exploreState;

useEffect(() => {
if (!catalogState) return;
if ("catalog" in query && query.catalog === catalogState) return;
Router.replace({
pathname: pathname?.replace(basePath, ""),
query: { ...query, catalog: catalogState },
});
}, [basePath, catalogState, pathname, query]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useConfig } from "../../hooks/useConfig";
import { useCurrentDetailTab } from "../../hooks/useCurrentDetailTab";
import { useEntityHeadTitle } from "../../hooks/useEntityHeadTitle";
import { useFetchEntity } from "../../hooks/useFetchEntity";
import { useUpdateURLCatalogParams } from "../../hooks/useUpdateURLCatalogParam";

// eslint-disable-next-line @typescript-eslint/no-explicit-any -- this data type can't be determined beforehand
export interface EntityDetailViewProps<T = any> {
Expand All @@ -34,6 +35,7 @@ function getTabs(entity: EntityConfig): Tab[] {
}

export const EntityDetailView = (props: EntityDetailViewProps): JSX.Element => {
useUpdateURLCatalogParams();
const { currentTab, route: tabRoute } = useCurrentDetailTab();
const { response } = useFetchEntity(props);
const { push, query } = useRouter();
Expand Down

0 comments on commit 76d78f2

Please sign in to comment.